diff --git a/configs/spresense/wifi/defconfig b/configs/spresense/wifi/defconfig index 9339db6af9c..a4e4a185ac5 100644 --- a/configs/spresense/wifi/defconfig +++ b/configs/spresense/wifi/defconfig @@ -39,6 +39,7 @@ CONFIG_FS_FAT=y CONFIG_FS_FATTIME=y CONFIG_FS_PROCFS=y CONFIG_FS_PROCFS_REGISTER=y +CONFIG_FS_SMARTFS=y CONFIG_HAVE_CXX=y CONFIG_HAVE_CXXINITIALIZE=y CONFIG_I2C=y @@ -46,6 +47,11 @@ CONFIG_LIB_SENDFILE_BUFSIZE=1024 CONFIG_MAX_WDOGPARMS=2 CONFIG_MMCSD=y CONFIG_MMCSD_SDIO=y +CONFIG_MTD_BYTE_WRITE=y +CONFIG_MTD_PARTITION=y +CONFIG_MTD_SMART=y +CONFIG_MTD_SMART_ENABLE_CRC=y +CONFIG_MTD_SMART_SECTOR_SIZE=4096 CONFIG_NAME_MAX=256 CONFIG_NET=y CONFIG_NETDB_DNSCLIENT=y @@ -55,6 +61,7 @@ CONFIG_NETUTILS_CODECS=y CONFIG_NETUTILS_FTPC=y CONFIG_NETUTILS_HTTPD_DIRLIST=y CONFIG_NETUTILS_HTTPD_SENDFILE=y +CONFIG_NETUTILS_NTPCLIENT_SERVER="133.243.238.243" CONFIG_NETUTILS_TELNETD=y CONFIG_NETUTILS_WEBCLIENT=y CONFIG_NETUTILS_WEBSERVER=y @@ -64,6 +71,7 @@ CONFIG_NET_TCP_NO_STACK=y CONFIG_NET_UDP_NO_STACK=y CONFIG_NET_USRSOCK=y CONFIG_NET_USRSOCK_CONNS=16 +CONFIG_NET_USRSOCK_UDP=y CONFIG_NFILE_DESCRIPTORS=8 CONFIG_NFILE_STREAMS=8 CONFIG_NSH_ARCHINIT=y @@ -95,6 +103,7 @@ CONFIG_START_YEAR=2019 CONFIG_SYSLOG_TIMESTAMP=y CONFIG_SYSTEM_NSH=y CONFIG_SYSTEM_NSH_CXXINITIALIZE=y +CONFIG_SYSTEM_NTPC=y CONFIG_SYSTEM_USBMSC=y CONFIG_UART1_SERIAL_CONSOLE=y CONFIG_USBDEV=y diff --git a/drivers/wireless/Kconfig b/drivers/wireless/Kconfig index c49988e9c4e..2490a40c4e7 100644 --- a/drivers/wireless/Kconfig +++ b/drivers/wireless/Kconfig @@ -36,6 +36,10 @@ config WL_GS2200M_SPI_FREQUENCY default 4000000 range 4000000 10000000 +config WL_GS2200M_DISABLE_DHCPC + bool "Disable the internal dhcp client" + default n + endif source drivers/wireless/spirit/Kconfig diff --git a/drivers/wireless/gs2200m.c b/drivers/wireless/gs2200m.c index e25a8d588fc..ae4a30c5964 100644 --- a/drivers/wireless/gs2200m.c +++ b/drivers/wireless/gs2200m.c @@ -98,7 +98,8 @@ enum pkt_state_e PKT_START = 0, PKT_EVENT, PKT_ESC_START, - PKT_BULK_DATA + PKT_BULK_DATA_TCP, + PKT_BULK_DATA_UDP, }; enum spi_status_e @@ -115,11 +116,12 @@ enum pkt_type_e TYPE_DISCONNECT = 2, TYPE_CONNECT = 3, TYPE_BOOT_MSG = 4, - TYPE_BULK_DATA = 5, - TYPE_FAIL = 6, - TYPE_TIMEOUT = 7, - TYPE_SPI_ERROR = 8, - TYPE_UNMATCH = 9, + TYPE_BULK_DATA_TCP = 5, + TYPE_BULK_DATA_UDP = 6, + TYPE_FAIL = 7, + TYPE_TIMEOUT = 8, + TYPE_SPI_ERROR = 9, + TYPE_UNMATCH = 10, }; struct evt_code_s @@ -130,14 +132,15 @@ struct evt_code_s struct pkt_dat_s { - struct dq_entry_s dq; - enum pkt_type_e type; - char cid; - uint8_t n; - FAR char *msg[NRESPMSG]; - uint16_t remain; /* bulk data length to be read */ - uint16_t len; /* bulk data length */ - FAR uint8_t *data; /* bulk data */ + struct dq_entry_s dq; + enum pkt_type_e type; + struct sockaddr_in addr; + char cid; + uint8_t n; + FAR char *msg[NRESPMSG]; + uint16_t remain; /* bulk data length to be read */ + uint16_t len; /* bulk data length */ + FAR uint8_t *data; /* bulk data */ }; struct pkt_ctx_s @@ -642,6 +645,18 @@ static bool _copy_data_from_pkt(FAR struct gs2200m_dev_s *dev, } errout: + + if (!msg->is_tcp) + { + /* Copy the source address and port */ + + memcpy(&msg->addr, &pkt_dat->addr, sizeof(pkt_dat->addr)); + + /* In udp case, treat the packet separately */ + + ret = false; + } + return ret; } @@ -1172,7 +1187,15 @@ static void _parse_pkt_in_s2(FAR struct pkt_ctx_s *pkt_ctx, /* NOTE: See 7.5.3.2 Bulk Data Handling */ - pkt_ctx->state = PKT_BULK_DATA; + pkt_ctx->state = PKT_BULK_DATA_TCP; + } + else if ('y' == c) + { + wlinfo("** y \n"); + + /* NOTE: See 7.5.3.2 Bulk Data Handling */ + + pkt_ctx->state = PKT_BULK_DATA_UDP; } else if ('F' == c) { @@ -1191,7 +1214,7 @@ static void _parse_pkt_in_s2(FAR struct pkt_ctx_s *pkt_ctx, } /**************************************************************************** - * Name: _parse_pkt_in_s3 (BULK data) + * Name: _parse_pkt_in_s3 (BULK data for TCP) ****************************************************************************/ static void _parse_pkt_in_s3(FAR struct pkt_ctx_s *pkt_ctx, @@ -1217,6 +1240,8 @@ static void _parse_pkt_in_s3(FAR struct pkt_ctx_s *pkt_ctx, pkt_ctx->dlen = _to_uint16((char *)pkt_ctx->ptr); pkt_ctx->ptr += 3; + wlinfo("dlen=%d \n", pkt_ctx->dlen); + /* Allocate memory for the packet */ pkt_dat->data = kmm_calloc(pkt_ctx->dlen, 1); @@ -1231,7 +1256,74 @@ static void _parse_pkt_in_s3(FAR struct pkt_ctx_s *pkt_ctx, if (0 == pkt_ctx->dlen) { pkt_ctx->state = PKT_START; - pkt_ctx->type = TYPE_BULK_DATA; + pkt_ctx->type = TYPE_BULK_DATA_TCP; + } + } +} + +/**************************************************************************** + * Name: _parse_pkt_in_s4 (BULK data for UDP: see Table 217) + ****************************************************************************/ + +static void _parse_pkt_in_s4(FAR struct pkt_ctx_s *pkt_ctx, + FAR struct pkt_dat_s *pkt_dat) +{ + char addr[17]; + char port[6]; + int n; + + ASSERT(pkt_dat); + + if ('z' == pkt_ctx->cid) + { + /*
*/ + + /* Read CID */ + + pkt_ctx->cid = (char)*(pkt_ctx->ptr); + pkt_ctx->ptr++; + + pkt_dat->cid = pkt_ctx->cid; + + /* Read address and port */ + + memset(addr, 0, sizeof(addr)); + memset(port, 0, sizeof(port)); + n = sscanf((char *)pkt_ctx->ptr, "%s %s\t", addr, port); + ASSERT(2 == n); + + wlinfo("from (%s:%s) \n", addr, port); + + inet_aton(addr, &pkt_dat->addr.sin_addr); + pkt_dat->addr.sin_port = htons((uint16_t)atoi(port)); + + /* Skip until data length */ + + for (; '\t' != (char)*(pkt_ctx->ptr); pkt_ctx->ptr++); + pkt_ctx->ptr++; + + /* Read data length */ + + pkt_ctx->dlen = _to_uint16((char *)pkt_ctx->ptr); + pkt_ctx->ptr += 3; + + wlinfo("dlen=%d \n", pkt_ctx->dlen); + + /* Allocate memory for the packet */ + + pkt_dat->data = kmm_calloc(pkt_ctx->dlen, 1); + ASSERT(pkt_dat->data); + } + else + { + _push_data_to_pkt(pkt_dat, *(pkt_ctx->ptr)); + + pkt_ctx->dlen--; + + if (0 == pkt_ctx->dlen) + { + pkt_ctx->state = PKT_START; + pkt_ctx->type = TYPE_BULK_DATA_UDP; } } } @@ -1269,10 +1361,14 @@ static enum pkt_type_e _parse_pkt(FAR uint8_t *p, uint16_t len, _parse_pkt_in_s2(&pkt_ctx, pkt_dat); break; - case PKT_BULK_DATA: + case PKT_BULK_DATA_TCP: _parse_pkt_in_s3(&pkt_ctx, pkt_dat); break; + case PKT_BULK_DATA_UDP: + _parse_pkt_in_s4(&pkt_ctx, pkt_dat); + break; + default: ASSERT(false); break; @@ -1442,6 +1538,10 @@ static enum pkt_type_e gs2200m_enable_dhcpc(FAR struct gs2200m_dev_s *dev, { char cmd[16]; +#ifdef CONFIG_WL_GS2200M_DISABLE_DHCPC + on = 0; +#endif + snprintf(cmd, sizeof(cmd), "AT+NDHCP=%d\r\n", on); return gs2200m_send_cmd(dev, cmd, NULL); } @@ -1662,12 +1762,13 @@ errout: } /**************************************************************************** - * Name: gs2200m_start_tcps - * NOTE: See 7.5.1.3 Start TCP Server + * Name: gs2200m_start_server + * NOTE: See 7.5.1.3 Start TCP Server, 7.5.1.4 Start UDP Server ****************************************************************************/ -static enum pkt_type_e gs2200m_start_tcps(FAR struct gs2200m_dev_s *dev, - FAR char *port, FAR char *cid) +static enum pkt_type_e gs2200m_start_server(FAR struct gs2200m_dev_s *dev, + FAR char *port, bool is_tcp, + FAR char *cid) { enum pkt_type_e r; struct pkt_dat_s pkt_dat; @@ -1677,7 +1778,14 @@ static enum pkt_type_e gs2200m_start_tcps(FAR struct gs2200m_dev_s *dev, /* Prepare cmd */ - snprintf(cmd, sizeof(cmd), "AT+NSTCP=%s\r\n", port); + if (is_tcp) + { + snprintf(cmd, sizeof(cmd), "AT+NSTCP=%s\r\n", port); + } + else + { + snprintf(cmd, sizeof(cmd), "AT+NSUDP=%s\r\n", port); + } /* Initialize pkt_dat and send */ @@ -1714,36 +1822,53 @@ errout: ****************************************************************************/ static enum pkt_type_e gs2200m_send_bulk(FAR struct gs2200m_dev_s *dev, - char cid, FAR const void *txdata, - uint16_t len) + FAR struct gs2200m_send_msg *msg) { enum pkt_type_e r; - const int bulk_hdr_size = 7; enum spi_status_e s; + int bulk_hdr_size; char digits[5]; - char cmd[10]; + char cmd[32]; memset(cmd, 0, sizeof(cmd)); /* Convert the data length to 4 ascii char */ - _to_ascii_char(len, digits); + _to_ascii_char(msg->len, digits); - wlinfo("** cid=%c len=%d digits=%s \n", cid, len, digits); + wlinfo("** cid=%c len=%d digits=%s \n", msg->cid, msg->len, digits); - /* NOTE: See 7.5.3.2 Bulk Data Handling - * Z - */ + if (msg->is_tcp) + { + /* NOTE: See 7.5.3.2 Bulk Data Handling for TCP + * Z + */ - snprintf(cmd, sizeof(cmd), "%cZ%c%s", ASCII_ESC, cid, digits); + snprintf(cmd, sizeof(cmd), "%cZ%c%s", ASCII_ESC, msg->cid, digits); + } + else + { + wlinfo("** addr=%s port=%d \n", inet_ntoa(msg->addr.sin_addr), + ntohs(msg->addr.sin_port)); + /* NOTE: See 7.5.3.2 Bulk Data Handling for UDP + * Y:: + */ + + snprintf(cmd, sizeof(cmd), "%cY%c%s:%d:%s", + ASCII_ESC, msg->cid, + inet_ntoa(msg->addr.sin_addr), ntohs(msg->addr.sin_port), + digits); + } + + bulk_hdr_size = strlen(cmd); memset(dev->tx_buff, 0, sizeof(dev->tx_buff)); memcpy(dev->tx_buff, cmd, bulk_hdr_size); - memcpy(dev->tx_buff + bulk_hdr_size, txdata, len); + memcpy(dev->tx_buff + bulk_hdr_size, msg->buf, msg->len); /* Send the bulk data */ - s = gs2200m_hal_write(dev, (char *)dev->tx_buff, len + bulk_hdr_size); + s = gs2200m_hal_write(dev, (char *)dev->tx_buff, msg->len + bulk_hdr_size); r = _spi_err_to_pkt_type(s); return r; @@ -1846,6 +1971,44 @@ static enum pkt_type_e gs2200m_get_version(FAR struct gs2200m_dev_s *dev) } #endif +/**************************************************************************** + * Name: gs2200m_ioctl_bind + ****************************************************************************/ + +static int gs2200m_ioctl_bind(FAR struct gs2200m_dev_s *dev, + FAR struct gs2200m_bind_msg *msg) +{ + enum pkt_type_e type = TYPE_OK; + char cid = 'z'; + int ret = OK; + + wlinfo("+++ start: (cid=%c, port=%s) \n", msg->cid, msg->port); + + /* Start TCP/UDP server and retrieve cid */ + + type = gs2200m_start_server(dev, msg->port, msg->is_tcp, &cid); + + if (type != TYPE_OK) + { + ret = -EINVAL; + goto errout; + } + + /* Enable the cid for server socket and if the pkt_q is empty */ + + _enable_cid(&dev->valid_cid_bits, cid, true); + _check_pkt_q_empty(dev, cid); + +errout: + + msg->type = type; + msg->cid = cid; + + wlinfo("+++ end: type=%d (cid=%c) \n", type, cid); + + return ret; +} + /**************************************************************************** * Name: gs2200m_ioctl_connect ****************************************************************************/ @@ -1912,7 +2075,10 @@ static int gs2200m_ioctl_connect(FAR struct gs2200m_dev_s *dev, static int gs2200m_ioctl_send(FAR struct gs2200m_dev_s *dev, FAR struct gs2200m_send_msg *msg) { + FAR struct gs2200m_bind_msg bmsg; enum pkt_type_e type; + bool assigned = false; + uint16_t s_port; int ret = OK; wlinfo("+++ start: (cid=%c) \n", msg->cid); @@ -1921,6 +2087,28 @@ static int gs2200m_ioctl_send(FAR struct gs2200m_dev_s *dev, gs2200m_set_gpio(dev, LED_GPIO, 1); #endif + /* If the msg is udp having unassgined cid */ + + if (!msg->is_tcp && 'z' == msg->cid) + { + memset(&bmsg, 0, sizeof(bmsg)); + + for (s_port = 50000; s_port < 60000; s_port++) + { + snprintf(bmsg.port, sizeof(bmsg.port), "%d", s_port); + + if (0 == gs2200m_ioctl_bind(dev, &bmsg)) + { + assigned = true; + break; + } + } + + ASSERT(assigned); + wlinfo("+++ cid is assigned for udp (cid=%c) \n", bmsg.cid); + msg->cid = bmsg.cid; + } + if (!_cid_is_set(&dev->valid_cid_bits, msg->cid)) { wlinfo("+++ already closed \n"); @@ -1928,7 +2116,7 @@ static int gs2200m_ioctl_send(FAR struct gs2200m_dev_s *dev, goto errout; } - type = gs2200m_send_bulk(dev, msg->cid, msg->buf, msg->len); + type = gs2200m_send_bulk(dev, msg); msg->type = type; @@ -2052,41 +2240,6 @@ errout: return ret; } -/**************************************************************************** - * Name: gs2200m_ioctl_bind - ****************************************************************************/ - -static int gs2200m_ioctl_bind(FAR struct gs2200m_dev_s *dev, - FAR struct gs2200m_bind_msg *msg) -{ - enum pkt_type_e type = TYPE_OK; - char cid = 'z'; - int ret = OK; - - wlinfo("+++ start: (cid=%c, port=%s) \n", msg->cid, msg->port); - - /* Start TCP server and retrieve cid */ - - type = gs2200m_start_tcps(dev, msg->port, &cid); - - /* Enable the cid for server socket and if the pkt_q is empty */ - - _enable_cid(&dev->valid_cid_bits, cid, true); - _check_pkt_q_empty(dev, cid); - - msg->type = type; - msg->cid = cid; - - if (type != TYPE_OK) - { - ret = -EINVAL; - } - - wlinfo("+++ end: type=%d (cid=%c) \n", type, cid); - - return ret; -} - /**************************************************************************** * Name: gs2200m_ioctl_accept ****************************************************************************/ @@ -2145,26 +2298,26 @@ static int gs2200m_ioctl_assoc_sta(FAR struct gs2200m_dev_s *dev, { enum pkt_type_e t; - /* Set to STA mode */ - - t = gs2200m_set_opmode(dev, 0); - ASSERT(TYPE_OK == t); - - /* Get mac address info */ - - t = gs2200m_get_mac(dev); - ASSERT(TYPE_OK == t); - /* Disassociate */ t = gs2200m_disassociate(dev); ASSERT(TYPE_OK == t); + /* Set to STA mode */ + + t = gs2200m_set_opmode(dev, 0); + ASSERT(TYPE_OK == t); + /* Enable DHCP Client */ t = gs2200m_enable_dhcpc(dev, 1); ASSERT(TYPE_OK == t); + /* Get mac address info */ + + t = gs2200m_get_mac(dev); + ASSERT(TYPE_OK == t); + /* Set WPA2 Passphrase */ if (TYPE_OK != gs2200m_calc_key(dev, msg->ssid, msg->key)) diff --git a/include/nuttx/wireless/gs2200m.h b/include/nuttx/wireless/gs2200m.h index 6f6887fa5e8..31ed81c4245 100644 --- a/include/nuttx/wireless/gs2200m.h +++ b/include/nuttx/wireless/gs2200m.h @@ -42,6 +42,7 @@ #include #include +#include #include #include @@ -81,6 +82,7 @@ struct gs2200m_bind_msg { char cid; uint8_t type; + bool is_tcp; char port[6]; }; @@ -92,19 +94,23 @@ struct gs2200m_accept_msg struct gs2200m_send_msg { - char cid; - uint8_t type; - FAR uint8_t *buf; + struct sockaddr_in addr; /* used for udp */ + bool is_tcp; + char cid; + uint8_t type; + FAR uint8_t *buf; uint16_t len; }; struct gs2200m_recv_msg { - char cid; - uint8_t type; - FAR uint8_t *buf; - uint16_t len; /* actual buffer length */ - uint16_t reqlen; /* requested size */ + struct sockaddr_in addr; /* used for udp */ + bool is_tcp; + char cid; + uint8_t type; + FAR uint8_t *buf; + uint16_t len; /* actual buffer length */ + uint16_t reqlen; /* requested size */ }; struct gs2200m_close_msg