Jim Flynn
/
aws-iot-device-sdk-mbed-c
Changes to enabled on-line compiler
platform/ezconnect/wnc14a2a-driver/WNC14A2AInterface/WNC14A2AInterface.h
- Committer:
- JMF
- Date:
- 2018-05-30
- Revision:
- 0:082731ede69f
File content as of revision 0:082731ede69f:
/** * copyright (c) 2017-2018, James Flynn * 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. */ /** * @file WNC14A2AInterface.h * @brief Implements a standard NetworkInterface class for use with WNC M14A2A * data module. * * @author James Flynn * * @date 1-Feb-2018 * */ #ifndef WNC14A2A_INTERFACE_H #define WNC14A2A_INTERFACE_H #include <stdint.h> #include "mbed.h" #include "Callback.h" #include "WNCDebug.h" #include "WncControllerK64F/WncControllerK64F.h" #define WNC14A2A_SOCKET_COUNT WncController::MAX_NUM_WNC_SOCKETS // If target board does not support Arduino pins, define pins as Not Connected #if defined(TARGET_FF_ARDUINO) #if !defined(MBED_CONF_WNC14A2A_LIBRARY_WNC_RX_BOOT_SEL) #define MBED_CONF_WNC14A2A_LIBRARY_WNC_RX_BOOT_SEL D1 #endif #if !defined(MBED_CONF_WNC14A2A_LIBRARY_WNC_POWER_ON) #define MBED_CONF_WNC14A2A_LIBRARY_WNC_POWER_ON D2 #endif #if !defined(MBED_CONF_WNC14A2A_LIBRARY_WNC_WAKEUP) #define MBED_CONF_WNC14A2A_LIBRARY_WNC_WAKEUP D6 #endif #if !defined(MBED_CONF_WNC14A2A_LIBRARY_WNC_RESET) #define MBED_CONF_WNC14A2A_LIBRARY_WNC_RESET D8 #endif #if !defined(MBED_CONF_WNC14A2A_LIBRARY_WNC_LVLTRANSLATOR) #define MBED_CONF_WNC14A2A_LIBRARY_WNC_LVLTRANSLATOR D9 #endif #if !defined(MBED_CONF_WNC14A2A_LIBRARY_WNC_CTS) #define MBED_CONF_WNC14A2A_LIBRARY_WNC_CTS D10 #endif #if !defined(MBED_CONF_WNC14A2A_LIBRARY_WNC_RXD) #define MBED_CONF_WNC14A2A_LIBRARY_WNC_RXD D11 #endif #if !defined(MBED_CONF_WNC14A2A_LIBRARY_WNC_TXD) #define MBED_CONF_WNC14A2A_LIBRARY_WNC_TXD D12 #endif #else // !defined(TARGET_FF_ARDUINO) #define MBED_CONF_WNC14A2A_LIBRARY_WNC_RX_BOOT_SEL NC #define MBED_CONF_WNC14A2A_LIBRARY_WNC_POWER_ON NC #define MBED_CONF_WNC14A2A_LIBRARY_WNC_WAKEUP NC #define MBED_CONF_WNC14A2A_LIBRARY_WNC_RESET NC #define MBED_CONF_WNC14A2A_LIBRARY_WNC_LVLTRANSLATOR NC #define MBED_CONF_WNC14A2A_LIBRARY_WNC_CTS NC #define MBED_CONF_WNC14A2A_LIBRARY_WNC_RXD NC #define MBED_CONF_WNC14A2A_LIBRARY_WNC_TXD NC #endif // !defined(TARGET_FF_ARDUINO) typedef struct smsmsg_t { string number; string date; string time; string msg; } IOTSMS; typedef struct socket_t { int socket; //index of this socket string url; SocketAddress addr; //address info for this socket bool opened; //is the socket opened bool connected; //is the socket connected int proto; //this is a TCP or UDP socket void (*_callback)(void*); //callback used with attach void *_cb_data; //callback data to be returned } WNCSOCKET; typedef struct rx_event_t { int m_rx_wnc_state; //state of the socket receive int m_rx_socket; //which socket is being rcvd on uint8_t *m_rx_dptr; //pointer to the users data buffer uint32_t m_rx_req_size; //Requested number of bytes to receive uint32_t m_rx_total_cnt; //Total number of bytes received int m_rx_timer; //Rx Timeout Timer int m_rx_disTO; //Flag to disable Timeout Timer void (*m_rx_callback)(void*); //callback used with attach void *m_rx_cb_data; //callback data to be returned uint32_t m_rx_return_cnt; //number of bytes the Event Queue is returning } RXEVENT; typedef struct tx_event_t { // Transmit Interrupt simulation to enabled non-blocking operation int m_tx_wnc_state; int m_tx_socket; uint8_t *m_tx_dptr; unsigned m_tx_orig_size; uint32_t m_tx_req_size; uint32_t m_tx_total_sent; void (*m_tx_callback)(void*); void *m_tx_cb_data; } TXEVENT; #define WNC_DEBUG 0 //1=enable the WNC startup debug output //0=disable the WNC startup debug output #define STOP_ON_FE 1 //1=hang forever if a fatal error occurs //0=simply return failed response for all socket calls #define DISPLAY_FE 1 //1 to display the fatal error when it occurs //0 to NOT display the fatal error #define RESETON_FE 0 //1 to cause the MCU to reset on fatal error //0 to NOT reset the MCU #define APN_DEFAULT "m2m.com.attz" /** Error Handling macros & data * @brief The macros CHK_WNCFE is used to check if a fatal error has occured. If it has * then execute the action specified: fail, void, null, resume * * CHK_WNCFE( condition-to-check, fail|void|null|resume ) * * 'fail' if you want FATAL_WNC_ERROR to be called. * 'void' if you want to execute a void return * 'null' if you want to execute a null return * 'resume' if you simply want to resume program execution * * There are several settings that control how FATAL_WNC_ERROR behaves: * 1) RESETON_FE determines if the system will reset or hang. * 2) DISPLAY_FE determine if an error message is generated or not * * The DISPLAY_FE setting determines if a failure message is displayed. * If set to 1, user sees this messageo: * * WNC FAILED @ source-file-name:source-file-line-number * * if not set, nothing is displayed. */ #define FATAL_FLAG WncController::WNC_NO_RESPONSE #define WNC_GOOD WncController::WNC_ON #define RETfail return -1 #define RETvoid return #define RETnull return NULL #define RETresume #define DORET(x) RET##x #define TOSTR(x) #x #define INTSTR(x) TOSTR(x) #define FATAL_STR (char*)(__FILE__ ":" INTSTR(__LINE__)) #if RESETON_FE == 1 //reset on fatal error #define MCURESET ((*((volatile unsigned long *)0xE000ED0CU))=(unsigned long)((0x5fa<<16) | 0x04L)) #define RSTMSG "RESET MCU! " #else #define MCURESET #define RSTMSG "" #endif #if DISPLAY_FE == 1 //display fatal error message #define PFE {if(_debugUart)_debugUart->printf((char*)RSTMSG "\r\n>>WNC FAILED @ %s\r\n", FATAL_STR);} #else #define PFE #endif #if STOP_ON_FE == 1 //halt cpu on fatal error #define FATAL_WNC_ERROR(v) {_fatal_err_loc=FATAL_STR;PFE;MCURESET;while(1);} #else #define FATAL_WNC_ERROR(v) {_fatal_err_loc=FATAL_STR;PFE;DORET(v);} #endif #define CHK_WNCFE(x,y) if( x ){FATAL_WNC_ERROR(y);} #define FIRMWARE_REV(x) (((WNC14A2AInterface*)x)->getWNCRev()) #define DBGMSG_DRV 0x04 #define DBGMSG_EQ 0x08 #define DBGMSG_SMS 0x10 #define DBGMSG_ARRY 0x20 #define MAX_SMS_MSGS 3 using namespace WncController_fk; /** WNC14A2AInterface class * Implementation of the NetworkInterface for WNC14A2A */ class WNC14A2AInterface : public NetworkStack, public NetworkInterface { public: /** WNC14A2AInterface Constructor. * @param optionally include a pointer to WNCDEBUG object for * debug information to be displayed. */ WNC14A2AInterface(WNCDebug *_dbgUart = NULL); virtual ~WNC14A2AInterface(); /** Set the cellular network credentials * * @param apn Optional, APN of network * @param user Optional, username --not used-- * @param pass Optional, password --not used-- * @return nsapi_error_t */ virtual nsapi_error_t set_credentials(const char *apn = 0, const char *username = 0, const char *password = 0); /** Connect to the network * * @param apn Optional, APN of network * @param user Optional, username --not used-- * @param pass Optional, password --not used-- * @return nsapi_error_t */ virtual nsapi_error_t connect(const char *apn, const char *username = 0, const char *password = 0); /** Connect to the network (no parameters) * * @return nsapi_error_t */ virtual nsapi_error_t connect(); /** disconnect from the network * * provided for completness, but function does nothing becase * WNC part can not disconnect from network once connected. * * @return nsapi_error_t */ virtual nsapi_error_t disconnect(); /** Get the IP address of WNC device. From NetworkStack Class * * @return IP address string or null */ virtual const char *get_ip_address(); /** Get the network assigned IP address. * * @return IP address or null */ const char *get_my_ip_address(); /** Get the MAC address of the WNC device. * * @return MAC address of the interface */ virtual const char *get_mac_address(); /** Attach a callback function for when a SMS is recevied * * @param function pointer to call */ void sms_attach(void (*callback)(IOTSMS *)); /** Set the level of Debug output * * @param bit field * basic AT command info= 0x01 * more AT command info = 0x02 * mbed driver info = 0x04 * dump buffers = 0x08 * all debug = 0x0f */ void doDebug(int v); /** Return the WNC reported Firmware Revision * * @param none. */ const char* getWNCRev(void); /** Query registered state of WNC * * @return true if registerd, false if not */ bool registered(); /** Start the SMS monitoring service */ void sms_start(void); /** start listening for incomming SMS messages * * @param time in msec to check */ void sms_listen(uint16_t=1000); // Configure device to listen for text messages /** retrieve a SMS message * * @param pointer to an array of IOTSMS messages */ int getSMS(IOTSMS **msg); /** send a SMS message * * @param a string containing number to send message to * @param a string containing message to send * @return true on success, 0 on failure */ int sendIOTSms(const string&, const string&); /** return this devices SMS number * * @brief The IOTSMS number used, isn't phone number, it is device ICCID. * * @return this devices IOTSMS number */ char* getSMSnbr(); protected: /** Get Host IP by name. * * @return nsapi_error_t */ virtual nsapi_error_t gethostbyname(const char* name, SocketAddress *address, nsapi_version_t version); /** return a pointer to the NetworkStack object * * @return The underlying NetworkStack object */ virtual NetworkStack *get_stack(); /** 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 */ virtual int socket_close(void *handle); /** Bind a server socket to a specific port. * * @brief Bind the socket to a specific port * @param handle Socket handle * @param address address to listen for * @return 0; */ virtual int socket_bind(void *handle, const SocketAddress &address); /** Start listening for incoming connections. * * @brief NOT SUPPORTED * @param handle Socket handle * @param backlog Number of pending connections that can be queued up at any * one time [Default: 1] * @return NSAPI_ERROR_UNSUPPORTED; * @note This function causes the receive time-out to be ignored resulting in continuous * monitoring of received data. This is non-standard behaviour but it is how the * mbed-cloud servcies use it... */ virtual int socket_listen(void *handle, int backlog); /** Accept a new connection. * * @brief NOT SUPPORTED * @return NSAPI_ERROR_UNSUPPORTED; */ virtual int socket_accept(nsapi_socket_t server, nsapi_socket_t *handle, SocketAddress *address=0); /** Connects this socket to the server. * * @param handle Socket handle * @param address SocketAddress * @return 0 on success, negative on failure */ virtual int socket_connect(void *handle, const SocketAddress &address); /** Send data to the remote host. * * @param handle Socket handle * @param data buffer to send * @param size length of buffer * @return Number of bytes written or negative on failure * * @note This call is blocking. */ virtual int socket_send(void *handle, const void *data, unsigned size); /** Receive data from the remote host. * * @param handle Socket handle * @param data buffer to store the recived data * @param size bytes to receive * @return received bytes received, negative on failure * * @note This call is not-blocking */ virtual int socket_recv(void *handle, void *data, unsigned size); /** Send a packet to a remote endpoint. * * @param handle Socket handle * @param address SocketAddress * @param data data to send * @param size number of bytes to send * @return the number of bytes sent or negative on failure * * @note This call is blocking. */ virtual int socket_sendto(void *handle, const SocketAddress &address, const void *data, unsigned size); /** Receive packet remote endpoint * * @param handle Socket handle * @param address SocketAddress * @param buffer buffer to store data to * @param size number of bytes to receive * @return the number bytes received or negative on failure * * @note This call is not-blocking. */ 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); /** get the status of internal errors * * @brief Called after any WNC14A2A operation to determine error specifics * @param none. */ uint16_t wnc14a2a_chk_error(void) { return m_errors; } private: //! WncController Class for interacting with the 14A2a hardware friend class WncControllerK64F; bool m_wncpoweredup; //track if WNC has been power-up unsigned m_debug; WncIpStats myNetStats; //maintaint the network statistics WncControllerK64F_fk::WncControllerK64F *m_pwnc; //pointer to the WncController instance WNCDebug *_debugUart; // Serial object for parser to communicate with radio char *_fatal_err_loc; // holds string containing location of fatal error nsapi_error_t m_errors; bool m_smsmoning; // Track if the SMS monitoring thread is running EventQueue sms_queue; // Queue used to schedule for SMS checks void (*_sms_cb)(IOTSMS *); // Callback when text message is received. User must define this as // a static function because I'm not handling an object offset IOTSMS m_MsgText, m_MsgText_array[MAX_SMS_MSGS]; // Used to pass SMS message to the user struct WncController::WncSmsList m_smsmsgs; //use the WncSmsList structure to hold messages EventQueue wnc_queue; // Queue used to schedule for receiving data void handle_sms_event(); // SMS tx/rx handler void wnc_eq_event(); // Simulated ISR int rx_event(RXEVENT *); // receive data handler int tx_event(TXEVENT *); // tx data handler char _mac_address[NSAPI_MAC_SIZE]; // local Mac void _dbOut(const char *format, ...); void _dbDump_arry( const uint8_t* data, unsigned int size ); WNCSOCKET _sockets[WNC14A2A_SOCKET_COUNT]; //WNC supports 8 open sockets but driver only supports 1 currently TXEVENT _socTxS[WNC14A2A_SOCKET_COUNT]; RXEVENT _socRxS[WNC14A2A_SOCKET_COUNT]; Thread _smsThread, _eqThread; //Event Queue thread for SMS and Rx/Tx data Mutex _pwnc_mutex; int _active_socket; UARTSerial mdmUart; WncIO wnc_io; }; #endif