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