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 easy-connect111

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:
Wed Apr 19 01:05:21 2017 +0000
Revision:
5:d197692c4447
Parent:
1:f925e07b044d
Child:
6:7fd9e590c4e7
Modified behavior of get_ip_address.

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 5:d197692c4447 59 WNC14A2AInterface::WNC14A2AInterface(BufferedSerial *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 1:f925e07b044d 330
JMF 1:f925e07b044d 331 debugOutput(_debugUart,(char*)"+ENTER gethostbyname()()\n+CURRENTLY:\n");
JMF 1:f925e07b044d 332 debugOutput(_debugUart,(char*)"+URL = %s\n+IP = %s\n+PORT= %d\n", name, address->get_ip_address(), address->get_port());
JMF 1:f925e07b044d 333 memset(ipAddrStr,0x00,sizeof(ipAddrStr));
JMF 1:f925e07b044d 334
JMF 1:f925e07b044d 335 if (!_pwnc || m_active_socket == -1)
JMF 1:f925e07b044d 336 return (_errors = NSAPI_ERROR_NO_SOCKET);
JMF 1:f925e07b044d 337
JMF 1:f925e07b044d 338 //Execute DNS query.
JMF 1:f925e07b044d 339 if( !_pwnc->resolveUrl(m_active_socket, name) )
JMF 1:f925e07b044d 340 return (_errors = NSAPI_ERROR_DEVICE_ERROR);
JMF 1:f925e07b044d 341
JMF 1:f925e07b044d 342 //Now, get the IP address that the URL was resolved to
JMF 1:f925e07b044d 343 if( !_pwnc->getIpAddr(m_active_socket, ipAddrStr) )
JMF 1:f925e07b044d 344 return (_errors = NSAPI_ERROR_DEVICE_ERROR);
JMF 1:f925e07b044d 345
JMF 1:f925e07b044d 346 _sockets[m_active_socket].url=name;
JMF 1:f925e07b044d 347 _sockets[m_active_socket].addr.set_ip_address(ipAddrStr);
JMF 1:f925e07b044d 348 address->set_ip_address(ipAddrStr);
JMF 1:f925e07b044d 349
JMF 1:f925e07b044d 350 debugOutput(_debugUart,(char*)"+resolveUrl returned IP=%s\n",ipAddrStr);
JMF 1:f925e07b044d 351 debugOutput(_debugUart,(char*)"+EXIT gethostbyname()\n+URL = %s\n+IP = %s\n+PORT= %d\n\n",
JMF 1:f925e07b044d 352 _sockets[m_active_socket].url.c_str(), address->get_ip_address(),
JMF 1:f925e07b044d 353 address->get_port());
JMF 1:f925e07b044d 354 _errors = ret;
JMF 1:f925e07b044d 355 return ret;
JMF 1:f925e07b044d 356 }
JMF 1:f925e07b044d 357
JMF 1:f925e07b044d 358 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 359 * using the specified socket, send the data.
JMF 1:f925e07b044d 360 *
JMF 1:f925e07b044d 361 * Input: handle of the socket to use
JMF 1:f925e07b044d 362 * pointer to the data to send
JMF 1:f925e07b044d 363 * amount of data being sent
JMF 1:f925e07b044d 364 *
JMF 1:f925e07b044d 365 * Output: none
JMF 1:f925e07b044d 366 *
JMF 1:f925e07b044d 367 * Return: number of bytes that was sent
JMF 1:f925e07b044d 368 */
JMF 1:f925e07b044d 369 int WNC14A2AInterface::socket_send(void *handle, const void *data, unsigned size)
JMF 1:f925e07b044d 370 {
JMF 1:f925e07b044d 371 WNCSOCKET *wnc = (WNCSOCKET *)handle;
JMF 1:f925e07b044d 372 int r = -1;
JMF 1:f925e07b044d 373 debugOutput(_debugUart,(char*)"+ENTER socket_send()\n");
JMF 1:f925e07b044d 374
JMF 1:f925e07b044d 375 if (!_pwnc || m_active_socket == -1) {
JMF 1:f925e07b044d 376 _errors = NSAPI_ERROR_NO_SOCKET;
JMF 1:f925e07b044d 377 return 0;
JMF 1:f925e07b044d 378 }
JMF 1:f925e07b044d 379 else
JMF 1:f925e07b044d 380 m_active_socket = wnc->socket; //just in case sending to a socket that wasn't last used
JMF 1:f925e07b044d 381
JMF 1:f925e07b044d 382 debugOutput(_debugUart,(char*)"+SOCKET %d is %s, URL=%s, IP=%s, PORT=%d\n",m_active_socket,
JMF 1:f925e07b044d 383 (char*)wnc->opened?"OPEN":"CLOSED",wnc->url.c_str(),wnc->addr.get_ip_address(),wnc->addr.get_port());
JMF 1:f925e07b044d 384 debugOutput(_debugUart,(char*)"+WRITE [%s] (%d bytes) to socket #%d\n",data,size,wnc->socket);
JMF 1:f925e07b044d 385
JMF 1:f925e07b044d 386 _pwnc_mutex.lock();
JMF 1:f925e07b044d 387 if( _pwnc->write(m_active_socket, (const uint8_t*)data, size) )
JMF 1:f925e07b044d 388 r = size;
JMF 1:f925e07b044d 389 else
JMF 1:f925e07b044d 390 debugOutput(_debugUart,(char*)"+ERROR: write to socket %d failed!\n",m_active_socket);
JMF 1:f925e07b044d 391 _pwnc_mutex.unlock();
JMF 1:f925e07b044d 392
JMF 1:f925e07b044d 393 debugOutput(_debugUart,(char*)"+EXIT socket_send(), successful: %d\n\n",r);
JMF 1:f925e07b044d 394 return r;
JMF 1:f925e07b044d 395 }
JMF 1:f925e07b044d 396
JMF 1:f925e07b044d 397 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 398 * Called to receive data.
JMF 1:f925e07b044d 399 *
JMF 1:f925e07b044d 400 * Input: handle to the socket we want to read from
JMF 1:f925e07b044d 401 *
JMF 1:f925e07b044d 402 * Output: data we receive is placed into the data buffer
JMF 1:f925e07b044d 403 * size is the size of the buffer
JMF 1:f925e07b044d 404 *
JMF 1:f925e07b044d 405 * Returns: The number of bytes received or -1 if an error occured
JMF 1:f925e07b044d 406 */
JMF 1:f925e07b044d 407 int WNC14A2AInterface::socket_recv(void *handle, void *data, unsigned size)
JMF 1:f925e07b044d 408 {
JMF 1:f925e07b044d 409 WNCSOCKET *wnc = (WNCSOCKET *)handle;
JMF 1:f925e07b044d 410 size_t done, cnt;
JMF 1:f925e07b044d 411 Timer t;
JMF 1:f925e07b044d 412
JMF 1:f925e07b044d 413 debugOutput(_debugUart,(char*)"+ENTER socket_recv(); read up to %d bytes\n",size);
JMF 1:f925e07b044d 414
JMF 1:f925e07b044d 415 memset(data,0x00,size);
JMF 1:f925e07b044d 416 if (!_pwnc || m_active_socket == -1) {
JMF 1:f925e07b044d 417 _errors = NSAPI_ERROR_NO_SOCKET;
JMF 1:f925e07b044d 418 return -1;
JMF 1:f925e07b044d 419 }
JMF 1:f925e07b044d 420 else
JMF 1:f925e07b044d 421 m_active_socket = wnc->socket; //just in case sending to a socket that wasn't last used
JMF 1:f925e07b044d 422
JMF 1:f925e07b044d 423 t.start();
JMF 1:f925e07b044d 424 do {
JMF 1:f925e07b044d 425 if( !(t.read_ms() % READ_EVERYMS) )
JMF 1:f925e07b044d 426 cnt = done = _pwnc->read(m_active_socket, (uint8_t *)data, (uint32_t) size);
JMF 1:f925e07b044d 427 done = (cnt || (t.read_ms() > WNC14A2A_MISC_TIMEOUT))? 1:0;
JMF 1:f925e07b044d 428 }
JMF 1:f925e07b044d 429 while( !done );
JMF 1:f925e07b044d 430 t.stop();
JMF 1:f925e07b044d 431
JMF 1:f925e07b044d 432 if( _pwnc->getWncStatus() != WNC_GOOD ) {
JMF 1:f925e07b044d 433 _errors = NSAPI_ERROR_DEVICE_ERROR;
JMF 1:f925e07b044d 434 return -1;
JMF 1:f925e07b044d 435 }
JMF 1:f925e07b044d 436
JMF 1:f925e07b044d 437 debugOutput(_debugUart,(char*)"+EXIT socket_recv(), ret=%d\n",cnt);
JMF 1:f925e07b044d 438 return cnt;
JMF 1:f925e07b044d 439 }
JMF 1:f925e07b044d 440
JMF 1:f925e07b044d 441 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 442 * Close a socket
JMF 1:f925e07b044d 443 *
JMF 1:f925e07b044d 444 * Input: the handle to the socket to close
JMF 1:f925e07b044d 445 *
JMF 1:f925e07b044d 446 * Output: none
JMF 1:f925e07b044d 447 *
JMF 1:f925e07b044d 448 * Return: -1 on error, otherwise 0
JMF 1:f925e07b044d 449 */
JMF 1:f925e07b044d 450 int WNC14A2AInterface::socket_close(void *handle)
JMF 1:f925e07b044d 451 {
JMF 1:f925e07b044d 452 WNCSOCKET *wnc = (WNCSOCKET*)handle;
JMF 1:f925e07b044d 453 debugOutput(_debugUart,(char*)"+CALLED socket_close()\n");
JMF 1:f925e07b044d 454
JMF 1:f925e07b044d 455 if (!_pwnc || m_active_socket == -1) {
JMF 1:f925e07b044d 456 _errors = NSAPI_ERROR_NO_SOCKET;
JMF 1:f925e07b044d 457 return -1;
JMF 1:f925e07b044d 458 }
JMF 1:f925e07b044d 459 else
JMF 1:f925e07b044d 460 m_active_socket = wnc->socket; //just in case sending to a socket that wasn't last used
JMF 1:f925e07b044d 461
JMF 1:f925e07b044d 462 if( !_pwnc->closeSocket(m_active_socket) ) {
JMF 1:f925e07b044d 463 _errors = NSAPI_ERROR_DEVICE_ERROR;
JMF 1:f925e07b044d 464 return -1;
JMF 1:f925e07b044d 465 }
JMF 1:f925e07b044d 466
JMF 1:f925e07b044d 467 wnc->opened = false; //no longer in use
JMF 1:f925e07b044d 468 wnc->addr = NULL; //not open
JMF 1:f925e07b044d 469 wnc->proto = 0; //assume TCP for now
JMF 1:f925e07b044d 470 _errors = NSAPI_ERROR_OK;
JMF 1:f925e07b044d 471 return 0;
JMF 1:f925e07b044d 472 }
JMF 1:f925e07b044d 473
JMF 1:f925e07b044d 474 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 475 * return the MAC for this device. Because there is no MAC Ethernet
JMF 1:f925e07b044d 476 * address to return, this function returns a bogus MAC address created
JMF 1:f925e07b044d 477 * from the ICCD on the SIM that is being used.
JMF 1:f925e07b044d 478 *
JMF 1:f925e07b044d 479 * Input: none
JMF 1:f925e07b044d 480 *
JMF 1:f925e07b044d 481 * Output: none
JMF 1:f925e07b044d 482 *
JMF 1:f925e07b044d 483 * Return: MAC string containing "NN:NN:NN:NN:NN:NN" or NULL
JMF 1:f925e07b044d 484 */
JMF 1:f925e07b044d 485 const char *WNC14A2AInterface::get_mac_address()
JMF 1:f925e07b044d 486 {
JMF 1:f925e07b044d 487 string mac, str;
JMF 1:f925e07b044d 488 debugOutput(_debugUart,(char*)"+ENTER get_mac_address()\n");
JMF 1:f925e07b044d 489
JMF 1:f925e07b044d 490 if( _pwnc->getICCID(&str) ) {
JMF 1:f925e07b044d 491 CHK_WNCFE((_pwnc->getWncStatus()==FATAL_FLAG), null);
JMF 1:f925e07b044d 492 mac = str.substr(3,20);
JMF 1:f925e07b044d 493 mac[2]=mac[5]=mac[8]=mac[11]=mac[14]=':';
JMF 1:f925e07b044d 494 strncpy(_mac_address, mac.c_str(), mac.length());
JMF 1:f925e07b044d 495 return _mac_address;
JMF 1:f925e07b044d 496 }
JMF 1:f925e07b044d 497 return NULL;
JMF 1:f925e07b044d 498 }
JMF 1:f925e07b044d 499
JMF 1:f925e07b044d 500 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 501 * return a pointer to the current WNC14A2AInterface
JMF 1:f925e07b044d 502 */
JMF 1:f925e07b044d 503 NetworkStack *WNC14A2AInterface::get_stack() {
JMF 1:f925e07b044d 504 debugOutput(_debugUart,(char*)"+CALLED get_stack()\n");
JMF 1:f925e07b044d 505 return this;
JMF 1:f925e07b044d 506 }
JMF 1:f925e07b044d 507
JMF 1:f925e07b044d 508 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 509 * Disconnnect from the 14A2A, but we can not do that
JMF 1:f925e07b044d 510 * so just return saying everything is ok.
JMF 1:f925e07b044d 511 */
JMF 1:f925e07b044d 512 nsapi_error_t WNC14A2AInterface::disconnect()
JMF 1:f925e07b044d 513 {
JMF 1:f925e07b044d 514 debugOutput(_debugUart,(char*)"+CALLED disconnect()\n");
JMF 1:f925e07b044d 515 return NSAPI_ERROR_OK;
JMF 1:f925e07b044d 516 }
JMF 1:f925e07b044d 517
JMF 1:f925e07b044d 518 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 519 * allow the user to change the APN. The API takes username and password
JMF 1:f925e07b044d 520 * but they are not used.
JMF 1:f925e07b044d 521 *
JMF 1:f925e07b044d 522 * Input: apn string
JMF 1:f925e07b044d 523 * username - not used
JMF 1:f925e07b044d 524 * password - not used
JMF 1:f925e07b044d 525 *
JMF 1:f925e07b044d 526 * Output: none
JMF 1:f925e07b044d 527 *
JMF 1:f925e07b044d 528 * Return: nsapi_error_t
JMF 1:f925e07b044d 529 */
JMF 1:f925e07b044d 530 nsapi_error_t WNC14A2AInterface::set_credentials(const char *apn, const char *username, const char *password)
JMF 1:f925e07b044d 531 {
JMF 1:f925e07b044d 532 debugOutput(_debugUart,(char*)"+ENTER set_credentials()\n");
JMF 1:f925e07b044d 533 if( !_pwnc )
JMF 1:f925e07b044d 534 return (_errors=NSAPI_ERROR_NO_CONNECTION);
JMF 1:f925e07b044d 535
JMF 1:f925e07b044d 536 if( !apn )
JMF 1:f925e07b044d 537 return (_errors=NSAPI_ERROR_PARAMETER);
JMF 1:f925e07b044d 538
JMF 1:f925e07b044d 539 if( !_pwnc->setApnName(apn) )
JMF 1:f925e07b044d 540 return (_errors=NSAPI_ERROR_DEVICE_ERROR);
JMF 1:f925e07b044d 541
JMF 1:f925e07b044d 542 return (_errors=NSAPI_ERROR_OK);
JMF 1:f925e07b044d 543 }
JMF 1:f925e07b044d 544
JMF 1:f925e07b044d 545 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 546 * Register a callback on state change of the socket.FROM NetworkStack
JMF 1:f925e07b044d 547 * @param handle Socket handle
JMF 1:f925e07b044d 548 * @param callback Function to call on state change
JMF 1:f925e07b044d 549 * @param data Argument to pass to callback
JMF 1:f925e07b044d 550 * @note Callback may be called in an interrupt context.
JMF 1:f925e07b044d 551 */
JMF 1:f925e07b044d 552 void WNC14A2AInterface::socket_attach(void *handle, void (*callback)(void *), void *data)
JMF 1:f925e07b044d 553 {
JMF 1:f925e07b044d 554 debugOutput(_debugUart,(char*)"+CALLED socket_attach()\n");
JMF 1:f925e07b044d 555 }
JMF 1:f925e07b044d 556
JMF 1:f925e07b044d 557 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 558 * check to see if we are currently regisered with the network.
JMF 1:f925e07b044d 559 *
JMF 1:f925e07b044d 560 * Input: none
JMF 1:f925e07b044d 561 *
JMF 1:f925e07b044d 562 * Output: none
JMF 1:f925e07b044d 563 *
JMF 1:f925e07b044d 564 * Return: ture if we are registerd, false if not or an error occured
JMF 1:f925e07b044d 565 */
JMF 1:f925e07b044d 566 bool WNC14A2AInterface::registered()
JMF 1:f925e07b044d 567 {
JMF 1:f925e07b044d 568 debugOutput(_debugUart,(char*)"+ENTER registered()\n");
JMF 1:f925e07b044d 569 if( !_pwnc ) {
JMF 1:f925e07b044d 570 _errors=NSAPI_ERROR_NO_CONNECTION;
JMF 1:f925e07b044d 571 return false;
JMF 1:f925e07b044d 572 }
JMF 1:f925e07b044d 573
JMF 1:f925e07b044d 574 if ( _pwnc->getWncStatus() == WNC_GOOD ){
JMF 1:f925e07b044d 575 _errors=NSAPI_ERROR_OK;
JMF 1:f925e07b044d 576 return true;
JMF 1:f925e07b044d 577 }
JMF 1:f925e07b044d 578 _errors=NSAPI_ERROR_NO_CONNECTION;
JMF 1:f925e07b044d 579 return false;
JMF 1:f925e07b044d 580 }
JMF 1:f925e07b044d 581
JMF 1:f925e07b044d 582 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 583 * doDebug is just a handy way to allow a developer to set different levels
JMF 1:f925e07b044d 584 * of debug for the WNC14A2A device.
JMF 1:f925e07b044d 585 *
JMF 1:f925e07b044d 586 * Input: a Bitfield of -
JMF 1:f925e07b044d 587 * basic debug = 0x01
JMF 1:f925e07b044d 588 * more debug = 0x02
JMF 1:f925e07b044d 589 * network debug = 0x04
JMF 1:f925e07b044d 590 * all debug = 0x07
JMF 1:f925e07b044d 591 *
JMF 1:f925e07b044d 592 * Output: none
JMF 1:f925e07b044d 593 *
JMF 1:f925e07b044d 594 * Returns: void
JMF 1:f925e07b044d 595 */
JMF 1:f925e07b044d 596 void WNC14A2AInterface::doDebug( int v )
JMF 1:f925e07b044d 597 {
JMF 1:f925e07b044d 598 if( !_pwnc )
JMF 1:f925e07b044d 599 _errors = NSAPI_ERROR_DEVICE_ERROR;
JMF 1:f925e07b044d 600 else
JMF 1:f925e07b044d 601 _pwnc->enableDebug( (v&1), (v&2) );
JMF 1:f925e07b044d 602
JMF 1:f925e07b044d 603 m_debug=(v&4);
JMF 1:f925e07b044d 604 debugOutput(_debugUart,(char*)"+SETTING debug flag to 0x%02X\n",v);
JMF 1:f925e07b044d 605 }
JMF 1:f925e07b044d 606
JMF 1:f925e07b044d 607 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 608 * Simple function to allow for writing debug messages. It always
JMF 1:f925e07b044d 609 * checks to see if debug has been enabled or not before it
JMF 1:f925e07b044d 610 * outputs the message.
JMF 1:f925e07b044d 611 *
JMF 1:f925e07b044d 612 * Input: The debug uart pointer followed by format string and vars
JMF 1:f925e07b044d 613 *
JMF 1:f925e07b044d 614 * Output: none
JMF 1:f925e07b044d 615 *
JMF 1:f925e07b044d 616 * Return: void
JMF 1:f925e07b044d 617 */
JMF 1:f925e07b044d 618 void WNC14A2AInterface::debugOutput(BufferedSerial *dbgOut, char * format, ...)
JMF 1:f925e07b044d 619 {
JMF 1:f925e07b044d 620 if( dbgOut && m_debug ) {
JMF 1:f925e07b044d 621 char buffer[256];
JMF 1:f925e07b044d 622 va_list args;
JMF 1:f925e07b044d 623 va_start (args, format);
JMF 1:f925e07b044d 624 vsnprintf(buffer, sizeof(buffer), format, args);
JMF 1:f925e07b044d 625 dbgOut->puts(buffer);
JMF 1:f925e07b044d 626 va_end (args);
JMF 1:f925e07b044d 627 }
JMF 1:f925e07b044d 628 }
JMF 1:f925e07b044d 629
JMF 1:f925e07b044d 630
JMF 1:f925e07b044d 631 ////////////////////////////////////////////////////////////////////
JMF 1:f925e07b044d 632 // UDP methods
JMF 1:f925e07b044d 633 ///////////////////////////////////////////////////////////////////
JMF 1:f925e07b044d 634
JMF 1:f925e07b044d 635 //-------------------------------------------------------------------------
JMF 1:f925e07b044d 636 //sends data to a UDP socket
JMF 1:f925e07b044d 637 int WNC14A2AInterface::socket_sendto(void *handle, const SocketAddress &address, const void *data, unsigned size)
JMF 1:f925e07b044d 638 {
JMF 1:f925e07b044d 639 WNCSOCKET *wnc = (WNCSOCKET *)handle;
JMF 1:f925e07b044d 640
JMF 1:f925e07b044d 641 debugOutput(_debugUart,(char*)"+CALLED socket_sendto()\n");
JMF 1:f925e07b044d 642 CHK_WNCFE(( _pwnc->getWncStatus() == FATAL_FLAG ), fail);
JMF 1:f925e07b044d 643 if (!wnc->opened) {
JMF 1:f925e07b044d 644 int err = socket_connect(wnc, address);
JMF 1:f925e07b044d 645 if (err < 0)
JMF 1:f925e07b044d 646 return err;
JMF 1:f925e07b044d 647 }
JMF 1:f925e07b044d 648 wnc->addr = address;
JMF 1:f925e07b044d 649
JMF 1:f925e07b044d 650 return socket_send(wnc, data, size);
JMF 1:f925e07b044d 651 }
JMF 1:f925e07b044d 652
JMF 1:f925e07b044d 653 //receives from a UDP socket
JMF 1:f925e07b044d 654 int WNC14A2AInterface::socket_recvfrom(void *handle, SocketAddress *address, void *buffer, unsigned size)
JMF 1:f925e07b044d 655 {
JMF 1:f925e07b044d 656 WNCSOCKET *wnc = (WNCSOCKET *)handle;
JMF 1:f925e07b044d 657 debugOutput(_debugUart,(char*)"+CALLED socket_recvfrom()\n");
JMF 1:f925e07b044d 658 int ret = socket_recv(wnc, (char *)buffer, size);
JMF 1:f925e07b044d 659 if (ret >= 0 && address)
JMF 1:f925e07b044d 660 *address = wnc->addr;
JMF 1:f925e07b044d 661 return ret;
JMF 1:f925e07b044d 662 }
JMF 1:f925e07b044d 663
JMF 1:f925e07b044d 664 ////////////////////////////////////////////////////////////////////
JMF 1:f925e07b044d 665 // SMS methods
JMF 1:f925e07b044d 666 ///////////////////////////////////////////////////////////////////
JMF 1:f925e07b044d 667
JMF 1:f925e07b044d 668 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 669 * IOTSMS message don't use a phone number, they use the device ICCID. This
JMF 1:f925e07b044d 670 * function returns the ICCID based number that is used for this device.
JMF 1:f925e07b044d 671 *
JMF 1:f925e07b044d 672 * Input: none
JMF 1:f925e07b044d 673 * Output: none
JMF 1:f925e07b044d 674 * Return: string containing the IOTSMS number to use
JMF 1:f925e07b044d 675 */
JMF 1:f925e07b044d 676 char* WNC14A2AInterface::getSMSnbr( void )
JMF 1:f925e07b044d 677 {
JMF 1:f925e07b044d 678 char * ret=NULL;
JMF 1:f925e07b044d 679 string iccid_str;
JMF 1:f925e07b044d 680 static string msisdn_str;
JMF 1:f925e07b044d 681
JMF 1:f925e07b044d 682 if( !_pwnc ) {
JMF 1:f925e07b044d 683 _errors=NSAPI_ERROR_NO_CONNECTION;
JMF 1:f925e07b044d 684 return NULL;
JMF 1:f925e07b044d 685 }
JMF 1:f925e07b044d 686
JMF 1:f925e07b044d 687 CHK_WNCFE(( _pwnc->getWncStatus() == FATAL_FLAG ), null);
JMF 1:f925e07b044d 688
JMF 1:f925e07b044d 689 if( !_pwnc->getICCID(&iccid_str) )
JMF 1:f925e07b044d 690 return ret;
JMF 1:f925e07b044d 691
JMF 1:f925e07b044d 692 CHK_WNCFE(( _pwnc->getWncStatus() == FATAL_FLAG ), null);
JMF 1:f925e07b044d 693
JMF 1:f925e07b044d 694 if( _pwnc->convertICCIDtoMSISDN(iccid_str, &msisdn_str) )
JMF 1:f925e07b044d 695 ret = (char*)msisdn_str.c_str();
JMF 1:f925e07b044d 696 return ret;
JMF 1:f925e07b044d 697 }
JMF 1:f925e07b044d 698
JMF 1:f925e07b044d 699
JMF 1:f925e07b044d 700 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 701 * Normally the user attaches his call-back function when performing
JMF 1:f925e07b044d 702 * the listen call which enables the SMS system, but this function
JMF 1:f925e07b044d 703 * allows them to update the callback if desired.
JMF 1:f925e07b044d 704 *
JMF 1:f925e07b044d 705 * input: pointer to the function to call
JMF 1:f925e07b044d 706 * output: none
JMF 1:f925e07b044d 707 * return: none
JMF 1:f925e07b044d 708 */
JMF 1:f925e07b044d 709 void WNC14A2AInterface::sms_attach(void (*callback)(IOTSMS *))
JMF 1:f925e07b044d 710 {
JMF 1:f925e07b044d 711 debugOutput(_debugUart,(char*)"+CALLED sms_attach() called\n");
JMF 1:f925e07b044d 712 _sms_cb = callback;
JMF 1:f925e07b044d 713 }
JMF 1:f925e07b044d 714
JMF 1:f925e07b044d 715 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 716 * Call this to start the SMS system. It is needed to reset the WNC
JMF 1:f925e07b044d 717 * internal data structures related to SMS messaging
JMF 1:f925e07b044d 718 */
JMF 1:f925e07b044d 719 void WNC14A2AInterface::sms_start(void)
JMF 1:f925e07b044d 720 {
JMF 1:f925e07b044d 721 _pwnc_mutex.lock(); //delete any message currently in storage
JMF 1:f925e07b044d 722 _pwnc->deleteSMSTextFromMem('*'); //so we are notified of new incomming messages
JMF 1:f925e07b044d 723 _pwnc_mutex.unlock();
JMF 1:f925e07b044d 724 }
JMF 1:f925e07b044d 725
JMF 1:f925e07b044d 726 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 727 * Initialize the IoT SMS system. Initializing it allows the user to set a
JMF 1:f925e07b044d 728 * polling period to check for SMS messages, and a SMS is recevied, then
JMF 1:f925e07b044d 729 * a user provided function is called.
JMF 1:f925e07b044d 730 *
JMF 1:f925e07b044d 731 * Input: polling period in seconds. If not specified 30 seconds is used.
JMF 1:f925e07b044d 732 * pointer to a users calllback function
JMF 1:f925e07b044d 733 * Output: none
JMF 1:f925e07b044d 734 *
JMF 1:f925e07b044d 735 * Returns: void
JMF 1:f925e07b044d 736 */
JMF 1:f925e07b044d 737 void WNC14A2AInterface::sms_listen(uint16_t pp)
JMF 1:f925e07b044d 738 {
JMF 1:f925e07b044d 739 debugOutput(_debugUart,(char*)"+CALLED sms_listen(%d) called\n",pp);
JMF 1:f925e07b044d 740 if( !_pwnc ) {
JMF 1:f925e07b044d 741 _errors=NSAPI_ERROR_NO_CONNECTION;
JMF 1:f925e07b044d 742 return;
JMF 1:f925e07b044d 743 }
JMF 1:f925e07b044d 744
JMF 1:f925e07b044d 745 CHK_WNCFE(( _pwnc->getWncStatus() == FATAL_FLAG ), fail);
JMF 1:f925e07b044d 746
JMF 1:f925e07b044d 747 if( m_smsmoning )
JMF 1:f925e07b044d 748 m_smsmoning = false;
JMF 1:f925e07b044d 749 if( pp < 1)
JMF 1:f925e07b044d 750 pp = 30;
JMF 1:f925e07b044d 751
JMF 1:f925e07b044d 752
JMF 1:f925e07b044d 753 debugOutput(_debugUart,(char*)"+setup event queue\n");
JMF 1:f925e07b044d 754 smsThread.start(callback(&sms_queue,&EventQueue::dispatch_forever));
JMF 1:f925e07b044d 755
JMF 1:f925e07b044d 756 _pwnc_mutex.lock(); //delete any message currently in storage
JMF 1:f925e07b044d 757 _pwnc->deleteSMSTextFromMem('*'); //so we are notified of new incomming messages
JMF 1:f925e07b044d 758 _pwnc_mutex.unlock();
JMF 1:f925e07b044d 759 sms_queue.call_every(pp*1000, mbed::Callback<void()>((WNC14A2AInterface*)this,&WNC14A2AInterface::handle_sms_event));
JMF 1:f925e07b044d 760
JMF 1:f925e07b044d 761 m_smsmoning = true;
JMF 1:f925e07b044d 762 debugOutput(_debugUart,(char*)"+EXIT sms_listen()\n");
JMF 1:f925e07b044d 763 }
JMF 1:f925e07b044d 764
JMF 1:f925e07b044d 765 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 766 * process to check SMS messages that is called at the user specified period
JMF 1:f925e07b044d 767 *
JMF 1:f925e07b044d 768 * input: none
JMF 1:f925e07b044d 769 * output:none
JMF 1:f925e07b044d 770 * return:void
JMF 1:f925e07b044d 771 */
JMF 1:f925e07b044d 772 void WNC14A2AInterface::handle_sms_event()
JMF 1:f925e07b044d 773 {
JMF 1:f925e07b044d 774 int msgs_available;
JMF 1:f925e07b044d 775 debugOutput(_debugUart,(char*)"+CALLED handle_sms_event() called\n");
JMF 1:f925e07b044d 776
JMF 1:f925e07b044d 777 if ( _sms_cb && m_smsmoning ) {
JMF 1:f925e07b044d 778 CHK_WNCFE((_pwnc->getWncStatus()==FATAL_FLAG), fail);
JMF 1:f925e07b044d 779 _pwnc_mutex.lock();
JMF 1:f925e07b044d 780 msgs_available = _pwnc->readUnreadSMSText(&m_smsmsgs, true);
JMF 1:f925e07b044d 781 _pwnc_mutex.unlock();
JMF 1:f925e07b044d 782 if( msgs_available ) {
JMF 1:f925e07b044d 783 debugOutput(_debugUart,(char*)"+Have %d unread texts present\n",m_smsmsgs.msgCount);
JMF 1:f925e07b044d 784 for( int i=0; i< m_smsmsgs.msgCount; i++ ) {
JMF 1:f925e07b044d 785 m_MsgText.number = m_smsmsgs.e[i].number;
JMF 1:f925e07b044d 786 m_MsgText.date = m_smsmsgs.e[i].date;
JMF 1:f925e07b044d 787 m_MsgText.time = m_smsmsgs.e[i].time;
JMF 1:f925e07b044d 788 m_MsgText.msg = m_smsmsgs.e[i].msg;
JMF 1:f925e07b044d 789 _sms_cb(&m_MsgText);
JMF 1:f925e07b044d 790 }
JMF 1:f925e07b044d 791 }
JMF 1:f925e07b044d 792 }
JMF 1:f925e07b044d 793 debugOutput(_debugUart,(char*)"+EXIT handle_sms_event\n");
JMF 1:f925e07b044d 794 }
JMF 1:f925e07b044d 795
JMF 1:f925e07b044d 796
JMF 1:f925e07b044d 797 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 798 * Check for any SMS messages that are present. If there are, then
JMF 1:f925e07b044d 799 * fetch them and pass to the users call-back function for processing
JMF 1:f925e07b044d 800 *
JMF 1:f925e07b044d 801 * input: pointer to a IOTSMS message buffer array (may be more than 1 msg)
JMF 1:f925e07b044d 802 * output:message buffer pointer is updated
JMF 1:f925e07b044d 803 * return: the number of messages being returned
JMF 1:f925e07b044d 804 */
JMF 1:f925e07b044d 805 int WNC14A2AInterface::getSMS(IOTSMS **pmsg)
JMF 1:f925e07b044d 806 {
JMF 1:f925e07b044d 807 int msgs_available;
JMF 1:f925e07b044d 808
JMF 1:f925e07b044d 809 debugOutput(_debugUart,(char*)"+CALLED getSMS()\n");
JMF 1:f925e07b044d 810 CHK_WNCFE((_pwnc->getWncStatus()==FATAL_FLAG), fail);
JMF 1:f925e07b044d 811
JMF 1:f925e07b044d 812 _pwnc_mutex.lock();
JMF 1:f925e07b044d 813 msgs_available = _pwnc->readUnreadSMSText(&m_smsmsgs, true);
JMF 1:f925e07b044d 814 _pwnc_mutex.unlock();
JMF 1:f925e07b044d 815
JMF 1:f925e07b044d 816 if( msgs_available ) {
JMF 1:f925e07b044d 817 debugOutput(_debugUart,(char*)"+Have %d unread texts present\n",m_smsmsgs.msgCount);
JMF 1:f925e07b044d 818 for( int i=0; i< m_smsmsgs.msgCount; i++ ) {
JMF 1:f925e07b044d 819 m_MsgText_array[i].number = m_smsmsgs.e[i].number;
JMF 1:f925e07b044d 820 m_MsgText_array[i].date = m_smsmsgs.e[i].date;
JMF 1:f925e07b044d 821 m_MsgText_array[i].time = m_smsmsgs.e[i].time;
JMF 1:f925e07b044d 822 m_MsgText_array[i].msg = m_smsmsgs.e[i].msg;
JMF 1:f925e07b044d 823 pmsg[i] = (IOTSMS*)&m_MsgText_array[i];
JMF 1:f925e07b044d 824 }
JMF 1:f925e07b044d 825 debugOutput(_debugUart,(char*)"+DONE getting messages\n");
JMF 1:f925e07b044d 826 msgs_available = m_smsmsgs.msgCount;
JMF 1:f925e07b044d 827 }
JMF 1:f925e07b044d 828 debugOutput(_debugUart,(char*)"+EXIT getSMS\n");
JMF 1:f925e07b044d 829 return msgs_available;
JMF 1:f925e07b044d 830 }
JMF 1:f925e07b044d 831
JMF 1:f925e07b044d 832
JMF 1:f925e07b044d 833 /*-------------------------------------------------------------------------
JMF 1:f925e07b044d 834 * send a message to the specified user number.
JMF 1:f925e07b044d 835 *
JMF 1:f925e07b044d 836 * input: string containing users number
JMF 1:f925e07b044d 837 * string with users message
JMF 1:f925e07b044d 838 * ouput: none
JMF 1:f925e07b044d 839 *
JMF 1:f925e07b044d 840 * return: true if no problems occures, false if failed to send
JMF 1:f925e07b044d 841 */
JMF 1:f925e07b044d 842 int WNC14A2AInterface::sendIOTSms(const string& number, const string& message)
JMF 1:f925e07b044d 843 {
JMF 1:f925e07b044d 844
JMF 1:f925e07b044d 845 debugOutput(_debugUart,(char*)"+CALLED sendIOTSms(%s,%s)\n",number.c_str(), message.c_str());
JMF 1:f925e07b044d 846 _pwnc_mutex.lock();
JMF 1:f925e07b044d 847 int i = _pwnc->sendSMSText((char*)number.c_str(), message.c_str());
JMF 1:f925e07b044d 848 _pwnc_mutex.unlock();
JMF 1:f925e07b044d 849
JMF 1:f925e07b044d 850 return i;
JMF 1:f925e07b044d 851 }
JMF 1:f925e07b044d 852
JMF 1:f925e07b044d 853 //
JMF 1:f925e07b044d 854 //-------------------------------------------------------------------------
JMF 1:f925e07b044d 855 //-------------------------------------------------------------------------
JMF 1:f925e07b044d 856 //-------------------------------------------------------------------------
JMF 1:f925e07b044d 857 // NetworkStack API's that are not support in the WNC14A2A
JMF 1:f925e07b044d 858 //-------------------------------------------------------------------------
JMF 1:f925e07b044d 859 //-------------------------------------------------------------------------
JMF 1:f925e07b044d 860 //-------------------------------------------------------------------------
JMF 1:f925e07b044d 861 //
JMF 1:f925e07b044d 862
JMF 1:f925e07b044d 863 int inline WNC14A2AInterface::socket_accept(nsapi_socket_t server, nsapi_socket_t *handle, SocketAddress *address)
JMF 1:f925e07b044d 864 {
JMF 1:f925e07b044d 865 debugOutput(_debugUart,(char*)"+CALLED socket_accept()\n");
JMF 1:f925e07b044d 866 _errors = NSAPI_ERROR_UNSUPPORTED;
JMF 1:f925e07b044d 867 return -1;
JMF 1:f925e07b044d 868 }
JMF 1:f925e07b044d 869
JMF 1:f925e07b044d 870 int inline WNC14A2AInterface::socket_bind(void *handle, const SocketAddress &address)
JMF 1:f925e07b044d 871 {
JMF 1:f925e07b044d 872 debugOutput(_debugUart,(char*)"+CALLED socket_bind()\n");
JMF 1:f925e07b044d 873 _errors = NSAPI_ERROR_UNSUPPORTED;
JMF 1:f925e07b044d 874 return -1;
JMF 1:f925e07b044d 875 }
JMF 1:f925e07b044d 876
JMF 1:f925e07b044d 877
JMF 1:f925e07b044d 878 int inline WNC14A2AInterface::socket_listen(void *handle, int backlog)
JMF 1:f925e07b044d 879 {
JMF 1:f925e07b044d 880 debugOutput(_debugUart,(char*)"+CALLED socket_listen()\n");
JMF 1:f925e07b044d 881 _errors = NSAPI_ERROR_UNSUPPORTED;
JMF 1:f925e07b044d 882 return -1;
JMF 1:f925e07b044d 883 }
JMF 1:f925e07b044d 884