WNC14A2A LTE Interface
Dependencies: WncControllerK64F
Fork of WNC14A2AInterface by
WNC14A2AInterface.cpp
- Committer:
- gie_design
- Date:
- 2017-09-09
- Revision:
- 9:23587afd52fe
- Parent:
- 7:9340bc9e8d64
File content as of revision 9:23587afd52fe:
#include "WNC14A2AInterface.h" #include <Thread.h> #include <string> /** WNC14A2AInterface class * Implementation of the NetworkInterface for the AT&T IoT Starter Kit * based on the WNC 14A2A LTE Data Module */ #define WNC14A2A_MISC_TIMEOUT 3000 #define WNC14A2A_RESTART_TIMEOUT 10000 #define WNC14A2A_COMMUNICATION_TIMEOUT 100 #define READ_EVERYMS 500 ///////////////////////////////////////////////////// // NXP GPIO Pins that are used to initialize the WNC Shield ///////////////////////////////////////////////////// DigitalOut mdm_uart2_rx_boot_mode_sel(PTC17); // on powerup, 0 = boot mode, 1 = normal boot DigitalOut mdm_power_on(PTB9); // 0 = modem on, 1 = modem off (hold high for >5 seconds to cycle modem) DigitalOut mdm_wakeup_in(PTC2); // 0 = let modem sleep, 1 = keep modem awake -- Note: pulled high on shield DigitalOut mdm_reset(PTC12); // active high DigitalOut shield_3v3_1v8_sig_trans_ena(PTC4); // 0 = disabled (all signals high impedence, 1 = translation active DigitalOut mdm_uart1_cts(PTD0); // Define pin associations for the controller class to use be careful to // keep the order of the pins in the initialization list. using namespace WncControllerK64F_fk; // namespace for the controller class use WncGpioPinListK64F wncPinList = { &mdm_uart2_rx_boot_mode_sel, &mdm_power_on, &mdm_wakeup_in, &mdm_reset, &shield_3v3_1v8_sig_trans_ena, &mdm_uart1_cts }; Thread smsThread; static Mutex _pwnc_mutex; static WNCSOCKET _sockets[WNC14A2A_SOCKET_COUNT]; BufferedSerial mdmUart(PTD3,PTD2,2048,1); //UART for WNC Module //------------------------------------------------------------------------- // // Class constructor. May be invoked with or without the APN and/or pointer // to a debug output. After the constructor has completed, the user can // check _errors to determine if any errors occured during instanciation. // _errors = 0 when no errors occured // 1 when power-on error occured // 2 when settng the APN error occured // 4 when unable to get the network configuration // 8 when allocating a new WncControllerK64F object failed // NSAPI_ERROR_UNSUPPORTED when attempting to create a second object // WNC14A2AInterface::WNC14A2AInterface(WNCDebug *dbg) : m_wncpoweredup(0), _pwnc(NULL), m_active_socket(-1), m_smsmoning(0) { _errors = NSAPI_ERROR_OK; m_debug=false; if( _pwnc ) { //can only have a single instance of class _errors = NSAPI_ERROR_UNSUPPORTED; return; } for( int i=0; i<WNC14A2A_SOCKET_COUNT; i++ ) { _sockets[i].socket = i; _sockets[i].addr = NULL; _sockets[i].opened=false; _sockets[i].proto=NSAPI_TCP; } memset(_mac_address,0x00,sizeof(_mac_address)); _debugUart = dbg; if( dbg != NULL ) { dbg->printf("Adding DEBUG output\n"); _pwnc = new WncControllerK64F(&wncPinList, &mdmUart, dbg); m_debug=true; if( _pwnc ) _pwnc->enableDebug(1,1); } else _pwnc = new WncControllerK64F_fk::WncControllerK64F(&wncPinList, &mdmUart, NULL); if( !_pwnc ) { debugOutput(_debugUart,(char*)", FAILED!\n"); _errors = NSAPI_ERROR_DEVICE_ERROR; } else debugOutput(_debugUart, (char*)"\n"); } /*------------------------------------------------------------------------- * standard destructor... free up allocated memory */ WNC14A2AInterface::~WNC14A2AInterface() { delete _pwnc; //free the existing WncControllerK64F object } nsapi_error_t WNC14A2AInterface::connect() { debugOutput(_debugUart,(char*)"+CALLED connect(void)\n"); return connect(NULL,NULL,NULL); } /*------------------------------------------------------------------------- * This call powers up the WNC module and connects to the user specified APN. If no APN is provided * a default one of 'm2m.com.attz' will be used (the NA APN) * * Input: *apn is the APN string to use * *username - NOT CURRENTLY USED * *password - NOT CURRENTLY USED * * Output: none * * Return: nsapi_error_t */ nsapi_error_t WNC14A2AInterface::connect(const char *apn, const char *username, const char *password) { debugOutput(_debugUart,(char*)"+ENTER connect(apn,user,pass)\n"); if( !_pwnc ) return (_errors=NSAPI_ERROR_NO_CONNECTION); if (!apn) apn = "m2m.com.attz"; if (!m_wncpoweredup) { debugOutput(_debugUart,(char*)"+call powerWncOn using '%s'\n",apn); _pwnc_mutex.lock(); m_wncpoweredup=_pwnc->powerWncOn(apn,40); _pwnc_mutex.unlock(); _errors = m_wncpoweredup? 1:0; } else { //we've already called powerWncOn and set the APN, so just set the APN debugOutput(_debugUart,(char*)"+already powered on, set APN to: %s\n",apn); _pwnc_mutex.lock(); _errors = _pwnc->setApnName(apn)? 1:0; _pwnc_mutex.unlock(); } _pwnc_mutex.lock(); _errors |= _pwnc->getWncNetworkingStats(&myNetStats)? 2:0; _pwnc_mutex.unlock(); debugOutput(_debugUart,(char*)"+EXIT connect %02X\n",_errors); return (!_errors)? NSAPI_ERROR_NO_CONNECTION : NSAPI_ERROR_OK; } /*-------------------------------------------------------------------------- * This function calls the WNC to retrieve the device (this WNC) connected IP * address once we are connected to the APN. * * Inputs: NONE. * * Output: none. * * Return: pointer to the IP string or NULL */ const char *WNC14A2AInterface::get_ip_address() { const char *ptr=NULL; _pwnc_mutex.lock(); if ( _pwnc->getWncNetworkingStats(&myNetStats) ) { CHK_WNCFE(( _pwnc->getWncStatus() == FATAL_FLAG ), null); ptr = &myNetStats.ip[0]; } _pwnc_mutex.unlock(); _errors=NSAPI_ERROR_NO_CONNECTION; return ptr; } #if 0 /*-------------------------------------------------------------------------- * This function calls the WNC to retrieve the currently connected IP address * it will be a bogus 192.168.0.1 if we are not connected to anyone * * Inputs: NONE. * * Output: none. * * Return: pointer to the IP string or NULL */ const char *WNC14A2AInterface::get_ip_address() { static char *ptr=NULL, ipAddrStr[25]; debugOutput(_debugUart,(char*)"+ENTER get_ip_address()\n"); memset(ipAddrStr, 0x00, sizeof(ipAddrStr)); _pwnc_mutex.lock(); if( _pwnc && m_active_socket != -1 ) if( _pwnc->getIpAddr(m_active_socket, ipAddrStr) ) ptr=ipAddrStr; _pwnc_mutex.unlock(); _errors=NSAPI_ERROR_NO_CONNECTION; return ptr; } #endif /* ------------------------------------------------------------------------- * Open a socket for the WNC. This doesn't actually open the socket within * the WNC, it only allocates a socket device and saves the pertinet info * that will be required with the WNC socket is opened. The m_active_socket * is also updated to this socket as it is assumed this socket should be used * for subsequent interactions. * * Input: * - a pointer to a handle pointer. * - The type of socket this will be, either NSAPI_UDP or NSAP_TCP * * Output: *handle is updated * * Return: * - socket being used if successful, -1 on failure */ int WNC14A2AInterface::socket_open(void **handle, nsapi_protocol_t proto) { int i; debugOutput(_debugUart,(char*)"+ENTER socket_open()\n"); // search through the available sockets (WNC can only support a max amount). for( i=0; i<WNC14A2A_SOCKET_COUNT; i++ ) if( !_sockets[i].opened ) break; if( i == WNC14A2A_SOCKET_COUNT ) { _errors=NSAPI_ERROR_NO_SOCKET; return -1; } m_active_socket = i; _sockets[i].socket = i; //save this index to make easier later-on _sockets[i].url=""; _sockets[i].opened = true; //ok, we are using this socket now _sockets[i].addr = NULL; //but we haven't opened it yet _sockets[i].proto = (proto == NSAPI_UDP) ? 0 : 1; //set it up for what WNC wants *handle = &_sockets[i]; debugOutput(_debugUart,(char*)"+USING Socket index %d, OPEN=%s, proto =%d\nEXIT socket_open()\n", i, _sockets[i].opened?"YES":"NO", _sockets[i].proto); _errors = NSAPI_ERROR_OK; return i; } /*------------------------------------------------------------------------- * Connect a socket to a IP/PORT. Before you can connect a socket, you must have opened * it. * * Input: handle - pointer to the socket to use * address- the IP/Port pair that will be used * * Output: none * * return: 0 or greater on success (value is the socket ID) * -1 on failure */ int WNC14A2AInterface::socket_connect(void *handle, const SocketAddress &address) { WNCSOCKET *wnc = (WNCSOCKET *)handle; debugOutput(_debugUart,(char*)"+ENTER socket_connect()\n"); debugOutput(_debugUart,(char*)"+IP = %s\n+PORT= %d\n", address.get_ip_address(), address.get_port()); if (!_pwnc || m_active_socket == -1) { _errors = NSAPI_ERROR_NO_SOCKET; return -1; } if( !wnc->opened ) { _errors = NSAPI_ERROR_NO_SOCKET; return -1; } m_active_socket = wnc->socket; //in case the user is asking for a different socket wnc->addr = address; //we will always connect using the URL if possible, if no url has been provided, try the IP address if( wnc->url.empty() ) { debugOutput(_debugUart,(char*)"+call openSocketIpAddr(%d,%s,%d,%d)\n",m_active_socket, address.get_ip_address(), address.get_port(), wnc->proto); if( !_pwnc->openSocketIpAddr(m_active_socket, address.get_ip_address(), address.get_port(), wnc->proto, WNC14A2A_COMMUNICATION_TIMEOUT) ) { _errors = NSAPI_ERROR_NO_SOCKET; return -1; } } else { debugOutput(_debugUart,(char*)"+call openSocketUrl(%d,%s,%d,%d)\n", m_active_socket, wnc->url.c_str(), wnc->addr.get_port(), wnc->proto); if( !_pwnc->openSocketUrl(m_active_socket, wnc->url.c_str(), wnc->addr.get_port(), wnc->proto) ) { _errors = NSAPI_ERROR_NO_SOCKET; return -1; } } debugOutput(_debugUart,(char*)"+SOCKET %d CONNECTED!\n+URL=%s\n+IP=%s; PORT=%d\n+EXIT socket_connect()\n\n",m_active_socket, wnc->url.c_str(), wnc->addr.get_ip_address(), wnc->addr.get_port()); return 0; } /*------------------------------------------------------------------------- * Perform a URL name resolve, update the IP/Port pair, and nsapi_version. nsapi_version * could be either NSAPI_IPv4 or NSAPI_IPv6 but this functional is hard coded ti NSAPI_IPv4 * for now. The currently active socket is used for the resolution. * * Input: name - the URL to resolve * * Output: address - the IP/PORT pair this URL resolves to * version - always assumed to be NSAPI_IPv4 currently * * Return: nsapi_error_t */ nsapi_error_t WNC14A2AInterface::gethostbyname(const char* name, SocketAddress *address, nsapi_version_t version) { nsapi_error_t ret = NSAPI_ERROR_OK; char ipAddrStr[25]; int t_socket = 0; //use a temporary socket place holder debugOutput(_debugUart,(char*)"+ENTER gethostbyname()()\n+CURRENTLY:\n"); debugOutput(_debugUart,(char*)"+URL = %s\n+IP = %s\n+PORT= %d\n", name, address->get_ip_address(), address->get_port()); memset(ipAddrStr,0x00,sizeof(ipAddrStr)); if (!_pwnc) return (_errors = NSAPI_ERROR_NO_SOCKET); if (m_active_socket != -1) //we might have been called before a socket was opened t_socket = m_active_socket; //if so, do nothing with the active socket index //Execute DNS query. if( !_pwnc->resolveUrl(t_socket, name) ) return (_errors = NSAPI_ERROR_DEVICE_ERROR); //Now, get the IP address that the URL was resolved to if( !_pwnc->getIpAddr(t_socket, ipAddrStr) ) return (_errors = NSAPI_ERROR_DEVICE_ERROR); address->set_ip_address(ipAddrStr); debugOutput(_debugUart,(char*)"+resolveUrl returned IP=%s\n",ipAddrStr); if( t_socket == m_active_socket ) { _sockets[m_active_socket].url=name; _sockets[m_active_socket].addr.set_ip_address(ipAddrStr); } debugOutput(_debugUart,(char*)"+EXIT gethostbyname()\n+URL = %s\n+IP = %s\n+PORT= %d\n\n", _sockets[m_active_socket].url.c_str(), address->get_ip_address(), address->get_port()); _errors = ret; return ret; } /*------------------------------------------------------------------------- * using the specified socket, send the data. * * Input: handle of the socket to use * pointer to the data to send * amount of data being sent * * Output: none * * Return: number of bytes that was sent */ int WNC14A2AInterface::socket_send(void *handle, const void *data, unsigned size) { WNCSOCKET *wnc = (WNCSOCKET *)handle; int r = -1; debugOutput(_debugUart,(char*)"+ENTER socket_send()\n"); if (!_pwnc || m_active_socket == -1) { _errors = NSAPI_ERROR_NO_SOCKET; return 0; } else m_active_socket = wnc->socket; //just in case sending to a socket that wasn't last used debugOutput(_debugUart,(char*)"+SOCKET %d is %s, URL=%s, IP=%s, PORT=%d\n",m_active_socket, (char*)wnc->opened?"OPEN":"CLOSED",wnc->url.c_str(),wnc->addr.get_ip_address(),wnc->addr.get_port()); debugOutput(_debugUart,(char*)"+WRITE [%s] (%d bytes) to socket #%d\n",data,size,wnc->socket); _pwnc_mutex.lock(); if( _pwnc->write(m_active_socket, (const uint8_t*)data, size) ) r = size; else debugOutput(_debugUart,(char*)"+ERROR: write to socket %d failed!\n",m_active_socket); _pwnc_mutex.unlock(); debugOutput(_debugUart,(char*)"+EXIT socket_send(), successful: %d\n\n",r); return r; } /*------------------------------------------------------------------------- * Called to receive data. * * Input: handle to the socket we want to read from * * Output: data we receive is placed into the data buffer * size is the size of the buffer * * Returns: The number of bytes received or -1 if an error occured */ int WNC14A2AInterface::socket_recv(void *handle, void *data, unsigned size) { WNCSOCKET *wnc = (WNCSOCKET *)handle; size_t done, cnt; Timer t; debugOutput(_debugUart,(char*)"+ENTER socket_recv(); read up to %d bytes\n",size); memset(data,0x00,size); if (!_pwnc || m_active_socket == -1) { _errors = NSAPI_ERROR_NO_SOCKET; return -1; } else m_active_socket = wnc->socket; //just in case sending to a socket that wasn't last used t.start(); do { if( !(t.read_ms() % READ_EVERYMS) ) cnt = done = _pwnc->read(m_active_socket, (uint8_t *)data, (uint32_t) size); done = (cnt || (t.read_ms() > WNC14A2A_MISC_TIMEOUT))? 1:0; } while( !done ); t.stop(); if( _pwnc->getWncStatus() != WNC_GOOD ) { _errors = NSAPI_ERROR_DEVICE_ERROR; return -1; } debugOutput(_debugUart,(char*)"+EXIT socket_recv(), ret=%d\n",cnt); return cnt; } /*------------------------------------------------------------------------- * Close a socket * * Input: the handle to the socket to close * * Output: none * * Return: -1 on error, otherwise 0 */ int WNC14A2AInterface::socket_close(void *handle) { WNCSOCKET *wnc = (WNCSOCKET*)handle; debugOutput(_debugUart,(char*)"+CALLED socket_close()\n"); if (!_pwnc || m_active_socket == -1) { _errors = NSAPI_ERROR_NO_SOCKET; return -1; } else m_active_socket = wnc->socket; //just in case sending to a socket that wasn't last used if( !_pwnc->closeSocket(m_active_socket) ) { _errors = NSAPI_ERROR_DEVICE_ERROR; return -1; } wnc->opened = false; //no longer in use wnc->addr = NULL; //not open wnc->proto = 0; //assume TCP for now _errors = NSAPI_ERROR_OK; return 0; } /*------------------------------------------------------------------------- * return the MAC for this device. Because there is no MAC Ethernet * address to return, this function returns a bogus MAC address created * from the ICCD on the SIM that is being used. * * Input: none * * Output: none * * Return: MAC string containing "NN:NN:NN:NN:NN:NN" or NULL */ const char *WNC14A2AInterface::get_mac_address() { string mac, str; debugOutput(_debugUart,(char*)"+ENTER get_mac_address()\n"); if( _pwnc->getICCID(&str) ) { CHK_WNCFE((_pwnc->getWncStatus()==FATAL_FLAG), null); mac = str.substr(3,20); mac[2]=mac[5]=mac[8]=mac[11]=mac[14]=':'; strncpy(_mac_address, mac.c_str(), mac.length()); return _mac_address; } return NULL; } /*------------------------------------------------------------------------- * return a pointer to the current WNC14A2AInterface */ NetworkStack *WNC14A2AInterface::get_stack() { debugOutput(_debugUart,(char*)"+CALLED get_stack()\n"); return this; } /*------------------------------------------------------------------------- * Disconnnect from the 14A2A, but we can not do that * so just return saying everything is ok. */ nsapi_error_t WNC14A2AInterface::disconnect() { debugOutput(_debugUart,(char*)"+CALLED disconnect()\n"); return NSAPI_ERROR_OK; } /*------------------------------------------------------------------------- * allow the user to change the APN. The API takes username and password * but they are not used. * * Input: apn string * username - not used * password - not used * * Output: none * * Return: nsapi_error_t */ nsapi_error_t WNC14A2AInterface::set_credentials(const char *apn, const char *username, const char *password) { debugOutput(_debugUart,(char*)"+ENTER set_credentials()\n"); if( !_pwnc ) return (_errors=NSAPI_ERROR_NO_CONNECTION); if( !apn ) return (_errors=NSAPI_ERROR_PARAMETER); if( !_pwnc->setApnName(apn) ) return (_errors=NSAPI_ERROR_DEVICE_ERROR); return (_errors=NSAPI_ERROR_OK); } /*------------------------------------------------------------------------- * Register a callback on state change of the socket.FROM NetworkStack * @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. */ void WNC14A2AInterface::socket_attach(void *handle, void (*callback)(void *), void *data) { debugOutput(_debugUart,(char*)"+CALLED socket_attach()\n"); } /*------------------------------------------------------------------------- * check to see if we are currently regisered with the network. * * Input: none * * Output: none * * Return: ture if we are registerd, false if not or an error occured */ bool WNC14A2AInterface::registered() { debugOutput(_debugUart,(char*)"+ENTER registered()\n"); if( !_pwnc ) { _errors=NSAPI_ERROR_NO_CONNECTION; return false; } if ( _pwnc->getWncStatus() == WNC_GOOD ){ _errors=NSAPI_ERROR_OK; return true; } _errors=NSAPI_ERROR_NO_CONNECTION; return false; } /*------------------------------------------------------------------------- * doDebug is just a handy way to allow a developer to set different levels * of debug for the WNC14A2A device. * * Input: a Bitfield of - * basic debug = 0x01 * more debug = 0x02 * network debug = 0x04 * all debug = 0x07 * * Output: none * * Returns: void */ void WNC14A2AInterface::doDebug( int v ) { if( !_pwnc ) _errors = NSAPI_ERROR_DEVICE_ERROR; else _pwnc->enableDebug( (v&1), (v&2) ); m_debug=(v&4); debugOutput(_debugUart,(char*)"+SETTING debug flag to 0x%02X\n",v); } /*------------------------------------------------------------------------- * Simple function to allow for writing debug messages. It always * checks to see if debug has been enabled or not before it * outputs the message. * * Input: The debug uart pointer followed by format string and vars * * Output: none * * Return: void */ void WNC14A2AInterface::debugOutput(WNCDebug *dbgOut, char * format, ...) { if( dbgOut && m_debug ) { char buffer[256]; va_list args; va_start (args, format); vsnprintf(buffer, sizeof(buffer), format, args); dbgOut->puts(buffer); va_end (args); } } //////////////////////////////////////////////////////////////////// // UDP methods /////////////////////////////////////////////////////////////////// //------------------------------------------------------------------------- //sends data to a UDP socket int WNC14A2AInterface::socket_sendto(void *handle, const SocketAddress &address, const void *data, unsigned size) { WNCSOCKET *wnc = (WNCSOCKET *)handle; debugOutput(_debugUart,(char*)"+CALLED socket_sendto()\n"); CHK_WNCFE(( _pwnc->getWncStatus() == FATAL_FLAG ), fail); if (!wnc->opened) { int err = socket_connect(wnc, address); if (err < 0) return err; } wnc->addr = address; return socket_send(wnc, data, size); } //receives from a UDP socket int WNC14A2AInterface::socket_recvfrom(void *handle, SocketAddress *address, void *buffer, unsigned size) { WNCSOCKET *wnc = (WNCSOCKET *)handle; debugOutput(_debugUart,(char*)"+CALLED socket_recvfrom()\n"); int ret = socket_recv(wnc, (char *)buffer, size); if (ret >= 0 && address) *address = wnc->addr; return ret; } //////////////////////////////////////////////////////////////////// // SMS methods /////////////////////////////////////////////////////////////////// /*------------------------------------------------------------------------- * IOTSMS message don't use a phone number, they use the device ICCID. This * function returns the ICCID based number that is used for this device. * * Input: none * Output: none * Return: string containing the IOTSMS number to use */ char* WNC14A2AInterface::getSMSnbr( void ) { char * ret=NULL; string iccid_str; static string msisdn_str; if( !_pwnc ) { _errors=NSAPI_ERROR_NO_CONNECTION; return NULL; } CHK_WNCFE(( _pwnc->getWncStatus() == FATAL_FLAG ), null); if( !_pwnc->getICCID(&iccid_str) ) return ret; CHK_WNCFE(( _pwnc->getWncStatus() == FATAL_FLAG ), null); if( _pwnc->convertICCIDtoMSISDN(iccid_str, &msisdn_str) ) ret = (char*)msisdn_str.c_str(); return ret; } /*------------------------------------------------------------------------- * Normally the user attaches his call-back function when performing * the listen call which enables the SMS system, but this function * allows them to update the callback if desired. * * input: pointer to the function to call * output: none * return: none */ void WNC14A2AInterface::sms_attach(void (*callback)(IOTSMS *)) { debugOutput(_debugUart,(char*)"+CALLED sms_attach() called\n"); _sms_cb = callback; } /*------------------------------------------------------------------------- * Call this to start the SMS system. It is needed to reset the WNC * internal data structures related to SMS messaging */ void WNC14A2AInterface::sms_start(void) { _pwnc_mutex.lock(); //delete any message currently in storage _pwnc->deleteSMSTextFromMem('*'); //so we are notified of new incomming messages _pwnc_mutex.unlock(); } /*------------------------------------------------------------------------- * Initialize the IoT SMS system. Initializing it allows the user to set a * polling period to check for SMS messages, and a SMS is recevied, then * a user provided function is called. * * Input: polling period in seconds. If not specified 30 seconds is used. * pointer to a users calllback function * Output: none * * Returns: void */ void WNC14A2AInterface::sms_listen(uint16_t pp) { debugOutput(_debugUart,(char*)"+CALLED sms_listen(%d) called\n",pp); if( !_pwnc ) { _errors=NSAPI_ERROR_NO_CONNECTION; return; } CHK_WNCFE(( _pwnc->getWncStatus() == FATAL_FLAG ), fail); if( m_smsmoning ) m_smsmoning = false; if( pp < 1) pp = 30; debugOutput(_debugUart,(char*)"+setup event queue\n"); smsThread.start(callback(&sms_queue,&EventQueue::dispatch_forever)); _pwnc_mutex.lock(); //delete any message currently in storage _pwnc->deleteSMSTextFromMem('*'); //so we are notified of new incomming messages _pwnc_mutex.unlock(); sms_queue.call_every(pp*1000, mbed::Callback<void()>((WNC14A2AInterface*)this,&WNC14A2AInterface::handle_sms_event)); m_smsmoning = true; debugOutput(_debugUart,(char*)"+EXIT sms_listen()\n"); } /*------------------------------------------------------------------------- * process to check SMS messages that is called at the user specified period * * input: none * output:none * return:void */ void WNC14A2AInterface::handle_sms_event() { int msgs_available; debugOutput(_debugUart,(char*)"+CALLED handle_sms_event() called\n"); if ( _sms_cb && m_smsmoning ) { CHK_WNCFE((_pwnc->getWncStatus()==FATAL_FLAG), fail); _pwnc_mutex.lock(); msgs_available = _pwnc->readUnreadSMSText(&m_smsmsgs, true); _pwnc_mutex.unlock(); if( msgs_available ) { debugOutput(_debugUart,(char*)"+Have %d unread texts present\n",m_smsmsgs.msgCount); for( int i=0; i< m_smsmsgs.msgCount; i++ ) { m_MsgText.number = m_smsmsgs.e[i].number; m_MsgText.date = m_smsmsgs.e[i].date; m_MsgText.time = m_smsmsgs.e[i].time; m_MsgText.msg = m_smsmsgs.e[i].msg; _sms_cb(&m_MsgText); } } } debugOutput(_debugUart,(char*)"+EXIT handle_sms_event\n"); } /*------------------------------------------------------------------------- * Check for any SMS messages that are present. If there are, then * fetch them and pass to the users call-back function for processing * * input: pointer to a IOTSMS message buffer array (may be more than 1 msg) * output:message buffer pointer is updated * return: the number of messages being returned */ int WNC14A2AInterface::getSMS(IOTSMS **pmsg) { int msgs_available; debugOutput(_debugUart,(char*)"+CALLED getSMS()\n"); CHK_WNCFE((_pwnc->getWncStatus()==FATAL_FLAG), fail); _pwnc_mutex.lock(); msgs_available = _pwnc->readUnreadSMSText(&m_smsmsgs, true); _pwnc_mutex.unlock(); if( msgs_available ) { debugOutput(_debugUart,(char*)"+Have %d unread texts present\n",m_smsmsgs.msgCount); for( int i=0; i< m_smsmsgs.msgCount; i++ ) { m_MsgText_array[i].number = m_smsmsgs.e[i].number; m_MsgText_array[i].date = m_smsmsgs.e[i].date; m_MsgText_array[i].time = m_smsmsgs.e[i].time; m_MsgText_array[i].msg = m_smsmsgs.e[i].msg; pmsg[i] = (IOTSMS*)&m_MsgText_array[i]; } debugOutput(_debugUart,(char*)"+DONE getting messages\n"); msgs_available = m_smsmsgs.msgCount; } debugOutput(_debugUart,(char*)"+EXIT getSMS\n"); return msgs_available; } /*------------------------------------------------------------------------- * send a message to the specified user number. * * input: string containing users number * string with users message * ouput: none * * return: true if no problems occures, false if failed to send */ int WNC14A2AInterface::sendIOTSms(const string& number, const string& message) { debugOutput(_debugUart,(char*)"+CALLED sendIOTSms(%s,%s)\n",number.c_str(), message.c_str()); _pwnc_mutex.lock(); int i = _pwnc->sendSMSText((char*)number.c_str(), message.c_str()); _pwnc_mutex.unlock(); return i; } // //------------------------------------------------------------------------- //------------------------------------------------------------------------- //------------------------------------------------------------------------- // NetworkStack API's that are not support in the WNC14A2A //------------------------------------------------------------------------- //------------------------------------------------------------------------- //------------------------------------------------------------------------- // int inline WNC14A2AInterface::socket_accept(nsapi_socket_t server, nsapi_socket_t *handle, SocketAddress *address) { debugOutput(_debugUart,(char*)"+CALLED socket_accept()\n"); _errors = NSAPI_ERROR_UNSUPPORTED; return -1; } int inline WNC14A2AInterface::socket_bind(void *handle, const SocketAddress &address) { debugOutput(_debugUart,(char*)"+CALLED socket_bind()\n"); _errors = NSAPI_ERROR_UNSUPPORTED; return -1; } int inline WNC14A2AInterface::socket_listen(void *handle, int backlog) { debugOutput(_debugUart,(char*)"+CALLED socket_listen()\n"); _errors = NSAPI_ERROR_UNSUPPORTED; return -1; }