Use this interface to connect to and interact with the WNC M14A2A LTE Cellular Data Module which is provided by Wistron NeWeb Corporation (WNC) when using ARMmbed v5. The interface provides a Networking interface that can be used with the AT&T Cellular IoT Starter Kit that is sold by Avnet (http://cloudconnectkits.org/product/att-cellular-iot-starter-kit).

Dependencies:   WncControllerK64F

Dependents:   easy-connect-wnc easy-connect

Use this interface to connect to and interact with the WNC M14A2A LTE Cellular Data Module which is provided by Wistron NeWeb Corporation (WNC) when using ARMmbed v5. The interface provides a Networking interface that can be used with the AT&T Cellular IoT Starter Kit that is sold by Avnet (http://cloudconnectkits.org/product/att-cellular-iot-starter-kit).

To demonstrate the use of the Interface, a series of example programs have been provided. Links to these examples are provided below. All examples can be compiled using both the on-line compiler and the ARMmbed CLI (command line interface, see https://github.com/ARMmbed/mbed-cli)

NOTE: This library/class is specific to the AT&T Cellular IoT Starter Kit which uses a FRDM-K64F. The users mbed.org compiler should be configured to use the FRDM-K64F platform.

Example Programs

Import the example programs below and follow the README.md in each to run the example program.

  • several examples of the interface using easy_connect.
  • SMS demonstration program that demonstrates SMS usage
  • Sockets demonstration program demonstrating using TCP sockets to interact with others
  • As new example program are developed, this README will be updated

WNC FIRMWARE VERSION

The WNC14A2AInterface class currently supports the following version(s):

  • MPSS: M14A2A_v11.21.162331 APSS: M14A2A_v11.27.162331

License

This library is released under the Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License and 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.

Committer:
JMF
Date:
Fri Apr 21 18:12:14 2017 +0000
Revision:
8:1c11661da488
Parent:
7:9340bc9e8d64
fixing virtual destructor warning.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JMF 1:f925e07b044d 1
JMF 1:f925e07b044d 2 #include "WNC14A2AInterface.h"
JMF 1:f925e07b044d 3 #include <Thread.h>
JMF 1:f925e07b044d 4 #include <string>
JMF 1:f925e07b044d 5
JMF 1:f925e07b044d 6 /** WNC14A2AInterface class
JMF 1:f925e07b044d 7 * Implementation of the NetworkInterface for the AT&T IoT Starter Kit
JMF 1:f925e07b044d 8 * based on the WNC 14A2A LTE Data Module
JMF 1:f925e07b044d 9 */
JMF 1:f925e07b044d 10
JMF 1:f925e07b044d 11 #define WNC14A2A_MISC_TIMEOUT 3000
JMF 1:f925e07b044d 12 #define WNC14A2A_RESTART_TIMEOUT 10000
JMF 1:f925e07b044d 13 #define WNC14A2A_COMMUNICATION_TIMEOUT 100
JMF 1:f925e07b044d 14 #define READ_EVERYMS 500
JMF 1:f925e07b044d 15
JMF 1:f925e07b044d 16 /////////////////////////////////////////////////////
JMF 1:f925e07b044d 17 // NXP GPIO Pins that are used to initialize the WNC Shield
JMF 1:f925e07b044d 18 /////////////////////////////////////////////////////
JMF 1:f925e07b044d 19 DigitalOut mdm_uart2_rx_boot_mode_sel(PTC17); // on powerup, 0 = boot mode, 1 = normal boot
JMF 1:f925e07b044d 20 DigitalOut mdm_power_on(PTB9); // 0 = modem on, 1 = modem off (hold high for >5 seconds to cycle modem)
JMF 1:f925e07b044d 21 DigitalOut mdm_wakeup_in(PTC2); // 0 = let modem sleep, 1 = keep modem awake -- Note: pulled high on shield
JMF 1:f925e07b044d 22 DigitalOut mdm_reset(PTC12); // active high
JMF 1:f925e07b044d 23 DigitalOut shield_3v3_1v8_sig_trans_ena(PTC4); // 0 = disabled (all signals high impedence, 1 = translation active
JMF 1:f925e07b044d 24 DigitalOut mdm_uart1_cts(PTD0);
JMF 1:f925e07b044d 25
JMF 1:f925e07b044d 26 // Define pin associations for the controller class to use be careful to
JMF 1:f925e07b044d 27 // keep the order of the pins in the initialization list.
JMF 1:f925e07b044d 28
JMF 1:f925e07b044d 29 using namespace WncControllerK64F_fk; // namespace for the controller class use
JMF 1:f925e07b044d 30
JMF 1:f925e07b044d 31 WncGpioPinListK64F wncPinList = {
JMF 1:f925e07b044d 32 &mdm_uart2_rx_boot_mode_sel,
JMF 1:f925e07b044d 33 &mdm_power_on,
JMF 1:f925e07b044d 34 &mdm_wakeup_in,
JMF 1:f925e07b044d 35 &mdm_reset,
JMF 1:f925e07b044d 36 &shield_3v3_1v8_sig_trans_ena,
JMF 1:f925e07b044d 37 &mdm_uart1_cts
JMF 1:f925e07b044d 38 };
JMF 1:f925e07b044d 39
JMF 1:f925e07b044d 40 Thread smsThread;
JMF 1:f925e07b044d 41 static Mutex _pwnc_mutex;
JMF 1:f925e07b044d 42
JMF 1:f925e07b044d 43 static WNCSOCKET _sockets[WNC14A2A_SOCKET_COUNT];
JMF 1:f925e07b044d 44 BufferedSerial mdmUart(PTD3,PTD2,1024,1); //UART for WNC Module
JMF 1:f925e07b044d 45
JMF 1:f925e07b044d 46 //-------------------------------------------------------------------------
JMF 1:f925e07b044d 47 //
JMF 1:f925e07b044d 48 // Class constructor. May be invoked with or without the APN and/or pointer
JMF 1:f925e07b044d 49 // to a debug output. After the constructor has completed, the user can
JMF 1:f925e07b044d 50 // check _errors to determine if any errors occured during instanciation.
JMF 1:f925e07b044d 51 // _errors = 0 when no errors occured
JMF 1:f925e07b044d 52 // 1 when power-on error occured
JMF 1:f925e07b044d 53 // 2 when settng the APN error occured
JMF 1:f925e07b044d 54 // 4 when unable to get the network configuration
JMF 1:f925e07b044d 55 // 8 when allocating a new WncControllerK64F object failed
JMF 1:f925e07b044d 56 // NSAPI_ERROR_UNSUPPORTED when attempting to create a second object
JMF 1:f925e07b044d 57 //
JMF 1:f925e07b044d 58
JMF 6:7fd9e590c4e7 59 WNC14A2AInterface::WNC14A2AInterface(WNCDebug *dbg) :
JMF 1:f925e07b044d 60 m_wncpoweredup(0),
JMF 1:f925e07b044d 61 _pwnc(NULL),
JMF 1:f925e07b044d 62 m_active_socket(-1),
JMF 1:f925e07b044d 63 m_smsmoning(0)
JMF 1:f925e07b044d 64 {
JMF 1:f925e07b044d 65 _errors = NSAPI_ERROR_OK;
JMF 1:f925e07b044d 66
JMF 1:f925e07b044d 67 m_debug=false;
JMF 1:f925e07b044d 68
JMF 1:f925e07b044d 69 if( _pwnc ) { //can only have a single instance of class
JMF 1:f925e07b044d 70 _errors = NSAPI_ERROR_UNSUPPORTED;
JMF 1:f925e07b044d 71 return;
JMF 1:f925e07b044d 72 }
JMF 1:f925e07b044d 73 for( int i=0; i<WNC14A2A_SOCKET_COUNT; i++ ) {
JMF 1:f925e07b044d 74 _sockets[i].socket = i;
JMF 1:f925e07b044d 75 _sockets[i].addr = NULL;
JMF 1:f925e07b044d 76 _sockets[i].opened=false;
JMF 1:f925e07b044d 77 _sockets[i].proto=NSAPI_TCP;
JMF 1:f925e07b044d 78 }
JMF 1:f925e07b044d 79
JMF 1:f925e07b044d 80
JMF 1:f925e07b044d 81 memset(_mac_address,0x00,sizeof(_mac_address));
JMF 1:f925e07b044d 82
JMF 5:d197692c4447 83 _debugUart = dbg;
JMF 5:d197692c4447 84 if( dbg != NULL ) {
JMF 5:d197692c4447 85 dbg->printf("Adding DEBUG output\n");
JMF 5:d197692c4447 86 _pwnc = new WncControllerK64F(&wncPinList, &mdmUart, dbg);
JMF 1:f925e07b044d 87 m_debug=true;
JMF 1:f925e07b044d 88 if( _pwnc )
JMF 1:f925e07b044d 89 _pwnc->enableDebug(1,1);
JMF 1:f925e07b044d 90 }
JMF 1:f925e07b044d 91 else
JMF 1:f925e07b044d 92 _pwnc = new WncControllerK64F_fk::WncControllerK64F(&wncPinList, &mdmUart, NULL);
JMF 1:f925e07b044d 93
JMF 1:f925e07b044d 94 if( !_pwnc ) {
JMF 1:f925e07b044d 95 debugOutput(_debugUart,(char*)", FAILED!\n");
JMF 1:f925e07b044d 96 _errors = NSAPI_ERROR_DEVICE_ERROR;
JMF 1:f925e07b044d 97 }
JMF 1:f925e07b044d 98 else
JMF 1:f925e07b044d 99 debugOutput(_debugUart, (char*)"\n");
JMF 1:f925e07b044d 100 }
JMF 1:f925e07b044d 101
JMF 1:f925e07b044d 102 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 103 * standard destructor... free up allocated memory
JMF 1:f925e07b044d 104 */
JMF 1:f925e07b044d 105
JMF 1:f925e07b044d 106 WNC14A2AInterface::~WNC14A2AInterface()
JMF 1:f925e07b044d 107 {
JMF 1:f925e07b044d 108 delete _pwnc; //free the existing WncControllerK64F object
JMF 1:f925e07b044d 109 }
JMF 1:f925e07b044d 110
JMF 1:f925e07b044d 111 nsapi_error_t WNC14A2AInterface::connect()
JMF 1:f925e07b044d 112 {
JMF 1:f925e07b044d 113 debugOutput(_debugUart,(char*)"+CALLED connect(void)\n");
JMF 1:f925e07b044d 114 return connect(NULL,NULL,NULL);
JMF 1:f925e07b044d 115 }
JMF 1:f925e07b044d 116
JMF 1:f925e07b044d 117 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 118 * This call powers up the WNC module and connects to the user specified APN. If no APN is provided
JMF 1:f925e07b044d 119 * a default one of 'm2m.com.attz' will be used (the NA APN)
JMF 1:f925e07b044d 120 *
JMF 1:f925e07b044d 121 * Input: *apn is the APN string to use
JMF 1:f925e07b044d 122 * *username - NOT CURRENTLY USED
JMF 1:f925e07b044d 123 * *password - NOT CURRENTLY USED
JMF 1:f925e07b044d 124 *
JMF 1:f925e07b044d 125 * Output: none
JMF 1:f925e07b044d 126 *
JMF 1:f925e07b044d 127 * Return: nsapi_error_t
JMF 1:f925e07b044d 128 */
JMF 1:f925e07b044d 129 nsapi_error_t WNC14A2AInterface::connect(const char *apn, const char *username, const char *password)
JMF 1:f925e07b044d 130 {
JMF 1:f925e07b044d 131 debugOutput(_debugUart,(char*)"+ENTER connect(apn,user,pass)\n");
JMF 1:f925e07b044d 132 if( !_pwnc )
JMF 1:f925e07b044d 133 return (_errors=NSAPI_ERROR_NO_CONNECTION);
JMF 1:f925e07b044d 134
JMF 1:f925e07b044d 135 if (!apn)
JMF 1:f925e07b044d 136 apn = "m2m.com.attz";
JMF 1:f925e07b044d 137
JMF 1:f925e07b044d 138 if (!m_wncpoweredup) {
JMF 1:f925e07b044d 139 debugOutput(_debugUart,(char*)"+call powerWncOn using '%s'\n",apn);
JMF 1:f925e07b044d 140 _pwnc_mutex.lock();
JMF 1:f925e07b044d 141 m_wncpoweredup=_pwnc->powerWncOn(apn,40);
JMF 1:f925e07b044d 142 _pwnc_mutex.unlock();
JMF 1:f925e07b044d 143 _errors = m_wncpoweredup? 1:0;
JMF 1:f925e07b044d 144 }
JMF 1:f925e07b044d 145 else { //we've already called powerWncOn and set the APN, so just set the APN
JMF 1:f925e07b044d 146 debugOutput(_debugUart,(char*)"+already powered on, set APN to: %s\n",apn);
JMF 1:f925e07b044d 147 _pwnc_mutex.lock();
JMF 1:f925e07b044d 148 _errors = _pwnc->setApnName(apn)? 1:0;
JMF 1:f925e07b044d 149 _pwnc_mutex.unlock();
JMF 1:f925e07b044d 150 }
JMF 1:f925e07b044d 151
JMF 1:f925e07b044d 152 _pwnc_mutex.lock();
JMF 1:f925e07b044d 153 _errors |= _pwnc->getWncNetworkingStats(&myNetStats)? 2:0;
JMF 1:f925e07b044d 154 _pwnc_mutex.unlock();
JMF 1:f925e07b044d 155
JMF 1:f925e07b044d 156 debugOutput(_debugUart,(char*)"+EXIT connect %02X\n",_errors);
JMF 1:f925e07b044d 157 return (!_errors)? NSAPI_ERROR_NO_CONNECTION : NSAPI_ERROR_OK;
JMF 1:f925e07b044d 158 }
JMF 1:f925e07b044d 159
JMF 1:f925e07b044d 160 /*--------------------------------------------------------------------------
JMF 1:f925e07b044d 161 * This function calls the WNC to retrieve the device (this WNC) connected IP
JMF 1:f925e07b044d 162 * address once we are connected to the APN.
JMF 1:f925e07b044d 163 *
JMF 1:f925e07b044d 164 * Inputs: NONE.
JMF 1:f925e07b044d 165 *
JMF 1:f925e07b044d 166 * Output: none.
JMF 1:f925e07b044d 167 *
JMF 1:f925e07b044d 168 * Return: pointer to the IP string or NULL
JMF 1:f925e07b044d 169 */
JMF 5:d197692c4447 170 const char *WNC14A2AInterface::get_ip_address()
JMF 1:f925e07b044d 171 {
JMF 1:f925e07b044d 172 const char *ptr=NULL;
JMF 1:f925e07b044d 173
JMF 1:f925e07b044d 174 _pwnc_mutex.lock();
JMF 1:f925e07b044d 175 if ( _pwnc->getWncNetworkingStats(&myNetStats) ) {
JMF 1:f925e07b044d 176 CHK_WNCFE(( _pwnc->getWncStatus() == FATAL_FLAG ), null);
JMF 1:f925e07b044d 177 ptr = &myNetStats.ip[0];
JMF 1:f925e07b044d 178 }
JMF 1:f925e07b044d 179 _pwnc_mutex.unlock();
JMF 1:f925e07b044d 180 _errors=NSAPI_ERROR_NO_CONNECTION;
JMF 1:f925e07b044d 181 return ptr;
JMF 1:f925e07b044d 182 }
JMF 1:f925e07b044d 183
JMF 5:d197692c4447 184 #if 0
JMF 1:f925e07b044d 185 /*--------------------------------------------------------------------------
JMF 1:f925e07b044d 186 * This function calls the WNC to retrieve the currently connected IP address
JMF 1:f925e07b044d 187 * it will be a bogus 192.168.0.1 if we are not connected to anyone
JMF 1:f925e07b044d 188 *
JMF 1:f925e07b044d 189 * Inputs: NONE.
JMF 1:f925e07b044d 190 *
JMF 1:f925e07b044d 191 * Output: none.
JMF 1:f925e07b044d 192 *
JMF 1:f925e07b044d 193 * Return: pointer to the IP string or NULL
JMF 1:f925e07b044d 194 */
JMF 1:f925e07b044d 195 const char *WNC14A2AInterface::get_ip_address()
JMF 1:f925e07b044d 196 {
JMF 1:f925e07b044d 197 static char *ptr=NULL, ipAddrStr[25];
JMF 1:f925e07b044d 198 debugOutput(_debugUart,(char*)"+ENTER get_ip_address()\n");
JMF 1:f925e07b044d 199
JMF 1:f925e07b044d 200 memset(ipAddrStr, 0x00, sizeof(ipAddrStr));
JMF 1:f925e07b044d 201 _pwnc_mutex.lock();
JMF 1:f925e07b044d 202
JMF 1:f925e07b044d 203 if( _pwnc && m_active_socket != -1 )
JMF 1:f925e07b044d 204 if( _pwnc->getIpAddr(m_active_socket, ipAddrStr) )
JMF 1:f925e07b044d 205 ptr=ipAddrStr;
JMF 1:f925e07b044d 206 _pwnc_mutex.unlock();
JMF 1:f925e07b044d 207 _errors=NSAPI_ERROR_NO_CONNECTION;
JMF 1:f925e07b044d 208 return ptr;
JMF 1:f925e07b044d 209 }
JMF 5:d197692c4447 210 #endif
JMF 1:f925e07b044d 211
JMF 1:f925e07b044d 212 /* -------------------------------------------------------------------------
JMF 1:f925e07b044d 213 * Open a socket for the WNC. This doesn't actually open the socket within
JMF 1:f925e07b044d 214 * the WNC, it only allocates a socket device and saves the pertinet info
JMF 1:f925e07b044d 215 * that will be required with the WNC socket is opened. The m_active_socket
JMF 1:f925e07b044d 216 * is also updated to this socket as it is assumed this socket should be used
JMF 1:f925e07b044d 217 * for subsequent interactions.
JMF 1:f925e07b044d 218 *
JMF 1:f925e07b044d 219 * Input:
JMF 1:f925e07b044d 220 * - a pointer to a handle pointer.
JMF 1:f925e07b044d 221 * - The type of socket this will be, either NSAPI_UDP or NSAP_TCP
JMF 1:f925e07b044d 222 *
JMF 1:f925e07b044d 223 * Output: *handle is updated
JMF 1:f925e07b044d 224 *
JMF 1:f925e07b044d 225 * Return:
JMF 1:f925e07b044d 226 * - socket being used if successful, -1 on failure
JMF 1:f925e07b044d 227 */
JMF 1:f925e07b044d 228 int WNC14A2AInterface::socket_open(void **handle, nsapi_protocol_t proto)
JMF 1:f925e07b044d 229 {
JMF 1:f925e07b044d 230 int i;
JMF 1:f925e07b044d 231 debugOutput(_debugUart,(char*)"+ENTER socket_open()\n");
JMF 1:f925e07b044d 232
JMF 1:f925e07b044d 233 // search through the available sockets (WNC can only support a max amount).
JMF 1:f925e07b044d 234 for( i=0; i<WNC14A2A_SOCKET_COUNT; i++ )
JMF 1:f925e07b044d 235 if( !_sockets[i].opened )
JMF 1:f925e07b044d 236 break;
JMF 1:f925e07b044d 237
JMF 1:f925e07b044d 238 if( i == WNC14A2A_SOCKET_COUNT ) {
JMF 1:f925e07b044d 239 _errors=NSAPI_ERROR_NO_SOCKET;
JMF 1:f925e07b044d 240 return -1;
JMF 1:f925e07b044d 241 }
JMF 1:f925e07b044d 242
JMF 1:f925e07b044d 243 m_active_socket = i;
JMF 1:f925e07b044d 244 _sockets[i].socket = i; //save this index to make easier later-on
JMF 1:f925e07b044d 245 _sockets[i].url="";
JMF 1:f925e07b044d 246 _sockets[i].opened = true; //ok, we are using this socket now
JMF 1:f925e07b044d 247 _sockets[i].addr = NULL; //but we haven't opened it yet
JMF 1:f925e07b044d 248 _sockets[i].proto = (proto == NSAPI_UDP) ? 0 : 1; //set it up for what WNC wants
JMF 1:f925e07b044d 249 *handle = &_sockets[i];
JMF 1:f925e07b044d 250
JMF 1:f925e07b044d 251 debugOutput(_debugUart,(char*)"+USING Socket index %d, OPEN=%s, proto =%d\nEXIT socket_open()\n",
JMF 1:f925e07b044d 252 i, _sockets[i].opened?"YES":"NO", _sockets[i].proto);
JMF 1:f925e07b044d 253
JMF 1:f925e07b044d 254 _errors = NSAPI_ERROR_OK;
JMF 1:f925e07b044d 255 return i;
JMF 1:f925e07b044d 256 }
JMF 1:f925e07b044d 257
JMF 1:f925e07b044d 258 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 259 * Connect a socket to a IP/PORT. Before you can connect a socket, you must have opened
JMF 1:f925e07b044d 260 * it.
JMF 1:f925e07b044d 261 *
JMF 1:f925e07b044d 262 * Input: handle - pointer to the socket to use
JMF 1:f925e07b044d 263 * address- the IP/Port pair that will be used
JMF 1:f925e07b044d 264 *
JMF 1:f925e07b044d 265 * Output: none
JMF 1:f925e07b044d 266 *
JMF 1:f925e07b044d 267 * return: 0 or greater on success (value is the socket ID)
JMF 1:f925e07b044d 268 * -1 on failure
JMF 1:f925e07b044d 269 */
JMF 1:f925e07b044d 270 int WNC14A2AInterface::socket_connect(void *handle, const SocketAddress &address)
JMF 1:f925e07b044d 271 {
JMF 1:f925e07b044d 272 WNCSOCKET *wnc = (WNCSOCKET *)handle;
JMF 1:f925e07b044d 273
JMF 1:f925e07b044d 274 debugOutput(_debugUart,(char*)"+ENTER socket_connect()\n");
JMF 1:f925e07b044d 275 debugOutput(_debugUart,(char*)"+IP = %s\n+PORT= %d\n", address.get_ip_address(), address.get_port());
JMF 1:f925e07b044d 276
JMF 1:f925e07b044d 277 if (!_pwnc || m_active_socket == -1) {
JMF 1:f925e07b044d 278 _errors = NSAPI_ERROR_NO_SOCKET;
JMF 1:f925e07b044d 279 return -1;
JMF 1:f925e07b044d 280 }
JMF 1:f925e07b044d 281
JMF 1:f925e07b044d 282 if( !wnc->opened ) {
JMF 1:f925e07b044d 283 _errors = NSAPI_ERROR_NO_SOCKET;
JMF 1:f925e07b044d 284 return -1;
JMF 1:f925e07b044d 285 }
JMF 1:f925e07b044d 286 m_active_socket = wnc->socket; //in case the user is asking for a different socket
JMF 1:f925e07b044d 287 wnc->addr = address;
JMF 1:f925e07b044d 288
JMF 1:f925e07b044d 289 //we will always connect using the URL if possible, if no url has been provided, try the IP address
JMF 1:f925e07b044d 290 if( wnc->url.empty() ) {
JMF 1:f925e07b044d 291 debugOutput(_debugUart,(char*)"+call openSocketIpAddr(%d,%s,%d,%d)\n",m_active_socket,
JMF 1:f925e07b044d 292 address.get_ip_address(), address.get_port(), wnc->proto);
JMF 1:f925e07b044d 293 if( !_pwnc->openSocketIpAddr(m_active_socket, address.get_ip_address(), address.get_port(),
JMF 1:f925e07b044d 294 wnc->proto, WNC14A2A_COMMUNICATION_TIMEOUT) ) {
JMF 1:f925e07b044d 295 _errors = NSAPI_ERROR_NO_SOCKET;
JMF 1:f925e07b044d 296 return -1;
JMF 1:f925e07b044d 297 }
JMF 1:f925e07b044d 298 }
JMF 1:f925e07b044d 299 else {
JMF 1:f925e07b044d 300 debugOutput(_debugUart,(char*)"+call openSocketUrl(%d,%s,%d,%d)\n", m_active_socket,
JMF 1:f925e07b044d 301 wnc->url.c_str(), wnc->addr.get_port(), wnc->proto);
JMF 1:f925e07b044d 302 if( !_pwnc->openSocketUrl(m_active_socket, wnc->url.c_str(), wnc->addr.get_port(), wnc->proto) ) {
JMF 1:f925e07b044d 303 _errors = NSAPI_ERROR_NO_SOCKET;
JMF 1:f925e07b044d 304 return -1;
JMF 1:f925e07b044d 305 }
JMF 1:f925e07b044d 306 }
JMF 1:f925e07b044d 307
JMF 1:f925e07b044d 308 debugOutput(_debugUart,(char*)"+SOCKET %d CONNECTED!\n+URL=%s\n+IP=%s; PORT=%d\n+EXIT socket_connect()\n\n",m_active_socket,
JMF 1:f925e07b044d 309 wnc->url.c_str(), wnc->addr.get_ip_address(), wnc->addr.get_port());
JMF 1:f925e07b044d 310 return 0;
JMF 1:f925e07b044d 311 }
JMF 1:f925e07b044d 312
JMF 1:f925e07b044d 313 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 314 * Perform a URL name resolve, update the IP/Port pair, and nsapi_version. nsapi_version
JMF 1:f925e07b044d 315 * could be either NSAPI_IPv4 or NSAPI_IPv6 but this functional is hard coded ti NSAPI_IPv4
JMF 1:f925e07b044d 316 * for now. The currently active socket is used for the resolution.
JMF 1:f925e07b044d 317 *
JMF 1:f925e07b044d 318 * Input: name - the URL to resolve
JMF 1:f925e07b044d 319 *
JMF 1:f925e07b044d 320 * Output: address - the IP/PORT pair this URL resolves to
JMF 1:f925e07b044d 321 * version - always assumed to be NSAPI_IPv4 currently
JMF 1:f925e07b044d 322 *
JMF 1:f925e07b044d 323 * Return: nsapi_error_t
JMF 1:f925e07b044d 324 */
JMF 1:f925e07b044d 325
JMF 1:f925e07b044d 326 nsapi_error_t WNC14A2AInterface::gethostbyname(const char* name, SocketAddress *address, nsapi_version_t version)
JMF 1:f925e07b044d 327 {
JMF 1:f925e07b044d 328 nsapi_error_t ret = NSAPI_ERROR_OK;
JMF 1:f925e07b044d 329 char ipAddrStr[25];
JMF 7:9340bc9e8d64 330 int t_socket = 0; //use a temporary socket place holder
JMF 1:f925e07b044d 331
JMF 1:f925e07b044d 332 debugOutput(_debugUart,(char*)"+ENTER gethostbyname()()\n+CURRENTLY:\n");
JMF 1:f925e07b044d 333 debugOutput(_debugUart,(char*)"+URL = %s\n+IP = %s\n+PORT= %d\n", name, address->get_ip_address(), address->get_port());
JMF 1:f925e07b044d 334 memset(ipAddrStr,0x00,sizeof(ipAddrStr));
JMF 1:f925e07b044d 335
JMF 7:9340bc9e8d64 336 if (!_pwnc)
JMF 1:f925e07b044d 337 return (_errors = NSAPI_ERROR_NO_SOCKET);
JMF 7:9340bc9e8d64 338
JMF 7:9340bc9e8d64 339 if (m_active_socket != -1) //we might have been called before a socket was opened
JMF 7:9340bc9e8d64 340 t_socket = m_active_socket; //if so, do nothing with the active socket index
JMF 1:f925e07b044d 341
JMF 1:f925e07b044d 342 //Execute DNS query.
JMF 7:9340bc9e8d64 343 if( !_pwnc->resolveUrl(t_socket, name) )
JMF 1:f925e07b044d 344 return (_errors = NSAPI_ERROR_DEVICE_ERROR);
JMF 1:f925e07b044d 345
JMF 1:f925e07b044d 346 //Now, get the IP address that the URL was resolved to
JMF 7:9340bc9e8d64 347 if( !_pwnc->getIpAddr(t_socket, ipAddrStr) )
JMF 1:f925e07b044d 348 return (_errors = NSAPI_ERROR_DEVICE_ERROR);
JMF 1:f925e07b044d 349
JMF 1:f925e07b044d 350 address->set_ip_address(ipAddrStr);
JMF 7:9340bc9e8d64 351 debugOutput(_debugUart,(char*)"+resolveUrl returned IP=%s\n",ipAddrStr);
JMF 7:9340bc9e8d64 352 if( t_socket == m_active_socket ) {
JMF 7:9340bc9e8d64 353 _sockets[m_active_socket].url=name;
JMF 7:9340bc9e8d64 354 _sockets[m_active_socket].addr.set_ip_address(ipAddrStr);
JMF 7:9340bc9e8d64 355 }
JMF 1:f925e07b044d 356
JMF 1:f925e07b044d 357 debugOutput(_debugUart,(char*)"+EXIT gethostbyname()\n+URL = %s\n+IP = %s\n+PORT= %d\n\n",
JMF 1:f925e07b044d 358 _sockets[m_active_socket].url.c_str(), address->get_ip_address(),
JMF 1:f925e07b044d 359 address->get_port());
JMF 1:f925e07b044d 360 _errors = ret;
JMF 1:f925e07b044d 361 return ret;
JMF 1:f925e07b044d 362 }
JMF 1:f925e07b044d 363
JMF 1:f925e07b044d 364 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 365 * using the specified socket, send the data.
JMF 1:f925e07b044d 366 *
JMF 1:f925e07b044d 367 * Input: handle of the socket to use
JMF 1:f925e07b044d 368 * pointer to the data to send
JMF 1:f925e07b044d 369 * amount of data being sent
JMF 1:f925e07b044d 370 *
JMF 1:f925e07b044d 371 * Output: none
JMF 1:f925e07b044d 372 *
JMF 1:f925e07b044d 373 * Return: number of bytes that was sent
JMF 1:f925e07b044d 374 */
JMF 1:f925e07b044d 375 int WNC14A2AInterface::socket_send(void *handle, const void *data, unsigned size)
JMF 1:f925e07b044d 376 {
JMF 1:f925e07b044d 377 WNCSOCKET *wnc = (WNCSOCKET *)handle;
JMF 1:f925e07b044d 378 int r = -1;
JMF 1:f925e07b044d 379 debugOutput(_debugUart,(char*)"+ENTER socket_send()\n");
JMF 1:f925e07b044d 380
JMF 1:f925e07b044d 381 if (!_pwnc || m_active_socket == -1) {
JMF 1:f925e07b044d 382 _errors = NSAPI_ERROR_NO_SOCKET;
JMF 1:f925e07b044d 383 return 0;
JMF 1:f925e07b044d 384 }
JMF 1:f925e07b044d 385 else
JMF 1:f925e07b044d 386 m_active_socket = wnc->socket; //just in case sending to a socket that wasn't last used
JMF 1:f925e07b044d 387
JMF 1:f925e07b044d 388 debugOutput(_debugUart,(char*)"+SOCKET %d is %s, URL=%s, IP=%s, PORT=%d\n",m_active_socket,
JMF 1:f925e07b044d 389 (char*)wnc->opened?"OPEN":"CLOSED",wnc->url.c_str(),wnc->addr.get_ip_address(),wnc->addr.get_port());
JMF 1:f925e07b044d 390 debugOutput(_debugUart,(char*)"+WRITE [%s] (%d bytes) to socket #%d\n",data,size,wnc->socket);
JMF 1:f925e07b044d 391
JMF 1:f925e07b044d 392 _pwnc_mutex.lock();
JMF 1:f925e07b044d 393 if( _pwnc->write(m_active_socket, (const uint8_t*)data, size) )
JMF 1:f925e07b044d 394 r = size;
JMF 1:f925e07b044d 395 else
JMF 1:f925e07b044d 396 debugOutput(_debugUart,(char*)"+ERROR: write to socket %d failed!\n",m_active_socket);
JMF 1:f925e07b044d 397 _pwnc_mutex.unlock();
JMF 1:f925e07b044d 398
JMF 1:f925e07b044d 399 debugOutput(_debugUart,(char*)"+EXIT socket_send(), successful: %d\n\n",r);
JMF 1:f925e07b044d 400 return r;
JMF 1:f925e07b044d 401 }
JMF 1:f925e07b044d 402
JMF 1:f925e07b044d 403 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 404 * Called to receive data.
JMF 1:f925e07b044d 405 *
JMF 1:f925e07b044d 406 * Input: handle to the socket we want to read from
JMF 1:f925e07b044d 407 *
JMF 1:f925e07b044d 408 * Output: data we receive is placed into the data buffer
JMF 1:f925e07b044d 409 * size is the size of the buffer
JMF 1:f925e07b044d 410 *
JMF 1:f925e07b044d 411 * Returns: The number of bytes received or -1 if an error occured
JMF 1:f925e07b044d 412 */
JMF 1:f925e07b044d 413 int WNC14A2AInterface::socket_recv(void *handle, void *data, unsigned size)
JMF 1:f925e07b044d 414 {
JMF 1:f925e07b044d 415 WNCSOCKET *wnc = (WNCSOCKET *)handle;
JMF 1:f925e07b044d 416 size_t done, cnt;
JMF 1:f925e07b044d 417 Timer t;
JMF 1:f925e07b044d 418
JMF 1:f925e07b044d 419 debugOutput(_debugUart,(char*)"+ENTER socket_recv(); read up to %d bytes\n",size);
JMF 1:f925e07b044d 420
JMF 1:f925e07b044d 421 memset(data,0x00,size);
JMF 1:f925e07b044d 422 if (!_pwnc || m_active_socket == -1) {
JMF 1:f925e07b044d 423 _errors = NSAPI_ERROR_NO_SOCKET;
JMF 1:f925e07b044d 424 return -1;
JMF 1:f925e07b044d 425 }
JMF 1:f925e07b044d 426 else
JMF 1:f925e07b044d 427 m_active_socket = wnc->socket; //just in case sending to a socket that wasn't last used
JMF 1:f925e07b044d 428
JMF 1:f925e07b044d 429 t.start();
JMF 1:f925e07b044d 430 do {
JMF 1:f925e07b044d 431 if( !(t.read_ms() % READ_EVERYMS) )
JMF 1:f925e07b044d 432 cnt = done = _pwnc->read(m_active_socket, (uint8_t *)data, (uint32_t) size);
JMF 1:f925e07b044d 433 done = (cnt || (t.read_ms() > WNC14A2A_MISC_TIMEOUT))? 1:0;
JMF 1:f925e07b044d 434 }
JMF 1:f925e07b044d 435 while( !done );
JMF 1:f925e07b044d 436 t.stop();
JMF 1:f925e07b044d 437
JMF 1:f925e07b044d 438 if( _pwnc->getWncStatus() != WNC_GOOD ) {
JMF 1:f925e07b044d 439 _errors = NSAPI_ERROR_DEVICE_ERROR;
JMF 1:f925e07b044d 440 return -1;
JMF 1:f925e07b044d 441 }
JMF 1:f925e07b044d 442
JMF 1:f925e07b044d 443 debugOutput(_debugUart,(char*)"+EXIT socket_recv(), ret=%d\n",cnt);
JMF 1:f925e07b044d 444 return cnt;
JMF 1:f925e07b044d 445 }
JMF 1:f925e07b044d 446
JMF 1:f925e07b044d 447 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 448 * Close a socket
JMF 1:f925e07b044d 449 *
JMF 1:f925e07b044d 450 * Input: the handle to the socket to close
JMF 1:f925e07b044d 451 *
JMF 1:f925e07b044d 452 * Output: none
JMF 1:f925e07b044d 453 *
JMF 1:f925e07b044d 454 * Return: -1 on error, otherwise 0
JMF 1:f925e07b044d 455 */
JMF 1:f925e07b044d 456 int WNC14A2AInterface::socket_close(void *handle)
JMF 1:f925e07b044d 457 {
JMF 1:f925e07b044d 458 WNCSOCKET *wnc = (WNCSOCKET*)handle;
JMF 1:f925e07b044d 459 debugOutput(_debugUart,(char*)"+CALLED socket_close()\n");
JMF 1:f925e07b044d 460
JMF 1:f925e07b044d 461 if (!_pwnc || m_active_socket == -1) {
JMF 1:f925e07b044d 462 _errors = NSAPI_ERROR_NO_SOCKET;
JMF 1:f925e07b044d 463 return -1;
JMF 1:f925e07b044d 464 }
JMF 1:f925e07b044d 465 else
JMF 1:f925e07b044d 466 m_active_socket = wnc->socket; //just in case sending to a socket that wasn't last used
JMF 1:f925e07b044d 467
JMF 1:f925e07b044d 468 if( !_pwnc->closeSocket(m_active_socket) ) {
JMF 1:f925e07b044d 469 _errors = NSAPI_ERROR_DEVICE_ERROR;
JMF 1:f925e07b044d 470 return -1;
JMF 1:f925e07b044d 471 }
JMF 1:f925e07b044d 472
JMF 1:f925e07b044d 473 wnc->opened = false; //no longer in use
JMF 1:f925e07b044d 474 wnc->addr = NULL; //not open
JMF 1:f925e07b044d 475 wnc->proto = 0; //assume TCP for now
JMF 1:f925e07b044d 476 _errors = NSAPI_ERROR_OK;
JMF 1:f925e07b044d 477 return 0;
JMF 1:f925e07b044d 478 }
JMF 1:f925e07b044d 479
JMF 1:f925e07b044d 480 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 481 * return the MAC for this device. Because there is no MAC Ethernet
JMF 1:f925e07b044d 482 * address to return, this function returns a bogus MAC address created
JMF 1:f925e07b044d 483 * from the ICCD on the SIM that is being used.
JMF 1:f925e07b044d 484 *
JMF 1:f925e07b044d 485 * Input: none
JMF 1:f925e07b044d 486 *
JMF 1:f925e07b044d 487 * Output: none
JMF 1:f925e07b044d 488 *
JMF 1:f925e07b044d 489 * Return: MAC string containing "NN:NN:NN:NN:NN:NN" or NULL
JMF 1:f925e07b044d 490 */
JMF 1:f925e07b044d 491 const char *WNC14A2AInterface::get_mac_address()
JMF 1:f925e07b044d 492 {
JMF 1:f925e07b044d 493 string mac, str;
JMF 1:f925e07b044d 494 debugOutput(_debugUart,(char*)"+ENTER get_mac_address()\n");
JMF 1:f925e07b044d 495
JMF 1:f925e07b044d 496 if( _pwnc->getICCID(&str) ) {
JMF 1:f925e07b044d 497 CHK_WNCFE((_pwnc->getWncStatus()==FATAL_FLAG), null);
JMF 1:f925e07b044d 498 mac = str.substr(3,20);
JMF 1:f925e07b044d 499 mac[2]=mac[5]=mac[8]=mac[11]=mac[14]=':';
JMF 1:f925e07b044d 500 strncpy(_mac_address, mac.c_str(), mac.length());
JMF 1:f925e07b044d 501 return _mac_address;
JMF 1:f925e07b044d 502 }
JMF 1:f925e07b044d 503 return NULL;
JMF 1:f925e07b044d 504 }
JMF 1:f925e07b044d 505
JMF 1:f925e07b044d 506 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 507 * return a pointer to the current WNC14A2AInterface
JMF 1:f925e07b044d 508 */
JMF 1:f925e07b044d 509 NetworkStack *WNC14A2AInterface::get_stack() {
JMF 1:f925e07b044d 510 debugOutput(_debugUart,(char*)"+CALLED get_stack()\n");
JMF 1:f925e07b044d 511 return this;
JMF 1:f925e07b044d 512 }
JMF 1:f925e07b044d 513
JMF 1:f925e07b044d 514 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 515 * Disconnnect from the 14A2A, but we can not do that
JMF 1:f925e07b044d 516 * so just return saying everything is ok.
JMF 1:f925e07b044d 517 */
JMF 1:f925e07b044d 518 nsapi_error_t WNC14A2AInterface::disconnect()
JMF 1:f925e07b044d 519 {
JMF 1:f925e07b044d 520 debugOutput(_debugUart,(char*)"+CALLED disconnect()\n");
JMF 1:f925e07b044d 521 return NSAPI_ERROR_OK;
JMF 1:f925e07b044d 522 }
JMF 1:f925e07b044d 523
JMF 1:f925e07b044d 524 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 525 * allow the user to change the APN. The API takes username and password
JMF 1:f925e07b044d 526 * but they are not used.
JMF 1:f925e07b044d 527 *
JMF 1:f925e07b044d 528 * Input: apn string
JMF 1:f925e07b044d 529 * username - not used
JMF 1:f925e07b044d 530 * password - not used
JMF 1:f925e07b044d 531 *
JMF 1:f925e07b044d 532 * Output: none
JMF 1:f925e07b044d 533 *
JMF 1:f925e07b044d 534 * Return: nsapi_error_t
JMF 1:f925e07b044d 535 */
JMF 1:f925e07b044d 536 nsapi_error_t WNC14A2AInterface::set_credentials(const char *apn, const char *username, const char *password)
JMF 1:f925e07b044d 537 {
JMF 1:f925e07b044d 538 debugOutput(_debugUart,(char*)"+ENTER set_credentials()\n");
JMF 1:f925e07b044d 539 if( !_pwnc )
JMF 1:f925e07b044d 540 return (_errors=NSAPI_ERROR_NO_CONNECTION);
JMF 1:f925e07b044d 541
JMF 1:f925e07b044d 542 if( !apn )
JMF 1:f925e07b044d 543 return (_errors=NSAPI_ERROR_PARAMETER);
JMF 1:f925e07b044d 544
JMF 1:f925e07b044d 545 if( !_pwnc->setApnName(apn) )
JMF 1:f925e07b044d 546 return (_errors=NSAPI_ERROR_DEVICE_ERROR);
JMF 1:f925e07b044d 547
JMF 1:f925e07b044d 548 return (_errors=NSAPI_ERROR_OK);
JMF 1:f925e07b044d 549 }
JMF 1:f925e07b044d 550
JMF 1:f925e07b044d 551 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 552 * Register a callback on state change of the socket.FROM NetworkStack
JMF 1:f925e07b044d 553 * @param handle Socket handle
JMF 1:f925e07b044d 554 * @param callback Function to call on state change
JMF 1:f925e07b044d 555 * @param data Argument to pass to callback
JMF 1:f925e07b044d 556 * @note Callback may be called in an interrupt context.
JMF 1:f925e07b044d 557 */
JMF 1:f925e07b044d 558 void WNC14A2AInterface::socket_attach(void *handle, void (*callback)(void *), void *data)
JMF 1:f925e07b044d 559 {
JMF 1:f925e07b044d 560 debugOutput(_debugUart,(char*)"+CALLED socket_attach()\n");
JMF 1:f925e07b044d 561 }
JMF 1:f925e07b044d 562
JMF 1:f925e07b044d 563 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 564 * check to see if we are currently regisered with the network.
JMF 1:f925e07b044d 565 *
JMF 1:f925e07b044d 566 * Input: none
JMF 1:f925e07b044d 567 *
JMF 1:f925e07b044d 568 * Output: none
JMF 1:f925e07b044d 569 *
JMF 1:f925e07b044d 570 * Return: ture if we are registerd, false if not or an error occured
JMF 1:f925e07b044d 571 */
JMF 1:f925e07b044d 572 bool WNC14A2AInterface::registered()
JMF 1:f925e07b044d 573 {
JMF 1:f925e07b044d 574 debugOutput(_debugUart,(char*)"+ENTER registered()\n");
JMF 1:f925e07b044d 575 if( !_pwnc ) {
JMF 1:f925e07b044d 576 _errors=NSAPI_ERROR_NO_CONNECTION;
JMF 1:f925e07b044d 577 return false;
JMF 1:f925e07b044d 578 }
JMF 1:f925e07b044d 579
JMF 1:f925e07b044d 580 if ( _pwnc->getWncStatus() == WNC_GOOD ){
JMF 1:f925e07b044d 581 _errors=NSAPI_ERROR_OK;
JMF 1:f925e07b044d 582 return true;
JMF 1:f925e07b044d 583 }
JMF 1:f925e07b044d 584 _errors=NSAPI_ERROR_NO_CONNECTION;
JMF 1:f925e07b044d 585 return false;
JMF 1:f925e07b044d 586 }
JMF 1:f925e07b044d 587
JMF 1:f925e07b044d 588 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 589 * doDebug is just a handy way to allow a developer to set different levels
JMF 1:f925e07b044d 590 * of debug for the WNC14A2A device.
JMF 1:f925e07b044d 591 *
JMF 1:f925e07b044d 592 * Input: a Bitfield of -
JMF 1:f925e07b044d 593 * basic debug = 0x01
JMF 1:f925e07b044d 594 * more debug = 0x02
JMF 1:f925e07b044d 595 * network debug = 0x04
JMF 1:f925e07b044d 596 * all debug = 0x07
JMF 1:f925e07b044d 597 *
JMF 1:f925e07b044d 598 * Output: none
JMF 1:f925e07b044d 599 *
JMF 1:f925e07b044d 600 * Returns: void
JMF 1:f925e07b044d 601 */
JMF 1:f925e07b044d 602 void WNC14A2AInterface::doDebug( int v )
JMF 1:f925e07b044d 603 {
JMF 1:f925e07b044d 604 if( !_pwnc )
JMF 1:f925e07b044d 605 _errors = NSAPI_ERROR_DEVICE_ERROR;
JMF 1:f925e07b044d 606 else
JMF 1:f925e07b044d 607 _pwnc->enableDebug( (v&1), (v&2) );
JMF 1:f925e07b044d 608
JMF 1:f925e07b044d 609 m_debug=(v&4);
JMF 1:f925e07b044d 610 debugOutput(_debugUart,(char*)"+SETTING debug flag to 0x%02X\n",v);
JMF 1:f925e07b044d 611 }
JMF 1:f925e07b044d 612
JMF 1:f925e07b044d 613 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 614 * Simple function to allow for writing debug messages. It always
JMF 1:f925e07b044d 615 * checks to see if debug has been enabled or not before it
JMF 1:f925e07b044d 616 * outputs the message.
JMF 1:f925e07b044d 617 *
JMF 1:f925e07b044d 618 * Input: The debug uart pointer followed by format string and vars
JMF 1:f925e07b044d 619 *
JMF 1:f925e07b044d 620 * Output: none
JMF 1:f925e07b044d 621 *
JMF 1:f925e07b044d 622 * Return: void
JMF 1:f925e07b044d 623 */
JMF 6:7fd9e590c4e7 624 void WNC14A2AInterface::debugOutput(WNCDebug *dbgOut, char * format, ...)
JMF 1:f925e07b044d 625 {
JMF 1:f925e07b044d 626 if( dbgOut && m_debug ) {
JMF 1:f925e07b044d 627 char buffer[256];
JMF 1:f925e07b044d 628 va_list args;
JMF 1:f925e07b044d 629 va_start (args, format);
JMF 1:f925e07b044d 630 vsnprintf(buffer, sizeof(buffer), format, args);
JMF 1:f925e07b044d 631 dbgOut->puts(buffer);
JMF 1:f925e07b044d 632 va_end (args);
JMF 1:f925e07b044d 633 }
JMF 1:f925e07b044d 634 }
JMF 1:f925e07b044d 635
JMF 1:f925e07b044d 636
JMF 1:f925e07b044d 637 ////////////////////////////////////////////////////////////////////
JMF 1:f925e07b044d 638 // UDP methods
JMF 1:f925e07b044d 639 ///////////////////////////////////////////////////////////////////
JMF 1:f925e07b044d 640
JMF 1:f925e07b044d 641 //-------------------------------------------------------------------------
JMF 1:f925e07b044d 642 //sends data to a UDP socket
JMF 1:f925e07b044d 643 int WNC14A2AInterface::socket_sendto(void *handle, const SocketAddress &address, const void *data, unsigned size)
JMF 1:f925e07b044d 644 {
JMF 1:f925e07b044d 645 WNCSOCKET *wnc = (WNCSOCKET *)handle;
JMF 1:f925e07b044d 646
JMF 1:f925e07b044d 647 debugOutput(_debugUart,(char*)"+CALLED socket_sendto()\n");
JMF 1:f925e07b044d 648 CHK_WNCFE(( _pwnc->getWncStatus() == FATAL_FLAG ), fail);
JMF 1:f925e07b044d 649 if (!wnc->opened) {
JMF 1:f925e07b044d 650 int err = socket_connect(wnc, address);
JMF 1:f925e07b044d 651 if (err < 0)
JMF 1:f925e07b044d 652 return err;
JMF 1:f925e07b044d 653 }
JMF 1:f925e07b044d 654 wnc->addr = address;
JMF 1:f925e07b044d 655
JMF 1:f925e07b044d 656 return socket_send(wnc, data, size);
JMF 1:f925e07b044d 657 }
JMF 1:f925e07b044d 658
JMF 1:f925e07b044d 659 //receives from a UDP socket
JMF 1:f925e07b044d 660 int WNC14A2AInterface::socket_recvfrom(void *handle, SocketAddress *address, void *buffer, unsigned size)
JMF 1:f925e07b044d 661 {
JMF 1:f925e07b044d 662 WNCSOCKET *wnc = (WNCSOCKET *)handle;
JMF 1:f925e07b044d 663 debugOutput(_debugUart,(char*)"+CALLED socket_recvfrom()\n");
JMF 1:f925e07b044d 664 int ret = socket_recv(wnc, (char *)buffer, size);
JMF 1:f925e07b044d 665 if (ret >= 0 && address)
JMF 1:f925e07b044d 666 *address = wnc->addr;
JMF 1:f925e07b044d 667 return ret;
JMF 1:f925e07b044d 668 }
JMF 1:f925e07b044d 669
JMF 1:f925e07b044d 670 ////////////////////////////////////////////////////////////////////
JMF 1:f925e07b044d 671 // SMS methods
JMF 1:f925e07b044d 672 ///////////////////////////////////////////////////////////////////
JMF 1:f925e07b044d 673
JMF 1:f925e07b044d 674 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 675 * IOTSMS message don't use a phone number, they use the device ICCID. This
JMF 1:f925e07b044d 676 * function returns the ICCID based number that is used for this device.
JMF 1:f925e07b044d 677 *
JMF 1:f925e07b044d 678 * Input: none
JMF 1:f925e07b044d 679 * Output: none
JMF 1:f925e07b044d 680 * Return: string containing the IOTSMS number to use
JMF 1:f925e07b044d 681 */
JMF 1:f925e07b044d 682 char* WNC14A2AInterface::getSMSnbr( void )
JMF 1:f925e07b044d 683 {
JMF 1:f925e07b044d 684 char * ret=NULL;
JMF 1:f925e07b044d 685 string iccid_str;
JMF 1:f925e07b044d 686 static string msisdn_str;
JMF 1:f925e07b044d 687
JMF 1:f925e07b044d 688 if( !_pwnc ) {
JMF 1:f925e07b044d 689 _errors=NSAPI_ERROR_NO_CONNECTION;
JMF 1:f925e07b044d 690 return NULL;
JMF 1:f925e07b044d 691 }
JMF 1:f925e07b044d 692
JMF 1:f925e07b044d 693 CHK_WNCFE(( _pwnc->getWncStatus() == FATAL_FLAG ), null);
JMF 1:f925e07b044d 694
JMF 1:f925e07b044d 695 if( !_pwnc->getICCID(&iccid_str) )
JMF 1:f925e07b044d 696 return ret;
JMF 1:f925e07b044d 697
JMF 1:f925e07b044d 698 CHK_WNCFE(( _pwnc->getWncStatus() == FATAL_FLAG ), null);
JMF 1:f925e07b044d 699
JMF 1:f925e07b044d 700 if( _pwnc->convertICCIDtoMSISDN(iccid_str, &msisdn_str) )
JMF 1:f925e07b044d 701 ret = (char*)msisdn_str.c_str();
JMF 1:f925e07b044d 702 return ret;
JMF 1:f925e07b044d 703 }
JMF 1:f925e07b044d 704
JMF 1:f925e07b044d 705
JMF 1:f925e07b044d 706 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 707 * Normally the user attaches his call-back function when performing
JMF 1:f925e07b044d 708 * the listen call which enables the SMS system, but this function
JMF 1:f925e07b044d 709 * allows them to update the callback if desired.
JMF 1:f925e07b044d 710 *
JMF 1:f925e07b044d 711 * input: pointer to the function to call
JMF 1:f925e07b044d 712 * output: none
JMF 1:f925e07b044d 713 * return: none
JMF 1:f925e07b044d 714 */
JMF 1:f925e07b044d 715 void WNC14A2AInterface::sms_attach(void (*callback)(IOTSMS *))
JMF 1:f925e07b044d 716 {
JMF 1:f925e07b044d 717 debugOutput(_debugUart,(char*)"+CALLED sms_attach() called\n");
JMF 1:f925e07b044d 718 _sms_cb = callback;
JMF 1:f925e07b044d 719 }
JMF 1:f925e07b044d 720
JMF 1:f925e07b044d 721 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 722 * Call this to start the SMS system. It is needed to reset the WNC
JMF 1:f925e07b044d 723 * internal data structures related to SMS messaging
JMF 1:f925e07b044d 724 */
JMF 1:f925e07b044d 725 void WNC14A2AInterface::sms_start(void)
JMF 1:f925e07b044d 726 {
JMF 1:f925e07b044d 727 _pwnc_mutex.lock(); //delete any message currently in storage
JMF 1:f925e07b044d 728 _pwnc->deleteSMSTextFromMem('*'); //so we are notified of new incomming messages
JMF 1:f925e07b044d 729 _pwnc_mutex.unlock();
JMF 1:f925e07b044d 730 }
JMF 1:f925e07b044d 731
JMF 1:f925e07b044d 732 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 733 * Initialize the IoT SMS system. Initializing it allows the user to set a
JMF 1:f925e07b044d 734 * polling period to check for SMS messages, and a SMS is recevied, then
JMF 1:f925e07b044d 735 * a user provided function is called.
JMF 1:f925e07b044d 736 *
JMF 1:f925e07b044d 737 * Input: polling period in seconds. If not specified 30 seconds is used.
JMF 1:f925e07b044d 738 * pointer to a users calllback function
JMF 1:f925e07b044d 739 * Output: none
JMF 1:f925e07b044d 740 *
JMF 1:f925e07b044d 741 * Returns: void
JMF 1:f925e07b044d 742 */
JMF 1:f925e07b044d 743 void WNC14A2AInterface::sms_listen(uint16_t pp)
JMF 1:f925e07b044d 744 {
JMF 1:f925e07b044d 745 debugOutput(_debugUart,(char*)"+CALLED sms_listen(%d) called\n",pp);
JMF 1:f925e07b044d 746 if( !_pwnc ) {
JMF 1:f925e07b044d 747 _errors=NSAPI_ERROR_NO_CONNECTION;
JMF 1:f925e07b044d 748 return;
JMF 1:f925e07b044d 749 }
JMF 1:f925e07b044d 750
JMF 1:f925e07b044d 751 CHK_WNCFE(( _pwnc->getWncStatus() == FATAL_FLAG ), fail);
JMF 1:f925e07b044d 752
JMF 1:f925e07b044d 753 if( m_smsmoning )
JMF 1:f925e07b044d 754 m_smsmoning = false;
JMF 1:f925e07b044d 755 if( pp < 1)
JMF 1:f925e07b044d 756 pp = 30;
JMF 1:f925e07b044d 757
JMF 1:f925e07b044d 758
JMF 1:f925e07b044d 759 debugOutput(_debugUart,(char*)"+setup event queue\n");
JMF 1:f925e07b044d 760 smsThread.start(callback(&sms_queue,&EventQueue::dispatch_forever));
JMF 1:f925e07b044d 761
JMF 1:f925e07b044d 762 _pwnc_mutex.lock(); //delete any message currently in storage
JMF 1:f925e07b044d 763 _pwnc->deleteSMSTextFromMem('*'); //so we are notified of new incomming messages
JMF 1:f925e07b044d 764 _pwnc_mutex.unlock();
JMF 1:f925e07b044d 765 sms_queue.call_every(pp*1000, mbed::Callback<void()>((WNC14A2AInterface*)this,&WNC14A2AInterface::handle_sms_event));
JMF 1:f925e07b044d 766
JMF 1:f925e07b044d 767 m_smsmoning = true;
JMF 1:f925e07b044d 768 debugOutput(_debugUart,(char*)"+EXIT sms_listen()\n");
JMF 1:f925e07b044d 769 }
JMF 1:f925e07b044d 770
JMF 1:f925e07b044d 771 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 772 * process to check SMS messages that is called at the user specified period
JMF 1:f925e07b044d 773 *
JMF 1:f925e07b044d 774 * input: none
JMF 1:f925e07b044d 775 * output:none
JMF 1:f925e07b044d 776 * return:void
JMF 1:f925e07b044d 777 */
JMF 1:f925e07b044d 778 void WNC14A2AInterface::handle_sms_event()
JMF 1:f925e07b044d 779 {
JMF 1:f925e07b044d 780 int msgs_available;
JMF 1:f925e07b044d 781 debugOutput(_debugUart,(char*)"+CALLED handle_sms_event() called\n");
JMF 1:f925e07b044d 782
JMF 1:f925e07b044d 783 if ( _sms_cb && m_smsmoning ) {
JMF 1:f925e07b044d 784 CHK_WNCFE((_pwnc->getWncStatus()==FATAL_FLAG), fail);
JMF 1:f925e07b044d 785 _pwnc_mutex.lock();
JMF 1:f925e07b044d 786 msgs_available = _pwnc->readUnreadSMSText(&m_smsmsgs, true);
JMF 1:f925e07b044d 787 _pwnc_mutex.unlock();
JMF 1:f925e07b044d 788 if( msgs_available ) {
JMF 1:f925e07b044d 789 debugOutput(_debugUart,(char*)"+Have %d unread texts present\n",m_smsmsgs.msgCount);
JMF 1:f925e07b044d 790 for( int i=0; i< m_smsmsgs.msgCount; i++ ) {
JMF 1:f925e07b044d 791 m_MsgText.number = m_smsmsgs.e[i].number;
JMF 1:f925e07b044d 792 m_MsgText.date = m_smsmsgs.e[i].date;
JMF 1:f925e07b044d 793 m_MsgText.time = m_smsmsgs.e[i].time;
JMF 1:f925e07b044d 794 m_MsgText.msg = m_smsmsgs.e[i].msg;
JMF 1:f925e07b044d 795 _sms_cb(&m_MsgText);
JMF 1:f925e07b044d 796 }
JMF 1:f925e07b044d 797 }
JMF 1:f925e07b044d 798 }
JMF 1:f925e07b044d 799 debugOutput(_debugUart,(char*)"+EXIT handle_sms_event\n");
JMF 1:f925e07b044d 800 }
JMF 1:f925e07b044d 801
JMF 1:f925e07b044d 802
JMF 1:f925e07b044d 803 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 804 * Check for any SMS messages that are present. If there are, then
JMF 1:f925e07b044d 805 * fetch them and pass to the users call-back function for processing
JMF 1:f925e07b044d 806 *
JMF 1:f925e07b044d 807 * input: pointer to a IOTSMS message buffer array (may be more than 1 msg)
JMF 1:f925e07b044d 808 * output:message buffer pointer is updated
JMF 1:f925e07b044d 809 * return: the number of messages being returned
JMF 1:f925e07b044d 810 */
JMF 1:f925e07b044d 811 int WNC14A2AInterface::getSMS(IOTSMS **pmsg)
JMF 1:f925e07b044d 812 {
JMF 1:f925e07b044d 813 int msgs_available;
JMF 1:f925e07b044d 814
JMF 1:f925e07b044d 815 debugOutput(_debugUart,(char*)"+CALLED getSMS()\n");
JMF 1:f925e07b044d 816 CHK_WNCFE((_pwnc->getWncStatus()==FATAL_FLAG), fail);
JMF 1:f925e07b044d 817
JMF 1:f925e07b044d 818 _pwnc_mutex.lock();
JMF 1:f925e07b044d 819 msgs_available = _pwnc->readUnreadSMSText(&m_smsmsgs, true);
JMF 1:f925e07b044d 820 _pwnc_mutex.unlock();
JMF 1:f925e07b044d 821
JMF 1:f925e07b044d 822 if( msgs_available ) {
JMF 1:f925e07b044d 823 debugOutput(_debugUart,(char*)"+Have %d unread texts present\n",m_smsmsgs.msgCount);
JMF 1:f925e07b044d 824 for( int i=0; i< m_smsmsgs.msgCount; i++ ) {
JMF 1:f925e07b044d 825 m_MsgText_array[i].number = m_smsmsgs.e[i].number;
JMF 1:f925e07b044d 826 m_MsgText_array[i].date = m_smsmsgs.e[i].date;
JMF 1:f925e07b044d 827 m_MsgText_array[i].time = m_smsmsgs.e[i].time;
JMF 1:f925e07b044d 828 m_MsgText_array[i].msg = m_smsmsgs.e[i].msg;
JMF 1:f925e07b044d 829 pmsg[i] = (IOTSMS*)&m_MsgText_array[i];
JMF 1:f925e07b044d 830 }
JMF 1:f925e07b044d 831 debugOutput(_debugUart,(char*)"+DONE getting messages\n");
JMF 1:f925e07b044d 832 msgs_available = m_smsmsgs.msgCount;
JMF 1:f925e07b044d 833 }
JMF 1:f925e07b044d 834 debugOutput(_debugUart,(char*)"+EXIT getSMS\n");
JMF 1:f925e07b044d 835 return msgs_available;
JMF 1:f925e07b044d 836 }
JMF 1:f925e07b044d 837
JMF 1:f925e07b044d 838
JMF 1:f925e07b044d 839 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 840 * send a message to the specified user number.
JMF 1:f925e07b044d 841 *
JMF 1:f925e07b044d 842 * input: string containing users number
JMF 1:f925e07b044d 843 * string with users message
JMF 1:f925e07b044d 844 * ouput: none
JMF 1:f925e07b044d 845 *
JMF 1:f925e07b044d 846 * return: true if no problems occures, false if failed to send
JMF 1:f925e07b044d 847 */
JMF 1:f925e07b044d 848 int WNC14A2AInterface::sendIOTSms(const string& number, const string& message)
JMF 1:f925e07b044d 849 {
JMF 1:f925e07b044d 850
JMF 1:f925e07b044d 851 debugOutput(_debugUart,(char*)"+CALLED sendIOTSms(%s,%s)\n",number.c_str(), message.c_str());
JMF 1:f925e07b044d 852 _pwnc_mutex.lock();
JMF 1:f925e07b044d 853 int i = _pwnc->sendSMSText((char*)number.c_str(), message.c_str());
JMF 1:f925e07b044d 854 _pwnc_mutex.unlock();
JMF 1:f925e07b044d 855
JMF 1:f925e07b044d 856 return i;
JMF 1:f925e07b044d 857 }
JMF 1:f925e07b044d 858
JMF 1:f925e07b044d 859 //
JMF 1:f925e07b044d 860 //-------------------------------------------------------------------------
JMF 1:f925e07b044d 861 //-------------------------------------------------------------------------
JMF 1:f925e07b044d 862 //-------------------------------------------------------------------------
JMF 1:f925e07b044d 863 // NetworkStack API's that are not support in the WNC14A2A
JMF 1:f925e07b044d 864 //-------------------------------------------------------------------------
JMF 1:f925e07b044d 865 //-------------------------------------------------------------------------
JMF 1:f925e07b044d 866 //-------------------------------------------------------------------------
JMF 1:f925e07b044d 867 //
JMF 1:f925e07b044d 868
JMF 1:f925e07b044d 869 int inline WNC14A2AInterface::socket_accept(nsapi_socket_t server, nsapi_socket_t *handle, SocketAddress *address)
JMF 1:f925e07b044d 870 {
JMF 1:f925e07b044d 871 debugOutput(_debugUart,(char*)"+CALLED socket_accept()\n");
JMF 1:f925e07b044d 872 _errors = NSAPI_ERROR_UNSUPPORTED;
JMF 1:f925e07b044d 873 return -1;
JMF 1:f925e07b044d 874 }
JMF 1:f925e07b044d 875
JMF 1:f925e07b044d 876 int inline WNC14A2AInterface::socket_bind(void *handle, const SocketAddress &address)
JMF 1:f925e07b044d 877 {
JMF 1:f925e07b044d 878 debugOutput(_debugUart,(char*)"+CALLED socket_bind()\n");
JMF 1:f925e07b044d 879 _errors = NSAPI_ERROR_UNSUPPORTED;
JMF 1:f925e07b044d 880 return -1;
JMF 1:f925e07b044d 881 }
JMF 1:f925e07b044d 882
JMF 1:f925e07b044d 883
JMF 1:f925e07b044d 884 int inline WNC14A2AInterface::socket_listen(void *handle, int backlog)
JMF 1:f925e07b044d 885 {
JMF 1:f925e07b044d 886 debugOutput(_debugUart,(char*)"+CALLED socket_listen()\n");
JMF 1:f925e07b044d 887 _errors = NSAPI_ERROR_UNSUPPORTED;
JMF 1:f925e07b044d 888 return -1;
JMF 1:f925e07b044d 889 }
JMF 1:f925e07b044d 890