summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDaniel Campora <daniel@wipy.io>2015-05-22 19:53:33 +0200
committerDaniel Campora <daniel@wipy.io>2015-05-22 19:53:33 +0200
commited56b0baba47e4d0697fdc2d81310a9a2c34c5df (patch)
tree260ea9aa95a23870487e8b0b24df9f7d41a86269
parent18030bd85d77367162162496ee025b7d98ad3c41 (diff)
downloadmicropython-ed56b0baba47e4d0697fdc2d81310a9a2c34c5df.tar.gz
micropython-ed56b0baba47e4d0697fdc2d81310a9a2c34c5df.zip
cc3200: Finally unlock the full wake on WLAN feature set.
-rw-r--r--cc3200/ftp/ftp.c8
-rw-r--r--cc3200/mods/modnetwork.c32
-rw-r--r--cc3200/mods/modnetwork.h5
-rw-r--r--cc3200/mods/modusocket.c190
-rw-r--r--cc3200/mods/modusocket.h36
-rw-r--r--cc3200/mods/modwlan.c24
-rw-r--r--cc3200/mods/pybsleep.c4
-rw-r--r--cc3200/mpconfigport.h1
-rw-r--r--cc3200/mptask.c9
-rw-r--r--cc3200/qstrdefsport.h1
-rw-r--r--cc3200/serverstask.c18
-rw-r--r--cc3200/serverstask.h1
-rw-r--r--cc3200/telnet/telnet.c13
13 files changed, 207 insertions, 135 deletions
diff --git a/cc3200/ftp/ftp.c b/cc3200/ftp/ftp.c
index 3dc0923ce2..d812f563af 100644
--- a/cc3200/ftp/ftp.c
+++ b/cc3200/ftp/ftp.c
@@ -40,6 +40,7 @@
#include "ftp.h"
#include "simplelink.h"
#include "modwlan.h"
+#include "modusocket.h"
#include "debug.h"
#include "serverstask.h"
#include "ff.h"
@@ -50,7 +51,6 @@
#include "updater.h"
#include "timeutils.h"
-
/******************************************************************************
DEFINE PRIVATE CONSTANTS
******************************************************************************/
@@ -429,6 +429,9 @@ static bool ftp_create_listening_socket (_i16 *sd, _u16 port, _u8 backlog) {
_sd = *sd;
if (_sd > 0) {
+ // add the new socket to the network administration
+ modusocket_socket_add(_sd, false);
+
// Enable non-blocking mode
nonBlockingOption.NonblockingEnabled = 1;
ASSERT (sl_SetSockOpt(_sd, SOL_SOCKET, SL_SO_NONBLOCKING, &nonBlockingOption, sizeof(nonBlockingOption)) == SL_SOC_OK);
@@ -464,6 +467,9 @@ static ftp_result_t ftp_wait_for_connection (_i16 l_sd, _i16 *n_sd) {
return E_FTP_RESULT_FAILED;
}
+ // add the new socket to the network administration
+ modusocket_socket_add(_sd, false);
+
// client connected, so go on
return E_FTP_RESULT_OK;
}
diff --git a/cc3200/mods/modnetwork.c b/cc3200/mods/modnetwork.c
index f7dfd139f8..dd91427f41 100644
--- a/cc3200/mods/modnetwork.c
+++ b/cc3200/mods/modnetwork.c
@@ -25,47 +25,22 @@
* THE SOFTWARE.
*/
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
+#include <std.h>
#include "py/mpstate.h"
#include MICROPY_HAL_H
#include "modnetwork.h"
#include "mpexception.h"
#include "serverstask.h"
+#include "simplelink.h"
+
/// \module network - network configuration
///
/// This module provides network drivers and routing configuration.
void mod_network_init0(void) {
- mp_obj_list_init(&MP_STATE_PORT(mod_network_nic_list), 0);
-}
-
-void mod_network_register_nic(mp_obj_t nic) {
- for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) {
- if (MP_STATE_PORT(mod_network_nic_list).items[i] == nic) {
- // nic already registered
- return;
- }
- }
- // nic not registered so add to list
- mp_obj_list_append(&MP_STATE_PORT(mod_network_nic_list), nic);
-}
-
-mp_obj_t mod_network_find_nic(void) {
- for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) {
- mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i];
- return nic;
- }
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
-}
-
-STATIC mp_obj_t network_route(void) {
- return &MP_STATE_PORT(mod_network_nic_list);
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_0(network_route_obj, network_route);
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
STATIC mp_obj_t network_server_start(void) {
@@ -97,7 +72,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(network_server_login_obj, network_server_login)
STATIC const mp_map_elem_t mp_module_network_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_network) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_WLAN), (mp_obj_t)&mod_network_nic_type_wlan },
- { MP_OBJ_NEW_QSTR(MP_QSTR_route), (mp_obj_t)&network_route_obj },
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
{ MP_OBJ_NEW_QSTR(MP_QSTR_start_server), (mp_obj_t)&network_server_start_obj },
diff --git a/cc3200/mods/modnetwork.h b/cc3200/mods/modnetwork.h
index 1b7811c93f..891513bc13 100644
--- a/cc3200/mods/modnetwork.h
+++ b/cc3200/mods/modnetwork.h
@@ -37,7 +37,7 @@ typedef struct _mod_network_nic_type_t {
mp_obj_type_t base;
// API for non-socket operations
- int (*gethostbyname)(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *ip_out, uint8_t family);
+ int (*gethostbyname)(const char *name, mp_uint_t len, uint8_t *ip_out, uint8_t family);
// API for socket operations; return -1 on error
int (*socket)(struct _mod_network_socket_obj_t *s, int *_errno);
@@ -57,7 +57,6 @@ typedef struct _mod_network_nic_type_t {
typedef struct _mod_network_socket_obj_t {
mp_obj_base_t base;
- mp_obj_t nic;
mod_network_nic_type_t *nic_type;
union {
struct {
@@ -74,7 +73,5 @@ typedef struct _mod_network_socket_obj_t {
extern const mod_network_nic_type_t mod_network_nic_type_wlan;
void mod_network_init0(void);
-void mod_network_register_nic(mp_obj_t nic);
-mp_obj_t mod_network_find_nic(void);
#endif // MODNETWORK_H_
diff --git a/cc3200/mods/modusocket.c b/cc3200/mods/modusocket.c
index 0d9564a48b..68a3252c98 100644
--- a/cc3200/mods/modusocket.c
+++ b/cc3200/mods/modusocket.c
@@ -34,62 +34,135 @@
#include "py/runtime.h"
#include "netutils.h"
#include "modnetwork.h"
+#include "modusocket.h"
#include "mpexception.h"
-/******************************************************************************/
-// socket class
+/******************************************************************************
+ DEFINE PRIVATE CONSTANTS
+ ******************************************************************************/
+#define MOD_NETWORK_MAX_SOCKETS 10
+
+/******************************************************************************
+ DEFINE PRIVATE TYPES
+ ******************************************************************************/
+typedef struct {
+ int16_t sd;
+ bool user;
+} modusocket_sock_t;
+
+/******************************************************************************
+ DEFINE PRIVATE DATA
+ ******************************************************************************/
+STATIC OsiLockObj_t modusocket_LockObj;
+STATIC modusocket_sock_t modusocket_sockets[MOD_NETWORK_MAX_SOCKETS] = {{.sd = -1}, {.sd = -1}, {.sd = -1}, {.sd = -1}, {.sd = -1},
+ {.sd = -1}, {.sd = -1}, {.sd = -1}, {.sd = -1}, {.sd = -1}};
+
+/******************************************************************************
+ DEFINE PUBLIC FUNCTIONS
+ ******************************************************************************/
+__attribute__ ((section (".boot")))
+void modusocket_pre_init (void) {
+ // create the wlan lock
+ ASSERT(OSI_OK == sl_LockObjCreate(&modusocket_LockObj, "SockLock"));
+ sl_LockObjUnlock (&modusocket_LockObj);
+}
-STATIC const mp_obj_type_t socket_type;
+void modusocket_socket_add (int16_t sd, bool user) {
+ sl_LockObjLock (&modusocket_LockObj, SL_OS_WAIT_FOREVER);
+ for (int i = 0; i < MOD_NETWORK_MAX_SOCKETS; i++) {
+ if (modusocket_sockets[i].sd < 0) {
+ modusocket_sockets[i].sd = sd;
+ modusocket_sockets[i].user = user;
+ break;
+ }
+ }
+ sl_LockObjUnlock (&modusocket_LockObj);
+}
-STATIC void socket_select_nic(mod_network_socket_obj_t *self) {
- // select a nic
- self->nic = mod_network_find_nic();
- self->nic_type = (mod_network_nic_type_t*)mp_obj_get_type(self->nic);
+void modusocket_socket_delete (int16_t sd) {
+ sl_LockObjLock (&modusocket_LockObj, SL_OS_WAIT_FOREVER);
+ for (int i = 0; i < MOD_NETWORK_MAX_SOCKETS; i++) {
+ if (modusocket_sockets[i].sd == sd) {
+ modusocket_sockets[i].sd = -1;
+ break;
+ }
+ }
+ sl_LockObjUnlock (&modusocket_LockObj);
+}
- // call the nic to open the socket
- int _errno;
- if (self->nic_type->socket(self, &_errno) != 0) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
+void modusocket_enter_sleep (void) {
+ fd_set socketset;
+ int16_t maxfd = 0;
+
+ sl_LockObjLock (&modusocket_LockObj, SL_OS_WAIT_FOREVER);
+ for (int i = 0; i < MOD_NETWORK_MAX_SOCKETS; i++) {
+ int16_t sd;
+ if ((sd = modusocket_sockets[i].sd) >= 0) {
+ FD_SET(sd, &socketset);
+ maxfd = (maxfd > sd) ? maxfd : sd;
+ }
}
+
+ // wait for any of the sockets to become ready...
+ sl_Select(maxfd + 1, &socketset, NULL, NULL, NULL);
+ sl_LockObjUnlock (&modusocket_LockObj);
}
+void modusocket_close_all_user_sockets (void) {
+ sl_LockObjLock (&modusocket_LockObj, SL_OS_WAIT_FOREVER);
+ for (int i = 0; i < MOD_NETWORK_MAX_SOCKETS; i++) {
+ if (modusocket_sockets[i].sd >= 0 && modusocket_sockets[i].user) {
+ sl_Close(modusocket_sockets[i].sd);
+ modusocket_sockets[i].sd = -1;
+ }
+ }
+ sl_LockObjUnlock (&modusocket_LockObj);
+}
+
+/******************************************************************************/
+// socket class
+
+STATIC const mp_obj_type_t socket_type;
+
// 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)
+ // 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->nic = MP_OBJ_NULL;
- s->nic_type = NULL;
+ s->nic_type = (mod_network_nic_type_t *)&mod_network_nic_type_wlan;
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) {
+ if (n_args > 0) {
s->u_param.domain = mp_obj_get_int(args[0]);
- if (n_args >= 2) {
+ if (n_args > 1) {
s->u_param.type = mp_obj_get_int(args[1]);
- if (n_args >= 3) {
+ if (n_args > 2) {
s->u_param.proto = mp_obj_get_int(args[2]);
- if (n_args == 4) {
+ if (n_args > 3) {
s->u_param.fileno = mp_obj_get_int(args[3]);
}
}
}
}
- socket_select_nic(s);
+ // create the socket
+ int _errno;
+ if (s->nic_type->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;
}
// method socket.close()
STATIC mp_obj_t socket_close(mp_obj_t self_in) {
mod_network_socket_obj_t *self = self_in;
- if (self->nic != MP_OBJ_NULL) {
- self->nic_type->close(self);
- }
+ self->nic_type->close(self);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(socket_close_obj, socket_close);
@@ -107,7 +180,6 @@ STATIC mp_obj_t socket_bind(mp_obj_t self_in, mp_obj_t addr_in) {
if (self->nic_type->bind(self, ip, port, &_errno) != 0) {
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
}
-
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_bind_obj, socket_bind);
@@ -116,16 +188,10 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_bind_obj, socket_bind);
STATIC mp_obj_t socket_listen(mp_obj_t self_in, mp_obj_t backlog) {
mod_network_socket_obj_t *self = self_in;
- if (self->nic == MP_OBJ_NULL) {
- // not connected
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ENOTCONN)));
- }
-
int _errno;
if (self->nic_type->listen(self, mp_obj_get_int(backlog), &_errno) != 0) {
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
}
-
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_listen_obj, socket_listen);
@@ -135,11 +201,10 @@ 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
+ // starts with empty nic so that the 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;
+ socket2->nic_type = MP_OBJ_NULL;
// accept incoming connection
uint8_t ip[MOD_NETWORK_IPV4ADDR_BUF_SIZE];
@@ -149,15 +214,16 @@ STATIC mp_obj_t socket_accept(mp_obj_t self_in) {
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;
+ // new socket has valid state, so set the nic to the same as parent
socket2->nic_type = self->nic_type;
+ // add the socket to the list
+ modusocket_socket_add(socket2->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;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(socket_accept_obj, socket_accept);
@@ -175,7 +241,6 @@ STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
if (self->nic_type->connect(self, ip, port, &_errno) != 0) {
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
}
-
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_connect_obj, socket_connect);
@@ -183,10 +248,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_connect_obj, socket_connect);
// method socket.send(bytes)
STATIC mp_obj_t socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
mod_network_socket_obj_t *self = self_in;
- if (self->nic == MP_OBJ_NULL) {
- // not connected
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EBADF)));
- }
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
int _errno;
@@ -201,10 +262,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_send_obj, socket_send);
// method socket.recv(bufsize)
STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) {
mod_network_socket_obj_t *self = self_in;
- if (self->nic == MP_OBJ_NULL) {
- // not connected
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ENOTCONN)));
- }
mp_int_t len = mp_obj_get_int(len_in);
vstr_t vstr;
vstr_init_len(&vstr, len);
@@ -234,13 +291,12 @@ STATIC mp_obj_t socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_
uint8_t ip[MOD_NETWORK_IPV4ADDR_BUF_SIZE];
mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_LITTLE);
- // call the NIC to sendto
+ // call the nic to sendto
int _errno;
mp_int_t ret = self->nic_type->sendto(self, bufinfo.buf, bufinfo.len, ip, port, &_errno);
if (ret == -1) {
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
}
-
return mp_obj_new_int(ret);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(socket_sendto_obj, socket_sendto);
@@ -248,10 +304,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(socket_sendto_obj, socket_sendto);
// method socket.recvfrom(bufsize)
STATIC mp_obj_t socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) {
mod_network_socket_obj_t *self = self_in;
- if (self->nic == MP_OBJ_NULL) {
- // not connected
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ENOTCONN)));
- }
vstr_t vstr;
vstr_init_len(&vstr, mp_obj_get_int(len_in));
byte ip[4];
@@ -299,7 +351,6 @@ STATIC mp_obj_t socket_setsockopt(mp_uint_t n_args, const mp_obj_t *args) {
if (self->nic_type->setsockopt(self, level, opt, optval, optlen, &_errno) != 0) {
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
}
-
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_setsockopt_obj, 4, 4, socket_setsockopt);
@@ -310,10 +361,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_setsockopt_obj, 4, 4, socket_s
// otherwise, timeout is in seconds
STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) {
mod_network_socket_obj_t *self = self_in;
- if (self->nic == MP_OBJ_NULL) {
- // not connected
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ENOTCONN)));
- }
mp_uint_t timeout;
if (timeout_in == mp_const_none) {
timeout = -1;
@@ -384,28 +431,19 @@ STATIC mp_obj_t mod_usocket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) {
const char *host = mp_obj_str_get_data(host_in, &hlen);
mp_int_t port = mp_obj_get_int(port_in);
- // find a NIC that can do a name lookup
- for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) {
- mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i];
- mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic);
- if (nic_type->gethostbyname != NULL) {
- // Only IPv4 is supported
- uint8_t out_ip[MOD_NETWORK_IPV4ADDR_BUF_SIZE];
- int32_t result = nic_type->gethostbyname(nic, host, hlen, out_ip, AF_INET);
- if (result != 0) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(result)));
- }
- mp_obj_tuple_t *tuple = mp_obj_new_tuple(5, NULL);
- tuple->items[0] = MP_OBJ_NEW_SMALL_INT(AF_INET);
- tuple->items[1] = MP_OBJ_NEW_SMALL_INT(SOCK_STREAM);
- tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0);
- tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_);
- tuple->items[4] = netutils_format_inet_addr(out_ip, port, NETUTILS_LITTLE);
- return mp_obj_new_list(1, (mp_obj_t*)&tuple);
- }
+ // ipv4 only
+ uint8_t out_ip[MOD_NETWORK_IPV4ADDR_BUF_SIZE];
+ int32_t result = mod_network_nic_type_wlan.gethostbyname(host, hlen, out_ip, AF_INET);
+ if (result != 0) {
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(result)));
}
-
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
+ mp_obj_tuple_t *tuple = mp_obj_new_tuple(5, NULL);
+ tuple->items[0] = MP_OBJ_NEW_SMALL_INT(AF_INET);
+ tuple->items[1] = MP_OBJ_NEW_SMALL_INT(SOCK_STREAM);
+ tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0);
+ tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_);
+ tuple->items[4] = netutils_format_inet_addr(out_ip, port, NETUTILS_LITTLE);
+ return mp_obj_new_list(1, (mp_obj_t*)&tuple);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_usocket_getaddrinfo_obj, mod_usocket_getaddrinfo);
diff --git a/cc3200/mods/modusocket.h b/cc3200/mods/modusocket.h
new file mode 100644
index 0000000000..c2c055325e
--- /dev/null
+++ b/cc3200/mods/modusocket.h
@@ -0,0 +1,36 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 Daniel Campora
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MODUSOCKET_H_
+#define MODUSOCKET_H_
+
+extern void modusocket_pre_init (void);
+extern void modusocket_socket_add (int16_t sd, bool user);
+extern void modusocket_socket_delete (int16_t sd);
+extern void modusocket_enter_sleep (void);
+extern void modusocket_close_all_user_sockets (void);
+
+#endif /* MODUSOCKET_H_ */
diff --git a/cc3200/mods/modwlan.c b/cc3200/mods/modwlan.c
index b05c046a99..cdcd375e66 100644
--- a/cc3200/mods/modwlan.c
+++ b/cc3200/mods/modwlan.c
@@ -36,6 +36,7 @@
#include "py/runtime.h"
#include "netutils.h"
#include "modnetwork.h"
+#include "modusocket.h"
#include "modwlan.h"
#include "pybioctl.h"
#include "debug.h"
@@ -229,6 +230,7 @@ void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent) {
{
CLR_STATUS_BIT(wlan_obj.status, STATUS_BIT_CONNECTION);
CLR_STATUS_BIT(wlan_obj.status, STATUS_BIT_IP_ACQUIRED);
+ // TODO reset the servers
}
break;
case SL_WLAN_STA_CONNECTED_EVENT:
@@ -243,6 +245,7 @@ void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent) {
break;
case SL_WLAN_STA_DISCONNECTED_EVENT:
wlan_obj.staconnected = false;
+ // TODO reset the servers
break;
case SL_WLAN_P2P_DEV_FOUND_EVENT:
// TODO
@@ -718,8 +721,6 @@ STATIC mp_obj_t wlan_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_k
}
wlan_obj.base.type = (mp_obj_type_t*)&mod_network_nic_type_wlan;
- // register with the network module
- mod_network_register_nic(&wlan_obj);
return &wlan_obj;
}
@@ -1065,7 +1066,7 @@ STATIC const mp_cb_methods_t wlan_cb_methods = {
/******************************************************************************/
// Micro Python bindings; WLAN socket
-STATIC int wlan_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip, uint8_t family) {
+STATIC int wlan_gethostbyname(const char *name, mp_uint_t len, uint8_t *out_ip, uint8_t family) {
uint32_t ip;
int result = sl_NetAppDnsGetHostByName((_i8 *)name, (_u16)len, (_u32*)&ip, (_u8)family);
@@ -1090,14 +1091,11 @@ STATIC int wlan_socket_socket(struct _mod_network_socket_obj_t *s, int *_errno)
// save the socket descriptor
s->sd = sd;
- // make it blocking by default
- int32_t optval = 0;
- sl_SetSockOpt(sd, SOL_SOCKET, SO_NONBLOCKING, &optval, (SlSocklen_t)sizeof(optval));
-
return 0;
}
STATIC void wlan_socket_close(mod_network_socket_obj_t *s) {
+ modusocket_socket_delete(s->sd);
s->closed = true;
sl_Close(s->sd);
}
@@ -1152,12 +1150,6 @@ STATIC int wlan_socket_connect(mod_network_socket_obj_t *s, byte *ip, mp_uint_t
}
STATIC int wlan_socket_send(mod_network_socket_obj_t *s, const byte *buf, mp_uint_t len, int *_errno) {
- if (s->closed) {
- sl_Close (s->sd);
- *_errno = EBADF;
- return -1;
- }
-
mp_int_t bytes = 0;
if (len > 0) {
bytes = sl_Send(s->sd, (const void *)buf, len, 0);
@@ -1173,7 +1165,7 @@ STATIC int wlan_socket_send(mod_network_socket_obj_t *s, const byte *buf, mp_uin
STATIC int wlan_socket_recv(mod_network_socket_obj_t *s, byte *buf, mp_uint_t len, int *_errno) {
// check if the socket is open
if (s->closed) {
- // socket is closed, but the CC3200 may have some data remaining in its buffer, so check
+ // socket is closed, but the there might be data remaining in the buffer, so check
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(s->sd, &rfds);
@@ -1182,8 +1174,8 @@ STATIC int wlan_socket_recv(mod_network_socket_obj_t *s, byte *buf, mp_uint_t le
tv.tv_usec = 2;
int nfds = sl_Select(s->sd + 1, &rfds, NULL, NULL, &tv);
if (nfds == -1 || !FD_ISSET(s->sd, &rfds)) {
- // no data waiting, so close socket and return 0 data
- sl_Close(s->sd);
+ // no data waiting, so close the socket and return 0 data
+ wlan_socket_close(s);
return 0;
}
}
diff --git a/cc3200/mods/pybsleep.c b/cc3200/mods/pybsleep.c
index 7e62418f4f..4226e6d1ce 100644
--- a/cc3200/mods/pybsleep.c
+++ b/cc3200/mods/pybsleep.c
@@ -52,6 +52,7 @@
#include "mpcallback.h"
#include "mperror.h"
#include "sleeprestore.h"
+#include "serverstask.h"
/******************************************************************************
DECLARE PRIVATE CONSTANTS
@@ -429,7 +430,7 @@ STATIC void PRCMInterruptHandler (void) {
pybsleep_wake_reason = PYB_SLP_WAKED_BY_GPIO;
break;
case PRCM_LPDS_TIMER:
- // disable the timer as a wake-up source
+ // disable the timer as wake-up source
pybsleep_data.timer_wake_pwrmode &= ~PYB_PWR_MODE_LPDS;
MAP_PRCMLPDSWakeupSourceDisable(PRCM_LPDS_TIMER);
mpcallback_handler(pybsleep_data.timer_lpds_wake_cb);
@@ -593,6 +594,7 @@ STATIC mp_obj_t pyb_sleep_suspend (mp_obj_t self_in) {
// do we need network wake-up?
if (pybsleep_data.wlan_lpds_wake_cb) {
MAP_PRCMLPDSWakeupSourceEnable (PRCM_LPDS_HOST_IRQ);
+ server_sleep_sockets();
}
else {
MAP_PRCMLPDSWakeupSourceDisable (PRCM_LPDS_HOST_IRQ);
diff --git a/cc3200/mpconfigport.h b/cc3200/mpconfigport.h
index 5bf6477ea4..fd60f04327 100644
--- a/cc3200/mpconfigport.h
+++ b/cc3200/mpconfigport.h
@@ -139,7 +139,6 @@ extern const struct _mp_obj_module_t mp_module_ubinascii;
const char *readline_hist[8]; \
mp_obj_t mp_const_user_interrupt; \
mp_obj_t pyb_config_main; \
- mp_obj_list_t mod_network_nic_list; \
mp_obj_list_t pybsleep_obj_list; \
mp_obj_list_t mpcallback_obj_list; \
mp_obj_list_t pyb_timer_channel_obj_list; \
diff --git a/cc3200/mptask.c b/cc3200/mptask.c
index 459d171302..7b730c5367 100644
--- a/cc3200/mptask.c
+++ b/cc3200/mptask.c
@@ -50,6 +50,7 @@
#include "mperror.h"
#include "simplelink.h"
#include "modnetwork.h"
+#include "modusocket.h"
#include "modwlan.h"
#include "serverstask.h"
#include "telnet.h"
@@ -255,6 +256,9 @@ soft_reset_exit:
// flush the serial flash buffer
sflash_disk_flush();
+ // clean-up the user socket space
+ modusocket_close_all_user_sockets();
+
#if MICROPY_HW_HAS_SDCARD
pybsd_deinit();
#endif
@@ -283,9 +287,12 @@ STATIC void mptask_pre_init (void) {
// this one allocates memory for the nvic vault
pybsleep_pre_init();
- // this one allocates mameory for the WLAN semaphore
+ // this one allocates memory for the WLAN semaphore
wlan_pre_init();
+ // this one allocates memory for the Socket semaphore
+ modusocket_pre_init();
+
#if MICROPY_HW_HAS_SDCARD
pybsd_init0();
#endif
diff --git a/cc3200/qstrdefsport.h b/cc3200/qstrdefsport.h
index ee07fb5ed3..c3fdf71f36 100644
--- a/cc3200/qstrdefsport.h
+++ b/cc3200/qstrdefsport.h
@@ -233,7 +233,6 @@ Q(IPPROTO_RAW)
// for network class
Q(network)
-Q(route)
Q(start_server)
Q(stop_server)
Q(server_running)
diff --git a/cc3200/serverstask.c b/cc3200/serverstask.c
index 550f0c0719..80f22987fe 100644
--- a/cc3200/serverstask.c
+++ b/cc3200/serverstask.c
@@ -36,6 +36,7 @@
#include "telnet.h"
#include "ftp.h"
#include "pybwdt.h"
+#include "modusocket.h"
/******************************************************************************
@@ -58,6 +59,7 @@ typedef struct {
DECLARE PRIVATE DATA
******************************************************************************/
static servers_Data_t servers_data = {.enabled = false, .do_disable = false, .do_enable = false};
+static volatile bool sleep_sockets = false;
/******************************************************************************
DECLARE PRIVATE FUNCTIONS
@@ -108,11 +110,17 @@ void TASK_Servers (void *pvParameters) {
ftp_run();
}
+ // set the alive flag for the wdt
+ pybwdt_srv_alive();
+
+ if (sleep_sockets) {
+ sleep_sockets = false;
+ modusocket_enter_sleep();
+ }
+
// move to the next cycle
cycle = cycle ? false : true;
HAL_Delay(SERVERS_CYCLE_TIME_MS);
- // set the alive flag for the wdt
- pybwdt_srv_alive();
}
}
@@ -133,8 +141,14 @@ bool servers_are_enabled (void) {
return servers_data.enabled;
}
+void server_sleep_sockets (void) {
+ sleep_sockets = true;
+ HAL_Delay (SERVERS_CYCLE_TIME_MS + 1);
+}
+
void servers_close_socket (int16_t *sd) {
if (*sd > 0) {
+ modusocket_socket_delete(*sd);
sl_Close(*sd);
*sd = -1;
}
diff --git a/cc3200/serverstask.h b/cc3200/serverstask.h
index 04b1367ff2..6607283136 100644
--- a/cc3200/serverstask.h
+++ b/cc3200/serverstask.h
@@ -59,5 +59,6 @@ extern void servers_stop (void);
extern bool servers_are_enabled (void);
extern void servers_close_socket (int16_t *sd);
extern void servers_set_login (char *user, char *pass);
+extern void server_sleep_sockets (void);
#endif /* SERVERSTASK_H_ */
diff --git a/cc3200/telnet/telnet.c b/cc3200/telnet/telnet.c
index a910437df4..0edc00cdb1 100644
--- a/cc3200/telnet/telnet.c
+++ b/cc3200/telnet/telnet.c
@@ -32,6 +32,7 @@
#include "telnet.h"
#include "simplelink.h"
#include "modwlan.h"
+#include "modusocket.h"
#include "debug.h"
#include "mpexception.h"
#include "serverstask.h"
@@ -322,6 +323,9 @@ static bool telnet_create_socket (void) {
// Open a socket for telnet
ASSERT ((telnet_data.sd = sl_Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) > 0);
if (telnet_data.sd > 0) {
+ // add the socket to the network administration
+ modusocket_socket_add(telnet_data.sd, false);
+
// Enable non-blocking mode
nonBlockingOption.NonblockingEnabled = 1;
ASSERT (sl_SetSockOpt(telnet_data.sd, SOL_SOCKET, SL_SO_NONBLOCKING, &nonBlockingOption, sizeof(nonBlockingOption)) == SL_SOC_OK);
@@ -352,15 +356,18 @@ static void telnet_wait_for_connection (void) {
return;
}
else {
- // close the listening socket, we don't need it anymore
- sl_Close(telnet_data.sd);
-
if (telnet_data.n_sd <= 0) {
// error
telnet_reset();
return;
}
+ // close the listening socket, we don't need it anymore
+ servers_close_socket(&telnet_data.sd);
+
+ // add the new socket to the network administration
+ modusocket_socket_add(telnet_data.n_sd, false);
+
// client connected, so go on
telnet_data.rxWindex = 0;
telnet_data.rxRindex = 0;