domain.c 7.1 KB

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