websocket_demo.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /*================================================================
  2. Copyright (c) 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
  3. Quectel Wireless Solution Proprietary and Confidential.
  4. =================================================================*/
  5. /*=================================================================
  6. EDIT HISTORY FOR MODULE
  7. This section contains comments describing changes made to the module.
  8. Notice that changes are listed in reverse chronological order.
  9. WHEN WHO WHAT, WHERE, WHY
  10. ------------ ------- -------------------------------------------------------------------------------
  11. =================================================================*/
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <stdlib.h>
  15. #include <stdint.h>
  16. #include "ql_api_osi.h"
  17. #include "ql_api_nw.h"
  18. #include "ql_log.h"
  19. #include "ql_api_datacall.h"
  20. #include "ql_ssl.h"
  21. #include "ql_api_websocket.h"
  22. static ql_task_t websocket_task = NULL;
  23. #define QL_WEBSOCKET_PDP_CID 1
  24. #define QL_WEBSOCKET_SSL_CTX_ID 1
  25. #define WS_MAX_TEST_DATA_LEN 1360
  26. #define WS_MAX_MSG_CNT 8
  27. typedef enum{
  28. QWS_EVENT_OPEN = 1001,
  29. QWS_EVENT_RECV,
  30. QWS_EVENT_CLOSE,
  31. }qws_event_code_e;
  32. typedef struct
  33. {
  34. int client_id;
  35. int cfg_id;
  36. ql_queue_t queue;
  37. ql_mutex_t ws_lock;
  38. }qws_ctx_t;
  39. qws_ctx_t ws_demo_client = {0};
  40. int ql_ws_service_cb(int client_id, qws_parm_t *cb_t)
  41. {
  42. int ret = QWS_OK;
  43. ql_event_t ws_event_send = {0};
  44. if(NULL == cb_t) goto exit;
  45. QL_WEBSOCKET_LOG("qws service_cb %d, type=%d",client_id, cb_t->type);
  46. switch (cb_t->type)
  47. {
  48. case QWS_CB_TYPE_OPEN: {
  49. //open event
  50. QL_WEBSOCKET_LOG("open code %d",cb_t->virtual);
  51. ws_event_send.id = QWS_EVENT_OPEN;
  52. ws_event_send.param1 = (uint32)client_id;
  53. ws_event_send.param2 = (uint32)cb_t->virtual;
  54. ret = ql_rtos_queue_release(ws_demo_client.queue, sizeof(ql_event_t), (uint8 *)&ws_event_send, 0);
  55. if(QL_OSI_SUCCESS != ret)
  56. {
  57. QL_WEBSOCKET_LOG("release faild");
  58. }
  59. }
  60. break;
  61. /* recv event*/
  62. case QWS_CB_TYPE_RECV: {
  63. //ToDo:
  64. //Cache and message notification processing data
  65. QL_WEBSOCKET_LOG("recv %d, %s",cb_t->size, cb_t->data);
  66. }
  67. break;
  68. case QWS_CB_TYPE_CLOSE: {
  69. //disconnect event
  70. //ToDo:
  71. //Abnormal reconnection is performed later
  72. QL_WEBSOCKET_LOG("disconn errcode %d",cb_t->virtual);
  73. }
  74. break;
  75. default:
  76. break;
  77. }
  78. exit:
  79. return ret;
  80. }
  81. static int datacall_satrt(void)
  82. {
  83. int ret = 0;
  84. int i = 0;
  85. ql_data_call_info_s info;
  86. char ip4_addr_str[16] = {0};
  87. uint8_t nSim = 0;
  88. ql_rtos_task_sleep_s(10);
  89. QL_WEBSOCKET_LOG("========== websocket demo start ==========");
  90. while((ret = ql_network_register_wait(nSim, 120)) != 0 && i < 10){
  91. i++;
  92. ql_rtos_task_sleep_s(1);
  93. }
  94. if(ret == 0){
  95. i = 0;
  96. QL_WEBSOCKET_LOG("====network registered!!!!====");
  97. }else{
  98. QL_WEBSOCKET_LOG("====network register failure!!!!!====");
  99. goto exit;
  100. }
  101. ql_set_data_call_asyn_mode(nSim, QL_WEBSOCKET_PDP_CID, 0);
  102. QL_WEBSOCKET_LOG("===start data call====");
  103. ret=ql_start_data_call(nSim, QL_WEBSOCKET_PDP_CID, QL_PDP_TYPE_IP, "uninet", NULL, NULL, 0);
  104. QL_WEBSOCKET_LOG("===data call result:%d", ret);
  105. if(ret != 0){
  106. QL_WEBSOCKET_LOG("====data call failure!!!!=====");
  107. }
  108. memset(&info, 0x00, sizeof(ql_data_call_info_s));
  109. ret = ql_get_data_call_info(nSim, QL_WEBSOCKET_PDP_CID, &info);
  110. if(ret != 0){
  111. QL_WEBSOCKET_LOG("ql_get_data_call_info ret: %d", ret);
  112. ql_stop_data_call(nSim, QL_WEBSOCKET_PDP_CID);
  113. goto exit;
  114. }
  115. QL_WEBSOCKET_LOG("info->QL_WEBSOCKET_PDP_CID: %d", info.profile_idx);
  116. QL_WEBSOCKET_LOG("info->ip_version: %d", info.ip_version);
  117. QL_WEBSOCKET_LOG("info->v4.state: %d", info.v4.state);
  118. inet_ntop(AF_INET, &info.v4.addr.ip, ip4_addr_str, sizeof(ip4_addr_str));
  119. QL_WEBSOCKET_LOG("info.v4.addr.ip: %s\r\n", ip4_addr_str);
  120. inet_ntop(AF_INET, &info.v4.addr.pri_dns, ip4_addr_str, sizeof(ip4_addr_str));
  121. QL_WEBSOCKET_LOG("info.v4.addr.pri_dns: %s\r\n", ip4_addr_str);
  122. inet_ntop(AF_INET, &info.v4.addr.sec_dns, ip4_addr_str, sizeof(ip4_addr_str));
  123. QL_WEBSOCKET_LOG("info.v4.addr.sec_dns: %s\r\n", ip4_addr_str);
  124. return 0;
  125. exit:
  126. return -1;
  127. }
  128. static void websocket_app_thread(void * arg)
  129. {
  130. int ret = 0;
  131. int flags_break = 0;
  132. uint32_t client_id = 0; /*max value QWS_CLIENT_ID_NUM*/
  133. uint32_t cfg_id = 0; /*max value QWS_CFG_ID_NUM*/
  134. char* test_data = NULL;
  135. qws_open_t open_t;
  136. ql_event_t qws_event_msg = {0};
  137. char url[] = "ws://220.180.239.212:8189/v1";
  138. /*step1: wait card init done and active*/
  139. ret = datacall_satrt();
  140. if (ret < 0) {
  141. QL_WEBSOCKET_LOG("websocket active ret=%d", ret);
  142. goto exit;
  143. }
  144. test_data = malloc(WS_MAX_TEST_DATA_LEN);
  145. if (NULL == test_data){
  146. goto exit;
  147. }
  148. ret = ql_rtos_queue_create(&ws_demo_client.queue, sizeof(ql_event_t), WS_MAX_MSG_CNT);
  149. if (ret != QL_OSI_SUCCESS)
  150. {
  151. QL_WEBSOCKET_LOG("queue_create failed!!!!");
  152. goto exit;
  153. }
  154. /*step2: init config */
  155. ql_ws_cfg_set_opt(cfg_id, QWS_CFG_CONN_PDPCID, QL_WEBSOCKET_PDP_CID);
  156. ql_ws_cfg_set_opt(cfg_id, QWS_CFG_CONN_SSLCTXID, QL_WEBSOCKET_SSL_CTX_ID);
  157. ql_ws_cfg_set_opt(cfg_id, QWS_CFG_CONN_URL, (char *)url);
  158. ql_ws_cfg_set_opt(cfg_id, QWS_CFG_RECV_CB, ql_ws_service_cb);
  159. /*step3: connect open*/
  160. memset(&open_t , 0, sizeof(qws_open_t));
  161. open_t.cfg_id = cfg_id;
  162. open_t.client_id = client_id;
  163. ret = ql_ws_open_proc(&open_t);
  164. if (ret != QWS_OK){
  165. QL_WEBSOCKET_LOG("websocket open err=%d", ret);
  166. goto exit;
  167. }
  168. //ToDo
  169. /*step5: recv data*/
  170. QL_WEBSOCKET_LOG("websocket running");
  171. //ToDo:
  172. flags_break = 0;
  173. for (;;)
  174. {
  175. memset(&qws_event_msg, 0x00, sizeof(ql_event_t));
  176. ql_rtos_queue_wait(ws_demo_client.queue, (uint8 *)&qws_event_msg, sizeof(ql_event_t), QL_WAIT_FOREVER);
  177. switch(qws_event_msg.id)
  178. {
  179. case QWS_EVENT_OPEN:
  180. {
  181. if(QL_OSI_SUCCESS == qws_event_msg.param2)//open success
  182. {
  183. memset(test_data , 0, WS_MAX_TEST_DATA_LEN);
  184. snprintf(test_data, WS_MAX_TEST_DATA_LEN, "%s", "Welcome to Websocket!");
  185. /*step4: send data*/
  186. qws_parm_t parm_t;
  187. parm_t.type = QWS_WRITE_PROT_TEXT;
  188. parm_t.data = test_data;
  189. parm_t.size = strlen(test_data);
  190. ret = ql_ws_write_proc(client_id, &parm_t);
  191. if (ret != QWS_OK){
  192. QL_WEBSOCKET_LOG("websocket write err=%d", ret);
  193. }
  194. }else{
  195. flags_break = 1;
  196. }
  197. }
  198. break;
  199. case QWS_EVENT_CLOSE:
  200. {
  201. flags_break = 1;
  202. }
  203. break;
  204. default:
  205. break;
  206. }
  207. if(flags_break)
  208. break;
  209. }
  210. /*step6: close exit*/
  211. ql_ws_close_proc(client_id);
  212. exit:
  213. QL_WEBSOCKET_LOG("websocket task exit!");
  214. if(test_data != NULL) free(test_data);
  215. websocket_task = NULL;
  216. ql_rtos_task_delete(NULL);/*self-destruction*/
  217. return;
  218. }
  219. int ql_websocket_app_init(void)
  220. {
  221. QlOSStatus err = QL_OSI_SUCCESS;
  222. err = ql_rtos_task_create(&websocket_task, 4*1024, APP_PRIORITY_NORMAL, "wssApp", websocket_app_thread, NULL, 5);
  223. if(err != QL_OSI_SUCCESS)
  224. {
  225. QL_WEBSOCKET_LOG("websocket init failed");
  226. }
  227. return err;
  228. }