WNC14A2A LTE Interface

Dependencies:   WncControllerK64F

Fork of WNC14A2AInterface by Avnet

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