/** * Clean up and free the ttcp structure */ static void ard_tcp_destroy(struct ttcp* ttcp) { err_t err = ERR_OK; DUMP_TCP_STATE(ttcp); if (getSock(ttcp)==-1) WARN("ttcp already deallocated!\n"); if (ttcp->tpcb) { tcp_arg(ttcp->tpcb, NULL); tcp_sent(ttcp->tpcb, NULL); tcp_recv(ttcp->tpcb, NULL); tcp_err(ttcp->tpcb, NULL); //TEMPORAQARY //err = tcp_close(ttcp->tpcb); INFO_TCP("Closing tpcb: state:0x%x err:%d\n", ttcp->tpcb->state, err); } if (ttcp->lpcb) { tcp_arg(ttcp->lpcb, NULL); tcp_accept(ttcp->lpcb, NULL); err = tcp_close(ttcp->lpcb); INFO_TCP("Closing lpcb: state:0x%x err:%d\n", ttcp->lpcb->state, err); } if (ttcp->upcb) { udp_disconnect(ttcp->upcb); udp_remove(ttcp->upcb); } if (ttcp->payload) free(ttcp->payload); free(ttcp); }
/** * Only used in TCP mode. */ static err_t atcp_recv_cb(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { struct ttcp* ttcp = arg; if (err == ERR_OK && p != NULL) { INFO_TCP("pcb:%p pbuf: %p err:%d len:%d\n", pcb, p, err, p->tot_len); DATA_LED_ON(); /* for print_stats() */ ttcp->recved += p->tot_len; if ((ttcp->verbose)||(verboseDebug & INFO_TCP_FLAG)) { INFO_TCP("len:%d\n",p->tot_len); DUMP_TCP(p->payload, p->tot_len); ttcp->print_cnt++; } insert_pBuf(p, ttcp->sock, (void*) pcb); tcp_recved(pcb, p->tot_len); pbuf_free(p); DATA_LED_OFF(); } /* p will be NULL when remote end is done */ if (err == ERR_OK && p == NULL) { INFO_TCP("atcp_recv_cb p=NULL\n"); close_conn(ttcp); } if (err!=ERR_OK) WARN("err=%d p=%p\n", err, p); return ERR_OK; }
/** * Start TCP transfer. */ static int atcp_start(struct ttcp* ttcp) { err_t err = ERR_OK; ttcp->tpcb = tcp_new(); if (ttcp->tpcb == NULL) { WARN("TTCP [%p]: could not allocate pcb\n", ttcp); return -1; } ttcp->payload = malloc(ttcp->buflen); if (ttcp->payload == NULL) { WARN("TTCP [%p]: could not allocate payload\n", ttcp); return -1; } tcp_arg(ttcp->tpcb, ttcp); atcp_init_pend_flags(); if (ttcp->mode == TTCP_MODE_TRANSMIT) { tcp_err(ttcp->tpcb, atcp_conn_cli_err_cb); tcp_recv(ttcp->tpcb, atcp_recv_cb); tcp_sent(ttcp->tpcb, tcp_data_sent); tcp_poll(ttcp->tpcb, atcp_poll_conn, 4); _connected = false; INFO_TCP("[tpcb]-%p payload:%p\n", ttcp->tpcb, ttcp->payload); DUMP_TCP_STATE(ttcp); if (tcp_connect(ttcp->tpcb, &ttcp->addr, ttcp->port, tcp_connect_cb) != ERR_OK) { WARN("TTCP [%p]: tcp connect failed\n", ttcp); return -1; } } else { INFO_TCP("BEFORE BIND ttcp:%p lpcb:%p pcb:%p\n", ttcp, ttcp->lpcb, ttcp->tpcb); INFO_TCP("[tpcb]-local:%d remote:%d state:%d\n", ttcp->tpcb->local_port, ttcp->tpcb->remote_port, ttcp->tpcb->state); err = tcp_bind(ttcp->tpcb, IP_ADDR_ANY, ttcp->port); if (err != ERR_OK){ WARN("TTCP [%p]: bind failed err=%d Port already used\n", ttcp, err); return -1; } ttcp->lpcb = tcp_listen(ttcp->tpcb); if (ttcp->lpcb == NULL) { WARN("TTCP [%p]: listen failed\n", ttcp); return -1; } if (ttcp->lpcb == ttcp->tpcb ) { WARN("TTCP [%p]: listen failed tpcb [%p] in listen mode\n", ttcp, ttcp->tpcb); return -1; } DUMP_TCP_STATE(ttcp); tcp_accept(ttcp->lpcb, atcp_accept_cb); } return 0; }
static err_t atcp_poll(void *arg, struct tcp_pcb *pcb) { struct ttcp* _ttcp = arg; if ((_ttcp) && (_ttcp->left>0)) ++tcp_poll_retries; if (tcp_poll_retries > 4) { WARN("ARD TCP [%p] arg=%p retries=%d\n", pcb, arg, tcp_poll_retries); tcp_poll_retries = 0; tcp_abort(pcb); atcp_init_pend_flags(); return ERR_ABRT; } WARN("ARD TCP [%p-%p] arg=%p retries=%d pend.close:%d\n", (_ttcp)?_ttcp->tpcb:0, pcb, arg, tcp_poll_retries, pending_close); if (_ttcp) tcp_send_data(_ttcp); if (pending_close) { err_t err = tcp_close(pcb); if (err == ERR_MEM) { pending_close = true; } else { atcp_init_pend_flags(); } INFO_TCP("ARD TCP [%p-%p] try to close pending:%d\n", pcb, (_ttcp)?_ttcp->tpcb:0, pending_close); } return ERR_OK; }
/** * Clean up and free the ttcp structure */ static void ard_tcp_abort(struct ttcp* ttcp) { INFO_TCP("Abort ttcb:%p tpcb:%p lpcb:%p\n", ttcp, ttcp->tpcb, ttcp->lpcb); if (ttcp->tpcb) { tcp_arg(ttcp->tpcb, NULL); tcp_sent(ttcp->tpcb, NULL); tcp_recv(ttcp->tpcb, NULL); tcp_err(ttcp->tpcb, NULL); tcp_abort(ttcp->tpcb); } if (ttcp->lpcb) { tcp_arg(ttcp->lpcb, NULL); tcp_accept(ttcp->lpcb, NULL); tcp_abort(ttcp->lpcb); } if (ttcp->upcb) { udp_disconnect(ttcp->upcb); udp_remove(ttcp->upcb); } if (ttcp->payload) free(ttcp->payload); free(ttcp); }
void ackAndFreeData(void* pcb, int len, uint8_t sock, uint8_t* data) { INFO_TCP("Ack pcb:%p len:%d sock:%d data:%p\n", pcb, len, sock, data); if (!IS_UDP_SOCK(sock)) ack_recved(pcb, len); if (data != NULL) freetData(data, sock); }
static void cleanSockState_cb(void *ctx) { struct ttcp* ttcp = ctx; int sock = getSock(ttcp); if (sock != -1) clearMapSockTcp(sock); INFO_TCP("TTCP [%p]: cleanSockState_cb %d\n", ttcp, sock); _connected = false; }
/** * Only used in TCP mode. */ static err_t tcp_connect_cb(void *arg, struct tcp_pcb *tpcb, err_t err) { struct ttcp* ttcp = arg; INFO_TCP("TTCP [%p-%p]: connect %d %d\n", ttcp, tpcb, err, ttcp->tpcb->state); _connected = ( ttcp->tpcb->state == ESTABLISHED) ? 1 : 0; tcp_poll_retries = 0; ttcp->start_time = timer_get_ms(); return ERR_OK; }
void ard_tcp_stop(void* ttcp) { struct ttcp* _ttcp = (struct ttcp*) ttcp; if (_ttcp == NULL) { WARN("ttcp = NULL!\n"); return; } if (_ttcp->mode == TTCP_MODE_TRANSMIT) { INFO_TCP("Destroy TCP connection...state:%d\n", _ttcp->tpcb->state); ard_tcp_destroy(_ttcp); clearMapSockTcp(getSock(_ttcp)); tcp_poll_retries = 0; }else{ INFO_TCP("Closing connection...state:%d\n", _ttcp->tpcb->state); DUMP_TCP_STATE(_ttcp); if ((_ttcp)&&(_ttcp->tpcb)&&(_ttcp->tpcb->state!=LAST_ACK)&&(_ttcp->tpcb->state!=CLOSED)) { close_conn(_ttcp); } pending_accept = false; } }
/** * Only used in TCP mode. */ static err_t atcp_accept_cb(void *arg, struct tcp_pcb *newpcb, err_t err) { struct ttcp* ttcp = arg; INFO_TCP("ARD TCP [%p]: accept new [%p]\n", ttcp, newpcb); INFO_TCP("local:%d remote:%d state:%d\n", newpcb->local_port, newpcb->remote_port, newpcb->state); if (pending_accept) { WARN("Accepting another connection: %p-%p\n", ttcp->tpcb, newpcb); return ERR_OK; } pending_accept = true; tcp_setprio(newpcb, TCP_PRIO_MIN); tcp_poll_retries = 0; ttcp->tpcb = newpcb; tcp_recv(ttcp->tpcb, atcp_recv_cb); tcp_err(ttcp->tpcb, atcp_conn_err_cb); tcp_poll(ttcp->tpcb, atcp_poll, 4); ttcp->start_time = timer_get_ms(); return ERR_OK; }
static void close_conn(struct ttcp *_ttcp) { tcp_arg(_ttcp->tpcb, NULL); tcp_sent(_ttcp->tpcb, NULL); tcp_recv(_ttcp->tpcb, NULL); err_t err = tcp_close(_ttcp->tpcb); INFO_TCP("Closing tpcb[%p]: state:0x%x err:%d\n",_ttcp->tpcb, _ttcp->tpcb->state, err); if (err == ERR_MEM) pending_close = true; else{ atcp_init_pend_flags(); WARN("----------------------\n"); } }
void closeConnections() { int i = 0; for (; i<MAX_SOCK_NUM; i++) { void* p = getTTCP(i); if (p) { ttcp_t* _ttcp = (ttcp_t* )p; INFO_TCP("Closing connections tpcb[%p] state:0x%x - lpcb[%p] state: 0x%x\n", _ttcp->tpcb, _ttcp->tpcb->state, _ttcp->lpcb, _ttcp->lpcb->state); //tcp_close(_ttcp->tpcb); ard_tcp_destroy(_ttcp); clearMapSockTcp(getSock(_ttcp)); } } }
static err_t tcp_data_sent(void *arg, struct tcp_pcb *pcb, u16_t len) { struct ttcp *_ttcp; LWIP_UNUSED_ARG(len); _ttcp = arg; tcp_poll_retries = 0; if (_ttcp) _ttcp->buff_sent = 1; INFO_TCP("Packet sent pcb:%p len:%d dur:%d left:%d count:%d\n", pcb, len, timer_get_ms() - startTime, (_ttcp)?(_ttcp->left):0, isDataSentCount); isDataSentCount = 0; if ((_ttcp)&&(_ttcp->left > 0)) { tcp_send_data(_ttcp); } return ERR_OK; }
static err_t atcp_poll_conn(void *arg, struct tcp_pcb *pcb) { struct ttcp* _ttcp = arg; ++tcp_poll_retries; if (tcp_poll_retries > 8) { WARN("ARD TCP [%p-%p] arg=%p retries=%d\n", pcb, _ttcp->tpcb, arg, tcp_poll_retries); tcp_poll_retries = 0; tcp_abort(pcb); return ERR_ABRT; } WARN("ARD TCP [%p-%p] arg=%p retries=%d pend.close:%d conn:%d\n", (_ttcp)?_ttcp->tpcb:0, pcb, arg, tcp_poll_retries, pending_close, _connected); if ((_ttcp)&&(_connected)) tcp_send_data(_ttcp); if (pending_close) { err_t err = tcp_close(pcb); if (err == ERR_MEM) { pending_close = true; } else { cleanSockState_cb(_ttcp); if (_ttcp->payload) free(_ttcp->payload); free(_ttcp); pending_close = false; } INFO_TCP("ARD TCP [%p-%p] try to close pending:%d\n", pcb, (_ttcp)?_ttcp->tpcb:0, pending_close); } return ERR_OK; }
int sendTcpData(void* p, uint8_t* buf, uint16_t len) { INFO_TCP("buf:%p len:%d\n", buf, len); DUMP_TCP(buf,len); struct ttcp* _ttcp = (struct ttcp*) p; if (_ttcp==NULL) { WARN("ttcp == NULL!\n"); return WL_FAILURE; } INFO_TCP_VER("CLI> p=%p _ttcp=%p state(tpcb):%d state(lpcb):%d\n", p, ((struct ttcp*) p)->tpcb, ((struct ttcp*) p)->tpcb->state, ((struct ttcp*) p)->lpcb->state); if ((_ttcp != NULL) && (_ttcp->tpcb != NULL) && (buf != NULL) && (len != 0) && (_ttcp->payload != NULL)) { if (_ttcp->tpcb->state == ESTABLISHED || _ttcp->tpcb->state == CLOSE_WAIT || _ttcp->tpcb->state == SYN_SENT || _ttcp->tpcb->state == SYN_RCVD) { memcpy(_ttcp->payload, buf, len); _ttcp->payload[len]='\0'; INFO_TCP_VER("%s\n", _ttcp->payload); _ttcp->left = len; tcp_sent(_ttcp->tpcb, tcp_data_sent); tcp_send_data(_ttcp); return WL_SUCCESS; } } //printk("Write failure _ttcp=%p _ttcp->tpcb=%p buf=%p len=%d\n", _ttcp, _ttcp->tpcb, buf, len); return WL_FAILURE; }
void setMapSock(uint8_t sock, void* _ttcp) { if (sock < MAX_SOCK_NUM) mapSockTCP[sock]=_ttcp; INFO_TCP("Map [%d, %p]\n", sock, _ttcp); }
static void cleanSockStateDelayed(void * arg) { INFO_TCP("arg %p\n", arg); timer_sched_timeout_cb(1000, TIMEOUT_ONESHOT, cleanSockState_cb, arg); }
/** * Start a new ttcp transfer. It should be possible to call this function * multiple times in order to get multiple ttcp streams. done_cb() will be * invoked upon completion. * */ int ard_tcp_start(struct ip_addr addr, uint16_t port, void *opaque, ard_tcp_done_cb_t *done_cb, int mode, uint16_t nbuf, uint16_t buflen, int udp, int verbose, uint8_t sock, void** _ttcp) { struct ttcp* ttcp; int status; if (mode != TTCP_MODE_TRANSMIT && mode != TTCP_MODE_RECEIVE) { WARN("TTCP [-]: invalid mode\n"); return -1; } if (nbuf == 0) { WARN("TTCP [-]: invalid nbuf\n"); return -1; } if (buflen == 0) { WARN("TTCP [-]: invalid buflen\n"); return -1; } ttcp = calloc(1, sizeof(struct ttcp)); if (ttcp == NULL) { WARN("TTCP [-]: could not allocate memory for ttcp\n"); return -1; } ttcp->addr = addr; ttcp->port = port; ttcp->nbuf = nbuf; ttcp->mode = mode; ttcp->left = nbuf * buflen; ttcp->done_cb = done_cb; ttcp->opaque = opaque; ttcp->udp = udp; ttcp->verbose = verbose; ttcp->buflen = buflen; if (ttcp->udp) status = udp_start(ttcp); else status = atcp_start(ttcp); if (status) { WARN("Start server FAILED!\n"); goto fail; } INFO_TCP("TTCP [%p-%p]: nbuf=%d, buflen=%d, port=%d (%s/%s)\n", ttcp, ttcp->tpcb, ttcp->nbuf, ttcp->buflen, ttcp->port, ttcp->udp ? "udp" : "tcp", ttcp->mode == TTCP_MODE_TRANSMIT ? "tx" : "rx"); *_ttcp = (void*) ttcp; ttcp->sock = sock; ttcp->buff_sent = 1; return 0; //fail: ard_tcp_abort(ttcp); fail: ard_tcp_destroy(ttcp); return -1; }