Add initial WINC1500 WiFi module driver.

* Note: partial implemented, based on CC3000 module (only scan, connect, ifconfig work)
This commit is contained in:
iabdalkader 2016-03-26 01:45:44 +02:00
parent f447455580
commit b92f146323
5 changed files with 711 additions and 1 deletions

View File

@ -164,6 +164,7 @@ OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/py/, \
py_fir.o \
py_gif.o \
py_mjpeg.o \
py_winc.o \
)
ifeq ($(TARGET), OPENMV1)

@ -1 +1 @@
Subproject commit 4129781aa0b1f42b8dfe50ccef4719ee683dfec5
Subproject commit 9cffbae8329690157cd329f1e7bde7798a65c345

View File

@ -67,6 +67,7 @@ SRCS += $(addprefix py/, \
py_fir.c \
py_gif.c \
py_mjpeg.c \
py_winc.c \
)
OBJS = $(addprefix $(BUILD)/, $(SRCS:.c=.o))

View File

@ -35,6 +35,7 @@
#include "sdcard.h"
#include "ff.h"
#include "mdefs.h"
#include "modnetwork.h"
#include "rng.h"
#include "led.h"
@ -334,6 +335,7 @@ soft_reset:
servo_init();
usbdbg_init();
mod_network_init();
// Remove the BASEPRI masking (if any)
irq_set_base_priority(0);

706
src/omv/py/py_winc.c Normal file
View File

@ -0,0 +1,706 @@
/*
* This file is part of the OpenMV project.
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
* This work is licensed under the MIT license, see the file LICENSE for details.
*
* WINC1500 Python module.
*
*/
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include "py/nlr.h"
#include "py/objtuple.h"
#include "py/objlist.h"
#include "py/stream.h"
#include "py/runtime.h"
#include "modnetwork.h"
#include "pin.h"
#include "genhdr/pins.h"
#include "spi.h"
#include "pybioctl.h"
// WINC's includes
#include "driver/include/m2m_wifi.h"
#include "driver/include/nmasic.h"
#include "socket/include/socket.h"
#define MAKE_SOCKADDR(addr, ip, port) \
struct sockaddr addr; \
addr.sa_family = AF_INET; \
addr.sa_data[0] = port >> 8; \
addr.sa_data[1] = port; \
addr.sa_data[2] = ip[0]; \
addr.sa_data[3] = ip[1]; \
addr.sa_data[4] = ip[2]; \
addr.sa_data[5] = ip[3];
#define UNPACK_SOCKADDR(addr, ip, port) \
port = (addr.sa_data[0] << 8) | addr.sa_data[1]; \
ip[0] = addr.sa_data[2]; \
ip[1] = addr.sa_data[3]; \
ip[2] = addr.sa_data[4]; \
ip[3] = addr.sa_data[5];
static volatile bool ip_obtained = false;
static volatile bool wlan_connected = false;
static void *async_request_data;
static volatile bool async_request_done = false;
/**
* Callback to get the Wi-Fi status update.
*
* msg_type: type of Wi-Fi notification. Possible types are:
* M2M_WIFI_RESP_CON_STATE_CHANGED
* M2M_WIFI_RESP_CONN_INFO
* M2M_WIFI_REQ_DHCP_CONF
* M2M_WIFI_REQ_WPS
* M2M_WIFI_RESP_IP_CONFLICT
* M2M_WIFI_RESP_SCAN_DONE
* M2M_WIFI_RESP_SCAN_RESULT
* M2M_WIFI_RESP_CURRENT_RSSI
* M2M_WIFI_RESP_CLIENT_INFO
* M2M_WIFI_RESP_PROVISION_INFO
* M2M_WIFI_RESP_DEFAULT_CONNECT
*
* In case Bypass mode is defined :
* M2M_WIFI_RESP_ETHERNET_RX_PACKET
*
* In case Monitoring mode is used:
* M2M_WIFI_RESP_WIFI_RX_PACKET
*
* msg: A pointer to a buffer containing the notification parameters (if any).
* It should be casted to the correct data type corresponding to the notification type.
*/
static void wifi_callback(uint8_t msg_type, void *msg)
{
// Index of scan list to request scan result.
static uint8_t scan_request_index = 0;
switch (msg_type) {
case M2M_WIFI_RESP_CURRENT_RSSI: {
int rssi = *((int8_t *)msg);
*((int*)async_request_data) = rssi;
async_request_done = true;
break;
}
case M2M_WIFI_RESP_CON_STATE_CHANGED: {
tstrM2mWifiStateChanged *pstrWifiState = (tstrM2mWifiStateChanged *)msg;
if (pstrWifiState->u8CurrState == M2M_WIFI_CONNECTED) {
wlan_connected = true;
m2m_wifi_request_dhcp_client();
} else if (pstrWifiState->u8CurrState == M2M_WIFI_DISCONNECTED) {
ip_obtained = false;
wlan_connected = false;
async_request_done = true;
}
break;
}
case M2M_WIFI_REQ_DHCP_CONF: {
ip_obtained = true;
async_request_done = true;
break;
}
case M2M_WIFI_RESP_CONN_INFO: {
// Connection info
tstrM2MConnInfo *con_info = (tstrM2MConnInfo*) msg;
// Get MAC Address.
uint8_t mac_addr[M2M_MAC_ADDRES_LEN];
m2m_wifi_get_mac_address(mac_addr);
// Format MAC address
VSTR_FIXED(mac_vstr, 18);
vstr_printf(&mac_vstr, "%02x:%02x:%02x:%02x:%02x:%02x", mac_addr[0],
mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
// Format IP address
VSTR_FIXED(ip_vstr, 16);
vstr_printf(&ip_vstr, "%d.%d.%d.%d", con_info->au8IPAddr[0],
con_info->au8IPAddr[1], con_info->au8IPAddr[2], con_info->au8IPAddr[3]);
// Add connection info
mp_obj_t info_list = (mp_obj_t) async_request_data;
mp_obj_list_append(info_list, mp_obj_new_int(con_info->s8RSSI));
mp_obj_list_append(info_list, mp_obj_new_int(con_info->u8SecType));
mp_obj_list_append(info_list, mp_obj_new_str(con_info->acSSID, strlen(con_info->acSSID), false));
mp_obj_list_append(info_list, mp_obj_new_str(mac_vstr.buf, mac_vstr.len, false));
mp_obj_list_append(info_list, mp_obj_new_str(ip_vstr.buf, ip_vstr.len, false));
async_request_done = true;
break;
}
case M2M_WIFI_RESP_SCAN_DONE: {
scan_request_index = 0;
tstrM2mScanDone *scan_info = (tstrM2mScanDone*) msg;
// The number of APs found in the last scan request.
if (scan_info->u8NumofCh <= 0) {
// Nothing found.
async_request_done = true;
} else {
// Found APs, request scan results.
m2m_wifi_req_scan_result(scan_request_index++);
}
break;
}
case M2M_WIFI_RESP_SCAN_RESULT: {
tstrM2mWifiscanResult *scan_result;
scan_result = (tstrM2mWifiscanResult*) msg;
// Format MAC address
VSTR_FIXED(mac_vstr, 18);
vstr_printf(&mac_vstr, "%02X:%02X:%02X:%02X:%02X:%02X",
scan_result->au8BSSID[0], scan_result->au8BSSID[1], scan_result->au8BSSID[2],
scan_result->au8BSSID[3], scan_result->au8BSSID[4], scan_result->au8BSSID[5]);
mp_obj_t ap[5] = {
mp_obj_new_int(scan_result->u8ch),
mp_obj_new_int(scan_result->s8rssi),
mp_obj_new_int(scan_result->u8AuthType),
mp_obj_new_str(mac_vstr.buf, mac_vstr.len, false),
mp_obj_new_str((const char*) scan_result->au8SSID, strlen((const char*) scan_result->au8SSID), false),
};
mp_obj_t scan_list = (mp_obj_t) async_request_data;
mp_obj_list_append(scan_list, mp_obj_new_tuple(MP_ARRAY_SIZE(ap), ap));
int num_found_ap = m2m_wifi_get_num_ap_found();
if (num_found_ap == scan_request_index) {
async_request_done = true;
} else {
// Request next scan result
m2m_wifi_req_scan_result(scan_request_index++);
}
break;
}
default:
break;
}
}
static int winc_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip)
{
// uint32_t ip;
//
// WINC1500_EXPORT(gethostbyname)((char*)name, len, &ip);
//
// 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 winc_socket_socket(mod_network_socket_obj_t *socket, int *_errno)
{
if (socket->u_param.domain != MOD_NETWORK_AF_INET) {
*_errno = 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;
default:
*_errno = EINVAL;
return -1;
}
// open socket
int fd = WINC1500_EXPORT(socket)(AF_INET, type, 0);
if (fd < 0) {
*_errno = fd;
return -1;
}
// store state of this socket
socket->u_state = fd;
//// make accept blocking by default
//int optval = SOCK_OFF;
//socklen_t optlen = sizeof(optval);
//WINC1500_EXPORT(setsockopt)(socket->u_state, SOL_SOCKET, SOCKOPT_ACCEPT_NONBLOCK, &optval, optlen);
return 0;
}
static void winc_socket_close(mod_network_socket_obj_t *socket)
{
WINC1500_EXPORT(close)(socket->u_state);
}
static int winc_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno)
{
MAKE_SOCKADDR(addr, ip, port)
int ret = WINC1500_EXPORT(bind)(socket->u_state, &addr, sizeof(addr));
if (ret != 0) {
*_errno = ret;
return -1;
}
return 0;
}
static int winc_socket_listen(mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno) {
int ret = WINC1500_EXPORT(listen)(socket->u_state, backlog);
if (ret != 0) {
*_errno = ret;
return -1;
}
return 0;
}
static int winc_socket_accept(mod_network_socket_obj_t *socket, mod_network_socket_obj_t *socket2, byte *ip, mp_uint_t *port, int *_errno)
{
// TODO
// accept incoming connection
int ret = WINC1500_EXPORT(accept)(socket->u_state, NULL, 0);
if (ret != 0) {
*_errno = ret;
return -1;
}
// store state in new socket object
socket2->u_state = ret;
return 0;
}
static int winc_socket_connect(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno)
{
MAKE_SOCKADDR(addr, ip, port)
int ret = WINC1500_EXPORT(connect)(socket->u_state, &addr, sizeof(addr));
if (ret != 0) {
*_errno = ret;
return -1;
}
return 0;
}
static mp_uint_t winc_socket_send(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno)
{
// Split the packet into smaller ones and send them out.
mp_int_t bytes = 0;
while (bytes < len) {
int n = MIN((len - bytes), SOCKET_BUFFER_MAX_LENGTH);
n = WINC1500_EXPORT(send)(socket->u_state, (uint8_t*)buf + bytes, n, 0);
if (n <= 0) {
*_errno = n;
return -1;
}
bytes += n;
}
return bytes;
}
static mp_uint_t winc_socket_recv(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno)
{
// check the socket is open
//if (winc_get_fd_closed_state(socket->u_state)) {
// // socket is closed, but CC3000 may have some data remaining in buffer, so check
// fd_set rfds;
// FD_ZERO(&rfds);
// FD_SET(socket->u_state, &rfds);
// timeval tv;
// tv.tv_sec = 0;
// tv.tv_usec = 1;
// int nfds = WINC1500_EXPORT(select)(socket->u_state + 1, &rfds, NULL, NULL, &tv);
// if (nfds == -1 || !FD_ISSET(socket->u_state, &rfds)) {
// // no data waiting, so close socket and return 0 data
// WINC1500_EXPORT(closesocket)(socket->u_state);
// return 0;
// }
//}
// TODO
// cap length at SOCKET_BUFFER_MAX_LENGTH
len = MIN(len, SOCKET_BUFFER_MAX_LENGTH);
// do the recv
int ret = WINC1500_EXPORT(recv)(socket->u_state, buf, len, 0);
if (ret < 0) {
*_errno = ret;
return -1;
}
return ret;
}
static mp_uint_t winc_socket_sendto(mod_network_socket_obj_t *socket,
const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno)
{
MAKE_SOCKADDR(addr, ip, port)
int ret = WINC1500_EXPORT(sendto)(socket->u_state, (byte*)buf, len, 0, (struct sockaddr*)&addr, sizeof(addr));
if (ret < 0) {
*_errno = ret;
return -1;
}
return ret;
}
static mp_uint_t winc_socket_recvfrom(mod_network_socket_obj_t *socket,
byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno)
{
//TODO
// struct sockaddr addr;
// socklen_t addr_len = sizeof(addr);
// mp_int_t ret = WINC1500_EXPORT(recvfrom)(socket->u_state, buf, len, 0, &addr, &addr_len);
// if (ret < 0) {
// *_errno = ret;
// return -1;
// }
// UNPACK_SOCKADDR(addr, ip, *port);
// return ret;
return 0;
}
static int winc_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 = WINC1500_EXPORT(setsockopt)(socket->u_state, level, opt, optval, optlen);
if (ret < 0) {
*_errno = ret;
return -1;
}
return 0;
}
//static int winc_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno)
//{
// int ret;
// if (timeout_ms == 0 || timeout_ms == -1) {
// int optval;
// socklen_t optlen = sizeof(optval);
// if (timeout_ms == 0) {
// // set non-blocking mode
// optval = SOCK_ON;
// } else {
// // set blocking mode
// optval = SOCK_OFF;
// }
// ret = WINC1500_EXPORT(setsockopt)(socket->u_state, SOL_SOCKET, SOCKOPT_RECV_NONBLOCK, &optval, optlen);
// if (ret == 0) {
// ret = WINC1500_EXPORT(setsockopt)(socket->u_state, SOL_SOCKET, SOCKOPT_ACCEPT_NONBLOCK, &optval, optlen);
// }
// } else {
// // set timeout
// socklen_t optlen = sizeof(timeout_ms);
// ret = WINC1500_EXPORT(setsockopt)(socket->u_state, SOL_SOCKET, SOCKOPT_RECV_TIMEOUT, &timeout_ms, optlen);
// }
//
// if (ret != 0) {
// *_errno = ret;
// return -1;
// }
//
// return 0;
//}
//static int winc_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno)
//{
// mp_uint_t ret;
// if (request == MP_IOCTL_POLL) {
// mp_uint_t flags = arg;
// ret = 0;
// int fd = socket->u_state;
//
// // init fds
// fd_set rfds, wfds, xfds;
// FD_ZERO(&rfds);
// FD_ZERO(&wfds);
// FD_ZERO(&xfds);
//
// // set fds if needed
// if (flags & MP_IOCTL_POLL_RD) {
// FD_SET(fd, &rfds);
//
// // A socked that just closed is available for reading. A call to
// // recv() returns 0 which is consistent with BSD.
// if (winc_get_fd_closed_state(fd)) {
// ret |= MP_IOCTL_POLL_RD;
// }
// }
// if (flags & MP_IOCTL_POLL_WR) {
// FD_SET(fd, &wfds);
// }
// if (flags & MP_IOCTL_POLL_HUP) {
// FD_SET(fd, &xfds);
// }
//
// // call cc3000 select with minimum timeout
// timeval tv;
// tv.tv_sec = 0;
// tv.tv_usec = 1;
// int nfds = WINC1500_EXPORT(select)(fd + 1, &rfds, &wfds, &xfds, &tv);
//
// // check for error
// if (nfds == -1) {
// *_errno = ret;
// return -1;
// }
//
// // check return of select
// if (FD_ISSET(fd, &rfds)) {
// ret |= MP_IOCTL_POLL_RD;
// }
// if (FD_ISSET(fd, &wfds)) {
// ret |= MP_IOCTL_POLL_WR;
// }
// if (FD_ISSET(fd, &xfds)) {
// ret |= MP_IOCTL_POLL_HUP;
// }
// } else {
// *_errno = EINVAL;
// ret = -1;
// }
// return ret;
//}
/******************************************************************************/
// Micro Python bindings; WINC class
typedef struct _winc_obj_t {
mp_obj_base_t base;
} winc_obj_t;
static const winc_obj_t winc_obj = {{(mp_obj_type_t*)&mod_network_nic_type_winc}};
// Initialise the module using the given SPI bus and pins and return a winc object.
// // TODO pass SPI pins
// init(pyb.SPI(2), pyb.Pin.cpu.A15, pyb.Pin.cpu.B10, pyb.Pin.cpu.B11)
static mp_obj_t winc_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args)
{
//// check arguments
//mp_arg_check_num(n_args, n_kw, 4, 4, false);
//// set the pins to use
//SpiInit(
// spi_get_handle(args[0]),
// pin_find(args[1]),
// pin_find(args[2]),
// pin_find(args[3])
//);
// Initialize the BSP.
nm_bsp_init();
// Initialize Wi-Fi parameters structure.
tstrWifiInitParam param;
memset((uint8_t *)&param, 0, sizeof(tstrWifiInitParam));
param.pfAppWifiCb = wifi_callback;
// Initialize Wi-Fi driver with data and status callbacks.
int ret = m2m_wifi_init(&param);
if (M2M_SUCCESS != ret) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "failed to init WINC1500 module"));
}
uint8_t mac_addr_valid;
uint8_t mac_addr[M2M_MAC_ADDRES_LEN];
// Get MAC Address from OTP.
m2m_wifi_get_otp_mac_address(mac_addr, &mac_addr_valid);
if (!mac_addr_valid) {
// User define MAC Address.
const char main_user_define_mac_address[] = {0xf8, 0xf0, 0x05, 0x20, 0x0b, 0x09};
// Cannot found MAC Address from OTP. Set user define MAC address.
m2m_wifi_set_mac_address((uint8_t *) main_user_define_mac_address);
}
// Initialize socket layer.
socketInit();
// register with network module
mod_network_register_nic((mp_obj_t)&winc_obj);
return (mp_obj_t)&winc_obj;
}
// method connect(ssid, key=None, *, security=WPA2, bssid=None)
static mp_obj_t winc_connect(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_ssid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_key, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_security, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = M2M_WIFI_SEC_WPA_PSK} },
};
// parse args
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
// get ssid
mp_uint_t ssid_len;
const char *ssid = mp_obj_str_get_data(args[0].u_obj, &ssid_len);
// get key and sec
mp_uint_t key_len = 0;
const char *key = NULL;
mp_uint_t sec = M2M_WIFI_SEC_OPEN;
if (args[1].u_obj != mp_const_none) {
key = mp_obj_str_get_data(args[1].u_obj, &key_len);
sec = args[2].u_int;
}
// connect to AP
if (m2m_wifi_connect((char*)ssid, ssid_len, sec, (void*)key, M2M_WIFI_CH_ALL) != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "could not connect to ssid=%s, sec=%d, key=%s\n", ssid, sec, key));
}
async_request_done = false;
while (async_request_done == false) {
// Handle pending events from network controller.
m2m_wifi_handle_events(NULL);
}
return mp_const_none;
}
static mp_obj_t winc_disconnect(mp_obj_t self_in)
{
m2m_wifi_disconnect();
return mp_const_none;
}
static mp_obj_t winc_isconnected(mp_obj_t self_in)
{
return MP_BOOL(wlan_connected && ip_obtained);
}
static mp_obj_t winc_ifconfig(mp_obj_t self_in)
{
mp_obj_t info_list;
info_list = mp_obj_new_list(0, NULL);
async_request_done = false;
async_request_data = info_list;
// Request connection info
m2m_wifi_get_connection_info();
while (async_request_done == false) {
// Handle pending events from network controller.
m2m_wifi_handle_events(NULL);
}
return info_list;
}
static mp_obj_t winc_scan(mp_obj_t self_in)
{
mp_obj_t scan_list;
scan_list = mp_obj_new_list(0, NULL);
async_request_done = false;
async_request_data = scan_list;
// Request scan.
m2m_wifi_request_scan(M2M_WIFI_CH_ALL);
while (async_request_done == false) {
// Handle pending events from network controller.
m2m_wifi_handle_events(NULL);
}
return scan_list;
}
static mp_obj_t winc_rssi(mp_obj_t self_in)
{
int rssi;
async_request_done = false;
async_request_data = &rssi;
// Request RSSI.
m2m_wifi_req_curr_rssi();
while (async_request_done == false) {
// Handle pending events from network controller.
m2m_wifi_handle_events(NULL);
}
return mp_obj_new_int(rssi);
}
static mp_obj_t winc_fw_version(mp_obj_t self_in)
{
//uint8_t pver[2];
//mp_obj_tuple_t *t_pver;
//nvmem_read_sp_version(pver);
//t_pver = mp_obj_new_tuple(2, NULL);
//t_pver->items[0] = mp_obj_new_int(pver[0]);
//t_pver->items[1] = mp_obj_new_int(pver[1]);
//return t_pver;
return mp_const_none;
}
static MP_DEFINE_CONST_FUN_OBJ_KW(winc_connect_obj, 1, winc_connect);
static MP_DEFINE_CONST_FUN_OBJ_1(winc_disconnect_obj, winc_disconnect);
static MP_DEFINE_CONST_FUN_OBJ_1(winc_isconnected_obj, winc_isconnected);
static MP_DEFINE_CONST_FUN_OBJ_1(winc_ifconfig_obj, winc_ifconfig);
static MP_DEFINE_CONST_FUN_OBJ_1(winc_scan_obj, winc_scan);
static MP_DEFINE_CONST_FUN_OBJ_1(winc_rssi_obj, winc_rssi);
static MP_DEFINE_CONST_FUN_OBJ_1(winc_fw_version_obj, winc_fw_version);
static const mp_map_elem_t winc_locals_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_connect), (mp_obj_t)&winc_connect_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_disconnect), (mp_obj_t)&winc_disconnect_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_isconnected), (mp_obj_t)&winc_isconnected_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_ifconfig), (mp_obj_t)&winc_ifconfig_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_scan), (mp_obj_t)&winc_scan_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_rssi), (mp_obj_t)&winc_rssi_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_fw_version), (mp_obj_t)&winc_fw_version_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_OPEN), MP_OBJ_NEW_SMALL_INT(M2M_WIFI_SEC_OPEN) }, // Network is not secured.
{ MP_OBJ_NEW_QSTR(MP_QSTR_WEP), MP_OBJ_NEW_SMALL_INT(M2M_WIFI_SEC_WEP) }, // Security type WEP (40 or 104) OPEN OR SHARED.
{ MP_OBJ_NEW_QSTR(MP_QSTR_WPA_PSK), MP_OBJ_NEW_SMALL_INT(M2M_WIFI_SEC_WPA_PSK) }, // Network is secured with WPA/WPA2 personal(PSK).
{ MP_OBJ_NEW_QSTR(MP_QSTR_802_1X), MP_OBJ_NEW_SMALL_INT(M2M_WIFI_SEC_802_1X) }, // Network is secured with WPA/WPA2 Enterprise.
};
static MP_DEFINE_CONST_DICT(winc_locals_dict, winc_locals_dict_table);
const mod_network_nic_type_t mod_network_nic_type_winc = {
.base = {
{ &mp_type_type },
.name = MP_QSTR_WINC,
.make_new = winc_make_new,
.locals_dict = (mp_obj_t)&winc_locals_dict,
},
.gethostbyname = winc_gethostbyname,
.socket = winc_socket_socket,
.close = winc_socket_close,
.bind = winc_socket_bind,
.listen = winc_socket_listen,
.accept = winc_socket_accept,
.connect = winc_socket_connect,
.send = winc_socket_send,
.recv = winc_socket_recv,
.sendto = winc_socket_sendto,
.recvfrom = winc_socket_recvfrom,
.setsockopt = winc_socket_setsockopt,
//.settimeout = winc_socket_settimeout,
//.ioctl = winc_socket_ioctl,
};