/** * connect to remote by specific connTimeout * * @param sckfd socket fd * @param remoteAddr remote inetAddress in char* format * @param remotePort remote port * @param connTimeout connection timeout in milliseconds * @return 0 means suc or -1 means fail */ int esp_tsocket_connect(int sckfd, const char* remoteAddr,const int remotePort, const int connTimeout) { assert(sckfd>0); int ret = -1; int error = -1; int len = sizeof(int); int ioctl_ret = -1; fd_set set; // set dest address struct sockaddr_in dest_addr; dest_addr.sin_family = AF_INET; dest_addr.sin_port = htons(remotePort); dest_addr.sin_addr.s_addr = inet_addr(remoteAddr); bzero(&dest_addr.sin_zero, sizeof(dest_addr.sin_zero)); // set nonblock mode unsigned long ul = 1; ioctl_ret = ioctl(sckfd, FIONBIO, &ul); if (ioctl_ret==-1) { esp_socket_close(sckfd); ret = -1; perror("esp_csocket esp_tsocket_connect() set nonblock mode fail"); return ret; } // connect by nonblock mode if (connect(sckfd, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr))==-1) { struct timeval timeout; timeout.tv_sec = connTimeout/1000; timeout.tv_usec = connTimeout%1000*1000; FD_ZERO(&set); FD_SET(sckfd, &set); // select until timeout if (select(sckfd + 1, NULL, &set, NULL, &timeout) > 0) { getsockopt(sckfd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len); if (error == 0) { ret = 0; } else { ret = -1; } } } else { ret = 0; } if (!ret) { // set block mode ul = 0; ioctl(sckfd, FIONBIO, &ul); if (ioctl_ret==-1) { esp_socket_close(sckfd); ret = -1; perror("esp_csocket esp_tsocket_connect() set block mode fail"); return ret; } } else { perror("esp_csocket esp_tsocket_connect() timeout"); esp_socket_close(sckfd); } return ret; }
STATIC void esp_socket_recv_callback(void *arg, char *pdata, unsigned short len) { struct espconn *conn = arg; esp_socket_obj_t *s = conn->reverse; if (s->cb_recv != mp_const_none) { call_function_2_protected(s->cb_recv, s, mp_obj_new_bytes((byte *)pdata, len)); } else { if (s->recvbuf == NULL) { s->recvbuf = gc_alloc(len, false); s->recvbuf_len = len; if (s->recvbuf != NULL) { memcpy(s->recvbuf, pdata, len); } } else { s->recvbuf = gc_realloc(s->recvbuf, s->recvbuf_len + len, true); if (s->recvbuf != NULL) { memcpy(&s->recvbuf[s->recvbuf_len], pdata, len); s->recvbuf_len += len; } } if (s->recvbuf == NULL) { esp_socket_close(s); return; } } }
STATIC void esp_socket_disconnect_callback(void *arg) { struct espconn *conn = arg; esp_socket_obj_t *s = conn->reverse; if (s->cb_disconnect != mp_const_none) { call_function_1_protected(s->cb_disconnect, s); } esp_socket_close(s); }
// method socket.__del__() STATIC mp_obj_t esp_socket___del__(mp_obj_t self_in) { esp_socket_obj_t *s = self_in; esp_socket_close(self_in); if (s->fromserver) { espconn_delete(s->espconn); } return mp_const_none; }