socket_demo.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  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 "ql_api_osi.h"
  16. #include "ql_api_nw.h"
  17. #include "ql_log.h"
  18. #include "ql_api_datacall.h"
  19. #include "sockets.h"
  20. #include "lwip/ip_addr.h"
  21. #include "lwip/ip6_addr.h"
  22. #include "lwip/netdb.h"
  23. #include "lwip/netif.h"
  24. #include "lwip/inet.h"
  25. #include "lwip/tcp.h"
  26. #include "ql_ssl.h"
  27. #define QL_SOCKET_LOG_LEVEL QL_LOG_LEVEL_INFO
  28. #define QL_SOCKET_LOG(msg, ...) QL_LOG(QL_SOCKET_LOG_LEVEL, "ql_Sock", msg, ##__VA_ARGS__)
  29. #define QL_SOCKET_LOG_PUSH(msg, ...) QL_LOG_PUSH("ql_SSL", msg, ##__VA_ARGS__)
  30. #define QL_SOCKET_DEMO_CHANGE_DEMO 0
  31. #if QL_SOCKET_DEMO_CHANGE_DEMO
  32. #define QL_SOCKET_DEMO_URL "www.baidu.com"
  33. #else
  34. #define QL_SOCKET_DEMO_URL "220.180.239.212"
  35. #endif
  36. static ql_task_t socket_demo_task = NULL;
  37. static char send_buf[128]={0};
  38. static int send_len = 0;
  39. static char recv_buf[128]={0};
  40. static int recv_len = 0;
  41. //获取socket接收缓存的剩余大小
  42. int ql_socket_get_free_size(int s,void *value)
  43. {
  44. int ret = ERR_OK;
  45. if (s < 0||value==NULL)
  46. {
  47. return -1;
  48. }
  49. *((int32_t *)value) =lwip_getRecvBufSize(s)-lwip_getRecvAvailSize(s);
  50. QL_SOCKET_LOG("socket free size:%d", *((int32_t *)value));
  51. if(*((int32_t *)value)<0)
  52. {
  53. ret = ERR_VAL;
  54. }
  55. return ret;
  56. }
  57. //获取socket发送缓存中已发送但未收到回应的数据大小
  58. int ql_socket_get_unacked_size(int s,void *value)
  59. {
  60. int ret = ERR_OK;
  61. if (s < 0||value==NULL)
  62. {
  63. return -1;
  64. }
  65. *((int32_t *)value) =lwip_getSentSize(s)-lwip_getAckedSize(s);
  66. QL_SOCKET_LOG("socket unacked size:%d", *((int32_t *)value));
  67. if(*((int32_t *)value)<0)
  68. {
  69. ret = ERR_VAL;
  70. }
  71. return ret;
  72. }
  73. static void socket_app_thread(void * arg)
  74. {
  75. int ret = 0;
  76. int i = 0;
  77. int profile_idx = 1;
  78. ql_data_call_info_s info;
  79. char ip4_addr_str[16] = {0};
  80. fd_set read_fds;
  81. fd_set write_fds;
  82. fd_set exp_fds;
  83. int socket_fd = -1;
  84. int flags = 0;
  85. int fd_changed = 0;
  86. int connected = 0;
  87. int closing = false;
  88. struct sockaddr_in local4, server_ipv4;
  89. struct addrinfo *pres = NULL;
  90. struct addrinfo *temp = NULL;
  91. uint8_t nSim = 0;
  92. ql_nw_data_count_info_s data_count_info = {0};
  93. #if QL_SOCKET_DEMO_CHANGE_DEMO
  94. ql_datacall_dns_info_s dns_pri = {0};
  95. ql_datacall_dns_info_s dns_sec = {0};
  96. #endif
  97. ql_rtos_task_sleep_s(10);
  98. QL_SOCKET_LOG("========== socket demo start ==========");
  99. QL_SOCKET_LOG("wait for network register done");
  100. while((ret = ql_network_register_wait(nSim, 120)) != 0 && i < 10){
  101. i++;
  102. ql_rtos_task_sleep_s(1);
  103. }
  104. if(ret == 0){
  105. i = 0;
  106. QL_SOCKET_LOG("====network registered!!!!====");
  107. }else{
  108. QL_SOCKET_LOG("====network register failure!!!!!====");
  109. goto exit;
  110. }
  111. ql_set_data_call_asyn_mode(nSim, profile_idx, 0);
  112. QL_SOCKET_LOG("===start data call====");
  113. ret=ql_start_data_call(nSim, profile_idx, QL_PDP_TYPE_IP, "uninet", NULL, NULL, 0);
  114. QL_SOCKET_LOG("===data call result:%d", ret);
  115. if(ret != 0){
  116. QL_SOCKET_LOG("====data call failure!!!!=====");
  117. }
  118. memset(&info, 0x00, sizeof(ql_data_call_info_s));
  119. ret = ql_get_data_call_info(nSim, profile_idx, &info);
  120. if(ret != 0){
  121. QL_SOCKET_LOG("ql_get_data_call_info ret: %d", ret);
  122. ql_stop_data_call(nSim, profile_idx);
  123. goto exit;
  124. }
  125. QL_SOCKET_LOG("info->profile_idx: %d", info.profile_idx);
  126. QL_SOCKET_LOG("info->ip_version: %d", info.ip_version);
  127. QL_SOCKET_LOG("info->v4.state: %d", info.v4.state);
  128. inet_ntop(AF_INET, &info.v4.addr.ip, ip4_addr_str, sizeof(ip4_addr_str));
  129. QL_SOCKET_LOG("info.v4.addr.ip: %s\r\n", ip4_addr_str);
  130. inet_ntop(AF_INET, &info.v4.addr.pri_dns, ip4_addr_str, sizeof(ip4_addr_str));
  131. QL_SOCKET_LOG("info.v4.addr.pri_dns: %s\r\n", ip4_addr_str);
  132. inet_ntop(AF_INET, &info.v4.addr.sec_dns, ip4_addr_str, sizeof(ip4_addr_str));
  133. QL_SOCKET_LOG("info.v4.addr.sec_dns: %s\r\n", ip4_addr_str);
  134. #if QL_SOCKET_DEMO_CHANGE_DEMO
  135. ql_datacall_get_dns_addr(nSim, profile_idx, &dns_pri, &dns_sec);
  136. QL_SOCKET_LOG("get_dns_pri:[%d][%s]", dns_pri.type, ip4addr_ntoa(&dns_pri.ip4));
  137. QL_SOCKET_LOG("get_dns_sec:[%d][%s]", dns_sec.type, ip4addr_ntoa(&dns_sec.ip4));
  138. memset(&dns_pri, 0x00, sizeof(ql_datacall_dns_info_s));
  139. dns_pri.type = QL_PDP_TYPE_IP;
  140. dns_sec.type = QL_PDP_TYPE_IP;
  141. ip4addr_aton("114.114.114.114", &(dns_pri.ip4));
  142. ip4addr_aton("8.8.8.8", &(dns_sec.ip4));
  143. ql_datacall_set_dns_addr(nSim, profile_idx, &dns_pri, &dns_sec);
  144. memset(&dns_pri, 0x00, sizeof(ql_datacall_dns_info_s));
  145. ql_datacall_get_dns_addr(nSim, profile_idx, &dns_pri, &dns_sec);
  146. QL_SOCKET_LOG("get_dns_pri:[%d][%s]", dns_pri.type, ip4addr_ntoa(&dns_pri.ip4));
  147. QL_SOCKET_LOG("get_dns_sec:[%d][%s]", dns_sec.type, ip4addr_ntoa(&dns_sec.ip4));
  148. #endif
  149. memset(&local4, 0x00, sizeof(struct sockaddr_in));
  150. local4.sin_family = AF_INET;
  151. local4.sin_port = 0;
  152. inet_aton(ip4addr_ntoa(&info.v4.addr.ip), &local4.sin_addr);
  153. loop:
  154. ret = getaddrinfo_with_pcid(QL_SOCKET_DEMO_URL, NULL, NULL, &pres, (uint32)profile_idx);
  155. if (ret < 0 || pres == NULL)
  156. {
  157. QL_SOCKET_LOG("DNS getaddrinfo failed! ret=%d; pres=%p!\n",ret,pres);
  158. goto exit;
  159. }
  160. FD_ZERO(&read_fds);
  161. FD_ZERO(&write_fds);
  162. FD_ZERO(&exp_fds);
  163. flags = 0;
  164. connected = 0;
  165. closing = false;
  166. i = 0;
  167. for(temp = pres; temp != NULL; temp = temp->ai_next){
  168. struct sockaddr_in * sin_res = (struct sockaddr_in *)temp->ai_addr;
  169. if(temp->ai_family == AF_INET){
  170. socket_fd = socket(temp->ai_family, SOCK_STREAM, 0);
  171. if(socket_fd < 0){
  172. continue;
  173. }
  174. ret = bind(socket_fd,(struct sockaddr *)&local4,sizeof(struct sockaddr));
  175. if(ret < 0){
  176. close(socket_fd);
  177. socket_fd = -1;
  178. continue;
  179. }
  180. flags |= O_NONBLOCK;
  181. fcntl(socket_fd, F_SETFL,flags);
  182. memset(&server_ipv4, 0x00, sizeof(struct sockaddr_in));
  183. server_ipv4.sin_family = temp->ai_family;
  184. server_ipv4.sin_port = htons(8252);
  185. server_ipv4.sin_addr = sin_res->sin_addr;
  186. ret = connect(socket_fd, (struct sockaddr *)&server_ipv4, sizeof(server_ipv4));
  187. if(ret == 0){
  188. connected = 1;
  189. break;
  190. }else{
  191. if(lwip_get_error(socket_fd) != EINPROGRESS){
  192. close(socket_fd);
  193. socket_fd = -1;
  194. continue;
  195. }else{
  196. break;
  197. }
  198. }
  199. }
  200. }
  201. if(socket_fd < 0){
  202. goto exit;
  203. }
  204. if(connected == 1){
  205. FD_SET(socket_fd, &read_fds);
  206. QL_SOCKET_LOG("=====connect to \"220.180.239.212:8252\" success=====");
  207. memset(send_buf, 0x00, 128);
  208. send_len = snprintf(send_buf, 128,"%d%s%d\r\n",i,"startAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAend",i);
  209. if(write(socket_fd, send_buf, send_len) != send_len){
  210. FD_SET(socket_fd, &write_fds);
  211. }else{
  212. i++;
  213. }
  214. }else{
  215. FD_SET(socket_fd, &write_fds);
  216. }
  217. FD_SET(socket_fd, &exp_fds);
  218. while(1){
  219. fd_changed = select(socket_fd+1, &read_fds, &write_fds, &exp_fds, NULL);
  220. if(fd_changed > 0){
  221. if(FD_ISSET(socket_fd, &write_fds)){
  222. FD_CLR(socket_fd, &write_fds);
  223. if(connected== 0){
  224. int value = 0;
  225. int len = 0;
  226. len = sizeof(value);
  227. getsockopt(socket_fd, SOL_SOCKET, SO_ERROR, &value, &len);
  228. QL_SOCKET_LOG("errno: %d", value);
  229. if(value == 0 || value == EISCONN ){
  230. QL_SOCKET_LOG("=====connect to \"220.180.239.212:8252\" success=====");
  231. connected = 1;
  232. FD_SET(socket_fd, &read_fds);
  233. memset(send_buf, 0x00, 128);
  234. send_len = snprintf(send_buf, 128,"%d%s%d\r\n",i,"startAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAend",i);
  235. write(socket_fd, send_buf, send_len);
  236. i++;
  237. }else{
  238. QL_SOCKET_LOG("=====connect to \"220.180.239.212:8252\" failed=====");
  239. close(socket_fd);
  240. socket_fd = -1;
  241. break;
  242. }
  243. }else{
  244. memset(send_buf, 0x00, 128);
  245. send_len = snprintf(send_buf, 128,"%d%s%d\r\n",i,"startAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAend",i);
  246. write(socket_fd, send_buf, send_len);
  247. i++;
  248. }
  249. }else if(FD_ISSET(socket_fd, &read_fds)){
  250. FD_CLR(socket_fd, &read_fds);
  251. memset(recv_buf,0x00, 128);
  252. recv_len = read(socket_fd, recv_buf, 128);
  253. if(recv_len > 0){
  254. QL_SOCKET_LOG(">>>>Recv: %s", recv_buf);
  255. memset(send_buf, 0x00, 128);
  256. send_len = snprintf(send_buf, 128,"%d%s%d\r\n",i,"startAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAend",i);
  257. write(socket_fd, send_buf, send_len);
  258. i++;
  259. FD_SET(socket_fd, &read_fds);
  260. if(ql_nw_get_data_count(nSim, &data_count_info) == 0)
  261. {
  262. QL_SOCKET_LOG("data count: uplink %llu, downlink %llu", data_count_info.uplink_data_count, data_count_info.downlink_data_count);
  263. }
  264. }else if(recv_len == 0){
  265. if(closing == false){
  266. QL_SOCKET_LOG("===passive close!!!!");
  267. shutdown(socket_fd, SHUT_WR);
  268. closing = true;
  269. FD_SET(socket_fd, &read_fds);
  270. }else{
  271. close(socket_fd);
  272. socket_fd = -1;
  273. break;
  274. }
  275. }else{
  276. if(lwip_get_error(socket_fd) == EAGAIN){
  277. FD_SET(socket_fd, &read_fds);
  278. }else{
  279. close(socket_fd);
  280. socket_fd = -1;
  281. break;
  282. }
  283. }
  284. }else if(FD_ISSET(socket_fd, &exp_fds)){
  285. FD_CLR(socket_fd, &exp_fds);
  286. close(socket_fd);
  287. socket_fd = -1;
  288. break;
  289. }
  290. }
  291. }
  292. if(pres!=NULL)
  293. {
  294. freeaddrinfo(pres);
  295. pres = NULL;
  296. }
  297. goto loop;
  298. exit:
  299. ql_rtos_task_delete(socket_demo_task);
  300. return;
  301. }
  302. int ql_socket_app_init(void)
  303. {
  304. QlOSStatus err = QL_OSI_SUCCESS;
  305. err = ql_rtos_task_create(&socket_demo_task, 16*1024, APP_PRIORITY_ABOVE_NORMAL, "QsocketApp", socket_app_thread, NULL, 5);
  306. if(err != QL_OSI_SUCCESS)
  307. {
  308. QL_SOCKET_LOG("socket_app init failed");
  309. }
  310. return err;
  311. }