domain.c 6.9 KB

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