WIZlib Library API  ver 1.0
WIZlib Library API User Menual
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cmdrun.c
Go to the documentation of this file.
1 
12 //#define FILE_LOG_SILENCE
13 #include "appmod/atcmd/cmdrun.h"
14 
15 
16 #define SOCK_STAT_TCP_MASK 0x2
17 #define SOCK_STAT_PROTMASK 0x3
18 #define SOCK_STAT_IDLE 0x0
19 #define SOCK_STAT_UDP 0x1
20 #define SOCK_STAT_TCP_SRV 0x2
21 #define SOCK_STAT_TCP_CLT 0x3
22 #define SOCK_STAT_CONNECTED 0x4
23 
24 #define EVENT_RESP(id_v, evt_v) printf("[V,%d,%d]\r\n", id_v, evt_v)
25 #define EVENT_RESP_SIZE(id_v, evt_v, size_v) printf("[V,%d,%d,%d]\r\n", id_v, evt_v, size_v)
26 #define CMD_RESP_RET(type_v, id_v) do{DBG("#");cmd_resp(type_v, id_v); return;}while(0)
27 #define MAKE_TCMD_DIGIT(arg_p, dgt_p) sprintf((char*)arg_p, "%d", dgt_p)
28 #define MAKE_TCMD_CHAR(arg_p, char_p) sprintf((char*)arg_p, "%c", char_p)
29 #define MAKE_TCMD_ADDR(arg_p, a1_p, a2_p, a3_p, a4_p) \
30  sprintf((char*)arg_p, "%d.%d.%d.%d", a1_p, a2_p, a3_p, a4_p)
31 #define MAKE_TCMD_STRING(arg_p, argsize_v, str_p) do { \
32  uint8 len = strlen((char*)str_p); \
33  if(len > argsize_v-1) {memcpy((char*)arg_p, (char*)str_p, argsize_v-1); arg_p[argsize_v-1]=0;} \
34  else {memcpy((char*)arg_p, (char*)str_p, len); arg_p[len]=0;} \
35 } while(0)
36 
37 enum {
38  SOCKEVENT_CONN = 0,
39  SOCKEVENT_DISCON = 1,
40  SOCKEVENT_CLS = 2,
41  SOCKEVENT_RECV = 3
42 };
43 
44 struct atc_eventq {
45  struct atc_eventq *next;
46  int8 id;
47  int8 event;
48 };
49 
50 extern void cmd_resp(int8 retval, int8 idval);
51 
52 static int8 sockstat[ATC_SOCK_NUM_TOTAL+ATC_SOCK_AO] = {0,}; // for sock check (0 is ignored)
53 static int8 sockbusy[ATC_SOCK_NUM_TOTAL+ATC_SOCK_AO] = {0,}; // for sock busy check
54 static uint16 sockport[ATC_SOCK_NUM_TOTAL+ATC_SOCK_AO] = {0,}; // for src port check
55 static uint8 udpip[ATC_SOCK_NUM_TOTAL+ATC_SOCK_AO][4] = {0,}; // to store UDP Destination address
56 static uint16 udpport[ATC_SOCK_NUM_TOTAL+ATC_SOCK_AO] = {0,}; // to store UDP Destination port
57 static uint16 tcpleft[ATC_SOCK_NUM_TOTAL+ATC_SOCK_AO] = {0,}; // remained data len to send for TCP Resend
58 static int8 recvord[ATC_SOCK_NUM_TOTAL+ATC_SOCK_AO] = {0,}; // for check order of data recv
59 static int8 recvnum = 0; // the number of sock which received data
60 struct atc_eventq *eventqueue;
61 uint8 eqp_cnt = 0;
62 
63 
64 static int8 sock_get(int8 initval, uint16 srcport)
65 {
66  int8 i;
67 
68  DBGCRTCA(initval<1||initval>3, "wrong init value(%d)", initval);
69 
70  for(i=ATC_SOCK_NUM_START; i<=ATC_SOCK_NUM_END; i++) {
71  if(sockstat[i] == SOCK_STAT_IDLE) {
72  sockstat[i] = initval;
73  sockport[i] = srcport; //DBGA("Sock(%d) Assign stt(%d), port(%d)", i, sockstat[i], sockport[i]);
74  return i;
75  }
76  }
77 
78  return RET_NOK;
79 }
80 
81 static int8 sock_put(uint8 sock)
82 {
83  DBGCRTCA(sock<ATC_SOCK_NUM_START||sock>ATC_SOCK_NUM_END, "wrong sock(%d)", sock);
84 
85  if(sockstat[sock] & SOCK_STAT_UDP) {
86  udpip[sock][0] = udpip[sock][1] = udpip[sock][2] = 0;
87  udpip[sock][3] = udpport[sock] = 0;
88  }
89  sockstat[sock] = SOCK_STAT_IDLE;
90  sockport[sock] = 0;
92  return RET_OK;
93 }
94 
95 static int8 event_enqueue(int8 id, int8 event)
96 {
97 #define QFULL -1
98  struct atc_eventq **eqdp;
99 
100 
101 
102 struct atc_eventq *tmp1 = eventqueue;
103 DBGFA("EVT1-cnt(%d)", eqp_cnt);
104 while(tmp1) {
105  LOGFA(", (%d-%d)", tmp1->id, tmp1->event);
106  tmp1 = tmp1->next;
107 }
108 NL1;
109 
110 
111 
112 
113 
114 
115  eqdp = &eventqueue;
116  if(eqp_cnt >= EVENT_QUEUE_SIZE-1) {
117  while((*eqdp)->next) eqdp = &(*eqdp)->next;
118  if((*eqdp)->event != QFULL) {
119  eqdp = &(*eqdp)->next;
120  *eqdp = malloc(sizeof(struct atc_eventq));
121  if(*eqdp == NULL) {
122  ERRA("malloc fail - size(%d)", sizeof(struct atc_eventq));
123  return RET_NOK;
124  }
125  (*eqdp)->id = QFULL;
126  (*eqdp)->event = QFULL;
127  eqp_cnt++;
128  }
129  DBG("EVT FULL");
130  return RET_NOK;
131  }
132 
133  while(*eqdp) eqdp = &(*eqdp)->next;
134 
135  *eqdp = malloc(sizeof(struct atc_eventq));
136  if(*eqdp == NULL) {
137  ERRA("malloc fail - size(%d)", sizeof(struct atc_eventq));
138  return RET_NOK;
139  }
140 
141  (*eqdp)->id = id;
142  (*eqdp)->event = event;
143  eqp_cnt++;
144 
145 
146 struct atc_eventq *tmp2 = eventqueue;
147 DBGFA("EVT2-cnt(%d)", eqp_cnt);
148 while(tmp2) {
149  LOGFA(", (%d-%d)", tmp2->id, tmp2->event);
150  tmp2 = tmp2->next;
151 }
152 NL1;
153 
154 
155  return RET_OK;
156 }
157 
158 static int8 event_dequeue(int8 *id, int8 *event)
159 {
160  struct atc_eventq *eqp, **eqdp;
161 
162  if(id == NULL || event == NULL) return RET_NOK;
163 
164 
165 struct atc_eventq *tmp3 = eventqueue;
166 DBGFA("EVT3-cnt(%d)", eqp_cnt);
167 while(tmp3) {
168  LOGFA(", (%d-%d)", tmp3->id, tmp3->event);
169  tmp3 = tmp3->next;
170 }
171 NL1;
172 
173 
174 
175  if(*id < 0) {
176  if(eqp_cnt == 0) return RET_NOK;
177  eqp = eventqueue;
178  eventqueue = eventqueue->next;
179  eqp_cnt--;
180  *id = eqp->id;
181  *event = eqp->event;
182  free(eqp);
183 
184 struct atc_eventq *tmp44 = eventqueue;
185 DBGFA("EVT4-cnt(%d)", eqp_cnt);
186 while(tmp44) {
187  LOGFA(", (%d-%d)", tmp44->id, tmp44->event);
188  tmp44 = tmp44->next;
189 }
190 NL1;
191 
192  return RET_OK;
193  } else {
194  eqdp = &eventqueue;
195  while(*eqdp) {
196  if((*eqdp)->id == *id) {
197  *event = (*eqdp)->event;
198  eqp = *eqdp;
199  *eqdp = (*eqdp)->next;
200  free(eqp);
201  eqp_cnt--;
202 
203 
204 struct atc_eventq *tmp5 = eventqueue;
205 DBGFA("EVT5-cnt(%d)", eqp_cnt);
206 while(tmp5) {
207  LOGFA(", (%d-%d)", tmp5->id, tmp5->event);
208  tmp5 = tmp5->next;
209 }
210 NL1;
211 
212  return RET_OK;
213  }
214  }
215  return RET_NOK;
216  }
217 }
218 
219 static void atc_resend_alarm(int8 arg)
220 {
221  int8 ret;
222 
223  ret = TCPReSendNB(arg);
224  if(ret != RET_OK) {
225  if(ret == SOCKERR_BUSY) {
226  alarm_set(WINDOWFULL_WAIT_TIME, atc_resend_alarm, arg);
227  } else if(ret == SOCKERR_WINDOW_FULL) {
228  sockbusy[arg] = VAL_FALSE;
229  DBGA("WATCH_SOCK_TCP_SEND fail - ret(%d)", ret);
230  cmd_resp(RET_TIMEOUT, arg);
231  } else {
232  sockbusy[arg] = VAL_FALSE;
233  DBGA("WATCH_SOCK_TCP_SEND fail - ret(%d)", ret);
234  cmd_resp(RET_TIMEOUT, arg);
235  sock_put(arg);
236  if(atci.poll != POLL_MODE_FULL) EVENT_RESP(arg, SOCKEVENT_CLS);
237  else event_enqueue(arg, SOCKEVENT_CLS);
238  }
239  } else sockwatch_set(arg, WATCH_SOCK_TCP_SEND);
240 }
241 
242 void atc_async_cb(uint8 sock, uint8 item, int32 ret)
243 {
244  DBGCRTCA(sock<ATC_SOCK_NUM_START||sock>ATC_SOCK_NUM_END, "wrong sock(%d)", sock);
245 
246  switch(item) {
247  case WATCH_SOCK_UDP_SEND: DBG("WATCH_SOCK_UDP_SEND");
248  sockbusy[sock] = VAL_FALSE; //DBGA("WATCH UDP Sent - sock(%d), item(%d)", sock, item);
249  if(ret == RET_OK) {
250  cmd_resp(RET_OK, sock);
251  } else {
252  DBGA("WATCH_SOCK_UDP_SEND fail - ret(%d)", ret);
253  cmd_resp(RET_TIMEOUT, sock);
254  }
255  break;
256  case WATCH_SOCK_TCP_SEND: DBG("WATCH_SOCK_TCP_SEND");
257  if(ret < RET_OK) {
258  sockbusy[sock] = VAL_FALSE;
259  DBGA("WATCH_SOCK_TCP_SEND fail - ret(%d)", ret);
260  cmd_resp(RET_TIMEOUT, sock);
261  sock_put(sock);
262  if(atci.poll != POLL_MODE_FULL) EVENT_RESP(sock, SOCKEVENT_CLS);
263  else event_enqueue(sock, SOCKEVENT_CLS);
264  } else {
265  tcpleft[sock] -= ret;
266  if(tcpleft[sock] > 0) {
267  ret = TCPReSendNB(sock);
268  if(ret != RET_OK) {
269  if(ret == SOCKERR_BUSY) {
270  alarm_set(WINDOWFULL_WAIT_TIME, atc_resend_alarm, sock);
271  } else if(ret == SOCKERR_WINDOW_FULL) {
272  sockbusy[sock] = VAL_FALSE;
273  DBGA("WATCH_SOCK_TCP_SEND fail - ret(%d)", ret);
274  cmd_resp(RET_TIMEOUT, sock);
275  } else {
276  sockbusy[sock] = VAL_FALSE;
277  DBGA("WATCH_SOCK_TCP_SEND fail - ret(%d)", ret);
278  cmd_resp(RET_TIMEOUT, sock);
279  sock_put(sock);
280  if(atci.poll != POLL_MODE_FULL) EVENT_RESP(sock, SOCKEVENT_CLS);
281  else event_enqueue(sock, SOCKEVENT_CLS);
282  }
283  } else sockwatch_set(sock, WATCH_SOCK_TCP_SEND);
284  } else {
285  sockbusy[sock] = VAL_FALSE;
286  cmd_resp(RET_OK, sock);
287  }
288  }
289  break;
290  case WATCH_SOCK_CONN_TRY: DBG("WATCH_SOCK_CONN_TRY");
291  sockbusy[sock] = VAL_FALSE;
292  if(ret == RET_OK) {
293  BITSET(sockstat[sock], SOCK_STAT_CONNECTED);
296  cmd_resp(RET_OK, sock);//cmd_resp(RET_ASYNC, sock);??
297  } else {
298  DBGA("WATCH_SOCK_CONN_EVT fail - ret(%d)", ret);
299  cmd_resp(RET_TIMEOUT, sock);
300  sock_put(sock);
301  }
302  break;
303  case WATCH_SOCK_CLS_TRY: DBG("WATCH_SOCK_CLS_TRY");
304  sockbusy[sock] = VAL_FALSE;
305  if(ret == RET_OK) {
306  cmd_resp(RET_OK, sock);
307  sock_put(sock);
308  } else {
309  CRITICAL_ERRA("WATCH_SOCK_CONN_EVT fail - ret(%d)", ret);
310  }
311  break;
312  case WATCH_SOCK_CONN_EVT: DBG("WATCH_SOCK_CONN_EVT");
313  if(ret == RET_OK) {
314  BITSET(sockstat[sock], SOCK_STAT_CONNECTED);
317  if(atci.poll != POLL_MODE_FULL) EVENT_RESP(sock, SOCKEVENT_CONN);
318  else event_enqueue(sock, SOCKEVENT_CONN);
319  } else {
320  CRITICAL_ERRA("WATCH_SOCK_CONN_EVT fail - ret(%d)", ret);
321  }
322  break;
323  case WATCH_SOCK_CLS_EVT: DBG("WATCH_SOCK_CLS_EVT");
324  sockbusy[sock] = VAL_FALSE;
325  if(ret == RET_OK) {
326  //if(sockwatch_chk(sock, WATCH_SOCK_CLS_TRY) == RET_OK) removed-직접처리
327  // cmd_resp(RET_OK, sock);
328  if((sockstat[sock] & SOCK_STAT_PROTMASK) == SOCK_STAT_TCP_SRV) {
329  DBGA("Conn(%d) Closed - back to the Listen state", sock);
330  BITCLR(sockstat[sock], SOCK_STAT_CONNECTED);
332  ret = TCPServerOpen(sock, sockport[sock]);
333  if(ret == RET_OK) {
335  if(atci.poll != POLL_MODE_FULL) EVENT_RESP(sock, SOCKEVENT_DISCON);
336  else event_enqueue(sock, SOCKEVENT_DISCON);
337  } else {
338  sock_put(sock);
339  if(atci.poll != POLL_MODE_FULL) EVENT_RESP(sock, SOCKEVENT_CLS);
340  else event_enqueue(sock, SOCKEVENT_CLS);
341  }
342  } else {
343  sock_put(sock);
344  if(atci.poll != POLL_MODE_FULL) EVENT_RESP(sock, SOCKEVENT_CLS);
345  else event_enqueue(sock, SOCKEVENT_CLS);
346  }
347  } else {
348  CRITICAL_ERRA("WATCH_SOCK_CONN_EVT fail - ret(%d)", ret);
349  }
350  break;
351  case WATCH_SOCK_RECV: DBG("WATCH_SOCK_RECV");
352  {
353  int8 i;
354 
355  DBGA("WATCH1-sock(%d),recvnum(%d),recvord(%d,%d,%d,%d,%d,%d,%d,%d)", sock, recvnum, recvord[0],
356  recvord[1], recvord[2], recvord[3], recvord[4], recvord[5], recvord[6], recvord[7]);
357 
358  if(atci.poll != POLL_MODE_NONE) {
359  if(recvord[sock] == 0) {
360  recvnum++;
361  recvord[sock] = 1;
362  for(i=ATC_SOCK_NUM_START; i<=ATC_SOCK_NUM_END; i++)
363  if(i != sock && recvord[i] != 0) recvord[i]++;
364  } //else { // 5200버퍼없어 못받고 잇다가 recv후 바로 수신되면 진입가능함 오류가 아님
365  // ERR("wrong recv order");
366  //}
367 
368  if(atci.poll != POLL_MODE_FULL)
369  EVENT_RESP_SIZE(sock, SOCKEVENT_RECV, GetSocketRxRecvBufferSize(sock));
370  else event_enqueue(sock, SOCKEVENT_RECV);
371  } else {
372  act_nrecv(sock, WORK_BUF_SIZE);
373  }
374 
375  DBGA("WATCH2-sock(%d),recvnum(%d),recvord(%d,%d,%d,%d,%d,%d,%d,%d)", sock, recvnum, recvord[0],
376  recvord[1], recvord[2], recvord[3], recvord[4], recvord[5], recvord[6], recvord[7]);
377  }
378  break;
379  default: CRITICAL_ERRA("wrong item(0x%x)", item);
380  }
381 }
382 
383 void act_nset_q(int8 num)
384 {
385  wiz_NetInfo ni;
386 
387  if(num == 1) {
388  GetNetInfo(&ni);
389  if(ni.dhcp == NETINFO_DHCP)
390  MAKE_TCMD_CHAR(atci.tcmd.arg1, 'D');
391  else MAKE_TCMD_CHAR(atci.tcmd.arg1, 'S');
392  CMD_RESP_RET(RET_OK, VAL_NONE);
393  } else if(num > 1) {
394  dhcp_get_storage(&ni);
395  switch(num) {
396  case 2: MAKE_TCMD_ADDR(atci.tcmd.arg1, ni.ip[0], ni.ip[1], ni.ip[2], ni.ip[3]); break;
397  case 3: MAKE_TCMD_ADDR(atci.tcmd.arg1, ni.sn[0], ni.sn[1], ni.sn[2], ni.sn[3]); break;
398  case 4: MAKE_TCMD_ADDR(atci.tcmd.arg1, ni.gw[0], ni.gw[1], ni.gw[2], ni.gw[3]); break;
399  case 5: MAKE_TCMD_ADDR(atci.tcmd.arg1, ni.dns[0], ni.dns[1], ni.dns[2], ni.dns[3]); break;
400  case 6: CMD_RESP_RET(RET_NOT_ALLOWED, VAL_NONE);
401  }
402  CMD_RESP_RET(RET_OK, VAL_NONE);
403  } else {
404  GetNetInfo(&ni);
405  if(ni.dhcp == NETINFO_DHCP)
406  MAKE_TCMD_CHAR(atci.tcmd.arg1, 'D');
407  else MAKE_TCMD_CHAR(atci.tcmd.arg1, 'S');
408  dhcp_get_storage(&ni);
409  MAKE_TCMD_ADDR(atci.tcmd.arg2, ni.ip[0], ni.ip[1], ni.ip[2], ni.ip[3]);
410  MAKE_TCMD_ADDR(atci.tcmd.arg3, ni.sn[0], ni.sn[1], ni.sn[2], ni.sn[3]);
411  MAKE_TCMD_ADDR(atci.tcmd.arg4, ni.gw[0], ni.gw[1], ni.gw[2], ni.gw[3]);
412  MAKE_TCMD_ADDR(atci.tcmd.arg5, ni.dns[0], ni.dns[1], ni.dns[2], ni.dns[3]);
413  CMD_RESP_RET(RET_OK, VAL_NONE);
414  }
415 }
416 
417 void act_nset_a(int8 mode, uint8 *ip, uint8 *sn,
418  uint8 *gw, uint8 *dns1, uint8 *dns2)
419 {
420  wiz_NetInfo ni = {0,};
421 
422  if(ip) memcpy(ni.ip, ip, 4);
423  if(sn) memcpy(ni.sn, sn, 4);
424  if(gw) memcpy(ni.gw, gw, 4);
425  if(dns1) memcpy(ni.dns, dns1, 4);
426  if(dns2) {
427  MAKE_TCMD_DIGIT(atci.tcmd.arg1, 6);
428  CMD_RESP_RET(RET_NOT_ALLOWED, VAL_NONE);
429  }
430 
431  if(mode == 'S') {
432  dhcp_static_mode(&ni);
433  dhcp_set_storage(&ni);
434  SetNetInfo(&ni);
435  } else if(mode == 'D') {
436  dhcp_set_storage(&ni);
437  dhcp_auto_start();
438  } else {
439  dhcp_set_storage(&ni);
440  GetNetInfo(&ni);
441  if(ni.dhcp == NETINFO_STATIC) SetNetInfo(&ni);
442  }
443  CMD_RESP_RET(RET_OK, VAL_NONE);
444 }
445 
446 void act_nstat(int8 num)
447 {
448  wiz_NetInfo ni = {0,};
449 
450  GetNetInfo(&ni);
451  if(num == 1) {
452  if(ni.dhcp == NETINFO_DHCP)
453  MAKE_TCMD_CHAR(atci.tcmd.arg1, 'D');
454  else MAKE_TCMD_CHAR(atci.tcmd.arg1, 'S');
455  CMD_RESP_RET(RET_OK, VAL_NONE);
456  } else if(num > 1) {
457  switch(num) {
458  case 2: MAKE_TCMD_ADDR(atci.tcmd.arg1, ni.ip[0], ni.ip[1], ni.ip[2], ni.ip[3]); break;
459  case 3: MAKE_TCMD_ADDR(atci.tcmd.arg1, ni.sn[0], ni.sn[1], ni.sn[2], ni.sn[3]); break;
460  case 4: MAKE_TCMD_ADDR(atci.tcmd.arg1, ni.gw[0], ni.gw[1], ni.gw[2], ni.gw[3]); break;
461  case 5: MAKE_TCMD_ADDR(atci.tcmd.arg1, ni.dns[0], ni.dns[1], ni.dns[2], ni.dns[3]); break;
462  case 6: CMD_RESP_RET(RET_NOT_ALLOWED, VAL_NONE);
463  }
464  CMD_RESP_RET(RET_OK, VAL_NONE);
465  } else {
466  if(ni.dhcp == NETINFO_DHCP)
467  MAKE_TCMD_CHAR(atci.tcmd.arg1, 'D');
468  else MAKE_TCMD_CHAR(atci.tcmd.arg1, 'S');
469  MAKE_TCMD_ADDR(atci.tcmd.arg2, ni.ip[0], ni.ip[1], ni.ip[2], ni.ip[3]);
470  MAKE_TCMD_ADDR(atci.tcmd.arg3, ni.sn[0], ni.sn[1], ni.sn[2], ni.sn[3]);
471  MAKE_TCMD_ADDR(atci.tcmd.arg4, ni.gw[0], ni.gw[1], ni.gw[2], ni.gw[3]);
472  MAKE_TCMD_ADDR(atci.tcmd.arg5, ni.dns[0], ni.dns[1], ni.dns[2], ni.dns[3]);
473  CMD_RESP_RET(RET_OK, VAL_NONE);
474  }
475 }
476 
477 void act_nmac_q(void)
478 {
479  wiz_NetInfo ni = {0,};
480 
481  GetNetInfo(&ni);
482  sprintf((char*)atci.tcmd.arg1, "%d:%d:%d:%d:%d:%d",
483  ni.mac[0], ni.mac[1], ni.mac[2], ni.mac[3], ni.mac[4], ni.mac[5]);
484  CMD_RESP_RET(RET_OK, VAL_NONE);
485 }
486 
487 void act_nmac_a(uint8 *mac)
488 {
489 #if 1 // Enable MAC change
490  wiz_NetInfo ni = {0,};
491 
492  memcpy(ni.mac, mac, 6);
493  SetNetInfo(&ni);
494  CMD_RESP_RET(RET_OK, VAL_NONE);
495 #else
496  CMD_RESP_RET(RET_NOT_ALLOWED, VAL_NONE);
497 #endif
498 }
499 
500 void act_nopen_q(void)
501 {
502  cmd_resp(RET_NOT_ALLOWED, VAL_NONE);
503 }
504 
505 void act_nopen_a(int8 type, uint16 sport, uint8 *dip, uint16 dport)
506 {
507  int8 ret, sock, i;
508 
509  for(i=ATC_SOCK_NUM_START; i<=ATC_SOCK_NUM_END; i++) {
510  if(sockstat[i] != SOCK_STAT_IDLE && sockport[i] == sport) {
511  DBGA("src port(%d) is using now by sock(%d)", sport, i);
512  MAKE_TCMD_DIGIT(atci.tcmd.arg1, 2);
513  CMD_RESP_RET(RET_USING_PORT, VAL_NONE);
514  }
515  }
516 
517  if(type == 'S') {
518  sock = sock_get(SOCK_STAT_TCP_SRV, sport);
519  if(sock == RET_NOK) CMD_RESP_RET(RET_NO_SOCK, VAL_NONE);
520  ret = TCPServerOpen(sock, sport);
521  if(ret != RET_OK) CMD_RESP_RET(RET_UNSPECIFIED, VAL_NONE);
523  MAKE_TCMD_DIGIT(atci.tcmd.arg1, sock);
524  CMD_RESP_RET(RET_OK, VAL_NONE);
525  } else if(type == 'C') {
526  sock = sock_get(SOCK_STAT_TCP_CLT, sport);
527  if(sock == RET_NOK) CMD_RESP_RET(RET_NO_SOCK, VAL_NONE);
528  ret = TCPCltOpenNB(sock, sport, dip, dport);
529  if(ret != RET_OK) {
530  DBGA("TCPCltOpenNB fail - ret(%d)", ret);
531  CMD_RESP_RET(RET_WRONG_ADDR, VAL_NONE);
532  }
534  sockbusy[sock] = VAL_TRUE;
535  CMD_RESP_RET(RET_ASYNC, sock);
536  } else {
537  sock = sock_get(SOCK_STAT_UDP, sport);
538  if(sock == RET_NOK) CMD_RESP_RET(RET_NO_SOCK, VAL_NONE);
539  if(dip != NULL) {
540  memcpy(udpip[sock], dip, 4);
541  udpport[sock] = dport;
542  }
543  UDPOpen(sock, sport);
545  MAKE_TCMD_DIGIT(atci.tcmd.arg1, sock);
546  CMD_RESP_RET(RET_OK, VAL_NONE);
547  }
548 }
549 
550 void act_ncls(uint8 sock)
551 {
552  int8 ret;
553 
554  if(sockbusy[sock] == VAL_TRUE) CMD_RESP_RET(RET_BUSY, VAL_NONE);
555  if(sockstat[sock] == SOCK_STAT_IDLE) CMD_RESP_RET(RET_SOCK_CLS, VAL_NONE);
556  if(sockstat[sock] & SOCK_STAT_TCP_MASK) {
557  ret = TCPCloseNB(sock);
558  if(ret != RET_OK) CMD_RESP_RET(RET_SOCK_CLS, VAL_NONE);
561  sockbusy[sock] = VAL_TRUE;
562  CMD_RESP_RET(RET_ASYNC, sock);
563  } else {
564  UDPClose(sock);
565  sock_put(sock);
566  CMD_RESP_RET(RET_OK, VAL_NONE);
567  }
568 }
569 
570 int8 act_nsend_chk(uint8 sock, uint16 *len, uint8 *dip, uint16 *dport)
571 {
572  uint16 availlen;
573 
574  if(sockbusy[sock] == VAL_TRUE) {
575  cmd_resp(RET_BUSY, VAL_NONE);
576  return RET_NOK;
577  }
578  if(sockstat[sock] == SOCK_STAT_IDLE) {
579  cmd_resp(RET_SOCK_CLS, VAL_NONE);
580  return RET_NOK;
581  }
582 
583  if(sockstat[sock] & SOCK_STAT_TCP_MASK) { // TCP
584  if(!(sockstat[sock] & SOCK_STAT_CONNECTED)) {
585  cmd_resp(RET_NOT_CONN, VAL_NONE);
586  return RET_NOK;
587  }
588  if(dip || dport) {
589  cmd_resp(RET_WRONG_ARG, VAL_NONE);
590  if(dip) MAKE_TCMD_DIGIT(atci.tcmd.arg1, 3);
591  else MAKE_TCMD_DIGIT(atci.tcmd.arg1, 4);
592  return RET_NOK;
593  }
594  } else { // UDP
595  if(dip == NULL) {
596  if(udpip[sock][0]==0 && udpip[sock][1]==0 &&
597  udpip[sock][2]==0 && udpip[sock][3]==0) {
598  DBG("No Predefined Dst IP");
599  MAKE_TCMD_DIGIT(atci.tcmd.arg1, 3);
600  cmd_resp(RET_WRONG_ARG, VAL_NONE);
601  return RET_NOK;
602  } else memcpy(atci.sendip, udpip[sock], 4);
603  }
604  if(dport == NULL) {
605  if(udpport[sock] == 0) {
606  DBG("No Predefined Dst Port");
607  MAKE_TCMD_DIGIT(atci.tcmd.arg1, 4);
608  cmd_resp(RET_WRONG_ARG, VAL_NONE);
609  return RET_NOK;
610  } else atci.sendport = udpport[sock];
611  }
612  }
613 
614  availlen = GetSocketTxFreeBufferSize(sock);
615  if(*len > availlen) {
616  DBGA("tx buf busy - req(%d), avail(%d)", *len, availlen);
617  MAKE_TCMD_DIGIT(atci.tcmd.arg1, availlen);
618  cmd_resp(RET_BUSY, VAL_NONE);
619  return RET_NOK;
620  }
621 
622  return RET_OK;
623 }
624 
625 void act_nsend(uint8 sock, int8 *buf, uint16 len, uint8 *dip, uint16 *dport)
626 {
627  int32 ret;
628 
629  if(sockstat[sock] & SOCK_STAT_TCP_MASK) { // TCP
630  ret = TCPSendNB(sock, buf, len);
631  if(ret == SOCKERR_BUSY)
632  CRITICAL_ERRA("Impossible TCP send busy - len(%d), avail(%d)",
633  len, GetSocketTxFreeBufferSize(sock));
634  if(ret != RET_OK) CMD_RESP_RET(RET_NOT_CONN, VAL_NONE);
635  tcpleft[sock] = len;
637  sockbusy[sock] = VAL_TRUE;
638  } else { // UDP
639  ret = UDPSendNB(sock, buf, len, dip, *dport);
640  if(ret == SOCKERR_BUSY)
641  CRITICAL_ERRA("Impossible UDP send busy - len(%d), avail(%d)",
642  len, GetSocketTxFreeBufferSize(sock));
643  if(ret < RET_OK) {
644  DBGA("UDPSendNB fail - ret(%d)", ret);
645  CMD_RESP_RET(RET_WRONG_ADDR, VAL_NONE);
646  } else {
647  DBGA("UDPSendNB SUCC - len(%d),sent(%d)", len, ret);
648  }
650  sockbusy[sock] = VAL_TRUE;
651  }
652 }
653 
654 void act_nrecv(int8 sock, uint16 maxlen)
655 {
656  int8 ret;
657  uint8 dstip[4], i;
658  uint16 dstport;
659  int32 len=0, offset=0;
660 
661  DBGA("DBG1-sock(%d),recvnum(%d),recvord(%d,%d,%d,%d,%d,%d,%d,%d)", sock, recvnum, recvord[0],
662  recvord[1], recvord[2], recvord[3], recvord[4], recvord[5], recvord[6], recvord[7]);
663 
664  if(sock == VAL_NONE) {
665  if(recvnum == 0) {
666  DBGA("no data - sock(%d)", sock);
667  ret = RET_NO_DATA;
668  goto FAIL_RET;
669  }
670  for(i=ATC_SOCK_NUM_START; i<=ATC_SOCK_NUM_END; i++) {
671  if(recvord[i] == recvnum) {
672  sock = i;
673  break;
674  }
675  }
676  DBGCRTCA(sock < 0, "wrong recv order - sock(%d),recvnum(%d),"
677  "recvord(%d,%d,%d,%d,%d,%d,%d,%d)", sock, recvnum, recvord[0], recvord[1],
678  recvord[2], recvord[3], recvord[4], recvord[5], recvord[6], recvord[7]);
679  }
680 
681  DBGA("DBG2-sock(%d),recvnum(%d),recvord(%d,%d,%d,%d,%d,%d,%d,%d)", sock, recvnum, recvord[0],
682  recvord[1], recvord[2], recvord[3], recvord[4], recvord[5], recvord[6], recvord[7]);
683 
684  if(sockstat[sock] == SOCK_STAT_IDLE) {
685  ret = RET_SOCK_CLS;
686  goto FAIL_RET;
687  }
688  if(sockstat[sock] & SOCK_STAT_TCP_MASK) { // TCP
689 DBGA("TCPdbg---rx(%d)",GetSocketRxRecvBufferSize(sock));
690  if(!(sockstat[sock] & SOCK_STAT_CONNECTED)) {
691  DBGA("not connected - sock(%d)", sock);
692  ret = RET_NOT_CONN;
693  goto FAIL_RET;
694  }
695  if(GetSocketRxRecvBufferSize(sock) == 0) {
696  DBGA("no data - sock(%d)", sock);
697  ret = RET_NO_DATA;
698  goto FAIL_RET;
699  }
700  len = TCPRecv(sock, atci.recvbuf, maxlen); DBGA("TCPdbg---m(%d)l(%d)f(%d)", maxlen, len, GetSocketRxRecvBufferSize(sock));
701  } else { // UDP
702  uint16 bufleft = maxlen;
703  if(GetSocketRxRecvBufferSize(sock) == 0) {
704  DBGA("no data - sock(%d)", sock);
705  ret = RET_NO_DATA;
706  goto FAIL_RET;
707  }
708 
709  do {
710  DBGCRTC(len + bufleft > WORK_BUF_SIZE, "buf not enough");
711  offset = UDPRecv(sock, &atci.recvbuf[len], bufleft, dstip, &dstport);
712  if(offset <= 0 || offset > (int32)bufleft) { // Abnormal case - I don't think this could happen but just in case.
713  if(offset > (int32)bufleft) {
714  ERRA("buf overflw - off(%d), maxlen(%d)", offset, bufleft);
715  if(len == 0) {
716  ret = RET_UNSPECIFIED;
717  goto FAIL_RET;
718  }
719  bufleft = 0;
720  } else {
721  ERRA("wrong reaction - ret(%d)", offset);
722  if(len == 0) {
723  if(offset == SOCKERR_CLOSED) {
724  ret = RET_SOCK_CLS;
725  goto FAIL_RET;
726  } else if(offset < 0) {
727  ret = RET_UNSPECIFIED;
728  goto FAIL_RET;
729  } else {
730  ret = RET_NO_DATA;
731  goto FAIL_RET;
732  }
733  }
734  }
735  } else { // Normal case
736  DBGA("UDP Recv - off(%d), len(%d), maxlen(%d)", offset, len, bufleft);
737  len += offset;
738  bufleft -= offset;
739  }
740  }
741  while(GetSocketRxRecvBufferSize(sock) && bufleft > 0);
742 
743  }
744  atci.recvbuf[len] = 0;
745  DBGA("RECV prt-len(%d), max(%d)", len, maxlen);
746 
747  MAKE_TCMD_DIGIT(atci.tcmd.arg1, len);
748  if((sockstat[sock] & SOCK_STAT_PROTMASK) == SOCK_STAT_UDP) {
749  MAKE_TCMD_ADDR(atci.tcmd.arg2, dstip[0], dstip[1], dstip[2], dstip[3]);
750  MAKE_TCMD_DIGIT(atci.tcmd.arg3, dstport);
751  }
752 
753  if(GetSocketRxRecvBufferSize(sock) == 0) { // If there is no data left.
754  if(recvord[sock] < recvnum) {
755  for(i=ATC_SOCK_NUM_START; i<=ATC_SOCK_NUM_END; i++)
756  if(recvord[i] > recvord[sock]) recvord[i]--;
757  }
758  recvord[sock] = 0;
759  recvnum--;
760 
761  if((sockstat[sock] & SOCK_STAT_PROTMASK) == SOCK_STAT_IDLE) { // 디버그용임. 안정되면 간단하게 수정할 것
762  CRITICAL_ERRA("Impossible status - recv from closed sock(%d)", sock);
763  } else if(sockstat[sock] & SOCK_STAT_TCP_MASK) { // TCP
764  if(sockstat[sock] & SOCK_STAT_CONNECTED)
766  } else if(sockstat[sock] & SOCK_STAT_UDP) {
768  } else CRITICAL_ERRA("Impossible status - wrong sock state(0x%x)", sockstat[sock]);
769 
770  cmd_resp(RET_RECV, sock);
771  printf("%s\r\n", atci.recvbuf);
772  } else {
773  cmd_resp(RET_RECV, sock);
774  printf("%s\r\n", atci.recvbuf);
775  EVENT_RESP_SIZE(sock, SOCKEVENT_RECV, GetSocketRxRecvBufferSize(sock));
776  // ????
777  //if(atci.poll != POLL_MODE_FULL)
778  // EVENT_RESP_SIZE(sock, SOCKEVENT_RECV, GetSocketRxRecvBufferSize(sock));
779  //else event_enqueue(sock, SOCKEVENT_RECV);
780  }
781 
782 DBGA("DBG3^1-sock(%d),recvnum(%d),recvord(%d,%d,%d,%d,%d,%d,%d,%d)", sock, recvnum, recvord[0],
783  recvord[1], recvord[2], recvord[3], recvord[4], recvord[5], recvord[6], recvord[7]);
784 
785 /*
786 if(atci.poll != POLL_MODE_NONE) {
787  if(recvord[sock] == 0) {
788  recvnum++;
789  recvord[sock] = 1;
790  for(i=ATC_SOCK_NUM_START; i<=ATC_SOCK_NUM_END; i++)
791  if(recvord[i] != 0) recvord[i]++;
792  } else {
793  ERR("wrong recv order");
794  }
795 
796  if(atci.poll != POLL_MODE_FULL)
797  EVENT_RESP_SIZE(sock, SOCKEVENT_RECV, GetSocketRxRecvBufferSize(sock));
798  else event_enqueue(sock, SOCKEVENT_RECV);
799 } else {
800  act_nrecv(sock, WORK_BUF_SIZE);
801 }
802 */
803 
804 
805 
806 
807 
808 
809  return;
810 
811 FAIL_RET:
812 
813  DBGA("DBG3^2-sock(%d),recvnum(%d),recvord(%d,%d,%d,%d,%d,%d,%d,%d)", sock, recvnum, recvord[0],
814  recvord[1], recvord[2], recvord[3], recvord[4], recvord[5], recvord[6], recvord[7]);
815 
816  CMD_RESP_RET(ret, VAL_NONE);
817 }
818 
819 void act_nsock(int8 sock)
820 {
821  uint8 tip[4];
822  uint16 tport;
823 
824  if(sock < ATC_SOCK_NUM_START)
825  {
826  int8 *dump, i, type, cnt_con=0, cnt_notcon=0;
827 
828  //DBG("NSOCK-start");
829  for(i=ATC_SOCK_NUM_START; i<=ATC_SOCK_NUM_END; i++) {
830  if(sockstat[i] != SOCK_STAT_IDLE) {
831  if((sockstat[i] & SOCK_STAT_PROTMASK) == SOCK_STAT_UDP) {
832  if(udpport[i] != 0) cnt_con++;
833  else cnt_notcon++;
834  } else {
835  if(sockstat[i] & SOCK_STAT_CONNECTED) cnt_con++;
836  else cnt_notcon++;
837  }
838  }
839  } //DBGA("NSOCK-con(%d),not(%d)", cnt_con, cnt_notcon);
840 
841  if(cnt_con+cnt_notcon == 0) {
842  cmd_resp_dump(VAL_NONE, NULL);
843  return;
844  }
845  dump = malloc((34*cnt_con)+(12*cnt_notcon)+1);
846  if(dump == NULL) CMD_RESP_RET(RET_NO_FREEMEM, VAL_NONE);
847  cnt_con = 0;
848  for(i=ATC_SOCK_NUM_START; i<=ATC_SOCK_NUM_END; i++) {
849  if(sockstat[i] == SOCK_STAT_IDLE) continue;
850  if(cnt_con != 0) {
851  dump[cnt_con++] = '\r';
852  dump[cnt_con++] = '\n';
853  }
854 
855  if((sockstat[i]&SOCK_STAT_PROTMASK)==SOCK_STAT_UDP) {
856  if(udpport[i]) {
857  sprintf((char*)&dump[cnt_con], "%d,%c,%d,%d.%d.%d.%d,%d", i, 'U', sockport[i],
858  udpip[i][0], udpip[i][1], udpip[i][2], udpip[i][3], udpport[i]);
859  } else {
860  sprintf((char*)&dump[cnt_con], "%d,%c,%d", i, 'U', sockport[i]);
861  }
862  } else {
863  if((sockstat[i]&SOCK_STAT_PROTMASK)==SOCK_STAT_TCP_SRV) type = 'S';
864  else type='C';
865  if(sockstat[i] & SOCK_STAT_CONNECTED) {
866  GetDstInfo((uint8)i, tip, &tport);
867  sprintf((char*)&dump[cnt_con], "%d,%c,%d,%d.%d.%d.%d,%d", i, type,
868  sockport[i], tip[0], tip[1], tip[2], tip[3], tport);
869  } else {
870  sprintf((char*)&dump[cnt_con], "%d,%c,%d", i, type, sockport[i]);
871  }
872  }
873  cnt_con += strlen((char*)&dump[cnt_con]);
874  }
875  cmd_resp_dump(VAL_NONE, dump);
876  }
877  else if(sock <= ATC_SOCK_NUM_END)
878  {
879  if(sockstat[sock] == SOCK_STAT_IDLE) {
880  sprintf((char*)atci.tcmd.arg1, "%c", 'I');
881  } else {
882  if((sockstat[sock] & SOCK_STAT_PROTMASK) == SOCK_STAT_UDP) {
883  sprintf((char*)atci.tcmd.arg1, "%c", 'U');
884  sprintf((char*)atci.tcmd.arg2, "%d", sockport[sock]);
885  if(udpport[sock]) {
886  sprintf((char*)atci.tcmd.arg3, "%d.%d.%d.%d",
887  udpip[sock][0], udpip[sock][1], udpip[sock][2], udpip[sock][3]);
888  sprintf((char*)atci.tcmd.arg4, "%d", udpport[sock]);
889  }
890  } else {
891  if((sockstat[sock] & SOCK_STAT_PROTMASK) == SOCK_STAT_TCP_SRV)
892  sprintf((char*)atci.tcmd.arg1, "%c", 'S');
893  else if((sockstat[sock] & SOCK_STAT_PROTMASK) == SOCK_STAT_TCP_CLT)
894  sprintf((char*)atci.tcmd.arg1, "%c", 'C');
895  else CRITICAL_ERRA("wrong sock state(0x%d)", sockstat[sock]);
896  sprintf((char*)atci.tcmd.arg2, "%d", sockport[sock]);
897  if(sockstat[sock] & SOCK_STAT_CONNECTED) {
898  GetDstInfo((uint8)sock, tip, &tport);
899  sprintf((char*)atci.tcmd.arg3, "%d.%d.%d.%d",
900  tip[0], tip[1], tip[2], tip[3]);
901  sprintf((char*)atci.tcmd.arg4, "%d", tport);
902  }
903  }
904  }
905  CMD_RESP_RET(RET_OK, VAL_NONE);
906  }
907  else CMD_RESP_RET(RET_WRONG_ARG, VAL_NONE);
908 }
909 
910 //void act_nopt(void)
911 //{
912 //
913 //}
914 #if 0
915 void act_wset(void)
916 {
917 
918 }
919 
920 void act_wstat(void)
921 {
922 
923 }
924 
925 void act_wscan(void)
926 {
927 
928 }
929 
930 void act_wjoin(void)
931 {
932 
933 }
934 
935 void act_wleave(void)
936 {
937 
938 }
939 
940 //void act_wsec(void)
941 //{
942 //
943 //}
944 
945 //void act_wwps(void)
946 //{
947 //
948 //}
949 #endif
950 void act_mset_q(int8 num)
951 {
952  if(atci.echo == VAL_ENABLE)
953  MAKE_TCMD_CHAR(atci.tcmd.arg1, 'E');
954  else MAKE_TCMD_CHAR(atci.tcmd.arg1, 'D');
955 
956  if(atci.poll == POLL_MODE_FULL)
957  MAKE_TCMD_CHAR(atci.tcmd.arg3, 'F');
958  else if(atci.poll == POLL_MODE_SEMI)
959  MAKE_TCMD_CHAR(atci.tcmd.arg3, 'S');
960  else MAKE_TCMD_CHAR(atci.tcmd.arg3, 'D');
961 
962  cmd_resp(RET_OK, VAL_NONE);
963 }
964 
965 void act_mset_a(int8 echo, int8 mode, int8 poll, int8 country)
966 {
967  DBGA("Set: echo(%c), poll(%c)", echo, poll);
968  if(echo == 'E') atci.echo = VAL_ENABLE;
969  else if(echo == 'D') atci.echo = VAL_DISABLE;
970 
971  if(poll == 'F') atci.poll = POLL_MODE_FULL;
972  else if(poll == 'S') atci.poll = POLL_MODE_SEMI;
973  else if(poll == 'D') atci.poll = POLL_MODE_NONE;
974  DBGA("echo(%d), poll(%d)", atci.echo, atci.poll);
975  cmd_resp(RET_OK, VAL_NONE);
976 }
977 
978 void act_mstat(void)
979 {
980  MAKE_TCMD_STRING(atci.tcmd.arg1, ARG_3_SIZE, ATC_VERSION);
981 
982  cmd_resp(RET_OK, VAL_NONE);
983 }
984 
985 void act_mevt_q(void)
986 {
987  int8 i, cnt, *tbuf;
988 
989  for(i=ATC_SOCK_NUM_START; i<=ATC_SOCK_NUM_END; i++) {
990  if(sockstat[i] != SOCK_STAT_IDLE) cnt++;
991  }
992 
993  cnt *= 7;
994 
995  tbuf = malloc(cnt+1);
996  if(tbuf == NULL) {
997  MAKE_TCMD_DIGIT(atci.tcmd.arg1, cnt+1);
998  CMD_RESP_RET(RET_NO_FREEMEM, VAL_NONE);
999  }
1000  for(i=ATC_SOCK_NUM_START; i<=ATC_SOCK_NUM_END; i++) {
1001  if(sockstat[i] != SOCK_STAT_IDLE)
1002  sprintf((char*)&tbuf[7*(i-ATC_SOCK_NUM_START)], "%1d,sock\r\n", i);
1003  }
1004  MAKE_TCMD_DIGIT(atci.tcmd.arg1, cnt);
1005  cmd_resp_dump(VAL_NONE, tbuf);
1006 }
1007 
1008 void act_mevt_a(int8 id)
1009 {
1010  int8 event;
1011 
1012  if(event_dequeue(&id, &event) != RET_OK) {
1013  CMD_RESP_RET(RET_NO_DATA, VAL_NONE);
1014  }
1015 
1016  if(id <= ATC_SOCK_NUM_END && event == SOCKEVENT_RECV)
1017  EVENT_RESP_SIZE(id, event, GetSocketRxRecvBufferSize(id));
1018  else EVENT_RESP(id, event);
1019 }
1020 
1021 //void act_musart(void)
1022 //{
1023 //
1024 //}
1025 
1026 //void act_mspi(void)
1027 //{
1028 //
1029 //}
1030 
1031 //void act_mprof(void)
1032 //{
1033 //
1034 //}
1035 
1036 //void act_fdhcpd(void)
1037 //{
1038 //
1039 //}
1040 
1041 //void act_fdns(void)
1042 //{
1043 //
1044 //}
1045 
1046 //void act_fping(void)
1047 //{
1048 //
1049 //}
1050 
1051 //void act_fgpio(void)
1052 //{
1053 //
1054 //}
1055 
1056 //void act_eset(void)
1057 //{
1058 //
1059 //}
1060 
1061 //void act_estat(void)
1062 //{
1063 //
1064 //}
1065 
1066 
1067 
1068 
1069 
1070 
1071 
1072