gprs_data_transfer_demo.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  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_log.h"
  17. #include "ql_api_nw.h"
  18. #include "ql_api_datacall.h"
  19. #include "ql_gprs_data_transfer.h"
  20. #define QL_DATACALL_LOG_LEVEL QL_LOG_LEVEL_INFO
  21. #define QL_TRANSFER_DEMO_LOG(msg, ...) QL_LOG(QL_DATACALL_LOG_LEVEL, "ql_gprs_data_transfer", msg, ##__VA_ARGS__)
  22. #define QL_SIM_NUM 2
  23. typedef struct
  24. {
  25. bool state;
  26. ql_sem_t act_sem;
  27. ql_sem_t deact_sem;
  28. }datacall_context_s;
  29. ql_task_t datacall_task = NULL;
  30. ql_sem_t ql_data_reg_sem[QL_SIM_NUM] = {0};
  31. datacall_context_s datacall_ctx[QL_SIM_NUM][PROFILE_IDX_NUM] = {0};
  32. void ql_nw_ind_callback(uint8_t sim_id, unsigned int ind_type, void *ind_msg_buf)
  33. {
  34. if(QUEC_NW_DATA_REG_STATUS_IND == ind_type)
  35. {
  36. ql_nw_common_reg_status_info_s *data_reg_status=(ql_nw_common_reg_status_info_s *)ind_msg_buf;
  37. QL_TRANSFER_DEMO_LOG("Sim%d data reg status changed, current status is %d", sim_id, data_reg_status->state);
  38. if((QL_NW_REG_STATE_HOME_NETWORK == data_reg_status->state) || (QL_NW_REG_STATE_ROAMING == data_reg_status->state))
  39. {
  40. ql_rtos_semaphore_release(ql_data_reg_sem[sim_id]);
  41. }
  42. }
  43. }
  44. void ql_datacall_ind_callback(uint8_t sim_id, unsigned int ind_type, int profile_idx, bool result, void *ctx)
  45. {
  46. QL_TRANSFER_DEMO_LOG("nSim = %d, profile_idx=%d, ind_type=0x%x, result=%d", sim_id, profile_idx, ind_type, result);
  47. if((profile_idx < PROFILE_IDX_MIN) || (profile_idx > PROFILE_IDX_MAX))
  48. {
  49. return;
  50. }
  51. switch(ind_type)
  52. {
  53. case QUEC_DATACALL_ACT_RSP_IND: //only received in asyn mode
  54. {
  55. datacall_ctx[sim_id][profile_idx - 1].state = (result == true)? QL_PDP_ACTIVED:QL_PDP_DEACTIVED;
  56. ql_rtos_semaphore_release(datacall_ctx[sim_id][profile_idx - 1].act_sem);
  57. break;
  58. }
  59. case QUEC_DATACALL_DEACT_RSP_IND: //only received in asyn mode
  60. {
  61. datacall_ctx[sim_id][profile_idx - 1].state = (result == true)? QL_PDP_DEACTIVED:QL_PDP_ACTIVED;
  62. ql_rtos_semaphore_release(datacall_ctx[sim_id][profile_idx - 1].deact_sem);
  63. break;
  64. }
  65. case QUEC_DATACALL_PDP_DEACTIVE_IND: //received in both asyn mode and sync mode
  66. {
  67. datacall_ctx[sim_id][profile_idx - 1].state = QL_PDP_DEACTIVED;
  68. ql_event_t event={0};
  69. event.id = QUEC_DATACALL_PDP_DEACTIVE_IND;
  70. event.param1 = profile_idx;
  71. ql_rtos_event_send(datacall_task, &event);
  72. break;
  73. }
  74. }
  75. }
  76. void data_transfer_tcpip_input(void *playlod, unsigned short tot_len)
  77. {
  78. QL_TRANSFER_DEMO_LOG("tot_len=%d",tot_len);
  79. QL_TRANSFER_DEMO_LOG("not free playlod!!!!!!!");
  80. }
  81. static void gprs_data_transfer_app_thread(void * arg)
  82. {
  83. int ret = 0, retry_count = 0;
  84. uint8_t sim_id = 0;
  85. int profile_idx = 1; //range 1 to 7
  86. ql_nw_reg_status_info_s nw_info = {0};
  87. ql_data_call_info_s info ={0};
  88. ql_event_t event;
  89. ql_rtos_semaphore_create(&ql_data_reg_sem[sim_id], 0);
  90. ret = ql_nw_register_cb(ql_nw_ind_callback);
  91. if(0 != ret)
  92. {
  93. QL_TRANSFER_DEMO_LOG("ql_nw_register_cb err, ret=0x%x", ret);
  94. goto exit;
  95. }
  96. ret = ql_nw_get_reg_status(sim_id, &nw_info);
  97. QL_TRANSFER_DEMO_LOG("ret: 0x%x, current data reg status=%d", ret, nw_info.data_reg.state);
  98. if((QL_NW_REG_STATE_HOME_NETWORK != nw_info.data_reg.state) && (QL_NW_REG_STATE_ROAMING != nw_info.data_reg.state))
  99. {
  100. ql_rtos_semaphore_wait(ql_data_reg_sem[sim_id], QL_WAIT_FOREVER); //wait network registered
  101. }
  102. ret = ql_datacall_register_cb(sim_id, profile_idx, ql_datacall_ind_callback, NULL);
  103. QL_TRANSFER_DEMO_LOG("ql_datacall_register_cb ret=0x%x", ret);
  104. ret = ql_set_data_call_asyn_mode(sim_id, profile_idx, 1); //If set to asynchronous mode, act_sem and deact_sem are need to be created
  105. ql_rtos_semaphore_create(&datacall_ctx[sim_id][profile_idx-1].act_sem, 0);
  106. ql_rtos_semaphore_create(&datacall_ctx[sim_id][profile_idx-1].deact_sem, 0);
  107. ret=ql_start_data_call(sim_id, profile_idx, QL_PDP_TYPE_IP, "cmnet", NULL, NULL, 0);
  108. if(0 != ret)
  109. {
  110. QL_TRANSFER_DEMO_LOG("ql_start_data_call err, ret=0x%x", ret);
  111. goto exit;
  112. }
  113. ql_rtos_semaphore_wait(datacall_ctx[sim_id][profile_idx-1].act_sem, QL_WAIT_FOREVER); //wait QUEC_DATACALL_ACT_RSP_IND
  114. QL_TRANSFER_DEMO_LOG("datacall state=%d", datacall_ctx[sim_id][profile_idx-1].state);
  115. ret = ql_get_data_call_info(sim_id, profile_idx, &info);
  116. QL_TRANSFER_DEMO_LOG("ql_get_data_call_info ret: 0x%x", ret);
  117. QL_TRANSFER_DEMO_LOG("info.profile_idx: %d, info.ip_version: %d", info.profile_idx, info.ip_version);
  118. QL_TRANSFER_DEMO_LOG("info->v4.state: %d, info.v6.state: %d", info.v4.state, info.v6.state);
  119. if(info.v4.state)
  120. {
  121. QL_TRANSFER_DEMO_LOG("info.v4.addr.ip: %s", ip4addr_ntoa(&(info.v4.addr.ip)));
  122. QL_TRANSFER_DEMO_LOG("info.v4.addr.pri_dns: %s", ip4addr_ntoa(&(info.v4.addr.pri_dns)));
  123. QL_TRANSFER_DEMO_LOG("info.v4.addr.sec_dns: %s", ip4addr_ntoa(&(info.v4.addr.sec_dns)));
  124. }
  125. if(info.v6.state)
  126. {
  127. QL_TRANSFER_DEMO_LOG("info.v6.addr.ip: %s", ip6addr_ntoa(&(info.v6.addr.ip)));
  128. QL_TRANSFER_DEMO_LOG("info.v6.addr.pri_dns: %s", ip6addr_ntoa(&(info.v6.addr.pri_dns)));
  129. QL_TRANSFER_DEMO_LOG("info.v6.addr.sec_dns: %s", ip6addr_ntoa(&(info.v6.addr.sec_dns)));
  130. }
  131. ql_gprs_data_transfer_input_cb_reg(data_transfer_tcpip_input);
  132. ret = ql_gprs_data_transfer_start(sim_id, profile_idx);
  133. if(ret == TRUE)
  134. {
  135. //ql_gprs_data_transfer_output("ip type data", strlen("ip type data"));
  136. }
  137. //ql_gprs_data_transfer_stop();
  138. while(1)
  139. {
  140. if(ql_event_try_wait(&event) != 0)
  141. {
  142. continue;
  143. }
  144. if(QUEC_DATACALL_PDP_DEACTIVE_IND == event.id)
  145. {
  146. ql_gprs_data_transfer_stop(); //stop gprs_data_transfer
  147. ql_rtos_task_sleep_ms(5000); //wait network status update
  148. ret = ql_nw_get_reg_status(sim_id, &nw_info);
  149. if((QL_NW_REG_STATE_HOME_NETWORK != nw_info.data_reg.state) && (QL_NW_REG_STATE_ROAMING != nw_info.data_reg.state))
  150. {
  151. ql_rtos_semaphore_wait(ql_data_reg_sem[sim_id], QL_WAIT_FOREVER);
  152. }
  153. ret = ql_set_data_call_asyn_mode(sim_id, profile_idx, 0); //Set to sync mode
  154. //Try reconnect 10 times, time interval is 20 seconds
  155. while(((ret = ql_start_data_call(sim_id, profile_idx, QL_PDP_TYPE_IP, "cmnet", NULL, NULL, 0)) != QL_DATACALL_SUCCESS) && (retry_count < 10))
  156. {
  157. retry_count++;
  158. QL_TRANSFER_DEMO_LOG("gprs reconnect fail, the retry count is %d", retry_count);
  159. ql_rtos_task_sleep_ms(20000);
  160. }
  161. if(QL_DATACALL_SUCCESS == ret)
  162. {
  163. retry_count = 0;
  164. datacall_ctx[sim_id][profile_idx - 1].state = QL_PDP_ACTIVED;
  165. ret = ql_get_data_call_info(sim_id, profile_idx, &info);
  166. QL_TRANSFER_DEMO_LOG("ql_get_data_call_info ret: 0x%x", ret);
  167. QL_TRANSFER_DEMO_LOG("info.profile_idx: %d, info.ip_version: %d", info.profile_idx, info.ip_version);
  168. QL_TRANSFER_DEMO_LOG("info->v4.state: %d, info.v6.state: %d", info.v4.state, info.v6.state);
  169. if(info.v4.state)
  170. {
  171. QL_TRANSFER_DEMO_LOG("info.v4.addr.ip: %s", ip4addr_ntoa(&(info.v4.addr.ip)));
  172. QL_TRANSFER_DEMO_LOG("info.v4.addr.pri_dns: %s", ip4addr_ntoa(&(info.v4.addr.pri_dns)));
  173. QL_TRANSFER_DEMO_LOG("info.v4.addr.sec_dns: %s", ip4addr_ntoa(&(info.v4.addr.sec_dns)));
  174. }
  175. if(info.v6.state)
  176. {
  177. QL_TRANSFER_DEMO_LOG("info.v6.addr.ip: %s", ip6addr_ntoa(&(info.v6.addr.ip)));
  178. QL_TRANSFER_DEMO_LOG("info.v6.addr.pri_dns: %s", ip6addr_ntoa(&(info.v6.addr.pri_dns)));
  179. QL_TRANSFER_DEMO_LOG("info.v6.addr.sec_dns: %s", ip6addr_ntoa(&(info.v6.addr.sec_dns)));
  180. }
  181. ql_gprs_data_transfer_input_cb_reg(data_transfer_tcpip_input);
  182. ql_gprs_data_transfer_start(sim_id, profile_idx);
  183. }
  184. }
  185. }
  186. exit:
  187. ql_rtos_semaphore_delete(ql_data_reg_sem[sim_id]);
  188. ql_rtos_semaphore_delete(datacall_ctx[sim_id][profile_idx-1].act_sem);
  189. ql_rtos_semaphore_delete(datacall_ctx[sim_id][profile_idx-1].deact_sem);
  190. ql_datacall_unregister_cb(sim_id, profile_idx, ql_datacall_ind_callback, NULL);
  191. ql_rtos_task_delete(datacall_task);
  192. }
  193. void ql_gprs_data_transfer_app_init(void)
  194. {
  195. QlOSStatus err = QL_OSI_SUCCESS;
  196. err = ql_rtos_task_create(&datacall_task, 4*1024, APP_PRIORITY_NORMAL, "QGPRSDATADEMO", gprs_data_transfer_app_thread, NULL, 10);
  197. if(err != QL_OSI_SUCCESS)
  198. {
  199. QL_TRANSFER_DEMO_LOG("task created failed");
  200. return;
  201. }
  202. }