static void atc_resend_alarm(int8 arg) { int8 ret; ret = TCPReSendNB(arg); if(ret != RET_OK) { if(ret == SOCKERR_BUSY) { alarm_set(WINDOWFULL_WAIT_TIME, atc_resend_alarm, arg); } else if(ret == SOCKERR_WINDOW_FULL) { sockbusy[arg] = VAL_FALSE; DBGA("WATCH_SOCK_TCP_SEND fail - ret(%d)", ret); cmd_resp(RET_TIMEOUT, arg); } else { sockbusy[arg] = VAL_FALSE; DBGA("WATCH_SOCK_TCP_SEND fail - ret(%d)", ret); sock_put(arg); cmd_resp(RET_TIMEOUT, arg); } } else sockwatch_set(arg, WATCH_SOCK_TCP_SEND); }
void act_mset_a(int8 echo, int8 mode, int8 poll, int8 country) { DBGA("Set: echo(%c), poll(%c)", echo, poll); if(echo == 'E') atci.echo = VAL_ENABLE; else if(echo == 'D') atci.echo = VAL_DISABLE; if(poll == 'F') atci.poll = POLL_MODE_FULL; else if(poll == 'S') atci.poll = POLL_MODE_SEMI; else if(poll == 'D') atci.poll = POLL_MODE_NONE; DBGA("echo(%d), poll(%d)", atci.echo, atci.poll); cmd_resp(RET_OK, VAL_NONE); }
void act_mset_q(int8 num) { if(atci.echo == VAL_ENABLE) MAKE_TCMD_CHAR(atci.tcmd.arg1, 'E'); else MAKE_TCMD_CHAR(atci.tcmd.arg1, 'D'); if(atci.poll == POLL_MODE_FULL) MAKE_TCMD_CHAR(atci.tcmd.arg3, 'F'); else if(atci.poll == POLL_MODE_SEMI) MAKE_TCMD_CHAR(atci.tcmd.arg3, 'S'); else MAKE_TCMD_CHAR(atci.tcmd.arg3, 'D'); cmd_resp(RET_OK, VAL_NONE); }
static void hdl_nsend(void) { int8 num = -1; int32 ret; uint8 *dip = NULL; uint16 *dport = NULL; if(atci.tcmd.sign == CMD_SIGN_NONE) RESP_CR(RET_WRONG_SIGN); if(atci.tcmd.sign == CMD_SIGN_QUEST) RESP_CR(RET_WRONG_SIGN); else if(atci.tcmd.sign == CMD_SIGN_INDIV) RESP_CR(RET_WRONG_SIGN); else if(atci.tcmd.sign == CMD_SIGN_EQUAL) { if(atci.tcmd.arg1[0] != 0) { if(str_check(isdigit, atci.tcmd.arg1) != RET_OK) RESP_CDR(RET_WRONG_ARG, 1); if(CHK_DGT_RANGE(atci.tcmd.arg1, num, ATC_SOCK_NUM_START, ATC_SOCK_NUM_END)) RESP_CDR(RET_RANGE_OUT, 1); } if(str_check(isdigit, atci.tcmd.arg2) != RET_OK || (atci.sendlen = atoi((char*)atci.tcmd.arg2)) < 1 || atci.sendlen > WORK_BUF_SIZE) RESP_CDR(RET_RANGE_OUT, 2); if(atci.tcmd.arg3[0]) { if(ip_check(atci.tcmd.arg3, atci.sendip) == RET_OK) dip = atci.sendip; else RESP_CDR(RET_WRONG_ARG, 3); } if(atci.tcmd.arg4[0]) { if(port_check(atci.tcmd.arg4, &atci.sendport)==RET_OK) dport = &atci.sendport; else RESP_CDR(RET_WRONG_ARG, 4); } CHK_ARG_LEN(atci.tcmd.arg5, 0, 5); CHK_ARG_LEN(atci.tcmd.arg6, 0, 6); CMD_CLEAR(); ret = act_nsend_chk(num, &atci.sendlen, dip, dport); if(ret != RET_OK) return; atci.sendsock = num; // 유효성 검사가 완료되면 SEND모드로 전환 atci.worklen = 0; cmd_resp(RET_ASYNC, num); } else CRITICAL_ERRA("wrong sign(%d)", atci.tcmd.sign); }
int8 act_nsend_chk(uint8 sock, uint16 *len, uint8 *dip, uint16 *dport) { uint16 availlen; if(sockbusy[sock] == VAL_TRUE) { cmd_resp(RET_BUSY, VAL_NONE); return RET_NOK; } if(sockstat[sock] == SOCK_STAT_IDLE) { cmd_resp(RET_SOCK_CLS, VAL_NONE); return RET_NOK; } if(sockstat[sock] & SOCK_STAT_TCP_MASK) { // TCP if(!(sockstat[sock] & SOCK_STAT_CONNECTED)) { cmd_resp(RET_NOT_CONN, VAL_NONE); return RET_NOK; } } else { // UDP if(dip == NULL) { if(udpip[sock][0]==0 && udpip[sock][1]==0 && udpip[sock][2]==0 && udpip[sock][3]==0) { DBG("no prev udpip"); cmd_resp(RET_WRONG_ADDR, VAL_NONE); return RET_NOK; } else memcpy(dip, udpip[sock], 4); } else memcpy(udpip[sock], dip, 4); if(dport == NULL) { if(udpport[sock] == 0) { DBG("no prev udpport"); cmd_resp(RET_WRONG_ADDR, VAL_NONE); return RET_NOK; } else *dport = udpport[sock]; } else udpport[sock] = *dport; } availlen = GetSocketTxFreeBufferSize(sock); if(*len > availlen) { DBGA("tx buf busy - req(%d), avail(%d)", *len, availlen); MAKE_TCMD_DIGIT(atci.tcmd.arg1, availlen); cmd_resp(RET_BUSY, VAL_NONE); return RET_NOK; } return RET_OK; }
void act_nrecv(int8 sock, uint16 maxlen) { uint8 dstip[4], i; uint16 dstport; int32 len; DBGA("Asock(%d)", sock); if(sock == VAL_NONE) { if(recvnum == 0) CMD_RESP_RET(RET_NO_DATA, VAL_NONE); for(i=ATC_SOCK_NUM_START; i<=ATC_SOCK_NUM_END; i++) { if(recvord[i] == recvnum) { sock = i; break; } } }DBGA("Bsock(%d)", sock); if(sockstat[sock] == SOCK_STAT_IDLE) CMD_RESP_RET(RET_SOCK_CLS, VAL_NONE); if(sockstat[sock] & SOCK_STAT_TCP_MASK) { // TCP if(!(sockstat[sock] & SOCK_STAT_CONNECTED)) CMD_RESP_RET(RET_NOT_CONN, VAL_NONE); if(GetSocketRxRecvBufferSize(sock) == 0) CMD_RESP_RET(RET_NO_DATA, VAL_NONE); len = TCPRecv(sock, atci.recvbuf, maxlen); } else { // UDP if(GetSocketRxRecvBufferSize(sock) == 0) CMD_RESP_RET(RET_NO_DATA, VAL_NONE); len = UDPRecv(sock, atci.recvbuf, maxlen, dstip, &dstport); if(len == 0) CMD_RESP_RET(RET_NO_DATA, VAL_NONE); else if(len == SOCKERR_CLOSED) CMD_RESP_RET(RET_SOCK_CLS, VAL_NONE); else if(len < 0) CMD_RESP_RET(RET_UNSPECIFIED, VAL_NONE); } atci.recvbuf[len] = 0; MAKE_TCMD_DIGIT(atci.tcmd.arg1, len); MAKE_TCMD_ADDR(atci.tcmd.arg2, dstip[0], dstip[1], dstip[2], dstip[3]); MAKE_TCMD_DIGIT(atci.tcmd.arg3, dstport); cmd_resp(RET_RECV, sock); printf("%s\r\n", atci.recvbuf); sockwatch_set(sock, WATCH_SOCK_RECV); }
static void hdl_mrst(void) { CMD_CLEAR(); cmd_resp(RET_OK, VAL_NONE); NVIC_SystemReset(); }
/** * @ingroup atcmd_module * ATCMD Module Handler. * If you use ATCMD Module, this should run in the main loop */ void atc_run(void) { int8 i, ret, recv_char; static int8 curidx = -1, curcnt = 0; static uint8 buflen = 0; //static bool prompt = TRUE; recv_char = (int8)getc_nonblk(WIZ_USART1); if(recv_char == RET_NOK) return; // 입력 값 없는 경우 printf("RECV: 0x%x\r\n", recv_char); if(atci.sendsock != VAL_NONE) { //if(atci.sendsock == VAL_INVALID) { // send fail등으로 더 받을 필요가 없더라도 정해진 size는 입력이 들어올 것으로 가정 // if(++atci.worklen >= atci.sendlen) { // atci.sendsock = VAL_NONE; // 그냥 카운트만 하고 버림 // cmd_resp(ret, VAL_NONE); // 마지막으로 실패 응답하고 나감 // } // return; //} atci.sendbuf[atci.worklen++] = recv_char; if(atci.worklen >= atci.sendlen) { // 입력이 완료되면 act_nsend(atci.sendsock, atci.sendbuf, atci.worklen, atci.sendip, &atci.sendport); atci.sendsock = VAL_NONE; } return; } //if(prompt == FALSE) { // prompt = TRUE; // putc('>', WIZ_USART1); //} if(isgraph(recv_char) == 0) // 제어 문자 처리 { //printf("ctrl\r\n"); switch(recv_char) { case 0x0d: // CR(\r) break; // do nothing case 0x0a: // LF(\n) printf("<ENT>"); if(atci.echo) printf("\r\n"); termbuf[buflen] = 0; curidx = -1; curcnt = 0; //prompt = FALSE; break; case 0x08: // BS printf("<BS>\r\n"); if(buflen != 0) { buflen--; termbuf[buflen] = 0; if(atci.echo) printf("\b \b"); } break; case 0x1b: // ESC printf("<ESC>\r\n"); Delay_ms(5); // For receiving rest key. (this is for the users using terminal, so little delay doesn't matter) { int8 sec_char = (int8)getc_nonblk(WIZ_USART1); int8 trd_char = (int8)getc_nonblk(WIZ_USART1); //printf("s(%x),t(%x)", sec_char, trd_char); if(sec_char == '[') { switch(trd_char) { case 'A': //printf("<U>\r\n"); if(curcnt >= prevcnt) break; // 최대 히스토리 수를 넘기면 break if(curidx == -1) curidx = previdx; // 처음 누르는 경우 현제 idx값 지정 for(i=0; i<buflen; i++) if(atci.echo) putc('\b', WIZ_USART1); // 입력화면 삭제 for(i=0; i<buflen; i++) if(atci.echo) putc(' ', WIZ_USART1); // 입력화면 삭제 for(i=0; i<buflen; i++) if(atci.echo) putc('\b', WIZ_USART1); // 입력화면 삭제 if(curidx == 0) curidx = PREVBUF_LAST; // 직전 값 지정 else curidx--; curcnt++; //printf("##%d, %d$$\r\n", curidx, prevlen);Delay_ms(5);printf("##%s$$\r\n", prevbuf[curidx]);Delay_ms(5); if(prevbuf[curidx]) { buflen = strlen((char*)prevbuf[curidx]); strcpy((char*)termbuf, (char*)prevbuf[curidx]); } else CRITICAL_ERR("prevbuf NULL"); if(atci.echo) printf("%s", termbuf); break; case 'B': //printf("<D>\r\n"); if(curcnt <= 0) break; // 처음이면 break for(i=0; i<buflen; i++) if(atci.echo) putc('\b', WIZ_USART1); // 입력화면 삭제 for(i=0; i<buflen; i++) if(atci.echo) putc(' ', WIZ_USART1); // 입력화면 삭제 for(i=0; i<buflen; i++) if(atci.echo) putc('\b', WIZ_USART1); // 입력화면 삭제 if(curidx == PREVBUF_LAST) curidx = 0; // 다음 값 지정 else curidx++; curcnt--; //printf("##%d, %d$$\r\n", curidx, prevlen);Delay_ms(5);printf("##%s$$\r\n", prevbuf[curidx]);Delay_ms(5); if(curcnt == 0) { buflen = 0; } else if(prevbuf[curidx]) { buflen = strlen((char*)prevbuf[curidx]); strcpy((char*)termbuf, (char*)prevbuf[curidx]); if(atci.echo) printf("%s", termbuf); } else CRITICAL_ERR("prevbuf NULL"); break; case 'C': break;//printf("<R>\r\n"); break; case 'D': break;//printf("<L>\r\n"); break; } } } break; //case 0x20: // break; //case 0x7f: //printf("<DEL>\r\n"); // memset(termbuf, 0, CMD_BUF_SIZE); // buflen = 0; //printf("DEL: cur(%d), mfunc(%c), depth(%d)\r\n", mi.cur, mtree[mi.cur-1].mfunc==NULL?'N':'Y', depth); // printf("\r\n"); // break; //case 0x1b: //printf("<ESC>\r\n"); // break; } } else if(buflen < ATCMD_BUF_SIZE-1) // -1 이유 : 0 이 하나 필요하므로 { termbuf[buflen++] = (uint8)recv_char; //termbuf[buflen] = 0; if(atci.echo) putc(recv_char, WIZ_USART1); //printf(" termbuf(%c, %s)\r\n", recv_char, termbuf); }//else { printf("input buffer stuffed\r\n"); } if(recv_char != 0x0a || buflen == 0) return; //LOGA("Command: %d, %s\r\n", buflen, termbuf); cmd_set_prev(buflen); buflen = 0; CMD_CLEAR(); ret = cmd_divide(termbuf); if(ret == RET_OK) { cmd_assign(); } else if(ret != RET_DONE) { cmd_resp(ret, VAL_NONE); } }
void act_mstat(void) { MAKE_TCMD_STRING(atci.tcmd.arg1, ARG_3_SIZE, ATC_VERSION); cmd_resp(RET_OK, VAL_NONE); }
void act_nopen_q(void) { cmd_resp(RET_NOT_ALLOWED, VAL_NONE); }
void atc_async_cb(uint8 sock, uint8 item, int32 ret) { DBGCRTCA(sock<ATC_SOCK_NUM_START||sock>ATC_SOCK_NUM_END, "wrong sock(%d)", sock); switch(item) { case WATCH_SOCK_UDP_SEND: DBG("WATCH_SOCK_UDP_SEND"); sockbusy[sock] = VAL_FALSE; //DBGA("WATCH UDP Sent - sock(%d), item(%d)", sock, item); if(ret == RET_OK) { cmd_resp(RET_OK, sock); } else { DBGA("WATCH_SOCK_UDP_SEND fail - ret(%d)", ret); cmd_resp(RET_TIMEOUT, sock); } break; case WATCH_SOCK_TCP_SEND: DBG("WATCH_SOCK_TCP_SEND"); if(ret < RET_OK) { sockbusy[sock] = VAL_FALSE; DBGA("WATCH_SOCK_TCP_SEND fail - ret(%d)", ret); sock_put(sock); cmd_resp(RET_TIMEOUT, sock); } else { tcpleft[sock] -= ret; if(tcpleft[sock] > 0) { ret = TCPReSendNB(sock); if(ret != RET_OK) { if(ret == SOCKERR_BUSY) { alarm_set(WINDOWFULL_WAIT_TIME, atc_resend_alarm, sock); } else if(ret == SOCKERR_WINDOW_FULL) { sockbusy[sock] = VAL_FALSE; DBGA("WATCH_SOCK_TCP_SEND fail - ret(%d)", ret); cmd_resp(RET_TIMEOUT, sock); } else { sockbusy[sock] = VAL_FALSE; DBGA("WATCH_SOCK_TCP_SEND fail - ret(%d)", ret); sock_put(sock); cmd_resp(RET_TIMEOUT, sock); } } else sockwatch_set(sock, WATCH_SOCK_TCP_SEND); } else { sockbusy[sock] = VAL_FALSE; cmd_resp(RET_OK, sock); } } break; case WATCH_SOCK_CONN_TRY: DBG("WATCH_SOCK_CONN_TRY"); sockbusy[sock] = VAL_FALSE; if(ret == RET_OK) { BITSET(sockstat[sock], SOCK_STAT_CONNECTED); sockwatch_set(sock, WATCH_SOCK_CLS_EVT); sockwatch_set(sock, WATCH_SOCK_RECV); cmd_resp(RET_ASYNC, sock); } else { DBGA("WATCH_SOCK_CONN_EVT fail - ret(%d)", ret); sock_put(sock); cmd_resp(RET_TIMEOUT, sock); } break; case WATCH_SOCK_CLS_TRY: DBG("WATCH_SOCK_CLS_TRY"); sockbusy[sock] = VAL_FALSE; if(ret == RET_OK) { sock_put(sock); cmd_resp(RET_ASYNC, sock); } else { CRITICAL_ERRA("WATCH_SOCK_CONN_EVT fail - ret(%d)", ret); } break; case WATCH_SOCK_CONN_EVT: DBG("WATCH_SOCK_CONN_EVT"); if(ret == RET_OK) { BITSET(sockstat[sock], SOCK_STAT_CONNECTED); sockwatch_set(sock, WATCH_SOCK_CLS_EVT); sockwatch_set(sock, WATCH_SOCK_RECV); if(atci.poll != POLL_MODE_FULL) EVENT_RESP(sock, SOCKEVENT_CONN); else event_enqueue(sock, SOCKEVENT_CONN); } else { CRITICAL_ERRA("WATCH_SOCK_CONN_EVT fail - ret(%d)", ret); } break; case WATCH_SOCK_CLS_EVT: DBG("WATCH_SOCK_CLS_EVT"); sockbusy[sock] = VAL_FALSE; if(ret == RET_OK) { if(sockwatch_chk(sock, WATCH_SOCK_CLS_TRY) == RET_OK) cmd_resp(RET_OK, sock); sock_put(sock); if(atci.poll != POLL_MODE_FULL) EVENT_RESP(sock, SOCKEVENT_CLS); else event_enqueue(sock, SOCKEVENT_CLS); } else { CRITICAL_ERRA("WATCH_SOCK_CONN_EVT fail - ret(%d)", ret); } break; case WATCH_SOCK_RECV: DBG("WATCH_SOCK_RECV"); { int8 i; if(atci.poll != POLL_MODE_NONE) { recvnum++; if(recvord[sock] == 0) { for(i=ATC_SOCK_NUM_START; i<=ATC_SOCK_NUM_END; i++) if(recvord[i] != 0) recvord[i]++; } else { for(i=ATC_SOCK_NUM_START; i<=ATC_SOCK_NUM_END; i++) if(recvord[i] != 0 && recvord[i] < recvord[sock]) recvord[i]++; } recvord[sock] = 1; if(atci.poll != POLL_MODE_FULL) EVENT_RESP_SIZE(sock, SOCKEVENT_RECV, GetSocketRxRecvBufferSize(sock)); else event_enqueue(sock, SOCKEVENT_RECV); } else { act_nrecv(sock, WORK_BUF_SIZE); } } break; default: CRITICAL_ERRA("wrong item(0x%x)", item); } }