EC600U_esp32_iap_uart/libwebsockets/websocket_demo.c
2024-02-05 17:39:56 +08:00

283 lines
6.9 KiB
C

/*================================================================
Copyright (c) 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
Quectel Wireless Solution Proprietary and Confidential.
=================================================================*/
/*=================================================================
EDIT HISTORY FOR MODULE
This section contains comments describing changes made to the module.
Notice that changes are listed in reverse chronological order.
WHEN WHO WHAT, WHERE, WHY
------------ ------- -------------------------------------------------------------------------------
=================================================================*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include "ql_api_osi.h"
#include "ql_api_nw.h"
#include "ql_log.h"
#include "ql_api_datacall.h"
#include "ql_ssl.h"
#include "ql_api_websocket.h"
static ql_task_t websocket_task = NULL;
#define QL_WEBSOCKET_PDP_CID 1
#define QL_WEBSOCKET_SSL_CTX_ID 1
#define WS_MAX_TEST_DATA_LEN 1360
#define WS_MAX_MSG_CNT 8
typedef enum{
QWS_EVENT_OPEN = 1001,
QWS_EVENT_RECV,
QWS_EVENT_CLOSE,
}qws_event_code_e;
typedef struct
{
int client_id;
int cfg_id;
ql_queue_t queue;
ql_mutex_t ws_lock;
}qws_ctx_t;
qws_ctx_t ws_demo_client = {0};
int ql_ws_service_cb(int client_id, qws_parm_t *cb_t)
{
int ret = QWS_OK;
ql_event_t ws_event_send = {0};
if(NULL == cb_t) goto exit;
QL_WEBSOCKET_LOG("qws service_cb %d, type=%d",client_id, cb_t->type);
switch (cb_t->type)
{
case QWS_CB_TYPE_OPEN: {
//open event
QL_WEBSOCKET_LOG("open code %d",cb_t->virtual);
ws_event_send.id = QWS_EVENT_OPEN;
ws_event_send.param1 = (uint32)client_id;
ws_event_send.param2 = (uint32)cb_t->virtual;
ret = ql_rtos_queue_release(ws_demo_client.queue, sizeof(ql_event_t), (uint8 *)&ws_event_send, 0);
if(QL_OSI_SUCCESS != ret)
{
QL_WEBSOCKET_LOG("release faild");
}
}
break;
/* recv event*/
case QWS_CB_TYPE_RECV: {
//ToDo:
//Cache and message notification processing data
QL_WEBSOCKET_LOG("recv %d, %s",cb_t->size, cb_t->data);
}
break;
case QWS_CB_TYPE_CLOSE: {
//disconnect event
//ToDo:
//Abnormal reconnection is performed later
QL_WEBSOCKET_LOG("disconn errcode %d",cb_t->virtual);
}
break;
default:
break;
}
exit:
return ret;
}
static int datacall_satrt(void)
{
int ret = 0;
int i = 0;
ql_data_call_info_s info;
char ip4_addr_str[16] = {0};
uint8_t nSim = 0;
ql_rtos_task_sleep_s(10);
QL_WEBSOCKET_LOG("========== websocket demo start ==========");
while((ret = ql_network_register_wait(nSim, 120)) != 0 && i < 10){
i++;
ql_rtos_task_sleep_s(1);
}
if(ret == 0){
i = 0;
QL_WEBSOCKET_LOG("====network registered!!!!====");
}else{
QL_WEBSOCKET_LOG("====network register failure!!!!!====");
goto exit;
}
ql_set_data_call_asyn_mode(nSim, QL_WEBSOCKET_PDP_CID, 0);
QL_WEBSOCKET_LOG("===start data call====");
ret=ql_start_data_call(nSim, QL_WEBSOCKET_PDP_CID, QL_PDP_TYPE_IP, "uninet", NULL, NULL, 0);
QL_WEBSOCKET_LOG("===data call result:%d", ret);
if(ret != 0){
QL_WEBSOCKET_LOG("====data call failure!!!!=====");
}
memset(&info, 0x00, sizeof(ql_data_call_info_s));
ret = ql_get_data_call_info(nSim, QL_WEBSOCKET_PDP_CID, &info);
if(ret != 0){
QL_WEBSOCKET_LOG("ql_get_data_call_info ret: %d", ret);
ql_stop_data_call(nSim, QL_WEBSOCKET_PDP_CID);
goto exit;
}
QL_WEBSOCKET_LOG("info->QL_WEBSOCKET_PDP_CID: %d", info.profile_idx);
QL_WEBSOCKET_LOG("info->ip_version: %d", info.ip_version);
QL_WEBSOCKET_LOG("info->v4.state: %d", info.v4.state);
inet_ntop(AF_INET, &info.v4.addr.ip, ip4_addr_str, sizeof(ip4_addr_str));
QL_WEBSOCKET_LOG("info.v4.addr.ip: %s\r\n", ip4_addr_str);
inet_ntop(AF_INET, &info.v4.addr.pri_dns, ip4_addr_str, sizeof(ip4_addr_str));
QL_WEBSOCKET_LOG("info.v4.addr.pri_dns: %s\r\n", ip4_addr_str);
inet_ntop(AF_INET, &info.v4.addr.sec_dns, ip4_addr_str, sizeof(ip4_addr_str));
QL_WEBSOCKET_LOG("info.v4.addr.sec_dns: %s\r\n", ip4_addr_str);
return 0;
exit:
return -1;
}
static void websocket_app_thread(void * arg)
{
int ret = 0;
int flags_break = 0;
uint32_t client_id = 0; /*max value QWS_CLIENT_ID_NUM*/
uint32_t cfg_id = 0; /*max value QWS_CFG_ID_NUM*/
char* test_data = NULL;
qws_open_t open_t;
ql_event_t qws_event_msg = {0};
char url[] = "ws://220.180.239.212:8189/v1";
/*step1: wait card init done and active*/
ret = datacall_satrt();
if (ret < 0) {
QL_WEBSOCKET_LOG("websocket active ret=%d", ret);
goto exit;
}
test_data = malloc(WS_MAX_TEST_DATA_LEN);
if (NULL == test_data){
goto exit;
}
ret = ql_rtos_queue_create(&ws_demo_client.queue, sizeof(ql_event_t), WS_MAX_MSG_CNT);
if (ret != QL_OSI_SUCCESS)
{
QL_WEBSOCKET_LOG("queue_create failed!!!!");
goto exit;
}
/*step2: init config */
ql_ws_cfg_set_opt(cfg_id, QWS_CFG_CONN_PDPCID, QL_WEBSOCKET_PDP_CID);
ql_ws_cfg_set_opt(cfg_id, QWS_CFG_CONN_SSLCTXID, QL_WEBSOCKET_SSL_CTX_ID);
ql_ws_cfg_set_opt(cfg_id, QWS_CFG_CONN_URL, (char *)url);
ql_ws_cfg_set_opt(cfg_id, QWS_CFG_RECV_CB, ql_ws_service_cb);
/*step3: connect open*/
memset(&open_t , 0, sizeof(qws_open_t));
open_t.cfg_id = cfg_id;
open_t.client_id = client_id;
ret = ql_ws_open_proc(&open_t);
if (ret != QWS_OK){
QL_WEBSOCKET_LOG("websocket open err=%d", ret);
goto exit;
}
//ToDo
/*step5: recv data*/
QL_WEBSOCKET_LOG("websocket running");
//ToDo:
flags_break = 0;
for (;;)
{
memset(&qws_event_msg, 0x00, sizeof(ql_event_t));
ql_rtos_queue_wait(ws_demo_client.queue, (uint8 *)&qws_event_msg, sizeof(ql_event_t), QL_WAIT_FOREVER);
switch(qws_event_msg.id)
{
case QWS_EVENT_OPEN:
{
if(QL_OSI_SUCCESS == qws_event_msg.param2)//open success
{
memset(test_data , 0, WS_MAX_TEST_DATA_LEN);
snprintf(test_data, WS_MAX_TEST_DATA_LEN, "%s", "Welcome to Websocket!");
/*step4: send data*/
qws_parm_t parm_t;
parm_t.type = QWS_WRITE_PROT_TEXT;
parm_t.data = test_data;
parm_t.size = strlen(test_data);
ret = ql_ws_write_proc(client_id, &parm_t);
if (ret != QWS_OK){
QL_WEBSOCKET_LOG("websocket write err=%d", ret);
}
}else{
flags_break = 1;
}
}
break;
case QWS_EVENT_CLOSE:
{
flags_break = 1;
}
break;
default:
break;
}
if(flags_break)
break;
}
/*step6: close exit*/
ql_ws_close_proc(client_id);
exit:
QL_WEBSOCKET_LOG("websocket task exit!");
if(test_data != NULL) free(test_data);
websocket_task = NULL;
ql_rtos_task_delete(NULL);/*self-destruction*/
return;
}
int ql_websocket_app_init(void)
{
QlOSStatus err = QL_OSI_SUCCESS;
err = ql_rtos_task_create(&websocket_task, 4*1024, APP_PRIORITY_NORMAL, "wssApp", websocket_app_thread, NULL, 5);
if(err != QL_OSI_SUCCESS)
{
QL_WEBSOCKET_LOG("websocket init failed");
}
return err;
}