From 9018e7830fbeba169f1fe04c3f8cbb4ae13d6cf5 Mon Sep 17 00:00:00 2001 From: Filip Jagodzinski Date: Mon, 29 Mar 2021 16:53:01 +0200 Subject: [PATCH 1/3] Mbed: Add wifi-ism43362 as a third party git submodule --- .gitmodules | 4 ++++ third_party/wifi-ism43362/repo | 1 + 2 files changed, 5 insertions(+) create mode 160000 third_party/wifi-ism43362/repo diff --git a/.gitmodules b/.gitmodules index cb58c6e01e3ebf..b0e8b2e5b0774d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -74,3 +74,7 @@ path = third_party/mbed-os/repo url = https://github.com/ARMmbed/mbed-os.git branch = feature-chip +[submodule "wifi-ism43362"] + path = third_party/wifi-ism43362/repo + url = https://github.com/ARMmbed/wifi-ism43362.git + branch = master diff --git a/third_party/wifi-ism43362/repo b/third_party/wifi-ism43362/repo new file mode 160000 index 00000000000000..d36718311672b7 --- /dev/null +++ b/third_party/wifi-ism43362/repo @@ -0,0 +1 @@ +Subproject commit d36718311672b7f5cc015c2c58ea88936837608c From 20b10230e19e4210ff1352d2b4a46f0925fc30a6 Mon Sep 17 00:00:00 2001 From: Filip Jagodzinski Date: Mon, 29 Mar 2021 16:59:10 +0200 Subject: [PATCH 2/3] Mbed: Use wifi-ism43362 submodule in the build script --- scripts/examples/mbed_example.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/examples/mbed_example.sh b/scripts/examples/mbed_example.sh index cfb99c20f8fab3..257feaa58939d3 100755 --- a/scripts/examples/mbed_example.sh +++ b/scripts/examples/mbed_example.sh @@ -85,8 +85,12 @@ MBED_CONFIG_PATH="$APP"/mbed/cmake_build/"$TARGET_BOARD"/develop/"$TOOLCHAIN"/ # Override Mbed OS path to development directory MBED_OS_PATH="$CHIP_ROOT"/third_party/mbed-os/repo -# Create symlink to mbed-os directory +# Add the Mbed OS driver for the ISM43362 Wi-Fi module +WIFI_ISM43362_PATH="$CHIP_ROOT"/third_party/wifi-ism43362/repo + +# Create symlinks to submodules ln -sfTr $MBED_OS_PATH "${APP}/mbed/mbed-os" +ln -sfTr $WIFI_ISM43362_PATH "${APP}/mbed/wifi-ism43362" # Generate config file for selected target, toolchain and hardware mbed-tools configure -t "$TOOLCHAIN" -m "$TARGET_BOARD" -p "$APP"/mbed/ From a6b76b9d0474763f3bc678d01fc38b4e20a8676a Mon Sep 17 00:00:00 2001 From: Filip Jagodzinski Date: Mon, 29 Mar 2021 17:04:38 +0200 Subject: [PATCH 3/3] Mbed: Remove wifi-ism43362 sources --- .../shell/mbed/wifi-ism43362/CMakeLists.txt | 23 - .../ISM43362/ATParser/ATParser.cpp | 456 --------- .../ISM43362/ATParser/ATParser.h | 246 ----- .../ATParser/BufferedSpi/Buffer/MyBuffer.cpp | 86 -- .../ATParser/BufferedSpi/Buffer/MyBuffer.h | 164 ---- .../ATParser/BufferedSpi/BufferedPrint.c | 44 - .../ATParser/BufferedSpi/BufferedSpi.cpp | 333 ------- .../ATParser/BufferedSpi/BufferedSpi.h | 234 ----- .../mbed/wifi-ism43362/ISM43362/ISM43362.cpp | 887 ------------------ .../mbed/wifi-ism43362/ISM43362/ISM43362.h | 292 ------ .../mbed/wifi-ism43362/ISM43362Interface.cpp | 640 ------------- .../mbed/wifi-ism43362/ISM43362Interface.h | 296 ------ examples/shell/mbed/wifi-ism43362/README.md | 61 -- .../shell/mbed/wifi-ism43362/mbed_lib.json | 84 -- 14 files changed, 3846 deletions(-) delete mode 100644 examples/shell/mbed/wifi-ism43362/CMakeLists.txt delete mode 100644 examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/ATParser.cpp delete mode 100644 examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/ATParser.h delete mode 100644 examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/BufferedSpi/Buffer/MyBuffer.cpp delete mode 100644 examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/BufferedSpi/Buffer/MyBuffer.h delete mode 100644 examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/BufferedSpi/BufferedPrint.c delete mode 100644 examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/BufferedSpi/BufferedSpi.cpp delete mode 100644 examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/BufferedSpi/BufferedSpi.h delete mode 100644 examples/shell/mbed/wifi-ism43362/ISM43362/ISM43362.cpp delete mode 100644 examples/shell/mbed/wifi-ism43362/ISM43362/ISM43362.h delete mode 100644 examples/shell/mbed/wifi-ism43362/ISM43362Interface.cpp delete mode 100644 examples/shell/mbed/wifi-ism43362/ISM43362Interface.h delete mode 100644 examples/shell/mbed/wifi-ism43362/README.md delete mode 100644 examples/shell/mbed/wifi-ism43362/mbed_lib.json diff --git a/examples/shell/mbed/wifi-ism43362/CMakeLists.txt b/examples/shell/mbed/wifi-ism43362/CMakeLists.txt deleted file mode 100644 index 8ce2b0e64132af..00000000000000 --- a/examples/shell/mbed/wifi-ism43362/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (c) 2020 ARM Limited. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 - -add_library(wifi-ism43362 INTERFACE) - -target_include_directories(wifi-ism43362 - INTERFACE - . - ISM43362 - ISM43362/ATParser - ISM43362/ATParser/BufferedSpi - ISM43362/ATParser/BufferedSpi/Buffer -) - -target_sources(wifi-ism43362 - INTERFACE - ISM43362Interface.cpp - ISM43362/ISM43362.cpp - ISM43362/ATParser/ATParser.cpp - ISM43362/ATParser/BufferedSpi/BufferedPrint.c - ISM43362/ATParser/BufferedSpi/BufferedSpi.cpp - ISM43362/ATParser/BufferedSpi/Buffer/MyBuffer.cpp -) diff --git a/examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/ATParser.cpp b/examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/ATParser.cpp deleted file mode 100644 index 8e0d259c740236..00000000000000 --- a/examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/ATParser.cpp +++ /dev/null @@ -1,456 +0,0 @@ -/* Copyright (c) 2015 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * @section DESCRIPTION - * - * Parser for the AT command syntax - * - */ - -#include "ATParser.h" -#include "mbed_debug.h" - -#ifdef LF -#undef LF -#define LF 10 -#else -#define LF 10 -#endif - -#ifdef CR -#undef CR -#define CR 13 -#else -#define CR 13 -#endif -#define MIN(a,b) (((a)<(b))?(a):(b)) - -// activate / de-activate debug -#define dbg_on 0 -#define AT_DATA_PRINT 0 -#define AT_COMMAND_PRINT 0 -#define AT_HEXA_DATA 0 - -ATParser::ATParser(BufferedSpi &serial_spi, const char *delimiter, int buffer_size, int timeout) : - _serial_spi(&serial_spi), - _buffer_size(buffer_size), _in_prev(0), _oobs(NULL) -{ - _buffer = new char[buffer_size]; - setTimeout(timeout); - setDelimiter(delimiter); -} - - -// getc/putc handling with timeouts -int ATParser::putc(char c) -{ - return _serial_spi->putc(c); -} - -int ATParser::getc() -{ - return _serial_spi->getc(); -} - -void ATParser::flush() -{ - _bufferMutex.lock(); - while (_serial_spi->readable()) { - _serial_spi->getc(); - } - _bufferMutex.unlock(); -} - -// read/write handling with timeouts -int ATParser::write(const char *data, int size_of_data, int size_in_buff) -{ - int i = 0; - _bufferMutex.lock(); - debug_if(dbg_on, "ATParser write: %d BYTES\r\n", size_of_data); - debug_if(AT_DATA_PRINT, "ATParser write: (ASCII) "); - for (; i < size_of_data; i++) { - debug_if(AT_DATA_PRINT, "%c", data[i]); - if (putc(data[i]) < 0) { - debug_if(AT_DATA_PRINT, "\r\n"); - _bufferMutex.unlock(); - return -1; - } - } - debug_if(AT_DATA_PRINT, "\r\n"); - - _serial_spi->buffsend(size_of_data + size_in_buff); - _bufferMutex.unlock(); - - return (size_of_data + size_in_buff); -} - -int ATParser::read(char *data) -{ - int readsize; - int i = 0; - - _bufferMutex.lock(); - - //this->flush(); - if (!_serial_spi->readable()) { - readsize = _serial_spi->read(); - } else { - debug_if(dbg_on, "Pending data when reading from WIFI\r\n"); - return -1; - } - - debug_if(dbg_on, "ATParser read: %d data avail in SPI\r\n", readsize); - - if (readsize < 0) { - _bufferMutex.unlock(); - return -1; - } - - for (i = 0 ; i < readsize; i++) { - int c = getc(); - if (c < 0) { - _bufferMutex.unlock(); - return -1; - } - data[i] = c; - } - -#if AT_HEXA_DATA - debug_if(AT_DATA_PRINT, "ATParser read: (HEXA) "); - for (i = 0; i < readsize; i++) { - debug_if(AT_DATA_PRINT, "%2X ", data[i]); - if ((i + 1) % 20 == 0) { - debug_if(AT_DATA_PRINT, "\r\n"); - } - } - debug_if(AT_DATA_PRINT, "\r\n"); -#endif - debug_if(AT_DATA_PRINT, "ATParser read: (ASCII) "); - for (i = 0; i < readsize; i++) { - debug_if(AT_DATA_PRINT, "%c", data[i]); - } - debug_if(AT_DATA_PRINT, "\r\n"); - - _bufferMutex.unlock(); - - return (readsize); -} - -// printf/scanf handling -int ATParser::vprintf(const char *format, va_list args) -{ - _bufferMutex.lock(); - if (vsprintf(_buffer, format, args) < 0) { - _bufferMutex.unlock(); - return false; - } - - int i = 0; - for (; _buffer[i]; i++) { - if (putc(_buffer[i]) < 0) { - _bufferMutex.unlock(); - return -1; - } - } - _bufferMutex.unlock(); - - return i; -} - -int ATParser::vscanf(const char *format, va_list args) -{ - // Since format is const, we need to copy it into our buffer to - // add the line's null terminator and clobber value-matches with asterisks. - // - // We just use the beginning of the buffer to avoid unnecessary allocations. - int i = 0; - int offset = 0; - - _bufferMutex.lock(); - - while (format[i]) { - if (format[i] == '%' && format[i + 1] != '%' && format[i + 1] != '*') { - _buffer[offset++] = '%'; - _buffer[offset++] = '*'; - i++; - } else { - _buffer[offset++] = format[i++]; - } - } - - // Scanf has very poor support for catching errors - // fortunately, we can abuse the %n specifier to determine - // if the entire string was matched. - _buffer[offset++] = '%'; - _buffer[offset++] = 'n'; - _buffer[offset++] = 0; - - // To workaround scanf's lack of error reporting, we actually - // make two passes. One checks the validity with the modified - // format string that only stores the matched characters (%n). - // The other reads in the actual matched values. - // - // We keep trying the match until we succeed or some other error - // derails us. - int j = 0; - - while (true) { - // Ran out of space - if (j + 1 >= _buffer_size - offset) { - _bufferMutex.unlock(); - return false; - } - // Recieve next character - int c = getc(); - if (c < 0) { - _bufferMutex.unlock(); - return -1; - } - _buffer[offset + j++] = c; - _buffer[offset + j] = 0; - - // Check for match - int count = -1; - sscanf(_buffer + offset, _buffer, &count); - - // We only succeed if all characters in the response are matched - if (count == j) { - // Store the found results - vsscanf(_buffer + offset, format, args); - _bufferMutex.unlock(); - return j; - } - } -} - - -// Command parsing with line handling -bool ATParser::vsend(const char *command, va_list args) -{ - int i = 0, j = 0; - _bufferMutex.lock(); - // Create and send command - if (vsprintf(_buffer, command, args) < 0) { - _bufferMutex.unlock(); - return false; - } - /* get buffer length */ - for (i = 0; _buffer[i]; i++) { - } - - for (j = 0; _delimiter[j]; j++) { - _buffer[i + j] = _delimiter[j]; - } - _buffer[i + j] = 0; // only to get a clean debug log - - bool ret = !(_serial_spi->buffwrite(_buffer, i + j) < 0); - - debug_if(AT_COMMAND_PRINT, "AT> %s\n", _buffer); - _bufferMutex.unlock(); - return ret; -} - -bool ATParser::vrecv(const char *response, va_list args) -{ - _bufferMutex.lock(); - - if (!_serial_spi->readable()) { - // debug_if(dbg_on, "NO DATA, read again\r\n"); - if (_serial_spi->read() < 0) { - return false; - } - } - // else { - // debug_if(dbg_on, "Pending data\r\n"); - // } - -restart: - _aborted = false; - // Iterate through each line in the expected response - while (response[0]) { - // Since response is const, we need to copy it into our buffer to - // add the line's null terminator and clobber value-matches with asterisks. - // - // We just use the beginning of the buffer to avoid unnecessary allocations. - int i = 0; - int offset = 0; - bool whole_line_wanted = false; - - while (response[i]) { - if (response[i] == '%' && response[i + 1] != '%' && response[i + 1] != '*') { - _buffer[offset++] = '%'; - _buffer[offset++] = '*'; - i++; - } else { - _buffer[offset++] = response[i++]; - // Find linebreaks, taking care not to be fooled if they're in a %[^\n] conversion specification - if (response[i - 1] == '\n' && !(i >= 3 && response[i - 3] == '[' && response[i - 2] == '^')) { - whole_line_wanted = true; - break; - } - } - } - - // Scanf has very poor support for catching errors - // fortunately, we can abuse the %n specifier to determine - // if the entire string was matched. - _buffer[offset++] = '%'; - _buffer[offset++] = 'n'; - _buffer[offset++] = 0; - - // debug_if(dbg_on, "ATParser vrecv: AT? ====%s====\n", _buffer); - // To workaround scanf's lack of error reporting, we actually - // make two passes. One checks the validity with the modified - // format string that only stores the matched characters (%n). - // The other reads in the actual matched values. - // - // We keep trying the match until we succeed or some other error - // derails us. - int j = 0; - - while (true) { - // Recieve next character - int c = getc(); - if (c < 0) { - debug_if(dbg_on, "AT(Timeout)\n"); - _bufferMutex.unlock(); - return false; - } - - // debug_if(AT_DATA_PRINT, "%2X ", c); - - _buffer[offset + j++] = c; - _buffer[offset + j] = 0; - - // Check for oob data - for (struct oob *oob = _oobs; oob; oob = oob->next) { - if ((unsigned)j == oob->len && memcmp( - oob->prefix, _buffer + offset, oob->len) == 0) { - debug_if(dbg_on, "AT! %s\n", oob->prefix); - oob->cb(); - - if (_aborted) { - debug_if(dbg_on, "AT(Aborted)\n"); - _bufferMutex.unlock(); - return false; - } - // oob may have corrupted non-reentrant buffer, - // so we need to set it up again - goto restart; - } - } - - // Check for match - int count = -1; - if (whole_line_wanted && c != '\n' && c != '\r') { - // Don't attempt scanning until we get delimiter if they included it in format - // This allows recv("Foo: %s\n") to work, and not match with just the first character of a string - // (scanf does not itself match whitespace in its format string, so \n is not significant to it) - // New ATCommand F0=2 ends with \r only whereas other commands end with \r\n , - // so take both characters \r and \n into account to determine the end of line - } else { - sscanf(_buffer + offset, _buffer, &count); - } - - // We only succeed if all characters in the response are matched - if (count == j) { - debug_if(AT_COMMAND_PRINT, "AT= ====%s====\n", _buffer + offset); - // Reuse the front end of the buffer - memcpy(_buffer, response, i); - _buffer[i] = 0; - - // Store the found results - vsscanf(_buffer + offset, _buffer, args); - - // Jump to next line and continue parsing - response += i; - break; - } - - // Clear the buffer when we hit a newline or ran out of space - // running out of space usually means we ran into binary data - if ((c == '\n') || (c == '\r')) { - debug_if(dbg_on, "New line AT<<< %s", _buffer + offset); - j = 0; - } - if ((j + 1 >= (_buffer_size - offset))) { - - debug_if(dbg_on, "Out of space AT<<< %s, j=%d", _buffer + offset, j); - j = 0; - } - } - } - - _bufferMutex.unlock(); - - return true; -} - - -// Mapping to vararg functions -int ATParser::printf(const char *format, ...) -{ - va_list args; - va_start(args, format); - int res = vprintf(format, args); - va_end(args); - return res; -} - -int ATParser::scanf(const char *format, ...) -{ - va_list args; - va_start(args, format); - int res = vscanf(format, args); - va_end(args); - return res; -} - -bool ATParser::send(const char *command, ...) -{ - va_list args; - va_start(args, command); - bool res = vsend(command, args); - va_end(args); - return res; -} - -bool ATParser::recv(const char *response, ...) -{ - va_list args; - va_start(args, response); - bool res = vrecv(response, args); - va_end(args); - return res; -} - - -// oob registration -void ATParser::oob(const char *prefix, Callback cb) -{ - struct oob *oob = new struct oob; - oob->len = strlen(prefix); - oob->prefix = prefix; - oob->cb = cb; - oob->next = _oobs; - _oobs = oob; -} - -void ATParser::abort() -{ - _aborted = true; -} - - - diff --git a/examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/ATParser.h b/examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/ATParser.h deleted file mode 100644 index 75edaaf8a245e2..00000000000000 --- a/examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/ATParser.h +++ /dev/null @@ -1,246 +0,0 @@ -/* Copyright (c) 2015 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * @section DESCRIPTION - * - * Parser for the AT command syntax - * - */ -#ifndef AT_PARSER_H -#define AT_PARSER_H - -#include "mbed.h" -#include -#include -#include "BufferedSpi.h" -#include "Callback.h" - -#define DEFAULT_SPI_TIMEOUT 60000 /* 1 minute */ - -/** -* Parser class for parsing AT commands -* -* Here are some examples: -* @code -* ATParser at = ATParser(serial, "\r\n"); -* int value; -* char buffer[100]; -* -* at.send("AT") && at.recv("OK"); -* at.send("AT+CWMODE=%d", 3) && at.recv("OK"); -* at.send("AT+CWMODE?") && at.recv("+CWMODE:%d\r\nOK", &value); -* at.recv("+IPD,%d:", &value); -* at.read(buffer, value); -* at.recv("OK"); -* @endcode -*/ -class ATParser { -private: - // Serial information - BufferedSpi *_serial_spi; - int _buffer_size; - char *_buffer; - Mutex _bufferMutex; - - // Parsing information - const char *_delimiter; - int _delim_size; - char _in_prev; - volatile bool _aborted; - - struct oob { - unsigned len; - const char *prefix; - mbed::Callback cb; - oob *next; - }; - oob *_oobs; - -public: - /** - * Constructor - * - * @param serial spi interface to use for AT commands - * @param buffer_size size of internal buffer for transaction - * @param timeout timeout of the connection - * @param delimiter string of characters to use as line delimiters - */ - ATParser(BufferedSpi &serial_spi, const char *delimiter = "\r\n", int buffer_size = 1440, int timeout = DEFAULT_SPI_TIMEOUT); - - /** - * Destructor - */ - ~ATParser() - { - while (_oobs) { - struct oob *oob = _oobs; - _oobs = oob->next; - delete oob; - } - delete[] _buffer; - } - - /** - * Allows timeout to be changed between commands - * - * @param timeout timeout of the connection - */ - void setTimeout(int timeout) - { - _serial_spi->setTimeout(timeout); - } - - /** - * Sets string of characters to use as line delimiters - * - * @param delimiter string of characters to use as line delimiters - */ - void setDelimiter(const char *delimiter) - { - _delimiter = delimiter; - _delim_size = strlen(delimiter); - } - - /** - * Sends an AT command - * - * Sends a formatted command using printf style formatting - * @see printf - * - * @param command printf-like format string of command to send which - * is appended with a newline - * @param ... all printf-like arguments to insert into command - * @return true only if command is successfully sent - */ - bool send(const char *command, ...); - - bool vsend(const char *command, va_list args); - - /** - * Receive an AT response - * - * Receives a formatted response using scanf style formatting - * @see scanf - * - * Responses are parsed line at a time. - * Any received data that does not match the response is ignored until - * a timeout occurs. - * - * @param response scanf-like format string of response to expect - * @param ... all scanf-like arguments to extract from response - * @return true only if response is successfully matched - */ - bool recv(const char *response, ...); - bool vrecv(const char *response, va_list args); - - - /** - * Write a single byte to the underlying stream - * - * @param c The byte to write - * @return The byte that was written or -1 during a timeout - */ - int putc(char c); - - /** - * Get a single byte from the underlying stream - * - * @return The byte that was read or -1 during a timeout - */ - int getc(); - - /** - * Write an array of bytes to the underlying stream - * assuming the header of the command is already in _txbuffer - * - * @param data the array of bytes to write - * @param size_of_data number of bytes in data array - * @param size_in_buff number of bytes already in the internal buff - * @return number of bytes written or -1 on failure - */ - int write(const char *data, int size_of_data, int size_in_buff); - - /** - * Read an array of bytes from the underlying stream - * - * @param data the destination for the read bytes - * @param size number of bytes to read - * @return number of bytes read or -1 on failure - */ - int read(char *data); - - /** - * Direct printf to underlying stream - * @see printf - * - * @param format format string to pass to printf - * @param ... arguments to printf - * @return number of bytes written or -1 on failure - */ - int printf(const char *format, ...); - int vprintf(const char *format, va_list args); - - /** - * Direct scanf on underlying stream - * @see ::scanf - * - * @param format format string to pass to scanf - * @param ... arguments to scanf - * @return number of bytes read or -1 on failure - */ - int scanf(const char *format, ...); - - int vscanf(const char *format, va_list args); - - /** - * Attach a callback for out-of-band data - * - * @param prefix string on when to initiate callback - * @param func callback to call when string is read - * @note out-of-band data is only processed during a scanf call - */ - void oob(const char *prefix, mbed::Callback func); - - /** - * Flushes the underlying stream - */ - void flush(); - - /** - * Abort current recv - * - * Can be called from oob handler to interrupt the current - * recv operation. - */ - void abort(); - - /** - * Process out-of-band data - * - * Process out-of-band data in the receive buffer. This function - * returns immediately if there is no data to process. - * - * @return true if oob data processed, false otherwise - */ - bool process_oob(void); - /** - * Get buffer_size - */ - int get_size(void) - { - return _buffer_size; - } - -}; -#endif diff --git a/examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/BufferedSpi/Buffer/MyBuffer.cpp b/examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/BufferedSpi/Buffer/MyBuffer.cpp deleted file mode 100644 index 1dafc855278425..00000000000000 --- a/examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/BufferedSpi/Buffer/MyBuffer.cpp +++ /dev/null @@ -1,86 +0,0 @@ - -/** - * @file Buffer.cpp - * @brief Software Buffer - Templated Ring Buffer for most data types - * @author sam grove - * @version 1.0 - * @see - * - * Copyright (c) 2013 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "MyBuffer.h" - -template -MyBuffer::MyBuffer(uint32_t size) -{ - _buf = new T [size]; - _size = size; - clear(); - - return; -} - -template -MyBuffer::~MyBuffer() -{ - delete [] _buf; - - return; -} - -template -uint32_t MyBuffer::getSize() -{ - return this->_size; -} - -template -uint32_t MyBuffer::getNbAvailable() -{ - if (_wloc >= _rloc) { - return (_wloc - _rloc); - } else { - return (_size - _rloc + _wloc); - } -} - -template -void MyBuffer::clear(void) -{ - _wloc = 0; - _rloc = 0; - memset(_buf, 0, _size); - - return; -} - -template -uint32_t MyBuffer::peek(char c) -{ - return 1; -} - -// make the linker aware of some possible types -template class MyBuffer; -template class MyBuffer; -template class MyBuffer; -template class MyBuffer; -template class MyBuffer; -template class MyBuffer; -template class MyBuffer; -template class MyBuffer; -template class MyBuffer; -template class MyBuffer; diff --git a/examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/BufferedSpi/Buffer/MyBuffer.h b/examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/BufferedSpi/Buffer/MyBuffer.h deleted file mode 100644 index 5f7a316842d45d..00000000000000 --- a/examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/BufferedSpi/Buffer/MyBuffer.h +++ /dev/null @@ -1,164 +0,0 @@ - -/** - * @file Buffer.h - * @brief Software Buffer - Templated Ring Buffer for most data types - * @author sam grove - * @version 1.0 - * @see - * - * Copyright (c) 2013 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MYBUFFER_H -#define MYBUFFER_H - -#include -#include - -/** A templated software ring buffer - * - * Example: - * @code - * #include "mbed.h" - * #include "MyBuffer.h" - * - * MyBuffer buf; - * - * int main() - * { - * buf = 'a'; - * buf.put('b'); - * char *head = buf.head(); - * puts(head); - * - * char whats_in_there[2] = {0}; - * int pos = 0; - * - * while(buf.available()) - * { - * whats_in_there[pos++] = buf; - * } - * printf("%c %c\n", whats_in_there[0], whats_in_there[1]); - * buf.clear(); - * error("done\n\n\n"); - * } - * @endcode - */ - -template -class MyBuffer { -private: - T *_buf; - volatile uint32_t _wloc; - volatile uint32_t _rloc; - uint32_t _size; - -public: - /** Create a Buffer and allocate memory for it - * @param size The size of the buffer - */ - MyBuffer(uint32_t size = 0x100); - - /** Get the size of the ring buffer - * @return the size of the ring buffer - */ - uint32_t getSize(); - uint32_t getNbAvailable(); - - /** Destry a Buffer and release it's allocated memory - */ - ~MyBuffer(); - - /** Add a data element into the buffer - * @param data Something to add to the buffer - */ - void put(T data); - - /** Remove a data element from the buffer - * @return Pull the oldest element from the buffer - */ - T get(void); - - /** Get the address to the head of the buffer - * @return The address of element 0 in the buffer - */ - T *head(void); - - /** Reset the buffer to 0. Useful if using head() to parse packeted data - */ - void clear(void); - - /** Determine if anything is readable in the buffer - * @return 1 if something can be read, 0 otherwise - */ - uint32_t available(void); - - /** Overloaded operator for writing to the buffer - * @param data Something to put in the buffer - * @return - */ - MyBuffer &operator= (T data) - { - put(data); - return *this; - } - - /** Overloaded operator for reading from the buffer - * @return Pull the oldest element from the buffer - */ - operator int(void) - { - return get(); - } - - uint32_t peek(char c); - -}; - -template -inline void MyBuffer::put(T data) -{ - _buf[_wloc++] = data; - _wloc %= (_size - 1); - - return; -} - -template -inline T MyBuffer::get(void) -{ - T data_pos = _buf[_rloc++]; - _rloc %= (_size - 1); - - return data_pos; -} - -template -inline T *MyBuffer::head(void) -{ - T *data_pos = &_buf[0]; - - return data_pos; -} - -template -inline uint32_t MyBuffer::available(void) -{ - return (_wloc == _rloc) ? 0 : 1; - //return 1; -} - -#endif - diff --git a/examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/BufferedSpi/BufferedPrint.c b/examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/BufferedSpi/BufferedPrint.c deleted file mode 100644 index 95009444dafcdc..00000000000000 --- a/examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/BufferedSpi/BufferedPrint.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2014-2015 ARM Limited. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include - -#include "mbed_error.h" - -size_t BufferedSpiThunk(void *buf_serial, const void *s, size_t length); - -int BufferedPrintfC(void *stream, int size, const char *format, va_list arg) -{ - int r; - char buffer[512]; - if (size >= 512) { - return -1; - } - memset(buffer, 0, size); - r = vsprintf(buffer, format, arg); - // this may not hit the heap but should alert the user anyways - if (r > (int32_t) size) { - error("%s %d buffer overwrite (max_buf_size: %d exceeded: %d)!\r\n", __FILE__, __LINE__, size, r); - return 0; - } - if (r > 0) { - BufferedSpiThunk(stream, buffer, r); - } - return r; -} diff --git a/examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/BufferedSpi/BufferedSpi.cpp b/examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/BufferedSpi/BufferedSpi.cpp deleted file mode 100644 index ac2c39a56f21d9..00000000000000 --- a/examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/BufferedSpi/BufferedSpi.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/** - * @file BufferedSpi.cpp - * @brief Software Buffer - Extends mbed SPI functionallity - * @author Armelle Duboc - * @version 1.0 - * @see - * - * Copyright (c) STMicroelectronics 2017 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "BufferedSpi.h" -#include -#include -#include "mbed_debug.h" -#include "mbed_error.h" - -// change to true to add few SPI debug lines -#define local_debug false - -extern "C" int BufferedPrintfC(void *stream, int size, const char *format, va_list arg); - -void BufferedSpi::DatareadyRising(void) -{ - if (_cmddata_rdy_rising_event == 1) { - _cmddata_rdy_rising_event = 0; - } -} - -int BufferedSpi::wait_cmddata_rdy_high(void) -{ - Timer timer; - timer.start(); - - /* wait for dataready = 1 */ - while (dataready.read() == 0) { - if (timer.read_ms() > _timeout) { - debug_if(local_debug, "ERROR: SPI write timeout\r\n"); - return -1; - } - } - - _cmddata_rdy_rising_event = 1; - - return 0; -} - -int BufferedSpi::wait_cmddata_rdy_rising_event(void) -{ - Timer timer; - timer.start(); - - while (_cmddata_rdy_rising_event == 1) { - if (timer.read_ms() > _timeout) { - _cmddata_rdy_rising_event = 0; - if (dataready.read() == 1) { - debug_if(local_debug, "ERROR: We missed rising event !! (timemout=%d)\r\n", _timeout); - } - debug_if(local_debug, "ERROR: SPI read timeout\r\n"); - return -1; - } - } - - return 0; -} - -BufferedSpi::BufferedSpi(PinName mosi, PinName miso, PinName sclk, PinName _nss, PinName _datareadypin, - uint32_t buf_size, uint32_t tx_multiple, const char *name) - : SPI(mosi, miso, sclk, NC), nss(_nss), _txbuf((uint32_t)(tx_multiple * buf_size)), _rxbuf(buf_size), dataready(_datareadypin) -{ - this->_buf_size = buf_size; - this->_tx_multiple = tx_multiple; - this->_sigio_event = 0; - - _datareadyInt = new InterruptIn(_datareadypin); - _datareadyInt->rise(callback(this, &BufferedSpi::DatareadyRising)); - - _cmddata_rdy_rising_event = 1; - nss = 1; - wait_us(15); - - return; -} - -BufferedSpi::~BufferedSpi(void) -{ - - return; -} - -void BufferedSpi::frequency(int hz) -{ - SPI::frequency(hz); -} - -void BufferedSpi::format(int bits, int mode) -{ - SPI::format(bits, mode); -} - -void BufferedSpi::disable_nss() -{ - nss = 1; - wait_us(15); - unlock(); -} - -void BufferedSpi::enable_nss() -{ - lock(); - nss = 0; - wait_us(15); -} - -int BufferedSpi::readable(void) -{ - return _rxbuf.available(); // note: look if things are in the buffer -} - -int BufferedSpi::writeable(void) -{ - return 1; // buffer allows overwriting by design, always true -} - -int BufferedSpi::getc(void) -{ - if (_rxbuf.available()) { - return _rxbuf; - } else { - return -1; - } -} - -int BufferedSpi::putc(int c) -{ - _txbuf = (char)c; - - return c; -} - -void BufferedSpi::flush_txbuf(void) -{ - _txbuf.clear(); -} - -int BufferedSpi::puts(const char *s) -{ - if (s != NULL) { - const char *ptr = s; - - while (*(ptr) != 0) { - _txbuf = *(ptr++); - } - _txbuf = '\n'; // done per puts definition - BufferedSpi::txIrq(); // only write to hardware in one place - return (ptr - s) + 1; - } - return 0; -} - -extern "C" size_t BufferedSpiThunk(void *buf_spi, const void *s, size_t length) -{ - BufferedSpi *buffered_spi = (BufferedSpi *)buf_spi; - return buffered_spi->buffwrite(s, length); -} - -int BufferedSpi::printf(const char *format, ...) -{ - va_list arg; - va_start(arg, format); - int r = BufferedPrintfC((void *)this, this->_buf_size, format, arg); - va_end(arg); - return r; -} - -ssize_t BufferedSpi::buffwrite(const void *s, size_t length) -{ - /* flush buffer from previous message */ - this->flush_txbuf(); - - if (wait_cmddata_rdy_high() < 0) { - debug_if(local_debug, "BufferedSpi::buffwrite timeout (%d)\r\n", _timeout); - return -1; - } - - this->enable_nss(); - - if (s != NULL && length > 0) { - /* 1st fill _txbuf */ - const char *ptr = (const char *)s; - const char *end = ptr + length; - - while (ptr != end) { - _txbuf = *(ptr++); - } - - /* 2nd write in SPI */ - BufferedSpi::txIrq(); // only write to hardware in one place - - this->disable_nss(); - return ptr - (const char *)s; - } - this->disable_nss(); - - return 0; -} - -ssize_t BufferedSpi::buffsend(size_t length) -{ - /* wait for dataready = 1 */ - if (wait_cmddata_rdy_high() < 0) { - debug_if(local_debug, "BufferedSpi::buffsend timeout (%d)\r\n", _timeout); - return -1; - } - - this->enable_nss(); - - BufferedSpi::txIrq(); // only write to hardware in one place - - this->disable_nss(); - - return length; -} - -ssize_t BufferedSpi::read() -{ - return this->read(0); -} - -ssize_t BufferedSpi::read(uint32_t max) -{ - uint32_t len = 0; - uint8_t FirstRemoved = 1; - int tmp; - - /* wait for data ready is up */ - if (wait_cmddata_rdy_rising_event() != 0) { - debug_if(local_debug, "BufferedSpi::read timeout (%d)\r\n", _timeout); - return -1; - } - - enable_nss(); - while (dataready.read() == 1 && (len < (_buf_size - 2))) { - tmp = SPI::write(0xAA); // dummy write to receive 2 bytes - - if (!((len == 0) && (tmp == 0x0A0D) && (FirstRemoved))) { - /* do not take into account the 2 firts \r \n char in the buffer */ - if ((max == 0) || (len < max)) { - _rxbuf = (char)(tmp & 0x00FF); - _rxbuf = (char)((tmp >> 8) & 0xFF); - len += 2; - } - } else { - FirstRemoved = 0; - } - } - disable_nss(); - - if (len >= _buf_size) { - debug_if(local_debug, "firmware ERROR ES_WIFI_ERROR_STUFFING_FOREVER\r\n"); - return -1; - } - - debug_if(local_debug, "SPI READ %" PRIu32 " BYTES\r\n", len); - - return len; -} - -void BufferedSpi::txIrq(void) -{ - /* write everything available in the _txbuffer */ - int value = 0; - int dbg_cnt = 0; - - while (_txbuf.available()) { - /* Get first 8 bits */ - value = _txbuf.get(); - /* then next 8 bits to build 16 bits words to be sent on SPI */ - if (_txbuf.available()) { - value |= ((_txbuf.get() << 8) & 0XFF00); - } else { - /* In case of ODD size, add a \n char padding */ - value |= (('\n' << 8) & 0XFF00); - } - SPI::write(value); - dbg_cnt++; - } - - debug_if(local_debug, "SPI Sent %d BYTES\r\n", 2 * dbg_cnt); - // disable the TX interrupt when there is nothing left to send - BufferedSpi::attach(NULL, BufferedSpi::TxIrq); - // trigger callback if necessary - if (_cbs[TxIrq]) { - _cbs[TxIrq](); - } - return; -} - -void BufferedSpi::prime(void) -{ - BufferedSpi::txIrq(); // only write to hardware in one place - return; -} - -void BufferedSpi::attach(Callback func, IrqType type) -{ - _cbs[type] = func; -} - -void BufferedSpi::sigio(Callback func) -{ - core_util_critical_section_enter(); - _sigio_cb = func; - if (_sigio_cb) { - if (_sigio_event == 1) { - _sigio_cb(); - _sigio_event = 0; - } - } - core_util_critical_section_exit(); -} - diff --git a/examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/BufferedSpi/BufferedSpi.h b/examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/BufferedSpi/BufferedSpi.h deleted file mode 100644 index 4b7d8d8728cdf7..00000000000000 --- a/examples/shell/mbed/wifi-ism43362/ISM43362/ATParser/BufferedSpi/BufferedSpi.h +++ /dev/null @@ -1,234 +0,0 @@ - -/** - * @file BufferedSpi.h - * @brief Software Buffer - Extends mbed SPI functionallity - * @author Armelle Duboc - * @version 1.0 - * @see - * - * Copyright (c) STMicroelectronics 2017 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef BUFFEREDSPI_H -#define BUFFEREDSPI_H - -#include "mbed.h" -#include "MyBuffer.h" - -/** A spi port (SPI) for communication with wifi device - * - * Can be used for Full Duplex communication, or Simplex by specifying - * one pin as NC (Not Connected) - * - * Example: - * @code - * #include "mbed.h" - * #include "BufferedSerial.h" - * - * BufferedSerial pc(USBTX, USBRX); - * - * int main() - * { - * while(1) - * { - * Timer s; - * - * s.start(); - * pc.printf("Hello World - buffered\n"); - * int buffered_time = s.read_us(); - * wait(0.1f); // give time for the buffer to empty - * - * s.reset(); - * printf("Hello World - blocking\n"); - * int polled_time = s.read_us(); - * s.stop(); - * wait(0.1f); // give time for the buffer to empty - * - * pc.printf("printf buffered took %d us\n", buffered_time); - * pc.printf("printf blocking took %d us\n", polled_time); - * wait(0.5f); - * } - * } - * @endcode - */ - -/** - * @class BufferedSpi - * @brief Software buffers and interrupt driven tx and rx for Serial - */ -class BufferedSpi : public SPI { -private: - DigitalOut nss; - MyBuffer _txbuf; - uint32_t _buf_size; - uint32_t _tx_multiple; - volatile int _timeout; - void txIrq(void); - void prime(void); - - InterruptIn *_datareadyInt; - volatile int _cmddata_rdy_rising_event; - void DatareadyRising(void); - int wait_cmddata_rdy_rising_event(void); - int wait_cmddata_rdy_high(void); - - - Callback _cbs[2]; - - Callback _sigio_cb; - uint8_t _sigio_event; - -public: - MyBuffer _rxbuf; - DigitalIn dataready; - enum IrqType { - RxIrq = 0, - TxIrq, - - IrqCnt - }; - - /** Create a BufferedSpi Port, connected to the specified transmit and receive pins - * @param SPI mosi pin - * @param SPI miso pin - * @param SPI sclk pin - * @param SPI nss pin - * @param Dataready pin - * @param buf_size printf() buffer size - * @param tx_multiple amount of max printf() present in the internal ring buffer at one time - * @param name optional name - */ - BufferedSpi(PinName mosi, PinName miso, PinName sclk, PinName nss, PinName datareadypin, uint32_t buf_size = 2500, uint32_t tx_multiple = 1, const char *name = NULL); - - /** Destroy a BufferedSpi Port - */ - virtual ~BufferedSpi(void); - - /** call to SPI frequency Function - */ - virtual void frequency(int hz); - - /** clear the transmit buffer - */ - virtual void flush_txbuf(void); - - /** call to SPI format function - */ - virtual void format(int bits, int mode); - - virtual void enable_nss(void); - - virtual void disable_nss(void); - - /** Check on how many bytes are in the rx buffer - * @return 1 if something exists, 0 otherwise - */ - virtual int readable(void); - - /** Check to see if the tx buffer has room - * @return 1 always has room and can overwrite previous content if too small / slow - */ - virtual int writeable(void); - - /** Get a single byte from the BufferedSpi Port. - * Should check readable() before calling this. - * @return A byte that came in on the SPI Port - */ - virtual int getc(void); - - /** Write a single byte to the BufferedSpi Port. - * @param c The byte to write to the SPI Port - * @return The byte that was written to the SPI Port Buffer - */ - virtual int putc(int c); - - /** Write a string to the BufferedSpi Port. Must be NULL terminated - * @param s The string to write to the Spi Port - * @return The number of bytes written to the Spi Port Buffer - */ - virtual int puts(const char *s); - - /** Write a formatted string to the BufferedSpi Port. - * @param format The string + format specifiers to write to the Spi Port - * @return The number of bytes written to the Spi Port Buffer - */ - virtual int printf(const char *format, ...); - - /** Write data to the Buffered Spi Port - * @param s A pointer to data to send - * @param length The amount of data being pointed to - * @return The number of bytes written to the Spi Port Buffer - */ - virtual ssize_t buffwrite(const void *s, std::size_t length); - - /** Send datas to the Spi port that are already present - * in the internal _txbuffer - * @param length - * @return the number of bytes written on the SPI port - */ - virtual ssize_t buffsend(size_t length); - - /** Read data from the Spi Port to the _rxbuf - * @param max: optional. = max sieze of the input read - * @return The number of bytes read from the SPI port and written to the _rxbuf - */ - virtual ssize_t read(); - virtual ssize_t read(uint32_t max); - - /** - * Allows timeout to be changed between commands - * - * @param timeout timeout of the connection in ms - */ - void setTimeout(int timeout) - { - /* this is a safe guard timeout at SPI level in case module is stuck */ - _timeout = timeout; - } - - /** Register a callback once any data is ready for sockets - * @param func Function to call on state change - */ - virtual void sigio(Callback func); - - /** Attach a function to call whenever a serial interrupt is generated - * @param func A pointer to a void function, or 0 to set as none - * @param type Which serial interrupt to attach the member function to (Serial::RxIrq for receive, TxIrq for transmit buffer empty) - */ - virtual void attach(Callback func, IrqType type = RxIrq); - - /** Attach a member function to call whenever a serial interrupt is generated - * @param obj pointer to the object to call the member function on - * @param method pointer to the member function to call - * @param type Which serial interrupt to attach the member function to (Serial::RxIrq for receive, TxIrq for transmit buffer empty) - */ - template - void attach(T *obj, void (T::*method)(), IrqType type = RxIrq) - { - attach(Callback(obj, method), type); - } - - /** Attach a member function to call whenever a serial interrupt is generated - * @param obj pointer to the object to call the member function on - * @param method pointer to the member function to call - * @param type Which serial interrupt to attach the member function to (Serial::RxIrq for receive, TxIrq for transmit buffer empty) - */ - template - void attach(T *obj, void (*method)(T *), IrqType type = RxIrq) - { - attach(Callback(obj, method), type); - } -}; -#endif diff --git a/examples/shell/mbed/wifi-ism43362/ISM43362/ISM43362.cpp b/examples/shell/mbed/wifi-ism43362/ISM43362/ISM43362.cpp deleted file mode 100644 index f2326c03f7d63c..00000000000000 --- a/examples/shell/mbed/wifi-ism43362/ISM43362/ISM43362.cpp +++ /dev/null @@ -1,887 +0,0 @@ -/* ISM43362 Example -* -* Copyright (c) STMicroelectronics 2018 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include -#include "ISM43362.h" -#include "mbed_debug.h" - -// activate / de-activate debug -#define ism_debug 0 - -/* The minimum FW version to have AP scan one by one is C3.5.2.5 (ATcommand F0=2) */ -#define SINGLE_AP_SCAN_FW_VERSION_NUMBER 3525 - -ISM43362::ISM43362(PinName mosi, PinName miso, PinName sclk, PinName nss, PinName resetpin, PinName datareadypin, PinName wakeup, bool debug) - : _bufferspi(mosi, miso, sclk, nss, datareadypin), - _parser(_bufferspi), - _resetpin(resetpin), - _packets(0), _packets_end(&_packets) -{ - DigitalOut wakeup_pin(wakeup); - _bufferspi.format(16, 0); /* 16bits, ploarity low, phase 1Edge, master mode */ - _bufferspi.frequency(20000000); /* up to 20 MHz */ - _active_id = 0xFF; - _FwVersionId = 0; - - _ism_debug = debug || ism_debug; - reset(); -} - -/** - * @brief Parses and returns number from string. - * @param ptr: pointer to string - * @param cnt: pointer to the number of parsed digit - * @retval integer value. - */ -#define CHARISHEXNUM(x) (((x) >= '0' && (x) <= '9') || \ - ((x) >= 'a' && (x) <= 'f') || \ - ((x) >= 'A' && (x) <= 'F')) -#define CHARISNUM(x) ((x) >= '0' && (x) <= '9') -#define CHAR2NUM(x) ((x) - '0') - - -extern "C" int32_t ParseNumber(char *ptr, uint8_t *cnt) -{ - uint8_t minus = 0, i = 0; - int32_t sum = 0; - - if (*ptr == '-') { /* Check for minus character */ - minus = 1; - ptr++; - i++; - } - if (*ptr == 'C') { /* input string from get_firmware_version is Cx.x.x.x */ - ptr++; - } - - while (CHARISNUM(*ptr) || (*ptr == '.')) { /* Parse number */ - if (*ptr == '.') { - ptr++; // next char - } else { - sum = 10 * sum + CHAR2NUM(*ptr); - ptr++; - i++; - } - } - - if (cnt != NULL) { /* Save number of characters used for number */ - *cnt = i; - } - if (minus) { /* Minus detected */ - return 0 - sum; - } - return sum; /* Return number */ -} - -uint32_t ISM43362::get_firmware_version(void) -{ - char tmp_buffer[250]; - char *ptr, *ptr2; - char _fw_version[16]; - - /* Use %[^\n] instead of %s to allow having spaces in the string */ - if (!(_parser.send("I?") && _parser.recv("%[^\n^\r]\r\n", tmp_buffer) && check_response())) { - debug_if(_ism_debug, "\tISM43362: get_firmware_version is FAIL\r\n"); - return 0; - } - debug_if(_ism_debug, "\tISM43362: get_firmware_version = %s\r\n", tmp_buffer); - - // Get the first version in the string - ptr = strtok((char *)tmp_buffer, ","); - ptr = strtok(NULL, ","); - ptr2 = strtok(NULL, ","); - if (ptr == NULL) { - debug_if(_ism_debug, "\tISM43362: get_firmware_version decoding is FAIL\r\n"); - return 0; - } - strncpy(_fw_version, ptr, ptr2 - ptr); - _FwVersionId = ParseNumber(_fw_version, NULL); - - return _FwVersionId; -} - -bool ISM43362::reset(void) -{ - char tmp_buffer[100]; - debug_if(_ism_debug, "\tISM43362: Reset Module\r\n"); - _resetpin = 0; - wait_us(10000); - _resetpin = 1; - rtos::ThisThread::sleep_for(500); - - /* Wait for prompt line : the string is "> ". */ - /* As the space char is not detected by sscanf function in parser.recv, */ - /* we need to use %[\n] */ - if (!_parser.recv(">%[^\n]", tmp_buffer)) { - debug_if(_ism_debug, "\tISM43362: Reset Module failed\r\n"); - return false; - } - return true; -} - -void ISM43362::print_rx_buff(void) -{ - char tmp[150] = {0}; - uint16_t i = 0; - debug_if(_ism_debug, "\tISM43362: "); - while (i < 150) { - int c = _parser.getc(); - if (c < 0) { - break; - } - tmp[i] = c; - debug_if(_ism_debug, "0x%2X ", c); - i++; - } - debug_if(_ism_debug, "\n"); - debug_if(_ism_debug, "\tISM43362: Buffer content =====%s=====\r\n", tmp); -} - -/* checks the standard OK response of the WIFI module, shouldbe: - * \r\nDATA\r\nOK\r\n>sp - * or - * \r\nERROR\r\nUSAGE\r\n>sp - * function returns true if OK, false otherwise. In case of error, - * print error content then flush buffer */ -bool ISM43362::check_response(void) -{ - char tmp_buffer[100]; - if (!_parser.recv("OK\r\n")) { - print_rx_buff(); - _parser.flush(); - return false; - } - - /* Then we should get the prompt: "> " */ - /* As the space char is not detected by sscanf function in parser.recv, */ - /* we need to use %[\n] */ - if (!_parser.recv(">%[^\n]", tmp_buffer)) { - debug_if(_ism_debug, "\tISM43362: Missing prompt in WIFI resp\r\n"); - print_rx_buff(); - _parser.flush(); - return false; - } - - /* Inventek module do stuffing / padding of data with 0x15, - * in case buffer contains such */ - while (1) { - int c = _parser.getc(); - if (c == 0x15) { - // debug_if(_ism_debug, "\tISM43362: Flush char 0x%x\n", c); - continue; - } else { - /* How to put it back if needed ? */ - break; - } - } - return true; -} - -bool ISM43362::dhcp(bool enabled) -{ - return (_parser.send("C4=%d", enabled ? 1 : 0) && check_response()); -} - -/* - * @brief Update wifi_module_country_code. - * @param country_code: User's country code. - * @retval boolean value : false ->error - -WiFi module is only able to receive 4 country codes: CA, US, FR and JP. -CA, US -> 11 channels -FR -> 13 channels -JP -> 14 channels - -Thus 3 country code groups can be defined : - -- Country Code Group corresponding to 11 channels : CountryCodeElevenChannels, -- Country Code Group corresponding to 13 channels : CountryCodeThirteenChannels, -- Country Code Group corresponding to 14 channels : CountryCodeFourteenChannels. - -For an user's country code (input country code), the function is specifying -to which Country Code Group it is belonging. - -For instance, -user's country code=VN (Vietnam - 13 channels) is belonging -to CountryCodeThirteenChannels. - -Thus function is specifying that WIFI module must be configured -with country code = FR. - -Function is updating WIFI_module_country_code with FR. - -*/ - -#ifdef MBED_CONF_ISM43362_WIFI_COUNTRY_CODE -bool ISM43362::check_country_code(const char *country_code) -{ - if ((!strcmp(country_code, "CA")) || (!strcmp(country_code, "US")) - || (!strcmp(country_code, "FR")) || (!strcmp(country_code, "JP"))) { - strcpy(WIFI_module_country_code, country_code); - return true; - } - - int k = 0; - - while (strcmp(CountryCodeThirteenChannels[k].cc, "ED")) { - if (!strcmp(CountryCodeThirteenChannels[k].cc, country_code)) { - strcpy(WIFI_module_country_code, "FR"); - return true; - } - - k++; - } - - k = 0; - - while (strcmp(CountryCodeElevenChannels[k].cc, "ED")) { - if (!strcmp(CountryCodeElevenChannels[k].cc, country_code)) { - strcpy(WIFI_module_country_code, "US"); - return true; - } - - k++; - } - - return false; -} -#endif - -int ISM43362::connect(const char *ap, const char *passPhrase, ism_security_t ap_sec) -{ - char tmp[256]; - - if (!(_parser.send("C1=%s", ap) && check_response())) { - return NSAPI_ERROR_PARAMETER; - } - - if (!(_parser.send("C2=%s", passPhrase) && check_response())) { - return NSAPI_ERROR_PARAMETER; - } - - /* Check security level is acceptable */ - if (ap_sec > ISM_SECURITY_WPA_WPA2) { - debug_if(_ism_debug, "\tISM43362: Unsupported security level %d\n", ap_sec); - return NSAPI_ERROR_UNSUPPORTED; - } - - if (!(_parser.send("C3=%d", ap_sec) && check_response())) { - return NSAPI_ERROR_PARAMETER; - } - -#ifdef MBED_CONF_ISM43362_WIFI_COUNTRY_CODE - /* Check country code is acceptable */ - bool ret = check_country_code(MBED_CONF_ISM43362_WIFI_COUNTRY_CODE); - if (ret == false) { - printf("ISM43362::connect Country Code ERROR\n"); - return NSAPI_ERROR_PARAMETER; - } - - if (!(_parser.send("CN=%s/0", WIFI_module_country_code) && check_response())) { - return NSAPI_ERROR_PARAMETER; - } -#endif - - if (_parser.send("C0")) { - while (_parser.recv("%[^\n]\n", tmp)) { - if (strstr(tmp, "OK")) { - _parser.flush(); - _conn_status = NSAPI_STATUS_GLOBAL_UP; - _conn_stat_cb(); - return NSAPI_ERROR_OK; - } - if (strstr(tmp, "JOIN")) { - _conn_status = NSAPI_STATUS_CONNECTING; - _conn_stat_cb(); - if (strstr(tmp, "Failed")) { - _parser.flush(); - return NSAPI_ERROR_AUTH_FAILURE; - } - } - } - } - - return NSAPI_ERROR_NO_CONNECTION; -} - -bool ISM43362::disconnect(void) -{ - _conn_status = NSAPI_STATUS_DISCONNECTED; - _conn_stat_cb(); - return (_parser.send("CD") && check_response()); -} - -const char *ISM43362::getIPAddress(void) -{ - char tmp_ip_buffer[250]; - char *ptr, *ptr2; - - /* Use %[^\n] instead of %s to allow having spaces in the string */ - if (!(_parser.send("C?") - && _parser.recv("%[^\n^\r]\r\n", tmp_ip_buffer) - && check_response())) { - debug_if(_ism_debug, "\tISM43362: getIPAddress LINE KO: %s\n", tmp_ip_buffer); - return 0; - } - - /* Get the IP address in the result */ - /* TODO : check if the begining of the string is always = "eS-WiFi_AP_C47F51011231," */ - ptr = strtok((char *)tmp_ip_buffer, ","); - ptr = strtok(NULL, ","); - ptr = strtok(NULL, ","); - ptr = strtok(NULL, ","); - ptr = strtok(NULL, ","); - ptr = strtok(NULL, ","); - ptr2 = strtok(NULL, ","); - if (ptr == NULL) { - return 0; - } - strncpy(_ip_buffer, ptr, ptr2 - ptr); - - tmp_ip_buffer[59] = 0; - debug_if(_ism_debug, "\tISM43362: receivedIPAddress: %s\n", _ip_buffer); - - return _ip_buffer; -} - -const char *ISM43362::getMACAddress(void) -{ - if (!(_parser.send("Z5") && _parser.recv("%s\r\n", _mac_buffer) && check_response())) { - debug_if(_ism_debug, "\tISM43362: receivedMacAddress LINE KO: %s\n", _mac_buffer); - return 0; - } - - debug_if(_ism_debug, "\tISM43362: receivedMacAddress:%s, size=%d\r\n", _mac_buffer, sizeof(_mac_buffer)); - - return _mac_buffer; -} - -const char *ISM43362::getGateway() -{ - char tmp[250]; - /* Use %[^\n] instead of %s to allow having spaces in the string */ - if (!(_parser.send("C?") && _parser.recv("%[^\n^\r]\r\n", tmp) && check_response())) { - debug_if(_ism_debug, "\tISM43362: getGateway LINE KO: %s\r\n", tmp); - return 0; - } - - /* Extract the Gateway in the received buffer */ - char *ptr; - ptr = strtok(tmp, ","); - for (int i = 0; i < 7; i++) { - if (ptr == NULL) { - break; - } - ptr = strtok(NULL, ","); - } - - strncpy(_gateway_buffer, ptr, sizeof(_gateway_buffer)); - - debug_if(_ism_debug, "\tISM43362: getGateway: %s\r\n", _gateway_buffer); - - return _gateway_buffer; -} - -const char *ISM43362::getNetmask() -{ - char tmp[250]; - /* Use %[^\n] instead of %s to allow having spaces in the string */ - if (!(_parser.send("C?") && _parser.recv("%[^\n^\r]\r\n", tmp) && check_response())) { - debug_if(_ism_debug, "\tISM43362: getNetmask LINE KO: %s\n", tmp); - return 0; - } - - /* Extract Netmask in the received buffer */ - char *ptr; - ptr = strtok(tmp, ","); - for (int i = 0; i < 6; i++) { - if (ptr == NULL) { - break; - } - ptr = strtok(NULL, ","); - } - - strncpy(_netmask_buffer, ptr, sizeof(_netmask_buffer)); - - debug_if(_ism_debug, "\tISM43362: getNetmask: %s\r\n", _netmask_buffer); - - return _netmask_buffer; -} - -int8_t ISM43362::getRSSI() -{ - int8_t rssi; - char tmp[25]; - - if (!(_parser.send("CR") && _parser.recv("%s\r\n", tmp) && check_response())) { - debug_if(_ism_debug, "\tISM43362: getRSSI LINE KO: %s\r\n", tmp); - return 0; - } - - rssi = ParseNumber(tmp, NULL); - - debug_if(_ism_debug, "\tISM43362: getRSSI: %d\r\n", rssi); - - return rssi; -} -/** - * @brief Parses Security type. - * @param ptr: pointer to string - * @retval Encryption type. - */ -extern "C" nsapi_security_t ParseSecurity(char *ptr) -{ - if (strstr(ptr, "Open")) { - return NSAPI_SECURITY_NONE; - } else if (strstr(ptr, "WEP")) { - return NSAPI_SECURITY_WEP; - } else if (strstr(ptr, "WPA2 AES")) { - return NSAPI_SECURITY_WPA2; - } else if (strstr(ptr, "WPA WPA2")) { - return NSAPI_SECURITY_WPA_WPA2; - } else if (strstr(ptr, "WPA2 TKIP")) { - return NSAPI_SECURITY_UNKNOWN; // no match in mbed - } else if (strstr(ptr, "WPA2")) { - return NSAPI_SECURITY_WPA2; // catch any other WPA2 formula - } else if (strstr(ptr, "WPA")) { - return NSAPI_SECURITY_WPA; - } else { - return NSAPI_SECURITY_UNKNOWN; - } -} - -/** - * @brief Convert char in Hex format to integer. - * @param a: character to convert - * @retval integer value. - */ -extern "C" uint8_t Hex2Num(char a) -{ - if (a >= '0' && a <= '9') { /* Char is num */ - return a - '0'; - } else if (a >= 'a' && a <= 'f') { /* Char is lowercase character A - Z (hex) */ - return (a - 'a') + 10; - } else if (a >= 'A' && a <= 'F') { /* Char is uppercase character A - Z (hex) */ - return (a - 'A') + 10; - } - - return 0; -} - -/** - * @brief Extract a hex number from a string. - * @param ptr: pointer to string - * @param cnt: pointer to the number of parsed digit - * @retval Hex value. - */ -extern "C" uint32_t ParseHexNumber(char *ptr, uint8_t *cnt) -{ - uint32_t sum = 0; - uint8_t i = 0; - - while (CHARISHEXNUM(*ptr)) { /* Parse number */ - sum <<= 4; - sum += Hex2Num(*ptr); - ptr++; - i++; - } - - if (cnt != NULL) { /* Save number of characters used for number */ - *cnt = i; - } - return sum; /* Return number */ -} - -bool ISM43362::isConnected(void) -{ - return getIPAddress() != 0; -} - -int ISM43362::scan(WiFiAccessPoint *res, unsigned limit) -{ - unsigned cnt = 0, num = 0; - char *ptr; - char tmp[256]; - bool found = false; - bool AP_Scan_1by1 = false; - - /* Recent FW version provide new AT command: F0=2 which allows to solve the issue too many APs - With too many APs (depending on SSID name length), there is no answer from firmware to F0 command. - F0=2 command allows to scan AP one by one. Command MR is then used to get next AP. */ - if (_FwVersionId >= SINGLE_AP_SCAN_FW_VERSION_NUMBER) { - AP_Scan_1by1 = true; - if (!(_parser.send("F0=2"))) { - debug_if(_ism_debug, "\tISM43362: F0=2 error\r\n"); - return 0; - } - } else { - if (!(_parser.send("F0"))) { - debug_if(_ism_debug, "\tISM43362: F0 error\r\n"); - return 0; - } - } - debug_if(_ism_debug, "\tISM43362: scan feature %u\r\n", AP_Scan_1by1); - - - /* Parse the received buffer and fill AP buffer */ - /* Use %[^\n] instead of %s to allow having spaces in the string */ - while (_parser.recv("%[^\n^\r]\r\n", tmp)) { - found = false; - debug_if(_ism_debug, "\tISM43362: received: %s\n", tmp); - - if (AP_Scan_1by1 == true) { - /* In case of scan AP 1 by 1, end of list is detected thanks to OK or ERROR*/ - if (strncmp("ERROR", (char *)tmp, 5) == 0) { - _parser.flush(); - return 0; - } - if ((strncmp("OK\r", (char *)tmp, 2) == 0)) { - /* reached end */ - break; - } - } - - if (limit == 0 || cnt < limit) { - nsapi_wifi_ap_t ap = {0}; - ptr = strtok(tmp, ","); - num = 0; - while ((ptr != NULL) && (!found)) { - switch (num++) { - case 0: /* Ignore index */ - case 4: /* Ignore Max Rate */ - case 5: /* Ignore Network Type */ - case 7: /* Ignore Radio Band */ - break; - case 1: - ptr[strlen(ptr) - 1] = 0; - strncpy((char *)ap.ssid, ptr + 1, 32); - break; - case 2: - for (int i = 0; i < 6; i++) { - ap.bssid[i] = ParseHexNumber(ptr + (i * 3), NULL); - } - break; - case 3: - ap.rssi = ParseNumber(ptr, NULL); - break; - case 6: - ap.security = ParseSecurity(ptr); - break; - case 8: - ap.channel = ParseNumber(ptr, NULL); - found = true; - break; - default: - break; - } - ptr = strtok(NULL, ","); - } - - if (found == true) { - if (res != NULL) { - res[cnt] = WiFiAccessPoint(ap); - } - cnt++; - } - } else { - debug_if(_ism_debug, "\tISM43362: |-> discarded\r\n"); - } - - if (AP_Scan_1by1 == true) { - _parser.flush(); - /* retrieve next AP */ - if (!(_parser.send("MR"))) { - debug_if(_ism_debug, "\tISM43362: scan error\r\n"); - return 0; - } - } - } - - /* We may stop before having read all the APs list, so flush the rest of - * it as well as OK commands */ - _parser.flush(); - - debug_if(_ism_debug, "\tISM43362: End of Scan: cnt=%d\n", cnt); - - return cnt; - -} - -int ISM43362::open(const char *type, int id, const char *addr, int port) -{ - static uint16_t rnglocalport = 0; - - if ((type == NULL) || (addr == NULL)) { - debug_if(_ism_debug, "\tISM43362: parameter error\n"); - return NSAPI_ERROR_PARAMETER; - } - - /* TODO : This is the implementation for the client socket, need to check if need to create openserver too */ - //IDs only 0-3 - if ((id < 0) || (id > 3)) { - debug_if(_ism_debug, "\tISM43362: open: wrong id\n"); - return NSAPI_ERROR_PARAMETER; - } - - /* Connection is either TCP or UDP */ - bool UDP_CONNECTION = false; /* TCP connection */ - - if (memcmp(type, "1", sizeof("1")) == 0) { - UDP_CONNECTION = true; - } - - /* Set communication socket */ - _active_id = id; - if (!(_parser.send("P0=%d", id) && check_response())) { - debug_if(_ism_debug, "\tISM43362: open: P0 issue\n"); - return NSAPI_ERROR_DEVICE_ERROR; - } - /* Set protocol */ - if (!(_parser.send("P1=%s", type) && check_response())) { - debug_if(_ism_debug, "\tISM43362: open: P1 issue\n"); - return NSAPI_ERROR_DEVICE_ERROR; - } - - /* The IANA range for ephemeral ports is 49152<96>65535. */ - /* implement automatic nr by sw because Queqtel assigns always the same initial nr */ - /* generate random local port number between 49152 and 65535 */ - if (rnglocalport == 0) { - /* just at first open since board reboot */ - rnglocalport = rand(); - rnglocalport = ((uint16_t)(rnglocalport & 0xFFFF) >> 2) + 49152; - } else { - /* from second time function execution, increment by one */ - rnglocalport += 1; - } - if (rnglocalport < 49152) { - rnglocalport = 49152; - } - - if (!UDP_CONNECTION) {/* TCP connection */ - - /* Set local port */ - if (!(_parser.send("P2=%d", rnglocalport) && check_response())) { - debug_if(_ism_debug, "\tISM43362: open: P2 issue\n"); - return NSAPI_ERROR_DEVICE_ERROR; - } - } - - /* Set address */ - if (!(_parser.send("P3=%s", addr) && check_response())) { - debug_if(_ism_debug, "\tISM43362: open: P3 issue\n"); - return NSAPI_ERROR_DEVICE_ERROR; - } - - if (UDP_CONNECTION) { - if (!(_parser.send("P4=%d", rnglocalport) && check_response())) { - debug_if(_ism_debug, "\tISM43362: open: P4 issue\n"); - return NSAPI_ERROR_DEVICE_ERROR; - } - } else { /* TCP connection */ - if (!(_parser.send("P4=%d", port) && check_response())) { - debug_if(_ism_debug, "\tISM43362: open: P4 issue\n"); - return NSAPI_ERROR_DEVICE_ERROR; - } - } - - /* In case of UDP, force client mode ORIGIN. */ - if (UDP_CONNECTION) { - /* Disable server */ - if (!(_parser.send("P5=0") && check_response())) { - debug_if(_ism_debug, "\tISM43362: open: P5 issue\n"); - return NSAPI_ERROR_DEVICE_ERROR; - } - } - - /* Start client */ - if (!(_parser.send("P6=1") && check_response())) { - debug_if(_ism_debug, "\tISM43362: open: P6 issue, id=%d, addr=%s\n", id, addr); - return NSAPI_ERROR_DEVICE_ERROR; - } - - if (UDP_CONNECTION) { - if (!(_parser.send("P0=%d", id) && check_response())) { - debug_if(_ism_debug, "\tISM43362: open: P0 issue\n"); - return NSAPI_ERROR_DEVICE_ERROR; - } - - if (!(_parser.send("P4=%d", port) && check_response())) { - debug_if(_ism_debug, "\tISM43362: open: P4 issue\n"); - return NSAPI_ERROR_DEVICE_ERROR; - } - } - - /* request as much data as possible - i.e. module max size */ - if (!(_parser.send("R1=%d", ES_WIFI_MAX_RX_PACKET_SIZE) && check_response())) { - debug_if(_ism_debug, "\tISM43362: open: R1 issue\n"); - return NSAPI_ERROR_DEVICE_ERROR; - } - - /* Non blocking mode : set Read Transport Timeout to 1ms */ - if (!(_parser.send("R2=1") && check_response())) { - debug_if(_ism_debug, "\tISM43362: open: R2 issue\n"); - return NSAPI_ERROR_DEVICE_ERROR; - } - - debug_if(_ism_debug, "\tISM43362: open ok with id %d type %s addr %s port %d\n", id, type, addr, port); - - return NSAPI_ERROR_OK; -} - - -bool ISM43362::send(int id, const void *data, uint32_t amount) -{ - // The Size limit has to be checked on caller side. - if (amount > ES_WIFI_MAX_TX_PACKET_SIZE) { - debug_if(_ism_debug, "\tISM43362 send: max issue\n"); - return false; - } - - /* Activate the socket id in the wifi module */ - if ((id < 0) || (id > 3)) { - return false; - } - if (_active_id != id) { - _active_id = id; - if (!(_parser.send("P0=%d", id) && check_response())) { - debug_if(_ism_debug, "\tISM43362 send: P0 issue\n"); - return false; - } - } - - /* set Write Transport Packet Size */ - int i = _parser.printf("S3=%d\r", (int)amount); - if (i < 0) { - debug_if(_ism_debug, "\tISM43362 send: S3 issue\n"); - return false; - } - i = _parser.write((const char *)data, amount, i); - if (i < 0) { - return false; - } - - if (!check_response()) { - return false; - } - - debug_if(_ism_debug, "\tISM43362 send: id %d amount %" PRIu32 "\n", id, amount); - return true; -} - -int ISM43362::check_recv_status(int id, void *data) -{ - int read_amount; - - debug_if(_ism_debug, "\tISM43362 check_recv_status: id %d\r\n", id); - - /* Activate the socket id in the wifi module */ - if ((id < 0) || (id > 3)) { - debug_if(_ism_debug, "\tISM43362 check_recv_status: ERROR with id %d\r\n", id); - return -1; - } - - if (_active_id != id) { - _active_id = id; - if (!(_parser.send("P0=%d", id) && check_response())) { - return -1; - } - } - - - if (!_parser.send("R0")) { - return -1; - } - read_amount = _parser.read((char *)data); - - if (read_amount < 0) { - debug_if(_ism_debug, "\tISM43362 check_recv_status: ERROR in data RECV, timeout?\r\n"); - return -1; /* nothing to read */ - } - - /* If there are spurious 0x15 at the end of the data, this is an error - * we hall can get rid off of them :-( - * This should not happen, but let's try to clean-up anyway - */ - char *cleanup = (char *) data; - while ((read_amount > 0) && (cleanup[read_amount - 1] == 0x15)) { - // debug_if(_ism_debug, "\tISM43362 check_recv_status: spurious 0X15 trashed\r\n"); - /* Remove the trailling char then search again */ - read_amount--; - } - - if ((read_amount >= 6) && (strncmp("OK\r\n> ", (char *)data, 6) == 0)) { - // debug_if(_ism_debug, "\tISM43362 check_recv_status: recv 2 nothing to read=%d\r\n", read_amount); - // read_amount -= 6; - return 0; /* nothing to read */ - } else if ((read_amount >= 8) && (strncmp((char *)((uint32_t) data + read_amount - 8), "\r\nOK\r\n> ", 8)) == 0) { - /* bypass ""\r\nOK\r\n> " if present at the end of the chain */ - read_amount -= 8; - } else { - debug_if(_ism_debug, "\tISM43362 check_recv_status: ERROR, flushing %d bytes: ", read_amount); - // for (int i = 0; i < read_amount; i++) { - // debug_if(_ism_debug, "%2X ", cleanup[i]); - // } - // debug_if(_ism_debug, "\r\n (ASCII)", cleanup); - cleanup[read_amount] = 0; - debug_if(_ism_debug, "%s\r\n", cleanup); - return -1; /* nothing to read */ - } - - debug_if(_ism_debug, "\tISM43362 check_recv_status: id %d read_amount=%d\r\n", id, read_amount); - return read_amount; -} - -bool ISM43362::close(int id) -{ - if ((id < 0) || (id > 3)) { - debug_if(_ism_debug, "\tISM43362: Wrong socket number\n"); - return false; - } - /* Set connection on this socket */ - debug_if(_ism_debug, "\tISM43362: CLOSE socket id=%d\n", id); - _active_id = id; - if (!(_parser.send("P0=%d", id) && check_response())) { - return false; - } - /* close this socket */ - if (!(_parser.send("P6=0") && check_response())) { - return false; - } - return true; -} - -bool ISM43362::readable() -{ - /* not applicable with SPI api */ - return true; -} - -bool ISM43362::writeable() -{ - /* not applicable with SPI api */ - return true; -} - -void ISM43362::attach(Callback status_cb) -{ - _conn_stat_cb = status_cb; -} - -nsapi_connection_status_t ISM43362::connection_status() const -{ - debug_if(_ism_debug, "\tISM43362: connection_status %d\n", _conn_status); - return _conn_status; -} diff --git a/examples/shell/mbed/wifi-ism43362/ISM43362/ISM43362.h b/examples/shell/mbed/wifi-ism43362/ISM43362/ISM43362.h deleted file mode 100644 index 9bf0e58ef27d8e..00000000000000 --- a/examples/shell/mbed/wifi-ism43362/ISM43362/ISM43362.h +++ /dev/null @@ -1,292 +0,0 @@ -/* ISM43362Interface Example - * Copyright (c) STMicroelectronics 2017 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ISM43362_H -#define ISM43362_H -#include "ATParser.h" - -#define ES_WIFI_MAX_SSID_NAME_SIZE 32 -#define ES_WIFI_MAX_PSWD_NAME_SIZE 32 -#define ES_WIFI_PRODUCT_ID_SIZE 32 -#define ES_WIFI_PRODUCT_NAME_SIZE 32 -#define ES_WIFI_FW_REV_SIZE 16 -#define ES_WIFI_API_REV_SIZE 16 -#define ES_WIFI_STACK_REV_SIZE 16 -#define ES_WIFI_RTOS_REV_SIZE 16 - -// The input range for AT Command 'R1' is 0 to 1200 bytes -// 'R1' Set Read Transport Packet Size (bytes) -#define ES_WIFI_MAX_RX_PACKET_SIZE 1200 -// Module maxume DATA payload for Tx packet is 1460 -#define ES_WIFI_MAX_TX_PACKET_SIZE 1460 -typedef enum ism_security { - ISM_SECURITY_NONE = 0x0, /*!< open access point */ - ISM_SECURITY_WEP = 0x1, /*!< phrase conforms to WEP */ - ISM_SECURITY_WPA = 0x2, /*!< phrase conforms to WPA */ - ISM_SECURITY_WPA2 = 0x3, /*!< phrase conforms to WPA2 */ - ISM_SECURITY_WPA_WPA2 = 0x4, /*!< phrase conforms to WPA/WPA2 */ - ISM_SECURITY_UNKNOWN = 0xFF, /*!< unknown/unsupported security in scan results */ -} ism_security_t; - -extern "C" int32_t ParseNumber(char *ptr, uint8_t *cnt); - -/** ISM43362Interface class. - This is an interface to a ISM43362 radio. - */ -class ISM43362 { -public: - ISM43362(PinName mosi, PinName miso, PinName clk, PinName nss, PinName resetpin, PinName datareadypin, PinName wakeup, bool debug = false); - - /** - * Check firmware version of ISM43362 - * - * @return fw version or null if no version is read - */ - uint32_t get_firmware_version(void); - - /** - * Reset ISM43362 - * - * @return true only if ISM43362 resets successfully - */ - bool reset(void); - - /** - * Enable/Disable DHCP - * - * @param enabled DHCP enabled when true - * @return true only if ISM43362 enables/disables DHCP successfully - */ - bool dhcp(bool enabled); - - /** - * Connect ISM43362 to AP - * - * @param ap the name of the AP - * @param passPhrase the password of AP - * @param ap_sec the security level of network AP - * @return nsapi_error enum - */ - int connect(const char *ap, const char *passPhrase, ism_security_t ap_sec); - - /** - * Disconnect ISM43362 from AP - * - * @return true only if ISM43362 is disconnected successfully - */ - bool disconnect(void); - - /** - * Get the IP address of ISM43362 - * - * @return null-teriminated IP address or null if no IP address is assigned - */ - const char *getIPAddress(void); - - /** - * Get the MAC address of ISM43362 - * - * @return null-terminated MAC address or null if no MAC address is assigned - */ - const char *getMACAddress(void); - - /** Get the local gateway - * - * @return Null-terminated representation of the local gateway - * or null if no network mask has been recieved - */ - const char *getGateway(); - - /** Get the local network mask - * - * @return Null-terminated representation of the local network mask - * or null if no network mask has been recieved - */ - const char *getNetmask(); - - /* Return RSSI for active connection - * - * @return Measured RSSI - */ - int8_t getRSSI(); - - /** - * Check if ISM43362 is conenected - * - * @return true only if the chip has an IP address - */ - bool isConnected(void); - - /** Scan for available networks - * - * @param ap Pointer to allocated array to store discovered AP, or 0 to only count available AP - * @param limit Size of allocated @a res array, or 0 to only count available AP - * @return Number of entries in @a res, or if @a count was 0 number of available networks, negative on error - * see @a nsapi_error - */ - int scan(WiFiAccessPoint *res, unsigned limit); - - /** - * Open a socketed connection - * - * @param type the type of socket to open "UDP" or "TCP" - * @param id id to give the new socket, valid 0-4 - * @param port port to open connection with - * @param addr the IP address of the destination - * @return - * @ NSAPI_ERROR_OK : socket opened successfully - * @ NSAPI_ERROR_PARAMETER : invalid configuration - * @ NSAPI_ERROR_DEVICE_ERROR : - * @ failure interfacing with the network processor - */ - int open(const char *type, int id, const char *addr, int port); - - /** - * Sends data to an open socket - * - * @param id id of socket to send to - * @param data data to be sent - * @param amount amount of data to be sent - max 1024 - * @return true only if data sent successfully - */ - bool send(int id, const void *data, uint32_t amount); - - /** - * Receives data from an open socket - * - * @param id id to receive from - * @param data placeholder for returned information - * @param amount number of bytes to be received - * @return the number of bytes received - */ - int32_t recv(int id, void *data, uint32_t amount); - - /** - * Closes a socket - * - * @param id id of socket to close, valid only 0-4 - * @return true only if socket is closed successfully - */ - bool close(int id); - - /** - * Checks if data is available - */ - bool readable(); - - /** - * Checks if data can be written - */ - bool writeable(); - - /** - * Attach a function to call whenever network state has changed - * - * @param func A pointer to a void function, or 0 to set as none - */ - void attach(Callback func); - - /** - * Check is datas are available to read for a socket - * @param id socket id - * @param data placeholder for returned information - * @param amount size to read for the check - * @return amount of read value, or -1 for errors - */ - int check_recv_status(int id, void *data); - - /** - * Attach a function to call whenever network state has changed - * - * @param obj pointer to the object to call the member function on - * @param method pointer to the member function to call - */ - template - void attach(T *obj, M method) - { - attach(Callback(obj, method)); - } - - /** Get the connection status - * - * @return The connection status according to ConnectionStatusType - */ - nsapi_connection_status_t connection_status() const; - - -private: - BufferedSpi _bufferspi; - ATParser _parser; - DigitalOut _resetpin; - volatile int _active_id; - void print_rx_buff(void); - bool check_response(void); - -#ifdef MBED_CONF_ISM43362_WIFI_COUNTRY_CODE - bool check_country_code(const char *country_code); - char WIFI_module_country_code[5]; -#endif - - struct packet { - struct packet *next; - int id; - uint32_t len; - // data follows - } *_packets, * *_packets_end; - void _packet_handler(); - bool _ism_debug; - - char _ip_buffer[16]; - char _gateway_buffer[16]; - char _netmask_buffer[16]; - char _mac_buffer[18]; - uint32_t _FwVersionId; - - // Connection state reporting - nsapi_connection_status_t _conn_status; - mbed::Callback _conn_stat_cb; - - typedef struct { - char cc[3]; - } COUNTRY_CODE; - - COUNTRY_CODE CountryCodeElevenChannels[12] = {"AS", "CA", "FM", "GU", "KY", "MP", "PR", "TW", - "UM", "US", "VI", "ED" - }; - - COUNTRY_CODE CountryCodeThirteenChannels[127] = {"AE", "AG", "AN", "AR", "AT", "AU", "AW", - "AZ", "BA", "BB", "BD", "BE", "BG", "BH", - "BM", "BN", "BO", "BR", "BS", "BT", "BY", - "CH", "CN", "CL", "CO", "CR", "CU", "CV", - "CY", "CZ", "DE", "DK", "DM", "DO", "EC", - "EE", "EG", "ES", "FI", "FK", "FR", "GB", - "GF", "GG", "GI", "GP", "GR", "GT", "HK", - "HN", "HR", "HT", "HU", "ID", "IE", "IL", - "IM", "IN", "IS", "IT", "JE", "JM", "JO", - "KE", "KI", "KR", "KW", "LA", "LB", "LI", - "LK", "LS", "LT", "LU", "LV", "MA", "MC", - "MK", "MO", "MQ", "MR", "MT", "MU", "MV", - "MW", "MX", "MY", "NG", "NI", "NL", "NO", - "NZ", "OM", "PA", "PE", "PG", "PH", "PK", - "PL", "PM", "PT", "RE", "RO", "RU", "SA", - "SE", "SG", "SI", "SK", "SV", "TH", "TJ", - "TN", "TR", "TT", "TZ", "UA", "UY", "UZ", - "VA", "VE", "VG", "VN", "YT", "ZA", "ZM", - "ED" - }; -}; - -#endif diff --git a/examples/shell/mbed/wifi-ism43362/ISM43362Interface.cpp b/examples/shell/mbed/wifi-ism43362/ISM43362Interface.cpp deleted file mode 100644 index a7e721e7464964..00000000000000 --- a/examples/shell/mbed/wifi-ism43362/ISM43362Interface.cpp +++ /dev/null @@ -1,640 +0,0 @@ -/* ISM43362 implementation of NetworkInterfaceAPI - * Copyright (c) STMicroelectronics 2018 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include "ISM43362Interface.h" -#include "mbed_debug.h" - -#if MBED_CONF_ISM43362_READ_THREAD_STACK_SIZE != 0 -#if MBED_CONF_ISM43362_READ_THREAD_STACK_STATICALLY_ALLOCATED == 1 -static uint8_t ism_wifi_thread_stack[MBED_CONF_ISM43362_READ_THREAD_STACK_SIZE]; -#else -static uint8_t *ism_wifi_thread_stack = NULL; -#endif // MBED_CONF_ISM43362_READ_THREAD_STACK_STATICALLY_ALLOCATED == 1 -#endif // MBED_CONF_ISM43362_READ_THREAD_STACK_SIZE != 0 - -// Product ID,FW Revision,API Revision,Stack Revision,RTOS Revision,CPU Clock,Product Name -#define LATEST_FW_VERSION_NUMBER "C3.5.2.5" // ISM43362-M3G-L44-SPI,C3.5.2.5.STM,v3.5.2,v1.4.0.rc1,v8.2.1,120000000,Inventek eS-WiFi - -// Set 1 to force debug information -#define ism_interface_debug 0 - -#define MIN(a,b) (((a)<(b))?(a):(b)) - -#define ISM43362_WIFI_IF_NAME "is0" - -// ISM43362Interface implementation -ISM43362Interface::ISM43362Interface(bool debug) - : _ism(MBED_CONF_ISM43362_WIFI_MOSI, MBED_CONF_ISM43362_WIFI_MISO, MBED_CONF_ISM43362_WIFI_SCLK, MBED_CONF_ISM43362_WIFI_NSS, MBED_CONF_ISM43362_WIFI_RESET, MBED_CONF_ISM43362_WIFI_DATAREADY, MBED_CONF_ISM43362_WIFI_WAKEUP, debug), -#if MBED_CONF_ISM43362_READ_THREAD_STACK_SIZE != 0 - thread_read_socket(osPriorityNormal, MBED_CONF_ISM43362_READ_THREAD_STACK_SIZE, ism_wifi_thread_stack, "ism43362"), -#endif - _conn_stat(NSAPI_STATUS_DISCONNECTED), - _conn_stat_cb(NULL) -{ - _ism_debug = ism_interface_debug || debug; - memset(_ids, 0, sizeof(_ids)); - memset(_socket_obj, 0, sizeof(_socket_obj)); - _ism.attach(this, &ISM43362Interface::update_conn_state_cb); - memset(_cbs, 0, sizeof(_cbs)); - memset(ap_ssid, 0, sizeof(ap_ssid)); - memset(ap_pass, 0, sizeof(ap_pass)); - ap_sec = ISM_SECURITY_UNKNOWN; - - thread_read_socket.start(callback(this, &ISM43362Interface::socket_check_read)); - - _mutex.lock(); - - // Check all supported firmware versions - _FwVersion = _ism.get_firmware_version(); - - if (!_FwVersion) { - error("ISM43362Interface: ERROR cannot read firmware version\r\n"); - } - - debug_if(_ism_debug, "ISM43362Interface: read_version = %" PRIu32 "\r\n", _FwVersion); - /* FW Revision should be with format "CX.X.X.X" with X as a single digit */ - if ((_FwVersion < 1000) || (_FwVersion > 9999)) { - debug_if(_ism_debug, "ISM43362Interface: read_version issue\r\n"); - } - -#if !TARGET_DISCO_F413ZH - if ((int32_t)_FwVersion < ParseNumber((char *)LATEST_FW_VERSION_NUMBER, NULL)) { - debug_if(_ism_debug, "ISM43362Interface: please update FW\r\n"); - } -#endif - - _connect_status = NSAPI_ERROR_NO_CONNECTION; - _mutex.unlock(); -} - -nsapi_error_t ISM43362Interface::connect(const char *ssid, const char *pass, nsapi_security_t security, - uint8_t channel) -{ - if (channel != 0) { - return NSAPI_ERROR_UNSUPPORTED; - } - - nsapi_error_t credentials_status = set_credentials(ssid, pass, security); - if (credentials_status) { - return credentials_status; - } - - return connect(); -} - -nsapi_error_t ISM43362Interface::connect() -{ - if (strlen(ap_ssid) == 0) { - return NSAPI_ERROR_NO_SSID; - } - - _mutex.lock(); - - if (!_ism.dhcp(true)) { - _mutex.unlock(); - return NSAPI_ERROR_DHCP_FAILURE; - } - - _connect_status = _ism.connect(ap_ssid, ap_pass, ap_sec); - debug_if(_ism_debug, "ISM43362Interface: connect_status %d\n", _connect_status); - - if (_connect_status != NSAPI_ERROR_OK) { - _mutex.unlock(); - return _connect_status; - } - - if (!_ism.getIPAddress()) { - _connect_status = NSAPI_ERROR_DHCP_FAILURE; - _mutex.unlock(); - return NSAPI_ERROR_DHCP_FAILURE; - } - - _mutex.unlock(); - - return NSAPI_ERROR_OK; -} - - -int ISM43362Interface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security) -{ - if ((ssid == NULL) || (strlen(ssid) == 0) || (strlen(ssid) > 32)) { - return NSAPI_ERROR_PARAMETER; - } - - if (security != NSAPI_SECURITY_NONE) { - if ((pass == NULL) || (strcmp(pass, "") == 0)) { - return NSAPI_ERROR_PARAMETER; - } - } - - if (strlen(pass) > 63) { - return NSAPI_ERROR_PARAMETER; - } - - _mutex.lock(); - memset(ap_ssid, 0, sizeof(ap_ssid)); - strncpy(ap_ssid, ssid, sizeof(ap_ssid)); - - memset(ap_pass, 0, sizeof(ap_pass)); - strncpy(ap_pass, pass, sizeof(ap_pass)); - - switch (security) { - case NSAPI_SECURITY_NONE: - ap_sec = ISM_SECURITY_NONE; - break; - case NSAPI_SECURITY_WEP: - ap_sec = ISM_SECURITY_WEP; - break; - case NSAPI_SECURITY_WPA: - ap_sec = ISM_SECURITY_WPA; - break; - case NSAPI_SECURITY_WPA2: - ap_sec = ISM_SECURITY_WPA2; - break; - case NSAPI_SECURITY_WPA_WPA2: - ap_sec = ISM_SECURITY_WPA_WPA2; - break; - default: - ap_sec = ISM_SECURITY_UNKNOWN; - break; - } - _mutex.unlock(); - - return NSAPI_ERROR_OK; -} - -int ISM43362Interface::set_channel(uint8_t channel) -{ - return NSAPI_ERROR_UNSUPPORTED; -} - -nsapi_error_t ISM43362Interface::disconnect() -{ - _mutex.lock(); - - if (_connect_status != NSAPI_ERROR_OK) { - _mutex.unlock(); - return NSAPI_ERROR_NO_CONNECTION; - } - - if (!_ism.disconnect()) { - _mutex.unlock(); - return NSAPI_ERROR_DEVICE_ERROR; - } - - _connect_status = NSAPI_ERROR_NO_CONNECTION; - _mutex.unlock(); - return NSAPI_ERROR_OK; -} - -const char *ISM43362Interface::get_ip_address() -{ - _mutex.lock(); - const char *ret = _ism.getIPAddress(); - _mutex.unlock(); - return ret; -} - -nsapi_error_t ISM43362Interface::get_ip_address(SocketAddress *address) -{ - if (!address) { - return NSAPI_ERROR_PARAMETER; - } - _mutex.lock(); - if (address->set_ip_address(_ism.getIPAddress())) { - _mutex.unlock(); - return NSAPI_ERROR_OK; - } - _mutex.unlock(); - return NSAPI_ERROR_NO_ADDRESS; -} - -const char *ISM43362Interface::get_mac_address() -{ - _mutex.lock(); - const char *ret = _ism.getMACAddress(); - _mutex.unlock(); - return ret; -} - -const char *ISM43362Interface::get_gateway() -{ - _mutex.lock(); - const char *ret = _ism.getGateway(); - _mutex.unlock(); - return ret; -} - -nsapi_error_t ISM43362Interface::get_gateway(SocketAddress *address) -{ - if (!address) { - return NSAPI_ERROR_PARAMETER; - } - _mutex.lock(); - if (address->set_ip_address(_ism.getGateway())) { - _mutex.unlock(); - return NSAPI_ERROR_OK; - } - _mutex.unlock(); - return NSAPI_ERROR_NO_ADDRESS; -} - -const char *ISM43362Interface::get_netmask() -{ - _mutex.lock(); - const char *ret = _ism.getNetmask(); - _mutex.unlock(); - return ret; -} - -nsapi_error_t ISM43362Interface::get_netmask(SocketAddress *address) -{ - if (!address) { - return NSAPI_ERROR_PARAMETER; - } - _mutex.lock(); - if (address->set_ip_address(_ism.getNetmask())) { - _mutex.unlock(); - return NSAPI_ERROR_OK; - } - _mutex.unlock(); - return NSAPI_ERROR_NO_ADDRESS; -} - -char *ISM43362Interface::get_interface_name(char *interface_name) -{ - memcpy(interface_name, ISM43362_WIFI_IF_NAME, sizeof(ISM43362_WIFI_IF_NAME)); - return interface_name; -} - -int8_t ISM43362Interface::get_rssi() -{ - _mutex.lock(); - int8_t ret = _ism.getRSSI(); - _mutex.unlock(); - return ret; -} - -int ISM43362Interface::scan(WiFiAccessPoint *res, unsigned count) -{ - _mutex.lock(); - int ret = _ism.scan(res, count); - _mutex.unlock(); - return ret; -} - -struct ISM43362_socket { - int id; - nsapi_protocol_t proto; - volatile bool connected; - SocketAddress addr; - char read_data[1400]; - volatile uint32_t read_data_size; -}; - -int ISM43362Interface::socket_open(void **handle, nsapi_protocol_t proto) -{ - _mutex.lock(); - - // Look for an unused socket - int id = -1; - for (int i = 0; i < ISM43362_SOCKET_COUNT; i++) { - if (!_ids[i]) { - id = i; - _ids[i] = true; - break; - } - } - - if (id == -1) { - _mutex.unlock(); - return NSAPI_ERROR_NO_SOCKET; - } - struct ISM43362_socket *socket = new struct ISM43362_socket; - if (!socket) { - _mutex.unlock(); - return NSAPI_ERROR_NO_SOCKET; - } - socket->id = id; - debug_if(_ism_debug, "ISM43362Interface: socket_open id=%d proto=%d\n", socket->id, proto); - memset(socket->read_data, 0, sizeof(socket->read_data)); - socket->addr = 0; - socket->read_data_size = 0; - socket->proto = proto; - socket->connected = false; - *handle = socket; - _mutex.unlock(); - - return 0; -} - -int ISM43362Interface::socket_close(void *handle) -{ - _mutex.lock(); - struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; - debug_if(_ism_debug, "ISM43362Interface: socket_close, id=%d\n", socket->id); - int err = 0; - - if (!_ism.close(socket->id)) { - err = NSAPI_ERROR_DEVICE_ERROR; - } - - socket->connected = false; - _ids[socket->id] = false; - _socket_obj[socket->id] = 0; - _mutex.unlock(); - delete socket; - return err; -} - -int ISM43362Interface::socket_bind(void *handle, const SocketAddress &address) -{ - return NSAPI_ERROR_UNSUPPORTED; -} - -int ISM43362Interface::socket_listen(void *handle, int backlog) -{ - return NSAPI_ERROR_UNSUPPORTED; -} - -int ISM43362Interface::socket_connect(void *handle, const SocketAddress &addr) -{ - _mutex.lock(); - int ret = socket_connect_nolock(handle, addr); - _mutex.unlock(); - return ret; -} - -int ISM43362Interface::socket_connect_nolock(void *handle, const SocketAddress &addr) -{ - struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; - const char *proto = (socket->proto == NSAPI_UDP) ? "1" : "0"; - if (_ism.open(proto, socket->id, addr.get_ip_address(), addr.get_port()) != NSAPI_ERROR_OK) { - return NSAPI_ERROR_DEVICE_ERROR; - } - _ids[socket->id] = true; - _socket_obj[socket->id] = (uint32_t)socket; - socket->connected = true; - return 0; - -} - - - -void ISM43362Interface::socket_check_read() -{ - while (1) { - for (int i = 0; i < ISM43362_SOCKET_COUNT; i++) { - _mutex.lock(); - if (_socket_obj[i] != 0) { - struct ISM43362_socket *socket = (struct ISM43362_socket *)_socket_obj[i]; - /* Check if there is something to read for this socket. But if it */ - /* has already been read : don't read again */ - if ((socket->connected) && (socket->read_data_size == 0) && _cbs[socket->id].callback) { - /* if no callback is set, no need to read ?*/ - // debug_if(_ism_debug, "ISM43362Interface socket_check_read: i %d\r\n", i); - int read_amount = _ism.check_recv_status(socket->id, socket->read_data); - if (read_amount > 0) { - socket->read_data_size = read_amount; - debug_if(_ism_debug, "ISM43362Interface socket_check_read read_amount %d\r\n", read_amount); - } else if (read_amount < 0) { - /* Mark donw connection has been lost or closed */ - debug_if(_ism_debug, "ISM43362Interface socket_check_read: i %d closed\r\n", i); - socket->connected = false; - } - if (read_amount != 0) { - /* There is something to read in this socket*/ - if (_cbs[socket->id].callback) { - _cbs[socket->id].callback(_cbs[socket->id].data); - } - } - } - } - _mutex.unlock(); - } - rtos::ThisThread::sleep_for(50); - } -} - -int ISM43362Interface::socket_accept(void *server, void **socket, SocketAddress *addr) -{ - return NSAPI_ERROR_UNSUPPORTED; -} - -int ISM43362Interface::socket_send(void *handle, const void *data, unsigned size) -{ - _mutex.lock(); - int ret = socket_send_nolock(handle, data, size); - _mutex.unlock(); - return ret; -} - -/* CAREFULL LOCK must be taken before callling this function */ -int ISM43362Interface::socket_send_nolock(void *handle, const void *data, unsigned size) -{ - struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; - - debug_if(_ism_debug, "ISM43362Interface socket_send_nolock id %d size %u\r\n", socket->id, size); - - if (size > ES_WIFI_MAX_TX_PACKET_SIZE) { - size = ES_WIFI_MAX_TX_PACKET_SIZE; - } - - if (!_ism.send(socket->id, data, size)) { - debug_if(_ism_debug, "ISM43362Interface: socket_send_nolock ERROR\r\n"); - return NSAPI_ERROR_DEVICE_ERROR; - } - - return size; -} - -int ISM43362Interface::socket_recv(void *handle, void *data, unsigned size) -{ - _mutex.lock(); - unsigned recv = 0; - struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; - char *ptr = (char *)data; - - // debug_if(_ism_debug, "ISM43362Interface socket_recv: req=%d read_data_size=%d connected %d\r\n", size, socket->read_data_size, socket->connected); - - if (!socket->connected) { - _mutex.unlock(); - if (socket->proto == NSAPI_UDP) { - return NSAPI_ERROR_WOULD_BLOCK; - } - return 0; - } - - if (socket->read_data_size == 0) { - /* if no callback is set, no need to read ?*/ - int read_amount = _ism.check_recv_status(socket->id, socket->read_data); - if (read_amount > 0) { - socket->read_data_size = read_amount; - } else if (read_amount < 0) { - socket->connected = false; - debug_if(_ism_debug, "ISM43362Interface socket_recv: socket closed\r\n"); - _mutex.unlock(); - return 0; - } - } - - if (socket->read_data_size != 0) { - // debug_if(_ism_debug, "ISM43362Interface socket_recv: read_data_size=%d\r\n", socket->read_data_size); - uint32_t i = 0; - while ((i < socket->read_data_size) && (i < size)) { - *ptr++ = socket->read_data[i]; - i++; - } - - recv += i; - - if (i >= socket->read_data_size) { - /* All the storeed data has been read, reset buffer */ - memset(socket->read_data, 0, sizeof(socket->read_data)); - socket->read_data_size = 0; - // debug_if(_ism_debug, "ISM43362Interface: Socket_recv buffer reset\r\n"); - } else { - /* In case there is remaining data in buffer, update socket content - * For now by shift copy of all data (not very efficient to be - * revised */ - while (i < socket->read_data_size) { - socket->read_data[i - size] = socket->read_data[i]; - i++; - } - - socket->read_data_size -= size; - } - } - // else { - // debug_if(_ism_debug, "ISM43362Interface socket_recv: Nothing in buffer\r\n"); - // } - - _mutex.unlock(); - - if (recv > 0) { - debug_if(_ism_debug, "ISM43362Interface socket_recv: recv=%d\r\n", recv); - return recv; - } else { - // debug_if(_ism_debug, "ISM43362Interface socket_recv: returns WOULD BLOCK\r\n"); - return NSAPI_ERROR_WOULD_BLOCK; - } -} - -int ISM43362Interface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size) -{ - _mutex.lock(); - struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; - - if (socket->connected && socket->addr != addr) { - if (!_ism.close(socket->id)) { - debug_if(_ism_debug, "ISM43362Interface: socket_sendto ERROR\r\n"); - _mutex.unlock(); - return NSAPI_ERROR_DEVICE_ERROR; - } - socket->connected = false; - _ids[socket->id] = false; - _socket_obj[socket->id] = 0; - } - - if (!socket->connected) { - int err = socket_connect_nolock(socket, addr); - if (err < 0) { - _mutex.unlock(); - return err; - } - socket->addr = addr; - } - - int ret = socket_send_nolock(socket, data, size); - - _mutex.unlock(); - - return ret; -} - -int ISM43362Interface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size) -{ - int ret = socket_recv(handle, data, size); - _mutex.lock(); - if ((ret >= 0) && addr) { - struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; - *addr = socket->addr; - } - _mutex.unlock(); - return ret; -} - -void ISM43362Interface::socket_attach(void *handle, void (*cb)(void *), void *data) -{ - _mutex.lock(); - struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; - debug_if(_ism_debug, "ISM43362Interface: socket_attach id %d\n", socket->id); - _cbs[socket->id].callback = cb; - _cbs[socket->id].data = data; - _mutex.unlock(); -} - -void ISM43362Interface::event() -{ - debug_if(_ism_debug, "ISM43362Interface: event\n"); - for (int i = 0; i < ISM43362_SOCKET_COUNT; i++) { - if (_cbs[i].callback) { - _cbs[i].callback(_cbs[i].data); - } - } -} - -void ISM43362Interface::attach(Callback status_cb) -{ - debug_if(_ism_debug, "ISM43362Interface: attach\n"); - _conn_stat_cb = status_cb; -} - -nsapi_connection_status_t ISM43362Interface::get_connection_status() const -{ - debug_if(_ism_debug, "ISM43362Interface: get_connection_status %d\n", _conn_stat); - return _conn_stat; -} - - -void ISM43362Interface::update_conn_state_cb() -{ - nsapi_connection_status_t prev_stat = _conn_stat; - _conn_stat = _ism.connection_status(); - debug_if(_ism_debug, "ISM43362Interface: update_conn_state_cb %d -> %d\n", prev_stat, _conn_stat); - - if (prev_stat == _conn_stat) { - return; - } - - // Inform upper layers - if (_conn_stat_cb) { - _conn_stat_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, _conn_stat); - } -} - - -#if MBED_CONF_ISM43362_PROVIDE_DEFAULT - -WiFiInterface *WiFiInterface::get_default_instance() -{ - static ISM43362Interface ism; - return &ism; -} - -#endif diff --git a/examples/shell/mbed/wifi-ism43362/ISM43362Interface.h b/examples/shell/mbed/wifi-ism43362/ISM43362Interface.h deleted file mode 100644 index f0f2e146ed079a..00000000000000 --- a/examples/shell/mbed/wifi-ism43362/ISM43362Interface.h +++ /dev/null @@ -1,296 +0,0 @@ -/* ISM43362 implementation of NetworkInterfaceAPI - * Copyright (c) STMicroelectronics 2017 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ISM43362_INTERFACE_H -#define ISM43362_INTERFACE_H - -#include "mbed.h" -#include "ISM43362.h" - - -#define ISM43362_SOCKET_COUNT 4 - -/** ISM43362Interface class - * Implementation of the NetworkStack for the ISM43362 - */ -class ISM43362Interface : public NetworkStack, public WiFiInterface { -public: - /** ISM43362Interface lifetime - * @param debug Enable debugging - */ - ISM43362Interface(bool debug = MBED_CONF_ISM43362_WIFI_DEBUG); - - /** Start the interface - * - * Attempts to connect to a WiFi network. Requires ssid and passphrase to be set. - * If passphrase is invalid, NSAPI_ERROR_AUTH_ERROR is returned. - * - * @return 0 on success, negative error code on failure - */ - virtual nsapi_error_t connect(); - - /** Start the interface - * - * Attempts to connect to a WiFi network. - * - * @param ssid Name of the network to connect to - * @param pass Security passphrase to connect to the network - * @param security Type of encryption for connection (Default: NSAPI_SECURITY_NONE) - * @param channel This parameter is not supported, setting it to anything else than 0 will result in NSAPI_ERROR_UNSUPPORTED - * @return 0 on success, or error code on failure - */ - virtual nsapi_error_t connect(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE, - uint8_t channel = 0); - - /** Set the WiFi network credentials - * - * @param ssid Name of the network to connect to - * @param pass Security passphrase to connect to the network - * @param security Type of encryption for connection - * (defaults to NSAPI_SECURITY_NONE) - * @return 0 on success, or error code on failure - */ - virtual int set_credentials(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE); - - /** Set the WiFi network channel - NOT SUPPORTED - * - * This function is not supported and will return NSAPI_ERROR_UNSUPPORTED - * - * @param channel Channel on which the connection is to be made, or 0 for any (Default: 0) - * @return Not supported, returns NSAPI_ERROR_UNSUPPORTED - */ - virtual int set_channel(uint8_t channel); - - /** Stop the interface - * @return 0 on success, negative on failure - */ - virtual nsapi_error_t disconnect(); - - /** Get the internally stored IP address - * @return IP address of the interface or null if not yet connected - */ - virtual const char *get_ip_address(); - - virtual nsapi_error_t get_ip_address(SocketAddress *address); - - /** Get the internally stored MAC address - * @return MAC address of the interface - */ - virtual const char *get_mac_address(); - - /** Get the local gateway - * - * @return Null-terminated representation of the local gateway - * or null if no network mask has been recieved - */ - virtual const char *get_gateway(); - - virtual nsapi_error_t get_gateway(SocketAddress *address); - - /** Get the local network mask - * - * @return Null-terminated representation of the local network mask - * or null if no network mask has been recieved - */ - virtual const char *get_netmask(); - - virtual nsapi_error_t get_netmask(SocketAddress *address); - - /** Get the network interface name - * - * @return Null-terminated representation of the network interface name - * or null if interface not exists - */ - virtual char *get_interface_name(char *interface_name); - - /** Gets the current radio signal strength for active connection - * - * @return Connection strength in dBm (negative value) - */ - virtual int8_t get_rssi(); - - /** Scan for available networks - * - * This function will block. - * - * @param ap Pointer to allocated array to store discovered AP - * @param count Size of allocated @a res array, or 0 to only count available AP - * @return Number of entries in @a, or if @a count was 0 number of available networks, negative on error - * see @a nsapi_error - */ - virtual int scan(WiFiAccessPoint *res, unsigned count); - - /** Register callback for status reporting - * - * The specified status callback function will be called on status changes - * on the network. The parameters on the callback are the event type and - * event-type dependent reason parameter. - * - * @param status_cb The callback for status changes - */ - virtual void attach(mbed::Callback status_cb); - - /** Get the connection status - * - * @return The connection status according to ConnectionStatusType - */ - virtual nsapi_connection_status_t get_connection_status() const; - -protected: - /** Open a socket - * @param handle Handle in which to store new socket - * @param proto Type of socket to open, NSAPI_TCP or NSAPI_UDP - * @return 0 on success, negative on failure - */ - virtual int socket_open(void **handle, nsapi_protocol_t proto); - - /** Close the socket - * @param handle Socket handle - * @return 0 on success, negative on failure - * @note On failure, any memory associated with the socket must still - * be cleaned up - */ - virtual int socket_close(void *handle); - - /** Bind a server socket to a specific port - * @param handle Socket handle - * @param address Local address to listen for incoming connections on - * @return 0 on success, negative on failure. - */ - virtual int socket_bind(void *handle, const SocketAddress &address); - - /** Start listening for incoming connections - * @param handle Socket handle - * @param backlog Number of pending connections that can be queued up at any - * one time [Default: 1] - * @return 0 on success, negative on failure - */ - virtual int socket_listen(void *handle, int backlog); - - /** Connects this TCP socket to the server - * @param handle Socket handle - * @param address SocketAddress to connect to - * @return 0 on success, negative on failure - */ - virtual int socket_connect(void *handle, const SocketAddress &address); - - /** Accept a new connection. - * @param handle Handle in which to store new socket - * @param server Socket handle to server to accept from - * @return 0 on success, negative on failure - * @note This call is not-blocking, if this call would block, must - * immediately return NSAPI_ERROR_WOULD_WAIT - */ - virtual int socket_accept(void *handle, void **socket, SocketAddress *address); - - /** Send data to the remote host - * @param handle Socket handle - * @param data The buffer to send to the host - * @param size The length of the buffer to send - * @return Number of written bytes on success, negative on failure - * @note This call is not-blocking, if this call would block, must - * immediately return NSAPI_ERROR_WOULD_WAIT - */ - virtual int socket_send(void *handle, const void *data, unsigned size); - - /** Receive data from the remote host - * @param handle Socket handle - * @param data The buffer in which to store the data received from the host - * @param size The maximum length of the buffer - * @return Number of received bytes on success, negative on failure - * @note This call is not-blocking, if this call would block, must - * immediately return NSAPI_ERROR_WOULD_WAIT - */ - virtual int socket_recv(void *handle, void *data, unsigned size); - - /** Send a packet to a remote endpoint - * @param handle Socket handle - * @param address The remote SocketAddress - * @param data The packet to be sent - * @param size The length of the packet to be sent - * @return The number of written bytes on success, negative on failure - * @note This call is not-blocking, if this call would block, must - * immediately return NSAPI_ERROR_WOULD_WAIT - */ - virtual int socket_sendto(void *handle, const SocketAddress &address, const void *data, unsigned size); - - /** Receive a packet from a remote endpoint - * @param handle Socket handle - * @param address Destination for the remote SocketAddress or null - * @param buffer The buffer for storing the incoming packet data - * If a packet is too long to fit in the supplied buffer, - * excess bytes are discarded - * @param size The length of the buffer - * @return The number of received bytes on success, negative on failure - * @note This call is not-blocking, if this call would block, must - * immediately return NSAPI_ERROR_WOULD_WAIT - */ - virtual int socket_recvfrom(void *handle, SocketAddress *address, void *buffer, unsigned size); - - /** Register a callback on state change of the socket - * @param handle Socket handle - * @param callback Function to call on state change - * @param data Argument to pass to callback - * @note Callback may be called in an interrupt context. - */ - virtual void socket_attach(void *handle, void (*callback)(void *), void *data); - - /** Provide access to the NetworkStack object - * - * @return The underlying NetworkStack object - */ - virtual NetworkStack *get_stack() - { - return this; - } - -private: - ISM43362 _ism; - bool _ids[ISM43362_SOCKET_COUNT]; - uint32_t _socket_obj[ISM43362_SOCKET_COUNT]; // store addresses of socket handles - Mutex _mutex; - Thread thread_read_socket; - char ap_ssid[33]; /* 32 is what 802.11 defines as longest possible name; +1 for the \0 */ - ism_security_t ap_sec; - uint8_t ap_ch; - char ap_pass[64]; /* The longest allowed passphrase */ - nsapi_error_t _connect_status ; - - bool _ism_debug; - uint32_t _FwVersion; - - void event(); - struct { - void (*callback)(void *); - void *data; - } _cbs[ISM43362_SOCKET_COUNT]; - - /** Function called by the socket read thread to check if data is available on the wifi module - * - */ - virtual void socket_check_read(); - int socket_send_nolock(void *handle, const void *data, unsigned size); - int socket_connect_nolock(void *handle, const SocketAddress &addr); - - // Connection state reporting to application - void update_conn_state_cb(); - nsapi_connection_status_t _conn_stat; - mbed::Callback _conn_stat_cb; - - -}; - -#endif diff --git a/examples/shell/mbed/wifi-ism43362/README.md b/examples/shell/mbed/wifi-ism43362/README.md deleted file mode 100644 index 05ec15c5073e0c..00000000000000 --- a/examples/shell/mbed/wifi-ism43362/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# ISM43362 WiFi driver for mbed-os - -The mbed OS driver for the ISM43362 WiFi module - -https://www.inventeksys.com/ism4336-m3g-l44-e-embedded-serial-to-wifi-module/ - - -## Currently supported platforms - -ISM43362 module is soldered on the following platforms from STMicroelectronics - - * [DISCO_L475VG_IOT01A](https://os.mbed.com/platforms/ST-Discovery-L475E-IOT01A/) - * [DISCO_F413ZH](https://os.mbed.com/platforms/ST-Discovery-F413H/) - * [B_L4S5I_IOT01A](https://os.mbed.com/platforms/B-L4S5I-IOT01A/) - -## Configuration - -Correct pins have already been configured for both supported platforms. - -Here is configured pins: - -- MBED_CONF_ISM43362_WIFI_MISO : spi-miso pin for the ism43362 connection -- MBED_CONF_ISM43362_WIFI_MOSI : spi-mosi pin for the ism43362 connection -- MBED_CONF_ISM43362_WIFI_SPI_SCLK : spi-clock pin for the ism43362 connection -- MBED_CONF_ISM43362_WIFI_SPI_NSS : spi-nss pin for the ism43362 connection -- MBED_CONF_ISM43362_WIFI_RESET : Reset pin for the ism43362 wifi module -- MBED_CONF_ISM43362_WIFI_DATAREADY : Data Ready pin for the ism43362 wifi module -- MBED_CONF_ISM43362_WIFI_WAKEUP : Wakeup pin for the ism43362 wifi module - -## Debug - -Some debug print on console can help to debug if necessary. - -- in ISM43362Interface.cpp file, set ism_interface_debug to 1 -- in ISM43362/ISM43362.cpp file, set ism_debug to 1 -- in ISM43362/ATParser/ATParser.cpp file, there are 3 different level : dbg_on / AT_DATA_PRINT / AT_COMMAND_PRINT - -Another way to enable these prints is overwrite MBED_CONF_ISM43362_WIFI_DEBUG in your json file: - "ism43362.wifi-debug": true - -## Options - -Country code can be specified by using the "ism43362.wifi-country-code" parameter of mbed_app.json. - -The default country code = US (USA) - -Link between code and country is here : -https://www.juniper.net/documentation/en_US/release-independent/junos/topics/reference/specifications/access-point-ax411-country-channel-support.html - -Useful to use all the Radio Channels available in a country. - - -## Firmware version & firmware update - -The recommended firmware version is ISM43362-M3G-L44-SPI-C3.5.2.5.STM - -The utility to upgrade firmware on B-L475-IOT01A and B_L4S5I_IOT01A boards can be found here: https://www.st.com/resource/en/utilities/inventek_fw_updater.zip - -It contains instructions and URL where to get firmware from (https://www.inventeksys.com/iwin/firmware/) - -Note that only Wifi module from DISCO_F413ZH cannot be updated (HW limitation). diff --git a/examples/shell/mbed/wifi-ism43362/mbed_lib.json b/examples/shell/mbed/wifi-ism43362/mbed_lib.json deleted file mode 100644 index 06f4c5f42dbac6..00000000000000 --- a/examples/shell/mbed/wifi-ism43362/mbed_lib.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "name": "ism43362", - "config": { - "wifi-country-code": { - "help": "Country Code to specify channel number" - }, - "wifi-miso": { - "help": "SPI-MISO connection to external device", - "value": "NC" - }, - "wifi-mosi": { - "help": "SPI-MOSI connection to external device", - "value": "NC" - }, - "wifi-sclk": { - "help": "SPI-CLOCK connection to external device", - "value": "NC" - }, - "wifi-nss": { - "help": "SPI chip select of external device", - "value": "NC" - }, - "wifi-reset": { - "help": "ISM43362 reset", - "value": "NC" - }, - "wifi-dataready": { - "help": "ISM43362 dataready", - "value": "NC" - }, - "wifi-wakeup": { - "help": "ISM43362 wakeup", - "value": "NC" - }, - "wifi-debug": { - "help": "Defines whether logging is on or off", - "value": false - }, - "provide-default": { - "help": "Provide default WifiInterface. [true/false]", - "value": false - }, - "read-thread-stack-size": { - "help": "Stack size of the read thread, defaults to MBED_CONF_APP_THREAD_STACK_SIZE or MBED_CONF_RTOS_THREAD_STACK_SIZE (default: 4096)", - "value": null - }, - "read-thread-stack-statically-allocated": { - "help": "Whether to statically allocate the memory for the read thread stack. Requires 'read-thread-stack-size' to be set.", - "value": false - } - }, - "target_overrides": { - "DISCO_F413ZH": { - "ism43362.wifi-miso": "PB_4", - "ism43362.wifi-mosi": "PB_5", - "ism43362.wifi-sclk": "PB_12", - "ism43362.wifi-nss": "PG_11", - "ism43362.wifi-reset": "PH_1", - "ism43362.wifi-dataready": "PG_12", - "ism43362.wifi-wakeup": "PB_15", - "ism43362.provide-default": true - }, - "DISCO_L475VG_IOT01A": { - "ism43362.wifi-miso": "PC_11", - "ism43362.wifi-mosi": "PC_12", - "ism43362.wifi-sclk": "PC_10", - "ism43362.wifi-nss": "PE_0", - "ism43362.wifi-reset": "PE_8", - "ism43362.wifi-dataready": "PE_1", - "ism43362.wifi-wakeup": "PB_13", - "ism43362.provide-default": true - }, - "B_L4S5I_IOT01A": { - "ism43362.wifi-miso": "PC_11", - "ism43362.wifi-mosi": "PC_12", - "ism43362.wifi-sclk": "PC_10", - "ism43362.wifi-nss": "PE_0", - "ism43362.wifi-reset": "PE_8", - "ism43362.wifi-dataready": "PE_1", - "ism43362.wifi-wakeup": "PB_13", - "ism43362.provide-default": true - } - } -}