示例#1
0
// constructor socket(family=AF_INET, type=SOCK_STREAM, proto=IPPROTO_TCP, fileno=None)
STATIC mp_obj_t socket_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
    mp_arg_check_num(n_args, n_kw, 0, 4, false);

    // create socket object (not bound to any NIC yet)
    mod_network_socket_obj_t *s = m_new_obj_with_finaliser(mod_network_socket_obj_t);
    s->base.type = (mp_obj_t)&socket_type;
    s->nic = MP_OBJ_NULL;
    s->nic_type = NULL;
    s->u_param.domain = AF_INET;
    s->u_param.type = SOCK_STREAM;
    s->u_param.proto = IPPROTO_TCP;
    s->u_param.fileno = -1;
    if (n_args >= 1) {
        s->u_param.domain = mp_obj_get_int(args[0]);
        if (n_args >= 2) {
            s->u_param.type = mp_obj_get_int(args[1]);
            if (n_args >= 3) {
                s->u_param.proto = mp_obj_get_int(args[2]);
                if (n_args == 4) {
                    s->u_param.fileno = mp_obj_get_int(args[3]);
                }
            }
        }
    }
    return s;
}
示例#2
0
// method socket.accept()
STATIC mp_obj_t socket_accept(mp_obj_t self_in) {
    mod_network_socket_obj_t *self = self_in;

    // create new socket object
    mod_network_socket_obj_t *socket2 = m_new_obj_with_finaliser(mod_network_socket_obj_t);
    // the new socket inherits all properties from its parent
    memcpy (socket2, self, sizeof(mod_network_socket_obj_t));

    // accept the incoming connection
    uint8_t ip[MOD_NETWORK_IPV4ADDR_BUF_SIZE];
    mp_uint_t port;
    int _errno;
    if (wlan_socket_accept(self, socket2, ip, &port, &_errno) != 0) {
        nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
    }

    // add the socket to the list
    modusocket_socket_add(socket2->sock_base.sd, true);

    // make the return value
    mp_obj_tuple_t *client = mp_obj_new_tuple(2, NULL);
    client->items[0] = socket2;
    client->items[1] = netutils_format_inet_addr(ip, port, NETUTILS_LITTLE);
    return client;
}
示例#3
0
// constructor socket(family=AF_INET, type=SOCK_STREAM, proto=IPPROTO_TCP, fileno=None)
STATIC mp_obj_t socket_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
    mp_arg_check_num(n_args, n_kw, 0, 4, false);

    // create socket object
    mod_network_socket_obj_t *s = m_new_obj_with_finaliser(mod_network_socket_obj_t);
    s->base.type = (mp_obj_t)&socket_type;
    s->u_param.domain = AF_INET;
    s->u_param.type = SOCK_STREAM;
    s->u_param.proto = IPPROTO_TCP;
    s->u_param.fileno = -1;
    if (n_args > 0) {
        s->u_param.domain = mp_obj_get_int(args[0]);
        if (n_args > 1) {
            s->u_param.type = mp_obj_get_int(args[1]);
            if (n_args > 2) {
                s->u_param.proto = mp_obj_get_int(args[2]);
                if (n_args > 3) {
                    s->u_param.fileno = mp_obj_get_int(args[3]);
                }
            }
        }
    }

    // create the socket
    int _errno;
    if (wlan_socket_socket(s, &_errno) != 0) {
        nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
    }

    modusocket_socket_add(s->sd, true);
    return s;
}
示例#4
0
// method socket.accept()
STATIC mp_obj_t socket_accept(mp_obj_t self_in) {
    mod_network_socket_obj_t *self = self_in;

    // create new socket object
    // starts with empty NIC so that finaliser doesn't run close() method if accept() fails
    mod_network_socket_obj_t *socket2 = m_new_obj_with_finaliser(mod_network_socket_obj_t);
    socket2->base.type = (mp_obj_t)&socket_type;
    socket2->nic = MP_OBJ_NULL;
    socket2->nic_type = NULL;

    // accept incoming connection
    uint8_t ip[MOD_NETWORK_IPV4ADDR_BUF_SIZE];
    mp_uint_t port;
    int _errno;
    if (self->nic_type->accept(self, socket2, ip, &port, &_errno) != 0) {
        nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
    }

    // new socket has valid state, so set the NIC to the same as parent
    socket2->nic = self->nic;
    socket2->nic_type = self->nic_type;

    // make the return value
    mp_obj_tuple_t *client = mp_obj_new_tuple(2, NULL);
    client->items[0] = socket2;
    client->items[1] = mod_network_format_inet_addr(ip, port);

    return client;
}
示例#5
0
// constructor socket(family=AF_INET, type=SOCK_STREAM, proto=IPPROTO_TCP, fileno=None)
STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
    mp_arg_check_num(n_args, n_kw, 0, 4, false);

    // create socket object
    mod_network_socket_obj_t *s = m_new_obj_with_finaliser(mod_network_socket_obj_t);
    s->base.type = (mp_obj_t)&socket_type;
    s->sock_base.u_param.domain = AF_INET;
    s->sock_base.u_param.type = SOCK_STREAM;
    s->sock_base.u_param.proto = IPPROTO_TCP;
    s->sock_base.u_param.fileno = -1;
    s->sock_base.has_timeout = false;
    s->sock_base.cert_req = false;

    if (n_args > 0) {
        s->sock_base.u_param.domain = mp_obj_get_int(args[0]);
        if (n_args > 1) {
            s->sock_base.u_param.type = mp_obj_get_int(args[1]);
            if (n_args > 2) {
                s->sock_base.u_param.proto = mp_obj_get_int(args[2]);
                if (n_args > 3) {
                    s->sock_base.u_param.fileno = mp_obj_get_int(args[3]);
                }
            }
        }
    }

    // create the socket
    int _errno;
    if (wlan_socket_socket(s, &_errno) != 0) {
        mp_raise_OSError(-_errno);
    }
    // add the socket to the list
    modusocket_socket_add(s->sock_base.sd, true);
    return s;
}
示例#6
0
STATIC mp_obj_t socket_accept(const mp_obj_t arg0) {
    socket_obj_t *self = MP_OBJ_TO_PTR(arg0);

    struct sockaddr addr;
    socklen_t addr_len = sizeof(addr);

    int new_fd = -1;
    for (int i=0; i<=self->retries; i++) {
        MP_THREAD_GIL_EXIT();
        new_fd = lwip_accept_r(self->fd, &addr, &addr_len);
        MP_THREAD_GIL_ENTER();
        if (new_fd >= 0) break;
        if (errno != EAGAIN) exception_from_errno(errno);
        check_for_exceptions();
    }
    if (new_fd < 0) mp_raise_OSError(MP_ETIMEDOUT);

    // create new socket object
    socket_obj_t *sock = m_new_obj_with_finaliser(socket_obj_t);
    sock->base.type = self->base.type;
    sock->fd = new_fd;
    sock->domain = self->domain;
    sock->type = self->type;
    sock->proto = self->proto;
    _socket_settimeout(sock, UINT64_MAX);

    // make the return value
    uint8_t *ip = (uint8_t*)&((struct sockaddr_in*)&addr)->sin_addr;
    mp_uint_t port = lwip_ntohs(((struct sockaddr_in*)&addr)->sin_port);
    mp_obj_tuple_t *client = mp_obj_new_tuple(2, NULL);
    client->items[0] = sock;
    client->items[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG);

    return client;
}
示例#7
0
STATIC mp_obj_t file_obj_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
    mp_arg_check_num(n_args, n_kw, 1, 2, false);
    const char *filename = mp_obj_str_get_str(args[0]);
    const char *mode = "r";
    if (n_args > 1) {
        mode = mp_obj_str_get_str(args[1]);
    }
    pyb_file_obj_t *self = m_new_obj_with_finaliser(pyb_file_obj_t);
    self->base.type = &file_obj_type;
    if (mode[0] == 'r') {
        // open for reading
        FRESULT res = f_open(&self->fp, filename, FA_READ);
        if (res != FR_OK) {
            printf("FileNotFoundError: [Errno 2] No such file or directory: '%s'\n", filename);
            return mp_const_none;
        }
    } else if (mode[0] == 'w') {
        // open for writing, truncate the file first
        FRESULT res = f_open(&self->fp, filename, FA_WRITE | FA_CREATE_ALWAYS);
        if (res != FR_OK) {
            printf("?FileError: could not create file: '%s'\n", filename);
            return mp_const_none;
        }
    } else {
        printf("ValueError: invalid mode: '%s'\n", mode);
        return mp_const_none;
    }
    return self;
}
示例#8
0
STATIC mp_obj_t file_obj_make_new(mp_obj_t type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
    mp_arg_check_num(n_args, n_kw, 1, 2, false);

    const char *fname = mp_obj_str_get_str(args[0]);

    int mode = 0;
    if (n_args == 1) {
        mode = FA_READ;
    } else {
        const char *mode_s = mp_obj_str_get_str(args[1]);
        // TODO make sure only one of r, w, x, a, and b, t are specified
        while (*mode_s) {
            switch (*mode_s++) {
                case 'r':
                    mode |= FA_READ;
                    break;
                case 'w':
                    mode |= FA_WRITE | FA_CREATE_ALWAYS;
                    break;
                case 'x':
                    mode |= FA_WRITE | FA_CREATE_NEW;
                    break;
                case 'a':
                    mode |= FA_WRITE | FA_OPEN_ALWAYS;
                    break;
                case '+':
                    mode |= FA_READ | FA_WRITE;
                    break;
                #if MICROPY_PY_IO_FILEIO
                case 'b':
                    type = (mp_obj_t)&mp_type_fileio;
                    break;
                #endif
                case 't':
                    type = (mp_obj_t)&mp_type_textio;
                    break;
            }
        }
    }

    pyb_file_obj_t *o = m_new_obj_with_finaliser(pyb_file_obj_t);
    o->base.type = type;

    FRESULT res = f_open(&o->fp, fname, mode);
    if (res != FR_OK) {
        m_del_obj(pyb_file_obj_t, o);
        nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
    }

    // for 'a' mode, we must begin at the end of the file
    if ((mode & FA_OPEN_ALWAYS) != 0) {
        f_lseek(&o->fp, f_size(&o->fp));
    }

    return o;
}
示例#9
0
// FIXME: Only supports two arguments at present
STATIC mp_obj_t lwip_socket_make_new(const mp_obj_type_t *type, mp_uint_t n_args,
                                     mp_uint_t n_kw, const mp_obj_t *args) {
    mp_arg_check_num(n_args, n_kw, 0, 4, false);

    lwip_socket_obj_t *socket = m_new_obj_with_finaliser(lwip_socket_obj_t);
    socket->base.type = (mp_obj_t)&lwip_socket_type;
    socket->domain = MOD_NETWORK_AF_INET;
    socket->type = MOD_NETWORK_SOCK_STREAM;
    socket->callback = MP_OBJ_NULL;
    if (n_args >= 1) {
        socket->domain = mp_obj_get_int(args[0]);
        if (n_args >= 2) {
            socket->type = mp_obj_get_int(args[1]);
        }
    }

    switch (socket->type) {
    case MOD_NETWORK_SOCK_STREAM:
        socket->pcb.tcp = tcp_new();
        break;
    case MOD_NETWORK_SOCK_DGRAM:
        socket->pcb.udp = udp_new();
        break;
    //case MOD_NETWORK_SOCK_RAW: socket->pcb.raw = raw_new(); break;
    default:
        nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EINVAL)));
    }

    if (socket->pcb.tcp == NULL) {
        nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_ENOMEM)));
    }

    switch (socket->type) {
    case MOD_NETWORK_SOCK_STREAM: {
        // Register the socket object as our callback argument.
        tcp_arg(socket->pcb.tcp, (void*)socket);
        // Register our error callback.
        tcp_err(socket->pcb.tcp, _lwip_tcp_error);
        break;
    }
    case MOD_NETWORK_SOCK_DGRAM: {
        // Register our receive callback now. Since UDP sockets don't require binding or connection
        // before use, there's no other good time to do it.
        udp_recv(socket->pcb.udp, _lwip_udp_incoming, (void*)socket);
        break;
    }
    }

    socket->incoming.pbuf = NULL;
    socket->timeout = -1;
    socket->state = STATE_NEW;
    socket->leftover_count = 0;
    return socket;
}
示例#10
0
STATIC mp_obj_t esp_socket_make_new_base() {
    esp_socket_obj_t *s = m_new_obj_with_finaliser(esp_socket_obj_t);
    s->recvbuf = NULL;
    s->base.type = (mp_obj_t)&esp_socket_type;
    s->cb_connect = mp_const_none;
    s->cb_recv = mp_const_none;
    s->cb_disconnect = mp_const_none;
    s->cb_sent = mp_const_none;
    s->fromserver = false;
    s->connlist = NULL;
    return s;
}
示例#11
0
static void get_fds(mp_obj_t *fdlist, uint fdlist_len, mp_obj_t *fdlist_out, fd_set *fdset)
{
    for (int i=0; i<fdlist_len; i++) {
        socket_t *s = fdlist[i];
        if (FD_ISSET(s->fd, fdset)) {
            socket_t *socket_obj = m_new_obj_with_finaliser(socket_t);
            socket_obj->base.type = (mp_obj_t)&socket_type;
            socket_obj->fd  = s->fd;
            mp_obj_list_append(fdlist_out, socket_obj);
        }
    }
}
示例#12
0
STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_arg_val_t *args) {
    int mode = 0;
    const char *mode_s = mp_obj_str_get_str(args[1].u_obj);
    // TODO make sure only one of r, w, x, a, and b, t are specified
    while (*mode_s) {
        switch (*mode_s++) {
            case 'r':
                mode |= FA_READ;
                break;
            case 'w':
                mode |= FA_WRITE | FA_CREATE_ALWAYS;
                break;
            case 'x':
                mode |= FA_WRITE | FA_CREATE_NEW;
                break;
            case 'a':
                mode |= FA_WRITE | FA_OPEN_ALWAYS;
                break;
            case '+':
                mode |= FA_READ | FA_WRITE;
                break;
            #if MICROPY_PY_IO_FILEIO
            case 'b':
                type = &mp_type_fileio;
                break;
            #endif
            case 't':
                type = &mp_type_textio;
                break;
        }
    }

    pyb_file_obj_t *o = m_new_obj_with_finaliser(pyb_file_obj_t);
    o->base.type = type;

    const char *fname = mp_obj_str_get_str(args[0].u_obj);
    assert(vfs != NULL);
    FRESULT res = f_open(&vfs->fatfs, &o->fp, fname, mode);
    if (res != FR_OK) {
        m_del_obj(pyb_file_obj_t, o);
        mp_raise_OSError(fresult_to_errno_table[res]);
    }

    // for 'a' mode, we must begin at the end of the file
    if ((mode & FA_OPEN_ALWAYS) != 0) {
        f_lseek(&o->fp, f_size(&o->fp));
    }

    return MP_OBJ_FROM_PTR(o);
}
示例#13
0
STATIC mp_obj_t ppp_make_new(mp_obj_t stream) {
    mp_get_stream_raise(stream, MP_STREAM_OP_READ | MP_STREAM_OP_WRITE);

    ppp_if_obj_t *self = m_new_obj_with_finaliser(ppp_if_obj_t);

    self->base.type = &ppp_if_type;
    self->stream = stream;
    self->active = false;
    self->connected = false;
    self->clean_close = false;
    self->client_task_handle = NULL;

    return MP_OBJ_FROM_PTR(self);
}
示例#14
0
STATIC mp_obj_t get_socket(size_t n_args, const mp_obj_t *args) {
    socket_obj_t *sock = m_new_obj_with_finaliser(socket_obj_t);
    sock->base.type = &socket_type;
    sock->domain = AF_INET;
    sock->type = SOCK_STREAM;
    sock->proto = 0;
    if (n_args > 0) {
        sock->domain = mp_obj_get_int(args[0]);
        if (n_args > 1) {
            sock->type = mp_obj_get_int(args[1]);
            if (n_args > 2) {
                sock->proto = mp_obj_get_int(args[2]);
            }
        }
    }

    sock->fd = lwip_socket(sock->domain, sock->type, sock->proto);
    if (sock->fd < 0) {
        exception_from_errno(errno);
    }
    _socket_settimeout(sock, UINT64_MAX);

    return MP_OBJ_FROM_PTR(sock);
}
示例#15
0
STATIC mp_obj_t lwip_socket_accept(mp_obj_t self_in) {
    lwip_socket_obj_t *socket = self_in;

    if (socket->pcb.tcp == NULL) {
        mp_raise_OSError(MP_EBADF);
    }
    if (socket->type != MOD_NETWORK_SOCK_STREAM) {
        mp_raise_OSError(MP_EOPNOTSUPP);
    }
    // I need to do this because "tcp_accepted", later, is a macro.
    struct tcp_pcb *listener = socket->pcb.tcp;
    if (listener->state != LISTEN) {
        mp_raise_OSError(MP_EINVAL);
    }

    // accept incoming connection
    if (socket->incoming.connection == NULL) {
        if (socket->timeout == 0) {
            mp_raise_OSError(MP_EAGAIN);
        } else if (socket->timeout != -1) {
            for (mp_uint_t retries = socket->timeout / 100; retries--;) {
                mp_hal_delay_ms(100);
                if (socket->incoming.connection != NULL) break;
            }
            if (socket->incoming.connection == NULL) {
                mp_raise_OSError(MP_ETIMEDOUT);
            }
        } else {
            while (socket->incoming.connection == NULL) {
                poll_sockets();
            }
        }
    }

    // create new socket object
    lwip_socket_obj_t *socket2 = m_new_obj_with_finaliser(lwip_socket_obj_t);
    socket2->base.type = (mp_obj_t)&lwip_socket_type;

    // We get a new pcb handle...
    socket2->pcb.tcp = socket->incoming.connection;
    socket->incoming.connection = NULL;

    // ...and set up the new socket for it.
    socket2->domain = MOD_NETWORK_AF_INET;
    socket2->type = MOD_NETWORK_SOCK_STREAM;
    socket2->incoming.pbuf = NULL;
    socket2->timeout = socket->timeout;
    socket2->state = STATE_CONNECTED;
    socket2->recv_offset = 0;
    socket2->callback = MP_OBJ_NULL;
    tcp_arg(socket2->pcb.tcp, (void*)socket2);
    tcp_err(socket2->pcb.tcp, _lwip_tcp_error);
    tcp_recv(socket2->pcb.tcp, _lwip_tcp_recv);

    tcp_accepted(listener);

    // make the return value
    uint8_t ip[NETUTILS_IPV4ADDR_BUFSIZE];
    memcpy(ip, &(socket2->pcb.tcp->remote_ip), sizeof(ip));
    mp_uint_t port = (mp_uint_t)socket2->pcb.tcp->remote_port;
    mp_obj_tuple_t *client = mp_obj_new_tuple(2, NULL);
    client->items[0] = socket2;
    client->items[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG);

    return client;
}
示例#16
0
STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) {
    // Verify the socket object has the full stream protocol
    mp_get_stream_raise(sock, MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL);

#if MICROPY_PY_USSL_FINALISER
    mp_obj_ssl_socket_t *o = m_new_obj_with_finaliser(mp_obj_ssl_socket_t);
#else
    mp_obj_ssl_socket_t *o = m_new_obj(mp_obj_ssl_socket_t);
#endif
    o->base.type = &ussl_socket_type;
    o->sock = sock;

    int ret;
    mbedtls_ssl_init(&o->ssl);
    mbedtls_ssl_config_init(&o->conf);
    mbedtls_x509_crt_init(&o->cacert);
    mbedtls_x509_crt_init(&o->cert);
    mbedtls_pk_init(&o->pkey);
    mbedtls_ctr_drbg_init(&o->ctr_drbg);
    #ifdef MBEDTLS_DEBUG_C
    // Debug level (0-4)
    mbedtls_debug_set_threshold(0);
    #endif

    mbedtls_entropy_init(&o->entropy);
    const byte seed[] = "upy";
    ret = mbedtls_ctr_drbg_seed(&o->ctr_drbg, mbedtls_entropy_func, &o->entropy, seed, sizeof(seed));
    if (ret != 0) {
        goto cleanup;
    }

    ret = mbedtls_ssl_config_defaults(&o->conf,
                    args->server_side.u_bool ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT,
                    MBEDTLS_SSL_TRANSPORT_STREAM,
                    MBEDTLS_SSL_PRESET_DEFAULT);
    if (ret != 0) {
        goto cleanup;
    }

    mbedtls_ssl_conf_authmode(&o->conf, MBEDTLS_SSL_VERIFY_NONE);
    mbedtls_ssl_conf_rng(&o->conf, mbedtls_ctr_drbg_random, &o->ctr_drbg);
    #ifdef MBEDTLS_DEBUG_C
    mbedtls_ssl_conf_dbg(&o->conf, mbedtls_debug, NULL);
    #endif

    ret = mbedtls_ssl_setup(&o->ssl, &o->conf);
    if (ret != 0) {
        goto cleanup;
    }

    if (args->server_hostname.u_obj != mp_const_none) {
        const char *sni = mp_obj_str_get_str(args->server_hostname.u_obj);
        ret = mbedtls_ssl_set_hostname(&o->ssl, sni);
        if (ret != 0) {
            goto cleanup;
        }
    }

    mbedtls_ssl_set_bio(&o->ssl, &o->sock, _mbedtls_ssl_send, _mbedtls_ssl_recv, NULL);

    if (args->key.u_obj != MP_OBJ_NULL) {
        size_t key_len;
        const byte *key = (const byte*)mp_obj_str_get_data(args->key.u_obj, &key_len);
        // len should include terminating null
        ret = mbedtls_pk_parse_key(&o->pkey, key, key_len + 1, NULL, 0);
        assert(ret == 0);

        size_t cert_len;
        const byte *cert = (const byte*)mp_obj_str_get_data(args->cert.u_obj, &cert_len);
        // len should include terminating null
        ret = mbedtls_x509_crt_parse(&o->cert, cert, cert_len + 1);
        assert(ret == 0);

        ret = mbedtls_ssl_conf_own_cert(&o->conf, &o->cert, &o->pkey);
        assert(ret == 0);
    }

    if (args->do_handshake.u_bool) {
        while ((ret = mbedtls_ssl_handshake(&o->ssl)) != 0) {
            if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
                printf("mbedtls_ssl_handshake error: -%x\n", -ret);
                goto cleanup;
            }
        }
    }

    return o;

cleanup:
    mbedtls_pk_free(&o->pkey);
    mbedtls_x509_crt_free(&o->cert);
    mbedtls_x509_crt_free(&o->cacert);
    mbedtls_ssl_free(&o->ssl);
    mbedtls_ssl_config_free(&o->conf);
    mbedtls_ctr_drbg_free(&o->ctr_drbg);
    mbedtls_entropy_free(&o->entropy);

    if (ret == MBEDTLS_ERR_SSL_ALLOC_FAILED) {
        mp_raise_OSError(MP_ENOMEM);
    } else {
        mp_raise_OSError(MP_EIO);
    }
}
示例#17
0
socket_obj_t *socket_new(void) {
    socket_obj_t *socket = m_new_obj_with_finaliser(socket_obj_t);
    socket->base.type = (mp_obj_t)&socket_type;
    socket->state = STATE_NEW;
    return socket;
}
示例#18
0
STATIC mp_obj_t lwip_socket_accept(mp_obj_t self_in) {
    lwip_socket_obj_t *socket = self_in;

    if (socket->pcb == NULL) {
        nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EBADF)));
    }
    if (socket->type != MOD_NETWORK_SOCK_STREAM) {
        nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EOPNOTSUPP)));
    }
    // I need to do this because "tcp_accepted", later, is a macro.
    struct tcp_pcb *listener = (struct tcp_pcb*)socket->pcb;
    if (listener->state != LISTEN) {
        nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EINVAL)));
    }

    // accept incoming connection
    if (socket->incoming == NULL) {
        if (socket->timeout != -1) {
            for (mp_uint_t retries = socket->timeout / 100; retries--;) {
                mp_hal_delay_ms(100);
                if (socket->incoming != NULL) break;
            }
            if (socket->incoming == NULL) {
                nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ETIMEDOUT)));
            }
        } else {
            while (socket->incoming == NULL) {
                mp_hal_delay_ms(100);
            }
        }
    }

    // create new socket object
    lwip_socket_obj_t *socket2 = m_new_obj_with_finaliser(lwip_socket_obj_t);
    socket2->base.type = (mp_obj_t)&lwip_socket_type;

    // We get a new pcb handle...
    socket2->pcb = socket->incoming;
    socket->incoming = NULL;

    // ...and set up the new socket for it.
    socket2->domain = MOD_NETWORK_AF_INET;
    socket2->type = MOD_NETWORK_SOCK_STREAM;
    socket2->incoming = NULL;
    socket2->timeout = socket->timeout;
    socket2->connected = 2;
    socket2->leftover_count = 0;
    tcp_arg((struct tcp_pcb*)socket2->pcb, (void*)socket2);
    tcp_err((struct tcp_pcb*)socket2->pcb, _lwip_tcp_error);
    tcp_recv((struct tcp_pcb*)socket2->pcb, _lwip_tcp_recv);

    tcp_accepted(listener);

    // make the return value
    uint8_t ip[NETUTILS_IPV4ADDR_BUFSIZE];
    memcpy(ip, &(((struct tcp_pcb*)socket2->pcb)->remote_ip), 4);
    mp_uint_t port = (mp_uint_t)((struct tcp_pcb*)socket2->pcb)->remote_port;
    mp_obj_tuple_t *client = mp_obj_new_tuple(2, NULL);
    client->items[0] = socket2;
    client->items[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG);

    return client;
}