summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDaniel Campora <daniel@wipy.io>2015-06-11 20:26:24 +0200
committerDaniel Campora <daniel@wipy.io>2015-07-02 16:30:00 +0200
commit9a65fa304c151f796ecfd040b0744ed7cdc88537 (patch)
tree2d953bd10cca04a968880157ecabadb80cd2644e
parent7c1c9af5d42bf4b922945cfa8398c9fc5610d3b4 (diff)
downloadmicropython-9a65fa304c151f796ecfd040b0744ed7cdc88537.tar.gz
micropython-9a65fa304c151f796ecfd040b0744ed7cdc88537.zip
cc3200: Add modussl, ssl sockets subclassed from normal sockets.
Stream methods were added to normal sockets as in the unix port.
-rw-r--r--cc3200/application.mk1
-rw-r--r--cc3200/mods/modnetwork.h13
-rw-r--r--cc3200/mods/moduhashlib.h32
-rw-r--r--cc3200/mods/modusocket.c107
-rw-r--r--cc3200/mods/modusocket.h3
-rw-r--r--cc3200/mods/modussl.c149
-rw-r--r--cc3200/mods/modwlan.c61
-rw-r--r--cc3200/mods/modwlan.h2
-rw-r--r--cc3200/mpconfigport.h3
-rw-r--r--cc3200/qstrdefsport.h15
10 files changed, 276 insertions, 110 deletions
diff --git a/cc3200/application.mk b/cc3200/application.mk
index 0ac98bf5f2..cfb90d6ffa 100644
--- a/cc3200/application.mk
+++ b/cc3200/application.mk
@@ -92,6 +92,7 @@ APP_MODS_SRC_C = $(addprefix mods/,\
modpyb.c \
moduos.c \
modusocket.c \
+ modussl.c \
modutime.c \
modwlan.c \
pybadc.c \
diff --git a/cc3200/mods/modnetwork.h b/cc3200/mods/modnetwork.h
index af9bdb6ef6..59034847b9 100644
--- a/cc3200/mods/modnetwork.h
+++ b/cc3200/mods/modnetwork.h
@@ -40,8 +40,7 @@ typedef struct _mod_network_nic_type_t {
mp_obj_type_t base;
} mod_network_nic_type_t;
-typedef struct _mod_network_socket_obj_t {
- mp_obj_base_t base;
+typedef struct _mod_network_socket_base_t {
union {
struct {
uint8_t domain;
@@ -51,8 +50,14 @@ typedef struct _mod_network_socket_obj_t {
} u_param;
int16_t sd;
};
- bool closed;
- bool has_timeout;
+ bool has_timeout;
+ bool cert_req;
+ bool closed;
+} mod_network_socket_base_t;
+
+typedef struct _mod_network_socket_obj_t {
+ mp_obj_base_t base;
+ mod_network_socket_base_t sock_base;
} mod_network_socket_obj_t;
/******************************************************************************
diff --git a/cc3200/mods/moduhashlib.h b/cc3200/mods/moduhashlib.h
deleted file mode 100644
index d89d9f001c..0000000000
--- a/cc3200/mods/moduhashlib.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * This file is part of the Micro Python project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2014 Paul Sokolovsky
- * 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 MODUHASHLIB_H_
-#define MODUHASHLIB_H_
-
-extern const mp_obj_module_t mp_module_uhashlib;
-
-#endif // MODUHASHLIB_H_
diff --git a/cc3200/mods/modusocket.c b/cc3200/mods/modusocket.c
index 57822e0ebc..e4211003cc 100644
--- a/cc3200/mods/modusocket.c
+++ b/cc3200/mods/modusocket.c
@@ -29,9 +29,12 @@
#include <string.h>
#include "simplelink.h"
-#include "py/mpstate.h"
+#include "py/mpconfig.h"
#include MICROPY_HAL_H
+#include "py/obj.h"
+#include "py/objstr.h"
#include "py/runtime.h"
+#include "py/stream.h"
#include "netutils.h"
#include "modnetwork.h"
#include "modwlan.h"
@@ -54,6 +57,7 @@ typedef struct {
/******************************************************************************
DEFINE PRIVATE DATA
******************************************************************************/
+STATIC const mp_obj_type_t socket_type;
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}};
@@ -121,8 +125,6 @@ void modusocket_close_all_user_sockets (void) {
/******************************************************************************/
// 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);
@@ -130,18 +132,22 @@ STATIC mp_obj_t socket_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_
// 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;
+ 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;
+ s->sock_base.closed = false;
+
if (n_args > 0) {
- s->u_param.domain = mp_obj_get_int(args[0]);
+ s->sock_base.u_param.domain = mp_obj_get_int(args[0]);
if (n_args > 1) {
- s->u_param.type = mp_obj_get_int(args[1]);
+ s->sock_base.u_param.type = mp_obj_get_int(args[1]);
if (n_args > 2) {
- s->u_param.proto = mp_obj_get_int(args[2]);
+ s->sock_base.u_param.proto = mp_obj_get_int(args[2]);
if (n_args > 3) {
- s->u_param.fileno = mp_obj_get_int(args[3]);
+ s->sock_base.u_param.fileno = mp_obj_get_int(args[3]);
}
}
}
@@ -153,8 +159,6 @@ STATIC mp_obj_t socket_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
}
- s->has_timeout = false;
- modusocket_socket_add(s->sd, true);
return s;
}
@@ -201,9 +205,10 @@ STATIC mp_obj_t socket_accept(mp_obj_t self_in) {
// create new socket object
mod_network_socket_obj_t *socket2 = m_new_obj_with_finaliser(mod_network_socket_obj_t);
- socket2->base.type = (mp_obj_t)&socket_type;
+ // the new socket inherits all properties from its parent
+ memcpy (socket2, self, sizeof(mod_network_socket_obj_t));
- // accept incoming connection
+ // accept the incoming connection
uint8_t ip[MOD_NETWORK_IPV4ADDR_BUF_SIZE];
mp_uint_t port;
int _errno;
@@ -212,7 +217,7 @@ STATIC mp_obj_t socket_accept(mp_obj_t self_in) {
}
// add the socket to the list
- modusocket_socket_add(socket2->sd, true);
+ modusocket_socket_add(socket2->sock_base.sd, true);
// make the return value
mp_obj_tuple_t *client = mp_obj_new_tuple(2, NULL);
@@ -230,9 +235,12 @@ STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
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 connect the socket
+ // connect the socket
int _errno;
if (wlan_socket_connect(self, ip, port, &_errno) != 0) {
+ if (!self->sock_base.cert_req && _errno == SL_ESECSNOVERIFY) {
+ return mp_const_none;
+ }
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
}
return mp_const_none;
@@ -246,7 +254,7 @@ STATIC mp_obj_t socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
int _errno;
mp_uint_t ret = wlan_socket_send(self, bufinfo.buf, bufinfo.len, &_errno);
- if (ret == -1) {
+ if (ret < 0) {
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
}
return mp_obj_new_int_from_uint(ret);
@@ -261,8 +269,8 @@ STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) {
vstr_init_len(&vstr, len);
int _errno;
mp_uint_t ret = wlan_socket_recv(self, (byte*)vstr.buf, len, &_errno);
- if (ret == -1) {
- if (_errno == EAGAIN && self->has_timeout) {
+ if (ret < 0) {
+ if (_errno == EAGAIN && self->sock_base.has_timeout) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TimeoutError, "timed out"));
}
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
@@ -291,7 +299,7 @@ STATIC mp_obj_t socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_
// call the nic to sendto
int _errno;
mp_int_t ret = wlan_socket_sendto(self, bufinfo.buf, bufinfo.len, ip, port, &_errno);
- if (ret == -1) {
+ if (ret < 0) {
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
}
return mp_obj_new_int(ret);
@@ -307,8 +315,8 @@ STATIC mp_obj_t socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) {
mp_uint_t port;
int _errno;
mp_int_t ret = wlan_socket_recvfrom(self, (byte*)vstr.buf, vstr.len, ip, &port, &_errno);
- if (ret == -1) {
- if (_errno == EAGAIN && self->has_timeout) {
+ if (ret < 0) {
+ if (_errno == EAGAIN && self->sock_base.has_timeout) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TimeoutError, "timed out"));
}
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
@@ -386,29 +394,48 @@ STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t blocking) {
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_setblocking_obj, socket_setblocking);
STATIC const mp_map_elem_t socket_locals_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR___del__), (mp_obj_t)&socket_close_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&socket_close_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_bind), (mp_obj_t)&socket_bind_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_listen), (mp_obj_t)&socket_listen_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_accept), (mp_obj_t)&socket_accept_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_connect), (mp_obj_t)&socket_connect_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&socket_send_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&socket_recv_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_sendto), (mp_obj_t)&socket_sendto_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_recvfrom), (mp_obj_t)&socket_recvfrom_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_setsockopt), (mp_obj_t)&socket_setsockopt_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_settimeout), (mp_obj_t)&socket_settimeout_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_setblocking), (mp_obj_t)&socket_setblocking_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR___del__), (mp_obj_t)&socket_close_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&socket_close_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_bind), (mp_obj_t)&socket_bind_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_listen), (mp_obj_t)&socket_listen_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_accept), (mp_obj_t)&socket_accept_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_connect), (mp_obj_t)&socket_connect_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&socket_send_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&socket_recv_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_sendto), (mp_obj_t)&socket_sendto_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_recvfrom), (mp_obj_t)&socket_recvfrom_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_setsockopt), (mp_obj_t)&socket_setsockopt_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_settimeout), (mp_obj_t)&socket_settimeout_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_setblocking), (mp_obj_t)&socket_setblocking_obj },
+
+ // stream methods
+ { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_readall), (mp_obj_t)&mp_stream_readall_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), (mp_obj_t)&mp_stream_readinto_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_readline), (mp_obj_t)&mp_stream_unbuffered_readline_obj},
+ { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj },
};
-STATIC MP_DEFINE_CONST_DICT(socket_locals_dict, socket_locals_dict_table);
+MP_DEFINE_CONST_DICT(socket_locals_dict, socket_locals_dict_table);
+
+STATIC mp_uint_t socket_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) {
+ mod_network_socket_obj_t *self = self_in;
+ return wlan_socket_recv(self, buf, size, errcode);
+}
+
+STATIC mp_uint_t socket_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode) {
+ mod_network_socket_obj_t *self = self_in;
+ return wlan_socket_send(self, buf, size, errcode);
+}
-mp_uint_t socket_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
+STATIC mp_uint_t socket_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
mod_network_socket_obj_t *self = self_in;
return wlan_socket_ioctl(self, request, arg, errcode);
}
-STATIC const mp_stream_p_t socket_stream_p = {
+const mp_stream_p_t socket_stream_p = {
+ .read = socket_read,
+ .write = socket_write,
.ioctl = socket_ioctl,
.is_text = false,
};
@@ -434,7 +461,7 @@ STATIC mp_obj_t mod_usocket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) {
// ipv4 only
uint8_t out_ip[MOD_NETWORK_IPV4ADDR_BUF_SIZE];
int32_t result = wlan_gethostbyname(host, hlen, out_ip, AF_INET);
- if (result != 0) {
+ 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);
diff --git a/cc3200/mods/modusocket.h b/cc3200/mods/modusocket.h
index c2c055325e..851f8e5be7 100644
--- a/cc3200/mods/modusocket.h
+++ b/cc3200/mods/modusocket.h
@@ -27,6 +27,9 @@
#ifndef MODUSOCKET_H_
#define MODUSOCKET_H_
+extern const mp_obj_dict_t socket_locals_dict;
+extern const mp_stream_p_t socket_stream_p;
+
extern void modusocket_pre_init (void);
extern void modusocket_socket_add (int16_t sd, bool user);
extern void modusocket_socket_delete (int16_t sd);
diff --git a/cc3200/mods/modussl.c b/cc3200/mods/modussl.c
new file mode 100644
index 0000000000..be7219284f
--- /dev/null
+++ b/cc3200/mods/modussl.c
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+
+#include <stdint.h>
+#include <std.h>
+
+#include "simplelink.h"
+#include "py/mpconfig.h"
+#include MICROPY_HAL_H
+#include "py/obj.h"
+#include "py/objstr.h"
+#include "py/runtime.h"
+#include "modnetwork.h"
+#include "modusocket.h"
+#include "mpexception.h"
+
+/******************************************************************************
+ DEFINE CONSTANTS
+ ******************************************************************************/
+#define SSL_CERT_NONE (0)
+#define SSL_CERT_OPTIONAL (1)
+#define SSL_CERT_REQUIRED (2)
+
+/******************************************************************************
+ DEFINE TYPES
+ ******************************************************************************/
+typedef struct _mp_obj_ssl_socket_t {
+ mp_obj_base_t base;
+ mod_network_socket_base_t sock_base;
+ mp_obj_t o_sock;
+} mp_obj_ssl_socket_t;
+
+/******************************************************************************
+ DECLARE PRIVATE DATA
+ ******************************************************************************/
+STATIC const mp_obj_type_t ssl_socket_type;
+
+/******************************************************************************/
+// Micro Python bindings; SSL class
+
+// ssl socket inherits from normal socket, so we take its
+// locals and stream methods
+STATIC const mp_obj_type_t ssl_socket_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_ussl,
+ .getiter = NULL,
+ .iternext = NULL,
+ .stream_p = &socket_stream_p,
+ .locals_dict = (mp_obj_t)&socket_locals_dict,
+};
+
+STATIC mp_obj_t mod_ssl_wrap_socket(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ STATIC const mp_arg_t allowed_args[] = {
+ { MP_QSTR_sock, MP_ARG_REQUIRED | MP_ARG_OBJ, },
+ { MP_QSTR_keyfile, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ { MP_QSTR_certfile, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ { MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_false} },
+ { MP_QSTR_cert_reqs, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SSL_CERT_NONE} },
+ { MP_QSTR_ca_certs, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ };
+
+ // parse arguments
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ // chech if ca validation is required
+ if (args[4].u_int != SSL_CERT_NONE && args[5].u_obj == mp_const_none) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ }
+
+ // server side param is irrelevant for us (at least for the moment)
+
+ // retrieve the file paths (with an 6 byte offset because to strip the '/flash' prefix)
+ const char *keyfile = (args[1].u_obj == mp_const_none) ? NULL : &(mp_obj_str_get_str(args[1].u_obj)[6]);
+ const char *certfile = (args[2].u_obj == mp_const_none) ? NULL : &(mp_obj_str_get_str(args[2].u_obj)[6]);
+ const char *cafile = (args[5].u_obj == mp_const_none || args[4].u_int != SSL_CERT_REQUIRED) ?
+ NULL : &(mp_obj_str_get_str(args[5].u_obj)[6]);
+
+ _i16 sd = ((mod_network_socket_obj_t *)args[0].u_obj)->sock_base.sd;
+ _i16 _errno;
+ if (keyfile && (_errno = sl_SetSockOpt(sd, SL_SOL_SOCKET, SL_SO_SECURE_FILES_PRIVATE_KEY_FILE_NAME, keyfile, strlen(keyfile))) < 0) {
+ goto socket_error;
+ }
+ if (certfile && (_errno = sl_SetSockOpt(sd, SL_SOL_SOCKET, SL_SO_SECURE_FILES_CERTIFICATE_FILE_NAME, certfile, strlen(certfile))) < 0) {
+ goto socket_error;
+ }
+ if (cafile && (_errno = sl_SetSockOpt(sd, SL_SOL_SOCKET, SL_SO_SECURE_FILES_CA_FILE_NAME, cafile, strlen(cafile))) < 0) {
+ goto socket_error;
+ }
+
+ // create the ssl socket
+ mp_obj_ssl_socket_t *ssl_sock = m_new_obj(mp_obj_ssl_socket_t);
+ // ssl socket inherits all properties from the original socket
+ memcpy (&ssl_sock->sock_base, &((mod_network_socket_obj_t *)args[0].u_obj)->sock_base, sizeof(mod_network_socket_base_t));
+ ssl_sock->base.type = &ssl_socket_type;
+ ssl_sock->sock_base.cert_req = (args[4].u_int == SSL_CERT_REQUIRED) ? true : false;
+ ssl_sock->o_sock = args[0].u_obj;
+
+ return ssl_sock;
+
+socket_error:
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_ssl_wrap_socket_obj, 1, mod_ssl_wrap_socket);
+
+STATIC const mp_map_elem_t mp_module_ussl_globals_table[] = {
+ { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_ussl) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_wrap_socket), (mp_obj_t)&mod_ssl_wrap_socket_obj },
+
+ // class exceptions
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SSLError), (mp_obj_t)&mp_type_OSError },
+
+ // class constants
+ { MP_OBJ_NEW_QSTR(MP_QSTR_CERT_NONE), MP_OBJ_NEW_SMALL_INT(SSL_CERT_NONE) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_CERT_OPTIONAL), MP_OBJ_NEW_SMALL_INT(SSL_CERT_OPTIONAL) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_CERT_REQUIRED), MP_OBJ_NEW_SMALL_INT(SSL_CERT_REQUIRED) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(mp_module_ussl_globals, mp_module_ussl_globals_table);
+
+const mp_obj_module_t mp_module_ussl = {
+ .base = { &mp_type_module },
+ .name = MP_QSTR_ussl,
+ .globals = (mp_obj_dict_t*)&mp_module_ussl_globals,
+};
+
diff --git a/cc3200/mods/modwlan.c b/cc3200/mods/modwlan.c
index 0f89266bee..4861660dd2 100644
--- a/cc3200/mods/modwlan.c
+++ b/cc3200/mods/modwlan.c
@@ -1134,32 +1134,30 @@ int wlan_gethostbyname(const char *name, mp_uint_t len, uint8_t *out_ip, uint8_t
int wlan_socket_socket(mod_network_socket_obj_t *s, int *_errno) {
// open the socket
- int16_t sd = sl_Socket(s->u_param.domain, s->u_param.type, s->u_param.proto);
+ int16_t sd = sl_Socket(s->sock_base.u_param.domain, s->sock_base.u_param.type, s->sock_base.u_param.proto);
// save the socket descriptor
- s->sd = sd;
+ s->sock_base.sd = sd;
if (sd < 0) {
*_errno = sd;
return -1;
}
- // mark the socket not closed
- s->closed = false;
-
return 0;
}
void wlan_socket_close(mod_network_socket_obj_t *s) {
// this is to prevent the finalizer to close a socket that failed when being created
- if (s->sd >= 0) {
- modusocket_socket_delete(s->sd);
- sl_Close(s->sd);
+ if (s->sock_base.sd >= 0) {
+ modusocket_socket_delete(s->sock_base.sd);
+ // TODO check return value and raise an exception if applicable
+ sl_Close(s->sock_base.sd);
}
- s->closed = true;
+ s->sock_base.closed = true;
}
int wlan_socket_bind(mod_network_socket_obj_t *s, byte *ip, mp_uint_t port, int *_errno) {
MAKE_SOCKADDR(addr, ip, port)
- int ret = sl_Bind(s->sd, &addr, sizeof(addr));
+ int ret = sl_Bind(s->sock_base.sd, &addr, sizeof(addr));
if (ret != 0) {
*_errno = ret;
return -1;
@@ -1168,7 +1166,7 @@ int wlan_socket_bind(mod_network_socket_obj_t *s, byte *ip, mp_uint_t port, int
}
int wlan_socket_listen(mod_network_socket_obj_t *s, mp_int_t backlog, int *_errno) {
- int ret = sl_Listen(s->sd, backlog);
+ int ret = sl_Listen(s->sock_base.sd, backlog);
if (ret != 0) {
*_errno = ret;
return -1;
@@ -1182,17 +1180,14 @@ int wlan_socket_accept(mod_network_socket_obj_t *s, mod_network_socket_obj_t *s2
sockaddr addr;
socklen_t addr_len = sizeof(addr);
- sd = sl_Accept(s->sd, &addr, &addr_len);
+ sd = sl_Accept(s->sock_base.sd, &addr, &addr_len);
// save the socket descriptor
- s2->sd = sd;
+ s2->sock_base.sd = sd;
if (sd < 0) {
*_errno = sd;
return -1;
}
- // mark the socket not closed
- s2->closed = false;
-
// return ip and port
UNPACK_SOCKADDR(addr, ip, *port);
@@ -1201,7 +1196,7 @@ int wlan_socket_accept(mod_network_socket_obj_t *s, mod_network_socket_obj_t *s2
int wlan_socket_connect(mod_network_socket_obj_t *s, byte *ip, mp_uint_t port, int *_errno) {
MAKE_SOCKADDR(addr, ip, port)
- int ret = sl_Connect(s->sd, &addr, sizeof(addr));
+ int ret = sl_Connect(s->sock_base.sd, &addr, sizeof(addr));
if (ret != 0) {
*_errno = ret;
return -1;
@@ -1212,7 +1207,7 @@ int wlan_socket_connect(mod_network_socket_obj_t *s, byte *ip, mp_uint_t port, i
int wlan_socket_send(mod_network_socket_obj_t *s, const byte *buf, mp_uint_t len, int *_errno) {
mp_int_t bytes = 0;
if (len > 0) {
- bytes = sl_Send(s->sd, (const void *)buf, len, 0);
+ bytes = sl_Send(s->sock_base.sd, (const void *)buf, len, 0);
}
if (bytes <= 0) {
*_errno = bytes;
@@ -1224,16 +1219,16 @@ int wlan_socket_send(mod_network_socket_obj_t *s, const byte *buf, mp_uint_t len
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) {
+ if (s->sock_base.closed) {
// 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);
+ FD_SET(s->sock_base.sd, &rfds);
timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 2;
- int nfds = sl_Select(s->sd + 1, &rfds, NULL, NULL, &tv);
- if (nfds == -1 || !FD_ISSET(s->sd, &rfds)) {
+ int nfds = sl_Select(s->sock_base.sd + 1, &rfds, NULL, NULL, &tv);
+ if (nfds == -1 || !FD_ISSET(s->sock_base.sd, &rfds)) {
// no data waiting, so close the socket and return 0 data
wlan_socket_close(s);
return 0;
@@ -1244,7 +1239,7 @@ int wlan_socket_recv(mod_network_socket_obj_t *s, byte *buf, mp_uint_t len, int
len = MIN(len, WLAN_MAX_RX_SIZE);
// do the recv
- int ret = sl_Recv(s->sd, buf, len, 0);
+ int ret = sl_Recv(s->sock_base.sd, buf, len, 0);
if (ret < 0) {
*_errno = ret;
return -1;
@@ -1255,7 +1250,7 @@ int wlan_socket_recv(mod_network_socket_obj_t *s, byte *buf, mp_uint_t len, int
int wlan_socket_sendto( mod_network_socket_obj_t *s, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno) {
MAKE_SOCKADDR(addr, ip, port)
- int ret = sl_SendTo(s->sd, (byte*)buf, len, 0, (sockaddr*)&addr, sizeof(addr));
+ int ret = sl_SendTo(s->sock_base.sd, (byte*)buf, len, 0, (sockaddr*)&addr, sizeof(addr));
if (ret < 0) {
*_errno = ret;
return -1;
@@ -1266,7 +1261,7 @@ int wlan_socket_sendto( mod_network_socket_obj_t *s, const byte *buf, mp_uint_t
int wlan_socket_recvfrom(mod_network_socket_obj_t *s, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) {
sockaddr addr;
socklen_t addr_len = sizeof(addr);
- mp_int_t ret = sl_RecvFrom(s->sd, buf, len, 0, &addr, &addr_len);
+ mp_int_t ret = sl_RecvFrom(s->sock_base.sd, buf, len, 0, &addr, &addr_len);
if (ret < 0) {
*_errno = ret;
return -1;
@@ -1275,8 +1270,8 @@ int wlan_socket_recvfrom(mod_network_socket_obj_t *s, byte *buf, mp_uint_t len,
return ret;
}
-int wlan_socket_setsockopt(mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno) {
- int ret = sl_SetSockOpt(socket->sd, level, opt, optval, optlen);
+int wlan_socket_setsockopt(mod_network_socket_obj_t *s, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno) {
+ int ret = sl_SetSockOpt(s->sock_base.sd, level, opt, optval, optlen);
if (ret < 0) {
*_errno = ret;
return -1;
@@ -1296,14 +1291,14 @@ int wlan_socket_settimeout(mod_network_socket_obj_t *s, mp_uint_t timeout_s, int
// set blocking mode
option.NonblockingEnabled = 0;
}
- ret = sl_SetSockOpt(s->sd, SOL_SOCKET, SO_NONBLOCKING, &option, sizeof(option));
+ ret = sl_SetSockOpt(s->sock_base.sd, SOL_SOCKET, SO_NONBLOCKING, &option, sizeof(option));
has_timeout = false;
} else {
// set timeout
struct SlTimeval_t timeVal;
timeVal.tv_sec = timeout_s; // seconds
timeVal.tv_usec = 0; // microseconds. 10000 microseconds resolution
- ret = sl_SetSockOpt(s->sd, SOL_SOCKET, SO_RCVTIMEO, &timeVal, sizeof(timeVal));
+ ret = sl_SetSockOpt(s->sock_base.sd, SOL_SOCKET, SO_RCVTIMEO, &timeVal, sizeof(timeVal));
has_timeout = true;
}
@@ -1312,7 +1307,7 @@ int wlan_socket_settimeout(mod_network_socket_obj_t *s, mp_uint_t timeout_s, int
return -1;
}
- s->has_timeout = has_timeout;
+ s->sock_base.has_timeout = has_timeout;
return 0;
}
@@ -1321,7 +1316,7 @@ int wlan_socket_ioctl (mod_network_socket_obj_t *s, mp_uint_t request, mp_uint_t
if (request == MP_IOCTL_POLL) {
mp_uint_t flags = arg;
ret = 0;
- int32_t sd = s->sd;
+ int32_t sd = s->sock_base.sd;
// init fds
fd_set rfds, wfds, xfds;
@@ -1335,7 +1330,7 @@ int wlan_socket_ioctl (mod_network_socket_obj_t *s, mp_uint_t request, mp_uint_t
// A socked that just closed is available for reading. A call to
// recv() returns 0 which is consistent with BSD.
- if (s->closed) {
+ if (s->sock_base.closed) {
ret |= MP_IOCTL_POLL_RD;
}
}
@@ -1346,7 +1341,7 @@ int wlan_socket_ioctl (mod_network_socket_obj_t *s, mp_uint_t request, mp_uint_t
FD_SET(sd, &xfds);
}
- // call simplelink select with minimum timeout
+ // call simplelink's select with minimum timeout
SlTimeval_t tv;
tv.tv_sec = 0;
tv.tv_usec = 1;
diff --git a/cc3200/mods/modwlan.h b/cc3200/mods/modwlan.h
index a811afdd78..c17a6e0b38 100644
--- a/cc3200/mods/modwlan.h
+++ b/cc3200/mods/modwlan.h
@@ -75,7 +75,7 @@ extern int wlan_socket_send(mod_network_socket_obj_t *s, const byte *buf, mp_uin
extern int wlan_socket_recv(mod_network_socket_obj_t *s, byte *buf, mp_uint_t len, int *_errno);
extern int wlan_socket_sendto( mod_network_socket_obj_t *s, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno);
extern int wlan_socket_recvfrom(mod_network_socket_obj_t *s, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno);
-extern int wlan_socket_setsockopt(mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno);
+extern int wlan_socket_setsockopt(mod_network_socket_obj_t *s, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno);
extern int wlan_socket_settimeout(mod_network_socket_obj_t *s, mp_uint_t timeout_s, int *_errno);
extern int wlan_socket_ioctl (mod_network_socket_obj_t *s, mp_uint_t request, mp_uint_t arg, int *_errno);
diff --git a/cc3200/mpconfigport.h b/cc3200/mpconfigport.h
index cb26683960..7f51261c46 100644
--- a/cc3200/mpconfigport.h
+++ b/cc3200/mpconfigport.h
@@ -108,6 +108,7 @@ extern const struct _mp_obj_module_t mp_module_usocket;
extern const struct _mp_obj_module_t mp_module_network;
extern const struct _mp_obj_module_t mp_module_uhashlib;
extern const struct _mp_obj_module_t mp_module_ubinascii;
+extern const struct _mp_obj_module_t mp_module_ussl;
#define MICROPY_PORT_BUILTIN_MODULES \
{ MP_OBJ_NEW_QSTR(MP_QSTR_pyb), (mp_obj_t)&pyb_module }, \
@@ -118,6 +119,7 @@ extern const struct _mp_obj_module_t mp_module_ubinascii;
{ MP_OBJ_NEW_QSTR(MP_QSTR_network), (mp_obj_t)&mp_module_network }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_uhashlib), (mp_obj_t)&mp_module_uhashlib }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_ubinascii), (mp_obj_t)&mp_module_ubinascii }, \
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ussl), (mp_obj_t)&mp_module_ussl }, \
#define MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS \
{ MP_OBJ_NEW_QSTR(MP_QSTR_re), (mp_obj_t)&mp_module_ure }, \
@@ -129,6 +131,7 @@ extern const struct _mp_obj_module_t mp_module_ubinascii;
{ MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&mp_module_usocket }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_hashlib), (mp_obj_t)&mp_module_uhashlib }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_binascii), (mp_obj_t)&mp_module_ubinascii }, \
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ssl), (mp_obj_t)&mp_module_ussl }, \
// extra constants
#define MICROPY_PORT_CONSTANTS \
diff --git a/cc3200/qstrdefsport.h b/cc3200/qstrdefsport.h
index 13a85a4fc7..3d37a0f4fc 100644
--- a/cc3200/qstrdefsport.h
+++ b/cc3200/qstrdefsport.h
@@ -237,6 +237,21 @@ Q(IPPROTO_TCP)
Q(IPPROTO_UDP)
Q(IPPROTO_RAW)
+// for ssl class
+Q(ssl)
+Q(ussl)
+Q(wrap_socket)
+Q(sock)
+Q(keyfile)
+Q(certfile)
+Q(server_side)
+Q(cert_reqs)
+Q(ca_certs)
+Q(SSLError)
+Q(CERT_NONE)
+Q(CERT_OPTIONAL)
+Q(CERT_REQUIRED)
+
// for network class
Q(network)
Q(server_running)