https_get_demo.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  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. /*
  13. * brief: get method
  14. */
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <stdlib.h>
  18. #include "ql_api_osi.h"
  19. #include "ql_log.h"
  20. #include "ql_api_datacall.h"
  21. #include "ql_http_client.h"
  22. #include "ql_fs.h"
  23. #define ROOT_CRT_PATH "UFS:root.crt"
  24. #define CLIENT_KEY_PATH "UFS:client.key"
  25. #define CLIENT_CRT_PATH "UFS:client.crt"
  26. #define QL_HTTP_LOG_LEVEL QL_LOG_LEVEL_INFO
  27. #define QL_HTTP_LOG(msg, ...) QL_LOG(QL_HTTP_LOG_LEVEL, "ql_HTTP", msg, ##__VA_ARGS__)
  28. #define QL_HTTP_LOG_PUSH(msg, ...) QL_LOG_PUSH("ql_HTTP", msg, ##__VA_ARGS__)
  29. struct cert_array_t {
  30. char *path;
  31. char *data;
  32. };
  33. #ifndef USE_CUST_KEY
  34. #define USE_CUST_KEY 0 // 自定义http证书、秘钥等, 默认关闭0
  35. #endif
  36. #if USE_CUST_KEY
  37. #define root_crt "-----BEGIN CERTIFICATE-----\n\
  38. MIIDYTCCAkkCFFr50PfFXMCG+Lg5XoZ1mPeMJ3P9MA0GCSqGSIb3DQEBCwUAMG0x\n\
  39. CzAJBgNVBAYTAmNuMQswCQYDVQQIDAJoZjELMAkGA1UEBwwCaGYxDTALBgNVBAoM\n\
  40. BHRlc3QxDTALBgNVBAsMBHRlc3QxDTALBgNVBAMMBHJvb3QxFzAVBgkqhkiG9w0B\n\
  41. CQEWCHJvb3QuY29tMB4XDTIxMDQyMDAxMjU0M1oXDTMxMDQxODAxMjU0M1owbTEL\n\
  42. MAkGA1UEBhMCY24xCzAJBgNVBAgMAmhmMQswCQYDVQQHDAJoZjENMAsGA1UECgwE\n\
  43. dGVzdDENMAsGA1UECwwEdGVzdDENMAsGA1UEAwwEcm9vdDEXMBUGCSqGSIb3DQEJ\n\
  44. ARYIcm9vdC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDG3HTp\n\
  45. zAarO7JJIfiDQTi8nsoAIYjAIDDY6PTdylLs/F5HJtiqWr1ZpyfC11hwRofFIE0u\n\
  46. i1V8BUEGaIYb3UgN8/y8w483Fi7+kZVm3NRK1yo2oMqvTQyMZzhqOv7hdsv17qdD\n\
  47. AN21iS7jna29Qzjcrt4jwZ1eRZtUXtZiVMZ/3UT3PKaJTtllVxVaDXhPMPuNh4w3\n\
  48. jA2aNlLqPc21zSIvHhFHQNHsNWKlxBvchomWKRpdDpW7D32RnjlCzYW4/RiHeCQa\n\
  49. 7+fdOpaUDuR8RIG8pDK5x3G4t8hcisGl88T0pqKmHNaG0WO6VqKHmOaSWq2+Gzmo\n\
  50. WZTLO0NPxcJGTGEXAgMBAAEwDQYJKoZIhvcNAQELBQADggEBABcdf529CGJ+QwgS\n\
  51. UBXtVubvZIsUKznFpFnVV/jvqjRTkQgHbohtkba6mCgGYYBUnc6uEVNXx1fVlXX/\n\
  52. 3mT+iC5zZh2dkNM8covcOCmI6yih9uwgdPURu56/clsY/8IqdH8DTcrDylqH1yVS\n\
  53. zsxRKTNvfWltO2avorufUg1swKCF5SsmK+SYpVpZYosCCfGe2PAdhllVpxtbrv2z\n\
  54. VDy2DqbWhYU0GOB6fd9trxeshHVAsyk5VczGRnPoy1yZ/h8hwnhUk5WuvEY0n3ce\n\
  55. ZxASiQTSVs4sC7H5navGt0dZH7W9VPvszyYdC7c1Dh+pbdn59d/YHYF+SmLwLX9/\n\
  56. c+kx7+E=\n\
  57. -----END CERTIFICATE-----"
  58. #define client_key "-----BEGIN RSA PRIVATE KEY-----\n\
  59. MIIEowIBAAKCAQEAx+raeEvE+/teiTFcAxYYJAMaePmtuUGfe5lcysRQTALSTmT1\n\
  60. VccV4HXai73Q3KS12lxeoc/ib/z+8cyoEAPATyYAUV8tDh76hOcgUX5g0hxvzA7H\n\
  61. 65xrgytGCL+CoU2eM6mDvLNo4tCNKxFRtYvgoq3zVaS57cK7WykagnsIawYl2ivz\n\
  62. BrbDchOv5fi+g/uJfRYFVTl54zbSSFUFar91q6QLEWENjKA8r4aTPsiIFARYIQly\n\
  63. OI7GHpH8QrNSOspdBVByUqpVXDJFBiX748uijp72cVNcye4pDVf27Iip6S0FCLc0\n\
  64. tIWwKnl5/d3IZIUG9yCXFEB933u7useVjoniYQIDAQABAoIBAQCla3silu+D4Vc0\n\
  65. BhewphOLmNXKzC4nYFlqmFfjn9UhUCRcocUvGPDNLjeL8aBlMhUXfd7/3Vfselcq\n\
  66. FMHrnm7+Dt+sdSh+yrtYRTbEt+G9ebI4EvLxzhhYDPKCQpUAi40gCl/rQDjFlPN6\n\
  67. c3Y81mUltvHmJ8uBJOSKZdR9qvgoNRLBJqk+ZAQzUK6iNbdEOZRkFyO7tJ0aI+QH\n\
  68. L3bAkqaimxku1QSCzE5dQ2JC9scFBhUNyBB+N7Gb03oYobozBPJu5LKCY0BpjRAM\n\
  69. crIEa3k9RPA0BLOQP51byBgKvwy8YK/P3ddVkb+W55fIm/ukjKuxUF1QiD44Kiql\n\
  70. U6hDlWcBAoGBAPLb/oO0kXPk71HQrTpSVQJZ21Xh+hAPRLntEJSsFrDIjYNheNX5\n\
  71. bcKJqR3JyA+NTJb5OZedAPYv5xtdWBS9HrMspMMMxZ1+0NbQQL/5rjEVoX8yqA5r\n\
  72. H1QWfq1RABfpOYjKVDal7H76VJF/Zi+Gbg4dPzUt5HFU1lFApObTEjR5AoGBANK8\n\
  73. Cq2rGUUX2qg0gd/OZW85Ov0CUwd9awNc2x6VaWG+gMSiEv2fiv8Ka2MvlQjjtmds\n\
  74. S8/G2jIbxkAHddopXGdXIsF2Pr2Bzw8bgKtPliMVte3dYOOoHdTt6P/MaFbNtwoJ\n\
  75. CKPRHAdSI0pYkdMjgMYQkOPBb3xY5+jO7eCk7pMpAoGATIHtrkQmRmJq2lVpHSRu\n\
  76. z2zLYkTsaD7HIeODA7Mq+spTen4seQw4/b4sXswAkJWs+SrOb+rwMJ5qqf5AD1h8\n\
  77. 4WlBBolxf+pBlErK+y+HJsNvuwiUVOZ+Whk0Exmfc+jvTR6gZQ7kcCQgnC2MXZB1\n\
  78. /1BLZ09r1iAp3DMHQAhihdECgYAo1xKGt7sM/eN9Z7enxRs5Y/D/qZynvfGoVC2P\n\
  79. Dsu+iqnv8a0Wg/3vEXjgXw9WCrOF9aH3oYUV4vYX4JpBbnSe/m8Y6S6dkXOsbNsR\n\
  80. 2DmzkPiSIa4uUJ1/b6AROu8Zq4KGqluHS/ZPoOZ/+QxBzAaf3AQIb6uIgL5pCvlk\n\
  81. 6PHniQKBgBPGQVFg7iGbbjnWGXL6nbvPWN4bfmy4ESIK3TN0p3UxZBnfAsArOl7D\n\
  82. HXMRUx2qW+WkUHpfKgqC17Q1srm6w/jJuZAYBkCgLhp3iy/ENtqdE2yYPSGSJnlh\n\
  83. sR94u9+nkJXw5d6u5xew/y5YelM+gH9X3fv87ulTV2fpoHRk8KH2\n\
  84. -----END RSA PRIVATE KEY-----"
  85. #define client_crt "-----BEGIN CERTIFICATE-----\n\
  86. MIIDbDCCAlQCFHu5iQ8zrC5zzju2bI/yWWnCYhW/MA0GCSqGSIb3DQEBCwUAMG0x\n\
  87. CzAJBgNVBAYTAmNuMQswCQYDVQQIDAJoZjELMAkGA1UEBwwCaGYxDTALBgNVBAoM\n\
  88. BHRlc3QxDTALBgNVBAsMBHRlc3QxDTALBgNVBAMMBHJvb3QxFzAVBgkqhkiG9w0B\n\
  89. CQEWCHJvb3QuY29tMB4XDTIxMDQyMDA3MDU1OFoXDTMxMDQxODA3MDU1OFoweDEL\n\
  90. MAkGA1UEBhMCY24xCzAJBgNVBAgMAmhmMQswCQYDVQQHDAJoZjENMAsGA1UECgwE\n\
  91. dGVzdDENMAsGA1UECwwEdGVzdDEYMBYGA1UEAwwPMjIwLjE4MC4yMzkuMjEyMRcw\n\
  92. FQYJKoZIhvcNAQkBFghyb290LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\n\
  93. AQoCggEBAMfq2nhLxPv7XokxXAMWGCQDGnj5rblBn3uZXMrEUEwC0k5k9VXHFeB1\n\
  94. 2ou90NyktdpcXqHP4m/8/vHMqBADwE8mAFFfLQ4e+oTnIFF+YNIcb8wOx+uca4Mr\n\
  95. Rgi/gqFNnjOpg7yzaOLQjSsRUbWL4KKt81Wkue3Cu1spGoJ7CGsGJdor8wa2w3IT\n\
  96. r+X4voP7iX0WBVU5eeM20khVBWq/daukCxFhDYygPK+Gkz7IiBQEWCEJcjiOxh6R\n\
  97. /EKzUjrKXQVQclKqVVwyRQYl++PLoo6e9nFTXMnuKQ1X9uyIqektBQi3NLSFsCp5\n\
  98. ef3dyGSFBvcglxRAfd97u7rHlY6J4mECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA\n\
  99. H5qIexLGos836/GIoOHyF1vG6n7VZhu2G8GF41XQs9KfvuJY3FQ4a7drHEujbdpI\n\
  100. 9J9mR8hUaafTjxQVytfekCYkTytsUzJO+qGnxGeS+xWJO/jc1NnPre8ldG1X13Rp\n\
  101. IbqwRbo0z6J/XrzJzbTVd/joxNBWuIXqCSb8SmKYLUeUOZVMG7autr4VryJgAFma\n\
  102. hOVJPl3sAEnKJ1dvJC+VXyeWwjfDdXK4RD0UgoDfux7UezAThMC/YKrLz+/kVkps\n\
  103. dG52zsbbIKZ/omgFgThUFuR36mc0DAL5+Exk5Fb0biB+mOzYTejzmZ/kWQS1EGxI\n\
  104. 0VZFtnOt9nIZ0+uH2sbHcQ==\n\
  105. -----END CERTIFICATE-----"
  106. #define cert_array_len 3
  107. struct cert_array_t cert_array[cert_array_len] = {
  108. { ROOT_CRT_PATH, root_crt },
  109. { CLIENT_KEY_PATH, client_key },
  110. { CLIENT_CRT_PATH, client_crt }
  111. };
  112. #endif
  113. enum CUST_HTTPS_CHECK {CUST_NONE=0, CUST_SINGLE, CUST_DOUBLE};
  114. ql_task_t http_get_task = NULL;
  115. static http_client_t http_cli = 0;
  116. static ql_sem_t http_semp = NULL;
  117. static void http_event_cb(http_client_t *client, int evt, int evt_code, void *arg)
  118. {
  119. QL_HTTP_LOG("*client:%d, http_cli:%d", *client, http_cli);
  120. if(*client != http_cli)
  121. return;
  122. QL_HTTP_LOG("evt:%d, evt_code:%d", evt, evt_code);
  123. switch(evt){
  124. case HTTP_EVENT_SESSION_ESTABLISH:{
  125. if(evt_code != QL_HTTP_OK){
  126. QL_HTTP_LOG("HTTP session create failed!!!!!");
  127. ql_rtos_semaphore_release(http_semp);
  128. }
  129. }
  130. break;
  131. case HTTP_EVENT_RESPONE_STATE_LINE:{
  132. if(evt_code == QL_HTTP_OK){
  133. int resp_code = 0;
  134. int content_length = 0;
  135. int chunk_encode = 0;
  136. char *location = NULL;
  137. ql_httpc_getinfo(client, HTTP_INFO_RESPONSE_CODE, &resp_code);
  138. QL_HTTP_LOG("response code:%d", resp_code);
  139. ql_httpc_getinfo(client, HTTP_INFO_CHUNK_ENCODE, &chunk_encode);
  140. if(chunk_encode == 0){
  141. ql_httpc_getinfo(client, HTTP_INFO_CONTENT_LEN, &content_length);
  142. QL_HTTP_LOG("content_length:%d",content_length);
  143. }else{
  144. QL_HTTP_LOG("http chunk encode!!!");
  145. }
  146. if(resp_code >= 300 && resp_code < 400){
  147. ql_httpc_getinfo(client, HTTP_INFO_LOCATION, &location);
  148. QL_HTTP_LOG("redirect location:%s", location);
  149. free(location);
  150. }
  151. }
  152. }
  153. break;
  154. case HTTP_EVENT_SESSION_DISCONNECT:{
  155. if(evt_code == QL_HTTP_OK){
  156. QL_HTTP_LOG("===http transfer end!!!!");
  157. }else{
  158. QL_HTTP_LOG("===http transfer occur exception!!!!!");
  159. }
  160. ql_rtos_semaphore_release(http_semp);
  161. }
  162. break;
  163. }
  164. }
  165. static int http_write_response_data(http_client_t *client, void *arg, char *data, int size, unsigned char end)
  166. {
  167. unsigned char *recbuff=NULL;
  168. QL_HTTP_LOG("recv size:%d", size);
  169. recbuff=malloc(size+1);
  170. if(NULL!=recbuff)
  171. {
  172. memset(recbuff, 0, size+1);
  173. memcpy(recbuff, data, size);
  174. QL_HTTP_LOG("recv data: %s", recbuff);
  175. free(recbuff);
  176. recbuff=NULL;
  177. }
  178. return size;
  179. }
  180. static int sim_net_register(int nSim, int profile_idx)
  181. {
  182. int ret = 0, i = 0;
  183. ql_data_call_info_s info;
  184. char ip4_addr_str[16] = {0};
  185. while((ret = ql_network_register_wait(nSim, 120)) != 0 && i < 10){
  186. i++;
  187. ql_rtos_task_sleep_ms(1000);
  188. }
  189. if(ret == 0) {
  190. i = 0;
  191. QL_HTTP_LOG("====network registered!!!!====");
  192. } else {
  193. QL_HTTP_LOG("====network register failure!!!!!====");
  194. return ret;
  195. }
  196. ql_set_data_call_asyn_mode(nSim, profile_idx, 0);
  197. ret=ql_start_data_call(nSim, profile_idx, QL_PDP_TYPE_IP, "uninet", NULL, NULL, 0);
  198. if(ret != 0) {
  199. QL_HTTP_LOG("====data call failure!!!!=====");
  200. }
  201. memset(&info, 0x00, sizeof(ql_data_call_info_s));
  202. ret = ql_get_data_call_info(nSim, profile_idx, &info);
  203. if(ret != 0) {
  204. QL_HTTP_LOG("ql_get_data_call_info ret: %d", ret);
  205. ql_stop_data_call(nSim, profile_idx);
  206. return ret;
  207. }
  208. QL_HTTP_LOG("info->profile_idx: %d", info.profile_idx);
  209. QL_HTTP_LOG("info->ip_version: %d", info.ip_version);
  210. QL_HTTP_LOG("info->v4.state: %d", info.v4.state);
  211. inet_ntop(AF_INET, &info.v4.addr.ip, ip4_addr_str, sizeof(ip4_addr_str));
  212. QL_HTTP_LOG("info.v4.addr.ip: %s\r\n", ip4_addr_str);
  213. inet_ntop(AF_INET, &info.v4.addr.pri_dns, ip4_addr_str, sizeof(ip4_addr_str));
  214. QL_HTTP_LOG("info.v4.addr.pri_dns: %s\r\n", ip4_addr_str);
  215. inet_ntop(AF_INET, &info.v4.addr.sec_dns, ip4_addr_str, sizeof(ip4_addr_str));
  216. QL_HTTP_LOG("info.v4.addr.sec_dns: %s\r\n", ip4_addr_str);
  217. return ret;
  218. }
  219. #if USE_CUST_KEY
  220. /*
  221. * 客户端证书秘钥初始化函数,将自定义证书秘钥写入自定义文件中
  222. */
  223. static int client_certfication_init()
  224. {
  225. int ret = 0;
  226. QFILE fp = -1;
  227. int i = 0;
  228. for(i = 0; i < cert_array_len; i++) {
  229. fp = ql_fopen(cert_array[i].path, "w+");
  230. if(fp < 0) {
  231. QL_HTTP_LOG("open file:%s failed!!!!", cert_array[i].path);
  232. return -1;
  233. }
  234. ret = ql_fwrite(cert_array[i].data, strlen(cert_array[i].data), 1, fp);
  235. if( ret != strlen(cert_array[i].data) ) {
  236. QL_HTTP_LOG("http write %d bytes data failure", ret);
  237. ql_fclose(fp);
  238. return -1;
  239. }
  240. ql_fclose(fp);
  241. }
  242. return 0;
  243. }
  244. #endif
  245. static void https_get_app_thread(void * arg)
  246. {
  247. int ret = 0;
  248. int profile_idx = 1;
  249. int run_num = 0;
  250. uint8_t nSim = 0;
  251. char *url[3] = {"https://220.180.239.212:9634/get_request", // https 无校验
  252. "https://220.180.239.212:9634/get_request", // https 单向认证
  253. "https://220.180.239.212:9633/get_request" // https 双向认证
  254. };
  255. int case_id = 0;
  256. ql_rtos_task_sleep_s(5);
  257. QL_HTTP_LOG("========== http new demo start ==========");
  258. QL_HTTP_LOG("wait for network register done");
  259. ret = sim_net_register(nSim, profile_idx);
  260. if( ret != 0 ) {
  261. QL_HTTP_LOG("sim register net failure , ret= %d", ret);
  262. goto exit;
  263. }
  264. #if USE_CUST_KEY
  265. ret = client_certfication_init();
  266. if( ret != 0 ) goto exit;
  267. #endif
  268. do {
  269. QL_HTTP_LOG("==============http_client_get_test[%d]================\n",run_num+1);
  270. ql_rtos_semaphore_create(&http_semp, 0);
  271. if(ql_httpc_new(&http_cli, http_event_cb, NULL) != QL_HTTP_OK){
  272. QL_HTTP_LOG("http client create failed!!!!");
  273. break;
  274. }
  275. ql_httpc_setopt(&http_cli, HTTP_CLIENT_OPT_SIM_ID, nSim);
  276. ql_httpc_setopt(&http_cli, HTTP_CLIENT_OPT_PDPCID, profile_idx);
  277. ql_httpc_setopt(&http_cli, HTTP_CLIENT_OPT_WRITE_FUNC, http_write_response_data);
  278. ql_httpc_setopt(&http_cli, HTTP_CLIENT_OPT_METHOD, HTTP_METHOD_GET);
  279. ql_httpc_setopt(&http_cli, HTTP_CLIENT_OPT_SSLCTXID, 1);
  280. case_id = run_num%3;
  281. switch( case_id ) {
  282. case CUST_NONE:
  283. ql_httpc_setopt(&http_cli, HTTP_CLIENT_OPT_SSL_VERIFY_LEVEL, HTTPS_VERIFY_NONE);
  284. break;
  285. case CUST_SINGLE:
  286. ql_httpc_setopt(&http_cli, HTTP_CLIENT_OPT_SSL_VERIFY_LEVEL, HTTPS_VERIFY_SERVER);
  287. ql_httpc_setopt(&http_cli, HTTP_CLIENT_OPT_SSL_CACERT_PATH, ROOT_CRT_PATH);
  288. break;
  289. case CUST_DOUBLE:
  290. ql_httpc_setopt(&http_cli, HTTP_CLIENT_OPT_SSL_VERIFY_LEVEL, HTTPS_VERIFY_SERVER_CLIENT);
  291. ql_httpc_setopt(&http_cli, HTTP_CLIENT_OPT_SSL_CACERT_PATH, ROOT_CRT_PATH);
  292. ql_httpc_setopt(&http_cli, HTTP_CLIENT_OPT_SSL_OWNCERT_PATH, CLIENT_CRT_PATH, CLIENT_KEY_PATH, NULL);
  293. break;
  294. default:
  295. break;
  296. }
  297. ql_httpc_setopt(&http_cli, HTTP_CLIENT_OPT_URL, url[case_id]);
  298. if(ql_httpc_perform(&http_cli) == QL_HTTP_OK) {
  299. QL_HTTP_LOG("wait http perform end!!!!!!");
  300. ql_rtos_semaphore_wait(http_semp, QL_WAIT_FOREVER);
  301. } else {
  302. QL_HTTP_LOG("http perform failed!!!!!!!!!!");
  303. }
  304. ql_httpc_release(&http_cli);
  305. http_cli = 0;
  306. QL_HTTP_LOG("==============http_client_test_end[%d]================\n",run_num+1);
  307. run_num++;
  308. if(http_semp != NULL)
  309. {
  310. ql_rtos_semaphore_delete(http_semp);
  311. http_semp = NULL;
  312. }
  313. ql_rtos_task_sleep_s(5);
  314. } while(1);
  315. exit:
  316. if(http_semp != NULL)
  317. {
  318. ql_rtos_semaphore_delete(http_semp);
  319. http_semp = NULL;
  320. }
  321. ql_rtos_task_delete(http_get_task);
  322. return;
  323. }
  324. void ql_https_get_app_init(void)
  325. {
  326. QlOSStatus err = QL_OSI_SUCCESS;
  327. err = ql_rtos_task_create(&http_get_task, 4096, APP_PRIORITY_NORMAL, "QhttpGet", https_get_app_thread, NULL, 5);
  328. if(err != QL_OSI_SUCCESS)
  329. {
  330. QL_HTTP_LOG("created task failed");
  331. }
  332. }