domain.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /*
  2. domain.c
  3. 域名解析功能
  4. */
  5. #include "includes.h"
  6. typedef struct{
  7. T_UINT8 status:4;
  8. T_UINT8 result:2;
  9. T_UINT16 timeout;
  10. T_UINT16 failTimeout;
  11. T_INT8 address[IP_DOMAIN_SIZE+1];
  12. }DOMAIN_INFO_DEF;
  13. #define DOMAIN_NUM_MAX 5 //support analyse max domain numbers
  14. DOMAIN_INFO_DEF domainInfo[DOMAIN_NUM_MAX];
  15. T_BOOL userDomainBusy=FALSE;
  16. T_UINT8 userDomainIndex;
  17. void dnsEntry(void *param){
  18. DOMAIN_INFO_DEF *domainInfo=(DOMAIN_INFO_DEF *)param;
  19. //LSAPI_DNS_RESULT_t dnsRet;
  20. //LSAPI_SOCK_IP_ADDR_t pAddr;
  21. wlog_info("[NewThread:dnsEntry]%x:%s",nwy_get_current_thread(),domainInfo->address);
  22. char *ip_str=nwy_gethostbyname(domainInfo->address);
  23. if(ip_str==NULL || 0==strlen(ip_str)){
  24. domainInfo->status=3;
  25. }else{
  26. snprintf(domainInfo->address, sizeof(domainInfo->address),"%s",ip_str);
  27. wlog_info("dnsEntry: %s",domainInfo->address);
  28. domainInfo->status=4;
  29. }
  30. userExitThread("dnsEntry");
  31. }
  32. static void userDomainCheck(void);
  33. /*
  34. tryAnalyseDomain
  35. 域名解析API操作
  36. */
  37. static DOMAIN_STEP tryAnalyseDomain(DOMAIN_INFO_DEF *domainInfo){
  38. //要开线程去获取,通过回调来处理,没有回调试方式是block
  39. if(NULL==nwy_create_thread("dnsEntry", dnsEntry,(void *)domainInfo,NWY_OSI_PRIORITY_NORMAL,1024,4))
  40. wlog_info("dns entry trhead null");
  41. return DOMAIN_WAIT;//wait
  42. }
  43. //检测任务是否空闲
  44. void isDomainIdle(void){
  45. T_UINT8 i;
  46. for(i=0;i<DOMAIN_NUM_MAX;i++){
  47. if(0!=domainInfo[i].status){
  48. ticketDeVote(TICKET_PT_DOMAIN);
  49. return;
  50. }
  51. }
  52. ticketVote(TICKET_PT_DOMAIN);
  53. }
  54. /*
  55. tryAnalyseDomain
  56. 域名解析任务
  57. */
  58. PT_THREAD (ptDomainTask(pt_timer_t *ptPool, struct pt *pt)){
  59. static pt_timer_t ptTimer;
  60. static T_UINT8 iniStatus=1;
  61. IPD_ENUM ipType;
  62. T_UINT8 i;
  63. T_UINT8 result;
  64. if(iniStatus){
  65. memset((T_UINT8 *)&domainInfo, 0, sizeof(DOMAIN_INFO_DEF));
  66. iniStatus=0;
  67. }
  68. PT_BEGIN(pt);
  69. while(1){
  70. userDomainCheck();
  71. if(talking.netWork.pdp==0) break;
  72. for(i=0;i<DOMAIN_NUM_MAX;i++){
  73. if(1==domainInfo[i].status){//have task to do, check ip or domain first
  74. wlog_info("Domain addr check[%d]:%s", i,domainInfo[i].address);
  75. if(FALSE==checkIpDomain(domainInfo[i].address, strlen(domainInfo[i].address), NULL, &ipType)){
  76. wlog_warn("Domain invalid addr");
  77. domainInfo[i].status=3;//failed
  78. }else{
  79. if(IPD_IP==ipType){//it is already ip
  80. domainInfo[i].status=4;//success
  81. }else domainInfo[i].status=2;//domain , need anaylise
  82. }
  83. }else if(2==domainInfo[i].status){//try analyse
  84. result=tryAnalyseDomain(&domainInfo[i]);
  85. if(DOMAIN_ERR==result){
  86. wlog_error("analyse failed");
  87. domainInfo[i].status=3;
  88. }else if(DOMAIN_OK==result){
  89. wlog_info("analyse ok:%s",domainInfo[i].address);
  90. domainInfo[i].status=4;
  91. }else if(DOMAIN_WAIT==result){
  92. domainInfo[i].status=5;//wait
  93. domainInfo[i].timeout=0;
  94. }
  95. }else if(5==domainInfo[i].status){
  96. if(++domainInfo[i].timeout>2000){//10秒没结果为超时
  97. wlog_warn("domain timeout");
  98. domainInfo[i].status=3;
  99. }
  100. }else if(3==domainInfo[i].status){//获取失败时,如果应用层未取值,超时扔掉值,否则系统无法休眠
  101. if(++domainInfo[i].failTimeout>=1000){
  102. domainInfo[i].status=0;
  103. wlog_warn("domain faild value timeout");
  104. }
  105. }else if(4==domainInfo[i].status){//获取成功时,如果应用层未取值,超时扔掉值,否则系统无法休眠
  106. if(++domainInfo[i].failTimeout>=1000){
  107. domainInfo[i].status=0;
  108. wlog_warn("domain ok value timeout");
  109. }
  110. }
  111. }
  112. isDomainIdle();
  113. PTTimerStart(ptPool, &ptTimer,1);//can be be fast
  114. PT_WAIT_UNTIL(pt, PTTimerIsExpired(&ptTimer));
  115. }
  116. PT_END(pt);
  117. }
  118. /*
  119. setDomainForIp
  120. 域名解析请求入队列
  121. */
  122. //addr, the address that need to anaylise
  123. //index, the index of domain queue feed back if return TRUE
  124. T_BOOL setDomainForIp(T_INT8 *addr, T_UINT8 *index){
  125. T_UINT8 i;
  126. for(i=0;i<DOMAIN_NUM_MAX;i++){
  127. if(domainInfo[i].status==0){//idle
  128. domainInfo[i].failTimeout=0;
  129. domainInfo[i].status=1;
  130. strncpy(domainInfo[i].address, addr, IP_DOMAIN_SIZE);
  131. *index=i;
  132. return TRUE;
  133. }
  134. }
  135. return FALSE;
  136. }
  137. /*
  138. getDomainForIp
  139. 域名解析结果查询
  140. */
  141. //index, this index of domain queue, which get form setDomainForIp
  142. //outIp, fill with ip data if success
  143. //outLen, the max size of outIp buffer
  144. //return, 0 busy, 1 failed, 2 ok
  145. T_UINT8 getDomainForIp(T_UINT8 index, T_INT8 *outIp, T_UINT8 outLen){
  146. T_UINT8 i,ret=DOMAIN_WAIT;
  147. i=index;
  148. if(i >= DOMAIN_NUM_MAX) return 1;//err
  149. switch(domainInfo[i].status){
  150. case 0:
  151. ret=DOMAIN_ERR;
  152. break;
  153. case 1:
  154. case 2:
  155. ret=DOMAIN_WAIT;//busy
  156. break;
  157. case 3:
  158. ret=DOMAIN_ERR;//failed
  159. domainInfo[i].status=0;
  160. break;
  161. case 4:
  162. ret=DOMAIN_OK;//ok
  163. strncpy(outIp, domainInfo[i].address, outLen);
  164. domainInfo[i].status=0;
  165. break;
  166. }
  167. return ret;
  168. }
  169. void tryDomain(T_UINT8 *data, T_UINT16 len){
  170. T_UINT16 i;
  171. for(i=0;i<len;i++){
  172. if(data[i]==' ' || data[i]=='\r'){
  173. data[i]=0;
  174. break;
  175. }
  176. }
  177. if(i<=3) return;
  178. wlog_info("user domain req:%s",data);
  179. if(userDomainBusy==TRUE){
  180. msgToOutter("+DOMAIN:SYNC\r\n");
  181. return;
  182. }
  183. if(FALSE==setDomainForIp((T_INT8 *)data, &userDomainIndex)) msgToOutter("+DOMAIN:BUSY\r\n");
  184. userDomainBusy=TRUE;
  185. }
  186. /*
  187. userDomainCheck
  188. 用户外部(串口)请求域名解析的检测操作
  189. */
  190. static void userDomainCheck(void){
  191. T_UINT8 ret;
  192. T_INT8 ipAddr[20];
  193. T_INT8 info[40];
  194. if(FALSE==userDomainBusy) return;
  195. ret=getDomainForIp(userDomainIndex, ipAddr, sizeof(ipAddr)-1);
  196. if(ret==1){
  197. msgToOutter("+DOMAIN:ERROR\r\n");
  198. goto UD_END;
  199. }else if(ret==0){}//wait
  200. else{
  201. snprintf(info, sizeof(info), "+DOMAIN:%s\r\n",ipAddr);
  202. msgToOutter(info);
  203. goto UD_END;
  204. }
  205. return;
  206. UD_END:
  207. userDomainBusy=FALSE;
  208. }