tcpUdp.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. #include "includes.h"
  2. #define TUP_SOCKET_NUN 2 //had better not lagger that DOMAIN_NUM_MAX
  3. typedef enum{
  4. TUPS_IDLE,
  5. TUPS_START,
  6. TUPS_DOMAIN,
  7. TUPS_LINK,
  8. TUPS_WAIT,
  9. TUPS_LINE
  10. }TUPS_ENUM;
  11. typedef struct{
  12. IPD_ENUM ipdType;
  13. TUP_ENUM tup;
  14. T_INT8 ipDomain[IP_DOMAIN_SIZE+1];
  15. T_UINT16 port;
  16. }TCPUDP_DEF;
  17. typedef struct{
  18. TUPS_ENUM status;
  19. T_BOOL needClose;
  20. TCPUDP_DEF server;
  21. T_UINT8 index;
  22. T_UINT32 time;
  23. T_BOOL printFlag;
  24. TUPSEND_DEF sendPara;
  25. }TUP_DEF;
  26. TUP_DEF tupPara[TUP_SOCKET_NUN];
  27. void tupRecv_cb(void *param){
  28. T_UINT8 buffer[TUP_DATA_MAX+EXT_DATA];
  29. T_INT8 buf[32];
  30. LSAPI_OSI_Event_t *pEvent = (LSAPI_OSI_Event_t *)param;
  31. TUPSEND_DEF *para=(TUPSEND_DEF *)pEvent->param3;
  32. int len_ret,tlen,i;
  33. bool needClose=false;
  34. showTupEventInfo("tcpUdp",pEvent->id,para,0);
  35. switch(pEvent->id){
  36. case LSAPI_SOCK_TCPIP_SOCKET_CONNECT_RSP:
  37. wlog_info("tupRecv_cb server ok:%d",para->fd);
  38. break;
  39. case LSAPI_SOCK_TCPIP_SOCKET_SEND_RSP:
  40. wlog_info("tupRecv_cb send:%d",para->fd);
  41. break;
  42. case LSAPI_SOCK_TCPIP_SOCKET_CLOSE_RSP:
  43. wlog_info("tupRecv_cb client shut:%d",para->fd);
  44. needClose=true;
  45. break;
  46. case LSAPI_SOCK_TCPIP_REV_DATA_IND:
  47. while(1){
  48. if(TUP_TCP==para->tupType)
  49. len_ret=LSAPI_SOCK_Recv(para->fd,buffer, TUP_DATA_MAX,0);
  50. else
  51. len_ret=LSAPI_SOCK_Recvfrom(para->fd,buffer, TUP_DATA_MAX,0,&para->sockAddr);
  52. if(len_ret>=0){
  53. if(len_ret==0) break;
  54. snprintf(buf,sizeof(buf), "+TCPRECV:%d,%d,",para->index+1,len_ret);
  55. tlen=strlen(buf);
  56. for(i=len_ret-1;i>=0;i--) buffer[i+tlen]=buffer[i];
  57. memcpy(buffer, buf,tlen);
  58. tlen += len_ret;
  59. buffer[tlen++]='\r';
  60. buffer[tlen++]='\n';
  61. msgSToOutter(buffer, tlen);
  62. wlog_info("tupRecv_cb recv[%d]%d",para->fd,len_ret);
  63. }else{
  64. wlog_warn("tupRecv_cb failed");
  65. break;
  66. }
  67. }
  68. break;
  69. case LSAPI_SOCK_TCPIP_CLOSE_IND:
  70. wlog_info("tupRecv_cb server shut:%d",para->fd);
  71. needClose=true;
  72. break;
  73. case LSAPI_SOCK_TCPIP_ERR_IND:
  74. wlog_info("tupRecv_cb server error:%d",para->fd);
  75. needClose=true;
  76. break;
  77. default: break;
  78. }
  79. LSAPI_OSI_Free(pEvent);
  80. if(needClose==true) threadPostEvent(LSAPI_OSI_ThreadCurrent(),USER_EVENT_EXIT);
  81. }
  82. T_UINT8 tupOpenApi(T_UINT8 socket,TCPUDP_DEF *para){
  83. T_UINT8 thisSocket;
  84. if(socket>TUP_SOCKET_NUN) return 1;//get error
  85. thisSocket=socket-1;
  86. if(TUPS_LINE==tupPara[thisSocket].status) return 2;//open already
  87. else if(TUPS_IDLE!=tupPara[thisSocket].status) return 3;//socket is opening
  88. tupPara[thisSocket].server.ipdType=para->ipdType;
  89. tupPara[thisSocket].server.tup=para->tup;
  90. tupPara[thisSocket].server.port=para->port;
  91. strcpy(tupPara[thisSocket].server.ipDomain, para->ipDomain);
  92. tupPara[thisSocket].time=getSysTick()+200;//if domain busy in 2 seconds, we set it to failed
  93. tupPara[thisSocket].needClose=FALSE;
  94. tupPara[thisSocket].sendPara.index=thisSocket;
  95. tupParaSet(&tupPara[thisSocket].sendPara, para->port, tupRecv_cb,TUP_API_THREAD_STACK);
  96. if(para->ipdType==IPD_IP) tupPara[thisSocket].status=TUPS_LINK;
  97. else tupPara[thisSocket].status=TUPS_START;
  98. return 0;//try open ok
  99. }
  100. T_UINT8 tupCloseApi(T_UINT8 socket){
  101. T_UINT8 thisSocket;
  102. if(socket>TUP_SOCKET_NUN) return 1;//get error
  103. thisSocket=socket-1;
  104. tupPara[thisSocket].needClose=TRUE;
  105. return 0;
  106. }
  107. void tupTest(void){
  108. tupOpen("1,122.224.240.106:11602,0\r\n",25);
  109. tupOpen("2,122.224.240.106:11602,0\r\n",25);
  110. }
  111. void isTupTaskIdle(void){
  112. T_UINT8 i;
  113. for(i=0;i<TUP_SOCKET_NUN;i++){
  114. if(tupPara[i].status!=TUPS_IDLE && tupPara[i].status!=TUPS_LINE){
  115. ticketDeVote(TICKET_PT_TUP);
  116. return;
  117. }
  118. }
  119. ticketVote(TICKET_PT_TUP);
  120. }
  121. //tup socket handler start...////////////////////////////////
  122. PT_THREAD (ptTupTask(pt_timer_t *ptPool, struct pt *pt)){
  123. static pt_timer_t ptTimer;
  124. static T_BOOL flag=TRUE;
  125. static T_UINT8 index=0;
  126. T_INT8 info[30];
  127. T_UINT8 ret;
  128. if(TRUE==flag){
  129. memset((T_UINT8 *)&tupPara, 0, sizeof(TUP_DEF));
  130. flag=FALSE;
  131. //tupTest();
  132. }
  133. PT_BEGIN(pt);
  134. while(1){
  135. if(TUPS_START==tupPara[index].status){
  136. if(getSysTick()<tupPara[index].time){
  137. if(tupPara[index].printFlag==FALSE){//just printf once
  138. tupPara[index].printFlag=TRUE;
  139. wlog_info("TUPS_START[%d]:%s,%d", index+1, tupPara[index].server.ipDomain,tupPara[index].server.port);
  140. }
  141. if(TRUE==setDomainForIp(tupPara[index].server.ipDomain, &tupPara[index].index)){
  142. //done, we wait result
  143. tupPara[index].time=getSysTick()+500;//we wait 5 seconds for domain result
  144. tupPara[index].status=TUPS_DOMAIN;
  145. wlog_info("TUPS_DOMAIN[%d]",index+1);
  146. }
  147. }else{//setDomainForIp Timeout , we make it failed and quit
  148. wlog_warn("TUPS_START[%d] timeout", index);
  149. snprintf(info, sizeof(info),"+TCPOPEN:%d,0\r\n",index+1);
  150. msgToOutter(info);
  151. tupPara[index].status=TUPS_IDLE;
  152. }
  153. }else if(TUPS_DOMAIN==tupPara[index].status){
  154. ret=getDomainForIp(tupPara[index].index, tupPara[index].server.ipDomain, IP_DOMAIN_SIZE);
  155. if(DOMAIN_ERR==ret){
  156. wlog_warn("TUPS_DOMAIN[%d] failed", index+1);
  157. snprintf(info, sizeof(info),"+TCPOPEN:%d,0\r\n",index+1);
  158. msgToOutter(info);
  159. tupPara[index].status=TUPS_IDLE;
  160. }else if(DOMAIN_OK==ret){
  161. //done
  162. wlog_info("TUPS_DOMAIN[%d]:%s", index+1, tupPara[index].server.ipDomain);
  163. tupPara[index].status=TUPS_LINK;
  164. }else{
  165. if(getSysTick()>tupPara[index].time){//timeout
  166. wlog_warn("TUPS_DOMAIN[%d] timeout", index+1);
  167. snprintf(info, sizeof(info),"+TCPOPEN:%d,0\r\n",index+1);
  168. msgToOutter(info);
  169. tupPara[index].status=TUPS_IDLE;
  170. }
  171. }
  172. }else if(TUPS_LINK==tupPara[index].status){
  173. //trying to open tcp/udp here
  174. snprintf(info, sizeof(info),"+TCPOPEN:%d,",index+1);
  175. switch(tryConnectTup(tupPara[index].server.ipDomain, tupPara[index].server.tup,&tupPara[index].sendPara)){
  176. case TUP_STATUS_FALSE:
  177. wlog_warn("tupOpen failed:%d", index+1);
  178. strcat(info, "0");
  179. tupPara[index].status=TUPS_IDLE;
  180. strcat(info, "\r\n");
  181. msgToOutter(info);
  182. break;
  183. case TUP_STATUS_TRUE:
  184. wlog_warn("tupOpen ok:%d", index+1);
  185. strcat(info, "1");
  186. tupPara[index].status=TUPS_LINE;
  187. strcat(info, "\r\n");
  188. msgToOutter(info);
  189. break;
  190. case TUP_STATUS_WAIT:
  191. wlog_warn("tupOpen and wait result:%d", index+1);
  192. tupPara[index].status=TUPS_WAIT;
  193. break;
  194. }
  195. }else if(TUPS_WAIT==tupPara[index].status){
  196. if(tupPara[index].sendPara.errno!=0 ||tupPara[index].sendPara.tupStatus==CNNT_ERROR){
  197. snprintf(info, sizeof(info),"+TCPOPEN:%d,0\r\n",index+1);
  198. msgToOutter(info);
  199. tupPara[index].needClose=TRUE;
  200. }else if(tupPara[index].sendPara.tupStatus==CNNT_OK){
  201. snprintf(info, sizeof(info),"+TCPOPEN:%d,1\r\n",index+1);
  202. msgToOutter(info);
  203. tupPara[index].status=TUPS_LINE;
  204. }
  205. }else if(TUPS_LINE==tupPara[index].status){
  206. if(tupPara[index].sendPara.tupStatus==CNNT_CLOSED) tupPara[index].needClose=TRUE;
  207. }
  208. if(tupPara[index].needClose==TRUE){
  209. snprintf(info, sizeof(info),"+TCPCLOSE:%d\r\n",index+1);
  210. if(TUPS_IDLE == tupPara[index].status){
  211. tupPara[index].needClose=FALSE;
  212. msgToOutter(info);
  213. }else if(TUPS_DOMAIN != tupPara[index].status){
  214. //exec tup close cmd now
  215. if(tupPara[index].sendPara.fd!=0){
  216. //wlog_info("***skip close fd for test");
  217. userCloseSocket(&tupPara[index].sendPara.fd);
  218. }
  219. wlog_warn("TUPS[%d] user close done",index+1);
  220. if(tupPara[index].status==TUPS_LINE) msgToOutter(info);//打开过,也就是输出过+TCPOPEN:x,1才输出+TCPCLOSE:x
  221. tupPara[index].status=TUPS_IDLE;
  222. tupPara[index].needClose=FALSE;
  223. }
  224. }
  225. if(++index>=TUP_SOCKET_NUN) index=0;
  226. isTupTaskIdle();
  227. PTTimerStart(ptPool, &ptTimer,1);//can be be fast
  228. PT_WAIT_UNTIL(pt, PTTimerIsExpired(&ptTimer));
  229. }
  230. PT_END(pt);
  231. }
  232. T_BOOL findPortIndexAndLastDouHaoIndex(T_UINT8 *src, T_UINT16 srcLen,T_UINT16 *portIndex, T_UINT16 *lastIndex){
  233. //1,www.baidu.com:12345,0
  234. //1,120.77.66.129:12345,1
  235. T_UINT8 i;
  236. T_BOOL findPortAlread=FALSE;
  237. *lastIndex=0;
  238. for(i=0;i<srcLen;i++){
  239. if(TRUE==findPortAlread){
  240. if(src[i]==','){
  241. if(i+1<srcLen){
  242. *lastIndex=i+1;
  243. break;
  244. }
  245. }
  246. }
  247. if(src[i] == ':'){
  248. *portIndex=i+1;
  249. findPortAlread=TRUE;
  250. }
  251. }
  252. return findPortAlread;
  253. }
  254. T_BOOL tupParaGet(T_UINT8 *src, T_UINT16 srcLen,T_UINT8 *socket,TCPUDP_DEF *tupCtrl){
  255. //analysis parameter from src,src[0]='='
  256. //AT+TCPOPEN=1,www.baidu.com:12345
  257. //AT+TCPOPEN=1,120.77.66.129:12345
  258. T_INT8 *p=src;
  259. T_UINT8 i;
  260. T_UINT16 portIndex,douhaoIndex;
  261. if(srcLen < 11)
  262. return FALSE;
  263. if(p[1] != ',')
  264. return FALSE;
  265. if(FALSE==findPortIndexAndLastDouHaoIndex(src,srcLen,&portIndex,&douhaoIndex))
  266. return FALSE;
  267. //socket
  268. if(p[0] <= '0' || p[0] > (TUP_SOCKET_NUN+0x30))
  269. return FALSE;
  270. *socket = atoi(p);
  271. //IP/DOMAIN
  272. if(FALSE == checkIpDomain(src+2,portIndex-2,tupCtrl->ipDomain,&tupCtrl->ipdType))
  273. return FALSE;
  274. //port
  275. if(src[portIndex] < '0' || src[portIndex] > '9')
  276. return FALSE;
  277. tupCtrl->port=atoi(src+portIndex);
  278. //tup
  279. if(douhaoIndex==0) tupCtrl->tup=TUP_TCP;
  280. else{
  281. if(src[douhaoIndex]=='0') tupCtrl->tup=TUP_TCP;
  282. else if(src[douhaoIndex]=='1') tupCtrl->tup=TUP_UDP;
  283. else return FALSE;
  284. }
  285. return TRUE;
  286. }
  287. void tupOpen(T_UINT8 *data, T_UINT16 len){
  288. TCPUDP_DEF tempTup;
  289. T_UINT8 socket,ret;
  290. T_INT8 info[30];
  291. wlog_info("user need tupopen");
  292. if(talking.netWork.netReady==0){
  293. wlog_warn("no netWork yet");
  294. msgToOutter("+TCPOPEN:NO NET\r\n");
  295. return;
  296. }
  297. if(FALSE==tupParaGet(data,len,&socket,&tempTup)){
  298. wlog_warn("tupopen para err");
  299. msgToOutter("+TCPOPEN:ERROR\r\n");
  300. }else{
  301. ret=tupOpenApi(socket, &tempTup);
  302. if(ret==1){
  303. wlog_error("tupopen socket error");
  304. msgToOutter("+TCPOPEN:ERROR\r\n");
  305. }else if(ret==2){
  306. wlog_warn("tupopen socket:%d open already", socket);
  307. snprintf(info, sizeof(info),"+TCPOPEN:%d,ALREADY\r\n", socket);
  308. msgToOutter(info);
  309. }else if(ret==3){
  310. wlog_warn("tupopen is opening");
  311. snprintf(info, sizeof(info),"+TCPOPEN:%d,SYNC\r\n", socket);
  312. msgToOutter(info);
  313. }else wlog_info("tupopen try open start ok");
  314. }
  315. }
  316. void tupStatus(T_UINT8 *data, T_UINT16 len){
  317. //AT+TCPSTATUS=socket
  318. T_UINT8 socket,status=0;
  319. T_INT8 buf[30];
  320. if(len != 3) goto CMD_ERROR;
  321. socket = atoi(data);
  322. if(socket < 1 || socket > TUP_SOCKET_NUN) goto CMD_ERROR;
  323. wlog_info("tupStatus %d",socket);
  324. socket --;
  325. if(tupPara[socket].status == TUPS_LINE) status=1;
  326. snprintf(buf,sizeof(buf),"+TCPSTATUS:%d,%d\r\n",socket+1,status);
  327. msgToOutter(buf);
  328. return;
  329. CMD_ERROR:
  330. msgToOutter("+TCPSTATUS:ERROR\r\n");
  331. }
  332. void tupClose(T_UINT8 *data, T_UINT16 len){
  333. T_UINT8 socket;
  334. if(len != 3) goto CMD_ERROR;
  335. socket = atoi(data);
  336. if(socket < 1 || socket > TUP_SOCKET_NUN) goto CMD_ERROR;
  337. wlog_info("tupClose %d",socket);
  338. tupCloseApi(socket);
  339. return;
  340. CMD_ERROR:
  341. msgToOutter("+TCPCLOSE:ERROR\r\n");
  342. }
  343. void tcpUdpShutDown(void){
  344. T_UINT8 i;
  345. for(i=1;i<=TUP_SOCKET_NUN;i++){
  346. if(TUPS_IDLE != tupPara[i-1].status)
  347. tupCloseApi(i);
  348. }
  349. }
  350. void tupSend(T_UINT8 *data, T_UINT16 len){
  351. //AT+TCPSEND=socket,len,data
  352. T_INT32 i;
  353. T_UINT8 temp;
  354. T_UINT32 dataIndex;
  355. T_UINT8 socket;
  356. T_INT8 buf[30];
  357. wlog_info("tupSend req");
  358. if(len < 5) goto CMD_ERROR;
  359. socket = atoi(data);
  360. if(socket < 1 || socket > TUP_SOCKET_NUN) goto CMD_ERROR;
  361. socket --;
  362. if(tupPara[socket].status != TUPS_LINE){
  363. socket ++;
  364. goto CMD_ERROR;
  365. }
  366. temp=0;
  367. dataIndex=-1;
  368. for(i=0;i<len;i++)
  369. if(data[i]==','){
  370. temp++;
  371. if(temp==2) dataIndex=i+1;
  372. }
  373. if(dataIndex==-1){
  374. socket ++;
  375. goto CMD_ERROR;
  376. }
  377. i=atoi(data+2);
  378. if(i==0) return;
  379. trySendTup(data+dataIndex, i, tupPara[socket].server.tup, &tupPara[socket].sendPara);
  380. snprintf(buf, sizeof(buf), "+TCPSEND:%d,%d\r\n",socket+1,i);
  381. msgToOutter(buf);
  382. wlog_info("tupSendData:%d",i);
  383. return;
  384. CMD_ERROR:
  385. snprintf(buf, sizeof(buf), "+TCPSEND:%d,ERROR\r\n",socket);
  386. msgToOutter(buf);
  387. }