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:
Tue Apr 18 00:05:54 2017 +0000
Revision:
1:f925e07b044d
Parent:
0:d6cb9ca0bae4
Child:
5:d197692c4447
Added README file.

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