STATIC int cc3k_socket_socket(mod_network_socket_obj_t *socket, int *_errno) { if (socket->u_param.domain != MOD_NETWORK_AF_INET) { *_errno = MP_EAFNOSUPPORT; return -1; } mp_uint_t type; switch (socket->u_param.type) { case MOD_NETWORK_SOCK_STREAM: type = SOCK_STREAM; break; case MOD_NETWORK_SOCK_DGRAM: type = SOCK_DGRAM; break; case MOD_NETWORK_SOCK_RAW: type = SOCK_RAW; break; default: *_errno = MP_EINVAL; return -1; } // open socket int fd = CC3000_EXPORT(socket)(AF_INET, type, 0); if (fd < 0) { *_errno = CC3000_EXPORT(errno); return -1; } // clear socket state cc3k_reset_fd_closed_state(fd); // store state of this socket socket->u_state = fd; // make accept blocking by default int optval = SOCK_OFF; socklen_t optlen = sizeof(optval); CC3000_EXPORT(setsockopt)(socket->u_state, SOL_SOCKET, SOCKOPT_ACCEPT_NONBLOCK, &optval, optlen); return 0; }
STATIC int cc3k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip) { uint32_t ip; if (CC3000_EXPORT(gethostbyname)((char*)name, len, &ip) < 0) { return CC3000_EXPORT(errno); } if (ip == 0) { // unknown host return ENOENT; } out_ip[0] = ip >> 24; out_ip[1] = ip >> 16; out_ip[2] = ip >> 8; out_ip[3] = ip; return 0; }
STATIC int cc3k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip) { uint32_t ip; // CC3000 gethostbyname is unreliable and usually returns -95 on first call for (int retry = 5; CC3000_EXPORT(gethostbyname)((char*)name, len, &ip) < 0; retry--) { if (retry == 0 || CC3000_EXPORT(errno) != -95) { return CC3000_EXPORT(errno); } HAL_Delay(50); } if (ip == 0) { // unknown host return ENOENT; } out_ip[0] = ip >> 24; out_ip[1] = ip >> 16; out_ip[2] = ip >> 8; out_ip[3] = ip; return 0; }
STATIC void cc3k_socket_close(mod_network_socket_obj_t *socket) { CC3000_EXPORT(closesocket)(socket->u_state); }
// make accept blocking by default int optval = SOCK_OFF; socklen_t optlen = sizeof(optval); CC3000_EXPORT(setsockopt)(socket->u_state, SOL_SOCKET, SOCKOPT_ACCEPT_NONBLOCK, &optval, optlen); return 0; } STATIC void cc3k_socket_close(mod_network_socket_obj_t *socket) { CC3000_EXPORT(closesocket)(socket->u_state); } STATIC int cc3k_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) { MAKE_SOCKADDR(addr, ip, port) int ret = CC3000_EXPORT(bind)(socket->u_state, &addr, sizeof(addr)); if (ret != 0) { *_errno = ret; return -1; } return 0; } STATIC int cc3k_socket_listen(mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno) { int ret = CC3000_EXPORT(listen)(socket->u_state, backlog); if (ret != 0) { *_errno = ret; return -1; } return 0; }