Jim Flynn
/
aws-iot-device-sdk-mbed-c
Changes to enabled on-line compiler
platform/ezconnect/wnc14a2a-driver/WNC14A2AInterface/WNC14A2AInterface.cpp@0:082731ede69f, 2018-05-30 (annotated)
- Committer:
- JMF
- Date:
- Wed May 30 20:59:51 2018 +0000
- Revision:
- 0:082731ede69f
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
JMF | 0:082731ede69f | 1 | /** |
JMF | 0:082731ede69f | 2 | * copyright (c) 2017-2018, James Flynn |
JMF | 0:082731ede69f | 3 | * SPDX-License-Identifier: Apache-2.0 |
JMF | 0:082731ede69f | 4 | */ |
JMF | 0:082731ede69f | 5 | |
JMF | 0:082731ede69f | 6 | /* |
JMF | 0:082731ede69f | 7 | * Licensed under the Apache License, Version 2.0 (the "License"); |
JMF | 0:082731ede69f | 8 | * you may not use this file except in compliance with the License. |
JMF | 0:082731ede69f | 9 | * You may obtain a copy of the License at |
JMF | 0:082731ede69f | 10 | * |
JMF | 0:082731ede69f | 11 | * http://www.apache.org/licenses/LICENSE-2.0 |
JMF | 0:082731ede69f | 12 | * |
JMF | 0:082731ede69f | 13 | * Unless required by applicable law or agreed to in writing, software |
JMF | 0:082731ede69f | 14 | * distributed under the License is distributed on an "AS IS" BASIS, |
JMF | 0:082731ede69f | 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
JMF | 0:082731ede69f | 16 | * |
JMF | 0:082731ede69f | 17 | * See the License for the specific language governing permissions and |
JMF | 0:082731ede69f | 18 | * limitations under the License. |
JMF | 0:082731ede69f | 19 | * |
JMF | 0:082731ede69f | 20 | */ |
JMF | 0:082731ede69f | 21 | |
JMF | 0:082731ede69f | 22 | /** |
JMF | 0:082731ede69f | 23 | * @file WNC14A2AInterface.cpp |
JMF | 0:082731ede69f | 24 | * @brief WNC14A2A implementation of NetworkInterfaceAPI for Mbed OS |
JMF | 0:082731ede69f | 25 | * |
JMF | 0:082731ede69f | 26 | * @author James Flynn |
JMF | 0:082731ede69f | 27 | * |
JMF | 0:082731ede69f | 28 | * @date 1-Feb-2018 |
JMF | 0:082731ede69f | 29 | */ |
JMF | 0:082731ede69f | 30 | |
JMF | 0:082731ede69f | 31 | #include "WNC14A2AInterface.h" |
JMF | 0:082731ede69f | 32 | #include <Thread.h> |
JMF | 0:082731ede69f | 33 | #include "mbed_events.h" |
JMF | 0:082731ede69f | 34 | #include "WNCIO.h" |
JMF | 0:082731ede69f | 35 | |
JMF | 0:082731ede69f | 36 | #include <string> |
JMF | 0:082731ede69f | 37 | #include <ctype.h> |
JMF | 0:082731ede69f | 38 | |
JMF | 0:082731ede69f | 39 | #define WNC_DEBUG 0 //1=enable the WNC startup debug output |
JMF | 0:082731ede69f | 40 | //0=disable the WNC startup debug output |
JMF | 0:082731ede69f | 41 | #define STOP_ON_FE 1 //1=hang forever if a fatal error occurs |
JMF | 0:082731ede69f | 42 | //0=simply return failed response for all socket calls |
JMF | 0:082731ede69f | 43 | #define DISPLAY_FE 1 //1 to display the fatal error when it occurs |
JMF | 0:082731ede69f | 44 | //0 to NOT display the fatal error |
JMF | 0:082731ede69f | 45 | #define RESETON_FE 0 //1 to cause the MCU to reset on fatal error |
JMF | 0:082731ede69f | 46 | //0 to NOT reset the MCU |
JMF | 0:082731ede69f | 47 | |
JMF | 0:082731ede69f | 48 | /** Error Handling macros & data |
JMF | 0:082731ede69f | 49 | * @brief The macros CHK_WNCFE is used to check if a fatal error has occured. If it has |
JMF | 0:082731ede69f | 50 | * then execute the action specified: fail, void, null, resume |
JMF | 0:082731ede69f | 51 | * |
JMF | 0:082731ede69f | 52 | * CHK_WNCFE( condition-to-check, fail|void|null|resume ) |
JMF | 0:082731ede69f | 53 | * |
JMF | 0:082731ede69f | 54 | * 'fail' if you want FATAL_WNC_ERROR to be called. |
JMF | 0:082731ede69f | 55 | * 'void' if you want to execute a void return |
JMF | 0:082731ede69f | 56 | * 'null' if you want to execute a null return |
JMF | 0:082731ede69f | 57 | * 'resume' if you simply want to resume program execution |
JMF | 0:082731ede69f | 58 | * |
JMF | 0:082731ede69f | 59 | * There are several settings that control how FATAL_WNC_ERROR behaves: |
JMF | 0:082731ede69f | 60 | * 1) RESETON_FE determines if the system will reset or hang. |
JMF | 0:082731ede69f | 61 | * 2) DISPLAY_FE determine if an error message is generated or not |
JMF | 0:082731ede69f | 62 | * |
JMF | 0:082731ede69f | 63 | * The DISPLAY_FE setting determines if a failure message is displayed. |
JMF | 0:082731ede69f | 64 | * If set to 1, user sees this messageo: |
JMF | 0:082731ede69f | 65 | * |
JMF | 0:082731ede69f | 66 | * WNC FAILED @ source-file-name:source-file-line-number |
JMF | 0:082731ede69f | 67 | * |
JMF | 0:082731ede69f | 68 | * if not set, nothing is displayed. |
JMF | 0:082731ede69f | 69 | */ |
JMF | 0:082731ede69f | 70 | |
JMF | 0:082731ede69f | 71 | #define FATAL_FLAG WncController::WNC_NO_RESPONSE |
JMF | 0:082731ede69f | 72 | #define WNC_GOOD WncController::WNC_ON |
JMF | 0:082731ede69f | 73 | |
JMF | 0:082731ede69f | 74 | #define RETfail return -1 |
JMF | 0:082731ede69f | 75 | #define RETvoid return |
JMF | 0:082731ede69f | 76 | #define RETnull return NULL |
JMF | 0:082731ede69f | 77 | #define RETresume |
JMF | 0:082731ede69f | 78 | |
JMF | 0:082731ede69f | 79 | #define DORET(x) RET##x |
JMF | 0:082731ede69f | 80 | |
JMF | 0:082731ede69f | 81 | #define TOSTR(x) #x |
JMF | 0:082731ede69f | 82 | #define INTSTR(x) TOSTR(x) |
JMF | 0:082731ede69f | 83 | #define FATAL_STR (char*)(__FILE__ ":" INTSTR(__LINE__)) |
JMF | 0:082731ede69f | 84 | |
JMF | 0:082731ede69f | 85 | #if RESETON_FE == 1 //reset on fatal error |
JMF | 0:082731ede69f | 86 | #define MCURESET ((*((volatile unsigned long *)0xE000ED0CU))=(unsigned long)((0x5fa<<16) | 0x04L)) |
JMF | 0:082731ede69f | 87 | #define RSTMSG "RESET MCU! " |
JMF | 0:082731ede69f | 88 | #else |
JMF | 0:082731ede69f | 89 | #define MCURESET |
JMF | 0:082731ede69f | 90 | #define RSTMSG "" |
JMF | 0:082731ede69f | 91 | #endif |
JMF | 0:082731ede69f | 92 | |
JMF | 0:082731ede69f | 93 | #if DISPLAY_FE == 1 //display fatal error message |
JMF | 0:082731ede69f | 94 | #define PFE {if(_debugUart)_debugUart->printf((char*)RSTMSG "\r\n>>WNC FAILED @ %s\r\n", FATAL_STR);} |
JMF | 0:082731ede69f | 95 | #else |
JMF | 0:082731ede69f | 96 | #define PFE |
JMF | 0:082731ede69f | 97 | #endif |
JMF | 0:082731ede69f | 98 | |
JMF | 0:082731ede69f | 99 | #if STOP_ON_FE == 1 //halt cpu on fatal error |
JMF | 0:082731ede69f | 100 | #define FATAL_WNC_ERROR(v) {_fatal_err_loc=FATAL_STR;PFE;MCURESET;while(1);} |
JMF | 0:082731ede69f | 101 | #else |
JMF | 0:082731ede69f | 102 | #define FATAL_WNC_ERROR(v) {_fatal_err_loc=FATAL_STR;PFE;DORET(v);} |
JMF | 0:082731ede69f | 103 | #endif |
JMF | 0:082731ede69f | 104 | |
JMF | 0:082731ede69f | 105 | #define CHK_WNCFE(x,y) if( x ){FATAL_WNC_ERROR(y);} |
JMF | 0:082731ede69f | 106 | |
JMF | 0:082731ede69f | 107 | // |
JMF | 0:082731ede69f | 108 | // Define different levels of debug output |
JMF | 0:082731ede69f | 109 | // |
JMF | 0:082731ede69f | 110 | #define DBGMSG_DRV 0x04 //driver enter/exit info |
JMF | 0:082731ede69f | 111 | #define DBGMSG_EQ 0x08 //driver event queue info |
JMF | 0:082731ede69f | 112 | #define DBGMSG_SMS 0x10 //driver SMS info |
JMF | 0:082731ede69f | 113 | #define DBGMSG_ARRY 0x20 //dump driver arrays |
JMF | 0:082731ede69f | 114 | |
JMF | 0:082731ede69f | 115 | #define WNC14A2A_READ_TIMEOUTMS 4000 //duration to read no data to receive in MS |
JMF | 0:082731ede69f | 116 | #define WNC14A2A_COMMUNICATION_TIMEOUT 100 //how long (ms) to wait for a WNC14A2A connect response |
JMF | 0:082731ede69f | 117 | #define WNC_BUFF_SIZE 1500 //total number of bytes in a single WNC call |
JMF | 0:082731ede69f | 118 | #define UART_BUFF_SIZE 4096 //size of our internal uart buffer.. define in *.json file |
JMF | 0:082731ede69f | 119 | |
JMF | 0:082731ede69f | 120 | #define EQ_FREQ 250 //frequency in ms to check for Tx/Rx data |
JMF | 0:082731ede69f | 121 | #define EQ_FREQ_SLOW 2000 //frequency in ms to check when in slow monitor mode |
JMF | 0:082731ede69f | 122 | |
JMF | 0:082731ede69f | 123 | // |
JMF | 0:082731ede69f | 124 | // The WNC device does not generate interrutps on received data, so this software polls |
JMF | 0:082731ede69f | 125 | // for data availablility. To implement a non-blocking mode, simulate interrupts using |
JMF | 0:082731ede69f | 126 | // mbed OS Event Queues. These Constants are used to manage the Rx/Tx states. |
JMF | 0:082731ede69f | 127 | // |
JMF | 0:082731ede69f | 128 | #define READ_INIT 10 |
JMF | 0:082731ede69f | 129 | #define READ_START 11 |
JMF | 0:082731ede69f | 130 | #define READ_ACTIVE 12 |
JMF | 0:082731ede69f | 131 | #define DATA_AVAILABLE 13 |
JMF | 0:082731ede69f | 132 | #define TX_IDLE 20 |
JMF | 0:082731ede69f | 133 | #define TX_STARTING 21 |
JMF | 0:082731ede69f | 134 | #define TX_ACTIVE 22 |
JMF | 0:082731ede69f | 135 | #define TX_COMPLETE 23 |
JMF | 0:082731ede69f | 136 | |
JMF | 0:082731ede69f | 137 | #if MBED_CONF_APP_WNC_DEBUG == true |
JMF | 0:082731ede69f | 138 | #define debugOutput(...) WNC14A2AInterface::_dbOut(__VA_ARGS__) |
JMF | 0:082731ede69f | 139 | #define debugDump_arry(...) WNC14A2AInterface::_dbDump_arry(__VA_ARGS__) |
JMF | 0:082731ede69f | 140 | #else |
JMF | 0:082731ede69f | 141 | #define debugOutput(...) {/* __VA_ARGS__ */} |
JMF | 0:082731ede69f | 142 | #define debugDump_arry(...) {/* __VA_ARGS__ */} |
JMF | 0:082731ede69f | 143 | #endif |
JMF | 0:082731ede69f | 144 | |
JMF | 0:082731ede69f | 145 | /* Constructor |
JMF | 0:082731ede69f | 146 | * |
JMF | 0:082731ede69f | 147 | * @brief May be invoked with or without the debug pointer. |
JMF | 0:082731ede69f | 148 | * @note After the constructor has completed, call check |
JMF | 0:082731ede69f | 149 | * m_errors to determine if any errors occured. Possible values: |
JMF | 0:082731ede69f | 150 | * NSAPI_ERROR_UNSUPPORTED |
JMF | 0:082731ede69f | 151 | * NSAPI_ERROR_DEVICE_ERROR |
JMF | 0:082731ede69f | 152 | */ |
JMF | 0:082731ede69f | 153 | WNC14A2AInterface::WNC14A2AInterface(WNCDebug *dbg) : |
JMF | 0:082731ede69f | 154 | m_wncpoweredup(0), |
JMF | 0:082731ede69f | 155 | m_debug(0), |
JMF | 0:082731ede69f | 156 | m_pwnc(NULL), |
JMF | 0:082731ede69f | 157 | m_errors(NSAPI_ERROR_OK), |
JMF | 0:082731ede69f | 158 | m_smsmoning(0), |
JMF | 0:082731ede69f | 159 | _active_socket(0), |
JMF | 0:082731ede69f | 160 | mdmUart(MBED_CONF_WNC14A2A_LIBRARY_WNC_TXD,MBED_CONF_WNC14A2A_LIBRARY_WNC_RXD,115200), |
JMF | 0:082731ede69f | 161 | wnc_io(&mdmUart) |
JMF | 0:082731ede69f | 162 | { |
JMF | 0:082731ede69f | 163 | _debugUart = dbg; |
JMF | 0:082731ede69f | 164 | memset(_mac_address,0x00,sizeof(_mac_address)); |
JMF | 0:082731ede69f | 165 | memset(_socTxS,0x00,sizeof(_socTxS)); |
JMF | 0:082731ede69f | 166 | memset(_socRxS,0x00,sizeof(_socRxS)); |
JMF | 0:082731ede69f | 167 | for( unsigned int i=0; i<WNC14A2A_SOCKET_COUNT; i++ ) { |
JMF | 0:082731ede69f | 168 | _sockets[i].socket = i; |
JMF | 0:082731ede69f | 169 | _sockets[i].addr = NULL; |
JMF | 0:082731ede69f | 170 | _sockets[i].opened=false; |
JMF | 0:082731ede69f | 171 | |
JMF | 0:082731ede69f | 172 | _sockets[i].connected=false; |
JMF | 0:082731ede69f | 173 | _sockets[i].proto=1; |
JMF | 0:082731ede69f | 174 | _socRxS[i].m_rx_socket=i; |
JMF | 0:082731ede69f | 175 | _socTxS[i].m_tx_socket=i; |
JMF | 0:082731ede69f | 176 | } |
JMF | 0:082731ede69f | 177 | } |
JMF | 0:082731ede69f | 178 | |
JMF | 0:082731ede69f | 179 | //! Standard destructor |
JMF | 0:082731ede69f | 180 | WNC14A2AInterface::~WNC14A2AInterface() |
JMF | 0:082731ede69f | 181 | { |
JMF | 0:082731ede69f | 182 | if( m_pwnc ) |
JMF | 0:082731ede69f | 183 | delete m_pwnc; //free the existing WncControllerK64F object |
JMF | 0:082731ede69f | 184 | } |
JMF | 0:082731ede69f | 185 | |
JMF | 0:082731ede69f | 186 | // - - - - - - - |
JMF | 0:082731ede69f | 187 | // SMS Functions |
JMF | 0:082731ede69f | 188 | // - - - - - - - |
JMF | 0:082731ede69f | 189 | |
JMF | 0:082731ede69f | 190 | char* WNC14A2AInterface::getSMSnbr( void ) |
JMF | 0:082731ede69f | 191 | { |
JMF | 0:082731ede69f | 192 | char * ret=NULL; |
JMF | 0:082731ede69f | 193 | string iccid_str; |
JMF | 0:082731ede69f | 194 | static string msisdn_str; |
JMF | 0:082731ede69f | 195 | |
JMF | 0:082731ede69f | 196 | if( !m_pwnc ) { |
JMF | 0:082731ede69f | 197 | m_errors=NSAPI_ERROR_DEVICE_ERROR; |
JMF | 0:082731ede69f | 198 | return NULL; |
JMF | 0:082731ede69f | 199 | } |
JMF | 0:082731ede69f | 200 | CHK_WNCFE(( m_pwnc->getWncStatus() == FATAL_FLAG ), null); |
JMF | 0:082731ede69f | 201 | |
JMF | 0:082731ede69f | 202 | _pwnc_mutex.lock(); |
JMF | 0:082731ede69f | 203 | if( !m_pwnc->getICCID(&iccid_str) ) { |
JMF | 0:082731ede69f | 204 | _pwnc_mutex.unlock(); |
JMF | 0:082731ede69f | 205 | return ret; |
JMF | 0:082731ede69f | 206 | } |
JMF | 0:082731ede69f | 207 | |
JMF | 0:082731ede69f | 208 | if( m_pwnc->convertICCIDtoMSISDN(iccid_str, &msisdn_str) ) |
JMF | 0:082731ede69f | 209 | ret = (char*)msisdn_str.c_str(); |
JMF | 0:082731ede69f | 210 | _pwnc_mutex.unlock(); |
JMF | 0:082731ede69f | 211 | return ret; |
JMF | 0:082731ede69f | 212 | } |
JMF | 0:082731ede69f | 213 | |
JMF | 0:082731ede69f | 214 | void WNC14A2AInterface::sms_attach(void (*callback)(IOTSMS *)) |
JMF | 0:082731ede69f | 215 | { |
JMF | 0:082731ede69f | 216 | debugOutput("ENTER/EXIT sms_attach()"); |
JMF | 0:082731ede69f | 217 | _sms_cb = callback; |
JMF | 0:082731ede69f | 218 | } |
JMF | 0:082731ede69f | 219 | |
JMF | 0:082731ede69f | 220 | void WNC14A2AInterface::sms_start(void) |
JMF | 0:082731ede69f | 221 | { |
JMF | 0:082731ede69f | 222 | _pwnc_mutex.lock(); |
JMF | 0:082731ede69f | 223 | m_pwnc->deleteSMSTextFromMem('*'); |
JMF | 0:082731ede69f | 224 | _pwnc_mutex.unlock(); |
JMF | 0:082731ede69f | 225 | } |
JMF | 0:082731ede69f | 226 | |
JMF | 0:082731ede69f | 227 | void WNC14A2AInterface::sms_listen(uint16_t pp) |
JMF | 0:082731ede69f | 228 | { |
JMF | 0:082731ede69f | 229 | debugOutput("ENTER sms_listen(%d)",pp); |
JMF | 0:082731ede69f | 230 | |
JMF | 0:082731ede69f | 231 | if( m_smsmoning ) |
JMF | 0:082731ede69f | 232 | m_smsmoning = false; |
JMF | 0:082731ede69f | 233 | if( pp < 1) |
JMF | 0:082731ede69f | 234 | pp = 30; |
JMF | 0:082731ede69f | 235 | |
JMF | 0:082731ede69f | 236 | debugOutput("setup sms_listen event queue"); |
JMF | 0:082731ede69f | 237 | _smsThread.start(callback(&sms_queue,&EventQueue::dispatch_forever)); |
JMF | 0:082731ede69f | 238 | |
JMF | 0:082731ede69f | 239 | sms_start(); |
JMF | 0:082731ede69f | 240 | sms_queue.call_every(pp*1000, mbed::Callback<void()>((WNC14A2AInterface*)this,&WNC14A2AInterface::handle_sms_event)); |
JMF | 0:082731ede69f | 241 | |
JMF | 0:082731ede69f | 242 | m_smsmoning = true; |
JMF | 0:082731ede69f | 243 | debugOutput("EXIT sms_listen()"); |
JMF | 0:082731ede69f | 244 | } |
JMF | 0:082731ede69f | 245 | |
JMF | 0:082731ede69f | 246 | void WNC14A2AInterface::handle_sms_event() |
JMF | 0:082731ede69f | 247 | { |
JMF | 0:082731ede69f | 248 | int msgs_available; |
JMF | 0:082731ede69f | 249 | debugOutput("ENTER handle_sms_event()"); |
JMF | 0:082731ede69f | 250 | |
JMF | 0:082731ede69f | 251 | if ( _sms_cb && m_smsmoning ) { |
JMF | 0:082731ede69f | 252 | _pwnc_mutex.lock(); |
JMF | 0:082731ede69f | 253 | msgs_available = m_pwnc->readUnreadSMSText(&m_smsmsgs, true); |
JMF | 0:082731ede69f | 254 | _pwnc_mutex.unlock(); |
JMF | 0:082731ede69f | 255 | if( msgs_available ) { |
JMF | 0:082731ede69f | 256 | debugOutput("Have %d unread texts present",m_smsmsgs.msgCount); |
JMF | 0:082731ede69f | 257 | for( int i=0; i< m_smsmsgs.msgCount; i++ ) { |
JMF | 0:082731ede69f | 258 | m_MsgText.number = m_smsmsgs.e[i].number; |
JMF | 0:082731ede69f | 259 | m_MsgText.date = m_smsmsgs.e[i].date; |
JMF | 0:082731ede69f | 260 | m_MsgText.time = m_smsmsgs.e[i].time; |
JMF | 0:082731ede69f | 261 | m_MsgText.msg = m_smsmsgs.e[i].msg; |
JMF | 0:082731ede69f | 262 | _sms_cb(&m_MsgText); |
JMF | 0:082731ede69f | 263 | } |
JMF | 0:082731ede69f | 264 | } |
JMF | 0:082731ede69f | 265 | } |
JMF | 0:082731ede69f | 266 | debugOutput("EXIT handle_sms_event"); |
JMF | 0:082731ede69f | 267 | } |
JMF | 0:082731ede69f | 268 | |
JMF | 0:082731ede69f | 269 | int WNC14A2AInterface::getSMS(IOTSMS **pmsg) |
JMF | 0:082731ede69f | 270 | { |
JMF | 0:082731ede69f | 271 | int msgs_available=0; |
JMF | 0:082731ede69f | 272 | |
JMF | 0:082731ede69f | 273 | debugOutput("ENTER getSMS()"); |
JMF | 0:082731ede69f | 274 | if( !m_pwnc ) |
JMF | 0:082731ede69f | 275 | m_errors=NSAPI_ERROR_DEVICE_ERROR; |
JMF | 0:082731ede69f | 276 | else{ |
JMF | 0:082731ede69f | 277 | CHK_WNCFE((m_pwnc->getWncStatus()==FATAL_FLAG), fail); |
JMF | 0:082731ede69f | 278 | _pwnc_mutex.lock(); |
JMF | 0:082731ede69f | 279 | msgs_available = m_pwnc->readUnreadSMSText(&m_smsmsgs, true); |
JMF | 0:082731ede69f | 280 | _pwnc_mutex.unlock(); |
JMF | 0:082731ede69f | 281 | } |
JMF | 0:082731ede69f | 282 | |
JMF | 0:082731ede69f | 283 | if( msgs_available ) { |
JMF | 0:082731ede69f | 284 | debugOutput("Have %d unread texts present",m_smsmsgs.msgCount); |
JMF | 0:082731ede69f | 285 | for( int i=0; i< m_smsmsgs.msgCount; i++ ) { |
JMF | 0:082731ede69f | 286 | m_MsgText_array[i].number = m_smsmsgs.e[i].number; |
JMF | 0:082731ede69f | 287 | m_MsgText_array[i].date = m_smsmsgs.e[i].date; |
JMF | 0:082731ede69f | 288 | m_MsgText_array[i].time = m_smsmsgs.e[i].time; |
JMF | 0:082731ede69f | 289 | m_MsgText_array[i].msg = m_smsmsgs.e[i].msg; |
JMF | 0:082731ede69f | 290 | pmsg[i] = (IOTSMS*)&m_MsgText_array[i]; |
JMF | 0:082731ede69f | 291 | } |
JMF | 0:082731ede69f | 292 | msgs_available = m_smsmsgs.msgCount; |
JMF | 0:082731ede69f | 293 | } |
JMF | 0:082731ede69f | 294 | debugOutput("EXIT getSMS"); |
JMF | 0:082731ede69f | 295 | return msgs_available; |
JMF | 0:082731ede69f | 296 | } |
JMF | 0:082731ede69f | 297 | |
JMF | 0:082731ede69f | 298 | |
JMF | 0:082731ede69f | 299 | int WNC14A2AInterface::sendIOTSms(const string& number, const string& message) |
JMF | 0:082731ede69f | 300 | { |
JMF | 0:082731ede69f | 301 | debugOutput("ENTER sendIOTSms(%s,%s)",number.c_str(), message.c_str()); |
JMF | 0:082731ede69f | 302 | |
JMF | 0:082731ede69f | 303 | if( !m_pwnc ) |
JMF | 0:082731ede69f | 304 | return (m_errors=NSAPI_ERROR_DEVICE_ERROR); |
JMF | 0:082731ede69f | 305 | CHK_WNCFE((m_pwnc->getWncStatus()==FATAL_FLAG), fail); |
JMF | 0:082731ede69f | 306 | |
JMF | 0:082731ede69f | 307 | _pwnc_mutex.lock(); |
JMF | 0:082731ede69f | 308 | int i = m_pwnc->sendSMSText((char*)number.c_str(), message.c_str()); |
JMF | 0:082731ede69f | 309 | _pwnc_mutex.unlock(); |
JMF | 0:082731ede69f | 310 | |
JMF | 0:082731ede69f | 311 | debugOutput("EXIT sendIOTSms(%s,%s)",number.c_str(), message.c_str()); |
JMF | 0:082731ede69f | 312 | return i; |
JMF | 0:082731ede69f | 313 | } |
JMF | 0:082731ede69f | 314 | |
JMF | 0:082731ede69f | 315 | |
JMF | 0:082731ede69f | 316 | // - - - - - - - - - - - |
JMF | 0:082731ede69f | 317 | // WNC Control Functions |
JMF | 0:082731ede69f | 318 | // - - - - - - - - - - - |
JMF | 0:082731ede69f | 319 | |
JMF | 0:082731ede69f | 320 | nsapi_error_t WNC14A2AInterface::connect() //can be called with no arguments or with arguments |
JMF | 0:082731ede69f | 321 | { |
JMF | 0:082731ede69f | 322 | debugOutput("ENTER connect(void)"); |
JMF | 0:082731ede69f | 323 | return connect(NULL,NULL,NULL); |
JMF | 0:082731ede69f | 324 | } |
JMF | 0:082731ede69f | 325 | |
JMF | 0:082731ede69f | 326 | nsapi_error_t WNC14A2AInterface::connect(const char *apn, const char *username, const char *password) |
JMF | 0:082731ede69f | 327 | { |
JMF | 0:082731ede69f | 328 | // |
JMF | 0:082731ede69f | 329 | // GPIO Pins used to initialize the WNC parts on the Avnet WNC Shield |
JMF | 0:082731ede69f | 330 | // |
JMF | 0:082731ede69f | 331 | // on powerup, 0 = boot mode, 1 = normal boot |
JMF | 0:082731ede69f | 332 | // 0=let modem sleep, 1=keep modem awake -- Note: pulled high on shield |
JMF | 0:082731ede69f | 333 | // active high |
JMF | 0:082731ede69f | 334 | // 0 = disabled (all signals high impedence, 1 = translation active |
JMF | 0:082731ede69f | 335 | // WNC doesn't utilize RTS/CTS but the pin is connected |
JMF | 0:082731ede69f | 336 | |
JMF | 0:082731ede69f | 337 | static DigitalOut mdm_uart2_rx_boot_mode_sel(MBED_CONF_WNC14A2A_LIBRARY_WNC_RX_BOOT_SEL); |
JMF | 0:082731ede69f | 338 | static DigitalOut mdm_power_on(MBED_CONF_WNC14A2A_LIBRARY_WNC_POWER_ON); |
JMF | 0:082731ede69f | 339 | static DigitalOut mdm_wakeup_in(MBED_CONF_WNC14A2A_LIBRARY_WNC_WAKEUP); |
JMF | 0:082731ede69f | 340 | static DigitalOut mdm_reset(MBED_CONF_WNC14A2A_LIBRARY_WNC_RESET); |
JMF | 0:082731ede69f | 341 | static DigitalOut shield_3v3_1v8_sig_trans_ena(MBED_CONF_WNC14A2A_LIBRARY_WNC_LVLTRANSLATOR); |
JMF | 0:082731ede69f | 342 | static DigitalOut mdm_uart1_cts(MBED_CONF_WNC14A2A_LIBRARY_WNC_CTS); |
JMF | 0:082731ede69f | 343 | |
JMF | 0:082731ede69f | 344 | //! associations for the controller class to use. Order of pins is critical. |
JMF | 0:082731ede69f | 345 | static WncControllerK64F_fk::WncGpioPinListK64F wncPinList = { |
JMF | 0:082731ede69f | 346 | &mdm_uart2_rx_boot_mode_sel, |
JMF | 0:082731ede69f | 347 | &mdm_power_on, |
JMF | 0:082731ede69f | 348 | &mdm_wakeup_in, |
JMF | 0:082731ede69f | 349 | &mdm_reset, |
JMF | 0:082731ede69f | 350 | &shield_3v3_1v8_sig_trans_ena, |
JMF | 0:082731ede69f | 351 | &mdm_uart1_cts |
JMF | 0:082731ede69f | 352 | }; |
JMF | 0:082731ede69f | 353 | |
JMF | 0:082731ede69f | 354 | debugOutput("ENTER connect(apn,user,pass)"); |
JMF | 0:082731ede69f | 355 | |
JMF | 0:082731ede69f | 356 | if( m_pwnc == NULL ) { |
JMF | 0:082731ede69f | 357 | m_pwnc = new WncControllerK64F_fk::WncControllerK64F(&wncPinList, &wnc_io, _debugUart); |
JMF | 0:082731ede69f | 358 | if( !m_pwnc ) { |
JMF | 0:082731ede69f | 359 | debugOutput("FAILED to open WncControllerK64!"); |
JMF | 0:082731ede69f | 360 | m_errors = NSAPI_ERROR_DEVICE_ERROR; |
JMF | 0:082731ede69f | 361 | return NSAPI_ERROR_NO_MEMORY; |
JMF | 0:082731ede69f | 362 | } |
JMF | 0:082731ede69f | 363 | CHK_WNCFE((m_pwnc->getWncStatus()==FATAL_FLAG), fail); |
JMF | 0:082731ede69f | 364 | #if MBED_CONF_APP_WNC_DEBUG == true |
JMF | 0:082731ede69f | 365 | m_pwnc->enableDebug( (MBED_CONF_APP_WNC_DEBUG_SETTING&1), (MBED_CONF_APP_WNC_DEBUG_SETTING&2) ); |
JMF | 0:082731ede69f | 366 | #endif |
JMF | 0:082731ede69f | 367 | } |
JMF | 0:082731ede69f | 368 | |
JMF | 0:082731ede69f | 369 | _eqThread.start(callback(&wnc_queue,&EventQueue::dispatch_forever)); |
JMF | 0:082731ede69f | 370 | |
JMF | 0:082731ede69f | 371 | if (!apn) |
JMF | 0:082731ede69f | 372 | apn = "m2m.com.attz"; |
JMF | 0:082731ede69f | 373 | |
JMF | 0:082731ede69f | 374 | _pwnc_mutex.lock(); |
JMF | 0:082731ede69f | 375 | if (!m_wncpoweredup) { |
JMF | 0:082731ede69f | 376 | debugOutput("call powerWncOn(%s,40)",apn); |
JMF | 0:082731ede69f | 377 | m_wncpoweredup=m_pwnc->powerWncOn(apn,40); |
JMF | 0:082731ede69f | 378 | m_errors = m_wncpoweredup? 1:0; |
JMF | 0:082731ede69f | 379 | } |
JMF | 0:082731ede69f | 380 | else { //powerWncOn already called, set a new APN |
JMF | 0:082731ede69f | 381 | debugOutput("set APN=%s",apn); |
JMF | 0:082731ede69f | 382 | m_errors = m_pwnc->setApnName(apn)? 1:0; |
JMF | 0:082731ede69f | 383 | } |
JMF | 0:082731ede69f | 384 | |
JMF | 0:082731ede69f | 385 | m_errors |= m_pwnc->getWncNetworkingStats(&myNetStats)? 2:0; |
JMF | 0:082731ede69f | 386 | _pwnc_mutex.unlock(); |
JMF | 0:082731ede69f | 387 | |
JMF | 0:082731ede69f | 388 | debugOutput("EXIT connect (%02X)",m_errors); |
JMF | 0:082731ede69f | 389 | return (!m_errors)? NSAPI_ERROR_NO_CONNECTION : NSAPI_ERROR_OK; |
JMF | 0:082731ede69f | 390 | } |
JMF | 0:082731ede69f | 391 | |
JMF | 0:082731ede69f | 392 | const char* WNC14A2AInterface::getWNCRev(void) |
JMF | 0:082731ede69f | 393 | { |
JMF | 0:082731ede69f | 394 | if( m_pwnc ) { |
JMF | 0:082731ede69f | 395 | const char * str = m_pwnc->getFirmRev(); |
JMF | 0:082731ede69f | 396 | return &str[12]; |
JMF | 0:082731ede69f | 397 | } |
JMF | 0:082731ede69f | 398 | else |
JMF | 0:082731ede69f | 399 | return NULL; |
JMF | 0:082731ede69f | 400 | } |
JMF | 0:082731ede69f | 401 | |
JMF | 0:082731ede69f | 402 | |
JMF | 0:082731ede69f | 403 | const char *WNC14A2AInterface::get_ip_address() |
JMF | 0:082731ede69f | 404 | { |
JMF | 0:082731ede69f | 405 | const char *ptr=NULL; |
JMF | 0:082731ede69f | 406 | |
JMF | 0:082731ede69f | 407 | if( !m_pwnc ) { |
JMF | 0:082731ede69f | 408 | m_errors=NSAPI_ERROR_DEVICE_ERROR; |
JMF | 0:082731ede69f | 409 | return ptr; |
JMF | 0:082731ede69f | 410 | } |
JMF | 0:082731ede69f | 411 | CHK_WNCFE((m_pwnc->getWncStatus()==FATAL_FLAG), null); |
JMF | 0:082731ede69f | 412 | |
JMF | 0:082731ede69f | 413 | _pwnc_mutex.lock(); |
JMF | 0:082731ede69f | 414 | if ( m_pwnc->getWncNetworkingStats(&myNetStats) ) { |
JMF | 0:082731ede69f | 415 | _pwnc_mutex.unlock(); |
JMF | 0:082731ede69f | 416 | ptr = &myNetStats.ip[0]; |
JMF | 0:082731ede69f | 417 | } |
JMF | 0:082731ede69f | 418 | else{ |
JMF | 0:082731ede69f | 419 | _pwnc_mutex.unlock(); |
JMF | 0:082731ede69f | 420 | m_errors=NSAPI_ERROR_NO_CONNECTION; |
JMF | 0:082731ede69f | 421 | } |
JMF | 0:082731ede69f | 422 | return ptr; |
JMF | 0:082731ede69f | 423 | } |
JMF | 0:082731ede69f | 424 | |
JMF | 0:082731ede69f | 425 | const char *WNC14A2AInterface::get_mac_address() |
JMF | 0:082731ede69f | 426 | { |
JMF | 0:082731ede69f | 427 | string mac, str; |
JMF | 0:082731ede69f | 428 | debugOutput("ENTER get_mac_address()"); |
JMF | 0:082731ede69f | 429 | |
JMF | 0:082731ede69f | 430 | if( m_pwnc ) { |
JMF | 0:082731ede69f | 431 | CHK_WNCFE((m_pwnc->getWncStatus()==FATAL_FLAG), null); |
JMF | 0:082731ede69f | 432 | _pwnc_mutex.lock(); |
JMF | 0:082731ede69f | 433 | if( m_pwnc->getICCID(&str) ) { |
JMF | 0:082731ede69f | 434 | _pwnc_mutex.unlock(); |
JMF | 0:082731ede69f | 435 | mac = str.substr(3,20); |
JMF | 0:082731ede69f | 436 | mac[2]=mac[5]=mac[8]=mac[11]=mac[14]=':'; |
JMF | 0:082731ede69f | 437 | strncpy(_mac_address, mac.c_str(), mac.length()); |
JMF | 0:082731ede69f | 438 | debugOutput("EXIT get_mac_address() - %s",_mac_address); |
JMF | 0:082731ede69f | 439 | return _mac_address; |
JMF | 0:082731ede69f | 440 | } |
JMF | 0:082731ede69f | 441 | _pwnc_mutex.unlock(); |
JMF | 0:082731ede69f | 442 | } |
JMF | 0:082731ede69f | 443 | debugOutput("EXIT get_mac_address() - NULL"); |
JMF | 0:082731ede69f | 444 | return NULL; |
JMF | 0:082731ede69f | 445 | } |
JMF | 0:082731ede69f | 446 | |
JMF | 0:082731ede69f | 447 | NetworkStack *WNC14A2AInterface::get_stack() { |
JMF | 0:082731ede69f | 448 | debugOutput("ENTER/EXIT get_stack()"); |
JMF | 0:082731ede69f | 449 | return this; |
JMF | 0:082731ede69f | 450 | } |
JMF | 0:082731ede69f | 451 | |
JMF | 0:082731ede69f | 452 | nsapi_error_t WNC14A2AInterface::disconnect() |
JMF | 0:082731ede69f | 453 | { |
JMF | 0:082731ede69f | 454 | debugOutput("ENTER/EXIT disconnect()"); |
JMF | 0:082731ede69f | 455 | return NSAPI_ERROR_OK; |
JMF | 0:082731ede69f | 456 | } |
JMF | 0:082731ede69f | 457 | |
JMF | 0:082731ede69f | 458 | nsapi_error_t WNC14A2AInterface::set_credentials(const char *apn, const char *username, const char *password) |
JMF | 0:082731ede69f | 459 | { |
JMF | 0:082731ede69f | 460 | |
JMF | 0:082731ede69f | 461 | m_errors=NSAPI_ERROR_OK; |
JMF | 0:082731ede69f | 462 | debugOutput("ENTER set_credentials()"); |
JMF | 0:082731ede69f | 463 | |
JMF | 0:082731ede69f | 464 | if( !m_pwnc ) |
JMF | 0:082731ede69f | 465 | return (m_errors=NSAPI_ERROR_DEVICE_ERROR); |
JMF | 0:082731ede69f | 466 | CHK_WNCFE((m_pwnc->getWncStatus()==FATAL_FLAG), fail); |
JMF | 0:082731ede69f | 467 | |
JMF | 0:082731ede69f | 468 | if( !apn ) |
JMF | 0:082731ede69f | 469 | return (m_errors=NSAPI_ERROR_PARAMETER); |
JMF | 0:082731ede69f | 470 | |
JMF | 0:082731ede69f | 471 | _pwnc_mutex.lock(); |
JMF | 0:082731ede69f | 472 | if( !m_pwnc->setApnName(apn) ) |
JMF | 0:082731ede69f | 473 | m_errors=NSAPI_ERROR_DEVICE_ERROR; |
JMF | 0:082731ede69f | 474 | _pwnc_mutex.unlock(); |
JMF | 0:082731ede69f | 475 | debugOutput("EXIT set_credentials()"); |
JMF | 0:082731ede69f | 476 | return m_errors; |
JMF | 0:082731ede69f | 477 | } |
JMF | 0:082731ede69f | 478 | |
JMF | 0:082731ede69f | 479 | bool WNC14A2AInterface::registered() |
JMF | 0:082731ede69f | 480 | { |
JMF | 0:082731ede69f | 481 | debugOutput("ENTER registered()"); |
JMF | 0:082731ede69f | 482 | m_errors=NSAPI_ERROR_OK; |
JMF | 0:082731ede69f | 483 | |
JMF | 0:082731ede69f | 484 | if( !m_pwnc ) { |
JMF | 0:082731ede69f | 485 | return (m_errors=NSAPI_ERROR_DEVICE_ERROR); |
JMF | 0:082731ede69f | 486 | } |
JMF | 0:082731ede69f | 487 | CHK_WNCFE((m_pwnc->getWncStatus()==FATAL_FLAG), fail); |
JMF | 0:082731ede69f | 488 | |
JMF | 0:082731ede69f | 489 | _pwnc_mutex.lock(); |
JMF | 0:082731ede69f | 490 | if ( m_pwnc->getWncStatus() != WNC_GOOD ) |
JMF | 0:082731ede69f | 491 | m_errors=NSAPI_ERROR_NO_CONNECTION; |
JMF | 0:082731ede69f | 492 | _pwnc_mutex.unlock(); |
JMF | 0:082731ede69f | 493 | |
JMF | 0:082731ede69f | 494 | debugOutput("EXIT registered()"); |
JMF | 0:082731ede69f | 495 | return (m_errors==NSAPI_ERROR_OK); |
JMF | 0:082731ede69f | 496 | } |
JMF | 0:082731ede69f | 497 | |
JMF | 0:082731ede69f | 498 | |
JMF | 0:082731ede69f | 499 | void WNC14A2AInterface::doDebug( int v ) |
JMF | 0:082731ede69f | 500 | { |
JMF | 0:082731ede69f | 501 | #if MBED_CONF_APP_WNC_DEBUG == true |
JMF | 0:082731ede69f | 502 | m_debug= v; |
JMF | 0:082731ede69f | 503 | debugOutput("SET debug flag to 0x%02X",v); |
JMF | 0:082731ede69f | 504 | #endif |
JMF | 0:082731ede69f | 505 | } |
JMF | 0:082731ede69f | 506 | |
JMF | 0:082731ede69f | 507 | /** function to dump a user provided array. |
JMF | 0:082731ede69f | 508 | * |
JMF | 0:082731ede69f | 509 | * @author James Flynn |
JMF | 0:082731ede69f | 510 | * @param data pointer to the data array to dump |
JMF | 0:082731ede69f | 511 | * @param size number of bytes to dump |
JMF | 0:082731ede69f | 512 | * @return void |
JMF | 0:082731ede69f | 513 | * @date 1-Feb-2018 |
JMF | 0:082731ede69f | 514 | */ |
JMF | 0:082731ede69f | 515 | void WNC14A2AInterface::_dbDump_arry( const uint8_t* data, unsigned int size ) |
JMF | 0:082731ede69f | 516 | { |
JMF | 0:082731ede69f | 517 | #if MBED_CONF_APP_WNC_DEBUG == true |
JMF | 0:082731ede69f | 518 | char buffer[256]; |
JMF | 0:082731ede69f | 519 | unsigned int i, k; |
JMF | 0:082731ede69f | 520 | |
JMF | 0:082731ede69f | 521 | if( _debugUart != NULL && (m_debug & DBGMSG_ARRY) ) { |
JMF | 0:082731ede69f | 522 | for (i=0; i<size; i+=16) { |
JMF | 0:082731ede69f | 523 | sprintf(buffer,"[WNC Driver]:0x%04X: ",i); |
JMF | 0:082731ede69f | 524 | _debugUart->puts(buffer); |
JMF | 0:082731ede69f | 525 | for (k=0; k<16; k++) { |
JMF | 0:082731ede69f | 526 | sprintf(buffer, "%02X ", data[i+k]); |
JMF | 0:082731ede69f | 527 | _debugUart->puts(buffer); |
JMF | 0:082731ede69f | 528 | } |
JMF | 0:082731ede69f | 529 | _debugUart->puts(" -- "); |
JMF | 0:082731ede69f | 530 | for (k=0; k<16; k++) { |
JMF | 0:082731ede69f | 531 | sprintf(buffer, "%2c", isprint(data[i+k])? data[i+k]:'.'); |
JMF | 0:082731ede69f | 532 | _debugUart->puts(buffer); |
JMF | 0:082731ede69f | 533 | } |
JMF | 0:082731ede69f | 534 | _debugUart->puts("\n\r"); |
JMF | 0:082731ede69f | 535 | } |
JMF | 0:082731ede69f | 536 | } |
JMF | 0:082731ede69f | 537 | #endif |
JMF | 0:082731ede69f | 538 | } |
JMF | 0:082731ede69f | 539 | |
JMF | 0:082731ede69f | 540 | void WNC14A2AInterface::_dbOut(const char *format, ...) |
JMF | 0:082731ede69f | 541 | { |
JMF | 0:082731ede69f | 542 | #if MBED_CONF_APP_WNC_DEBUG == true |
JMF | 0:082731ede69f | 543 | char buffer[256]; |
JMF | 0:082731ede69f | 544 | |
JMF | 0:082731ede69f | 545 | sprintf(buffer,"[WNC Driver]: "); |
JMF | 0:082731ede69f | 546 | if( _debugUart != NULL && (m_debug & (DBGMSG_DRV|DBGMSG_EQ|DBGMSG_SMS)) ) { |
JMF | 0:082731ede69f | 547 | va_list args; |
JMF | 0:082731ede69f | 548 | va_start (args, format); |
JMF | 0:082731ede69f | 549 | _debugUart->puts(buffer); |
JMF | 0:082731ede69f | 550 | if( m_debug & DBGMSG_DRV ) |
JMF | 0:082731ede69f | 551 | vsnprintf(buffer, sizeof(buffer), format, args); |
JMF | 0:082731ede69f | 552 | if( m_debug & DBGMSG_EQ ) |
JMF | 0:082731ede69f | 553 | vsnprintf(buffer, sizeof(buffer), format, args); |
JMF | 0:082731ede69f | 554 | if( m_debug & DBGMSG_SMS ) |
JMF | 0:082731ede69f | 555 | vsnprintf(buffer, sizeof(buffer), format, args); |
JMF | 0:082731ede69f | 556 | _debugUart->puts(buffer); |
JMF | 0:082731ede69f | 557 | _debugUart->putc('\n'); |
JMF | 0:082731ede69f | 558 | va_end (args); |
JMF | 0:082731ede69f | 559 | } |
JMF | 0:082731ede69f | 560 | #endif |
JMF | 0:082731ede69f | 561 | } |
JMF | 0:082731ede69f | 562 | |
JMF | 0:082731ede69f | 563 | // - - - - - - - - - - - - - - - |
JMF | 0:082731ede69f | 564 | // WNC Socket Based operatioins |
JMF | 0:082731ede69f | 565 | // - - - - - - - - - - - - - - - |
JMF | 0:082731ede69f | 566 | |
JMF | 0:082731ede69f | 567 | nsapi_error_t WNC14A2AInterface::gethostbyname(const char* name, SocketAddress *address, nsapi_version_t version) |
JMF | 0:082731ede69f | 568 | { |
JMF | 0:082731ede69f | 569 | nsapi_error_t ret = NSAPI_ERROR_OK; |
JMF | 0:082731ede69f | 570 | char ipAddrStr[25]; |
JMF | 0:082731ede69f | 571 | |
JMF | 0:082731ede69f | 572 | debugOutput("ENTER gethostbyname(); IP=%s; PORT=%d; URL=%s;", address->get_ip_address(), address->get_port(), name); |
JMF | 0:082731ede69f | 573 | |
JMF | 0:082731ede69f | 574 | if( !m_pwnc ) |
JMF | 0:082731ede69f | 575 | return (m_errors=NSAPI_ERROR_DEVICE_ERROR); |
JMF | 0:082731ede69f | 576 | CHK_WNCFE((m_pwnc->getWncStatus()==FATAL_FLAG), fail); |
JMF | 0:082731ede69f | 577 | |
JMF | 0:082731ede69f | 578 | memset(ipAddrStr,0x00,sizeof(ipAddrStr)); |
JMF | 0:082731ede69f | 579 | |
JMF | 0:082731ede69f | 580 | //Execute DNS query. |
JMF | 0:082731ede69f | 581 | _pwnc_mutex.lock(); |
JMF | 0:082731ede69f | 582 | if( !m_pwnc->resolveUrl(_active_socket, name) ) |
JMF | 0:082731ede69f | 583 | ret = m_errors = NSAPI_ERROR_DEVICE_ERROR; |
JMF | 0:082731ede69f | 584 | |
JMF | 0:082731ede69f | 585 | //Get IP address that the URL was resolved to |
JMF | 0:082731ede69f | 586 | if( !m_pwnc->getIpAddr(_active_socket, ipAddrStr) ) |
JMF | 0:082731ede69f | 587 | ret = m_errors = NSAPI_ERROR_DEVICE_ERROR; |
JMF | 0:082731ede69f | 588 | _pwnc_mutex.unlock(); |
JMF | 0:082731ede69f | 589 | |
JMF | 0:082731ede69f | 590 | address->set_ip_address(ipAddrStr); |
JMF | 0:082731ede69f | 591 | |
JMF | 0:082731ede69f | 592 | debugOutput("EXIT gethostbyname(); IP=%s; PORT=%d; URL=%s;", address->get_ip_address(), address->get_port(), name); |
JMF | 0:082731ede69f | 593 | return (m_errors = ret); |
JMF | 0:082731ede69f | 594 | } |
JMF | 0:082731ede69f | 595 | |
JMF | 0:082731ede69f | 596 | int WNC14A2AInterface::socket_open(void **handle, nsapi_protocol_t proto) |
JMF | 0:082731ede69f | 597 | { |
JMF | 0:082731ede69f | 598 | unsigned int i; |
JMF | 0:082731ede69f | 599 | |
JMF | 0:082731ede69f | 600 | debugOutput("ENTER socket_open()"); |
JMF | 0:082731ede69f | 601 | |
JMF | 0:082731ede69f | 602 | //find the next available socket... |
JMF | 0:082731ede69f | 603 | for( i=0; i<WNC14A2A_SOCKET_COUNT; i++ ) |
JMF | 0:082731ede69f | 604 | if( !_sockets[i].opened ) |
JMF | 0:082731ede69f | 605 | break; |
JMF | 0:082731ede69f | 606 | |
JMF | 0:082731ede69f | 607 | if( i == WNC14A2A_SOCKET_COUNT ) { |
JMF | 0:082731ede69f | 608 | m_errors=NSAPI_ERROR_NO_SOCKET; |
JMF | 0:082731ede69f | 609 | return -1; |
JMF | 0:082731ede69f | 610 | } |
JMF | 0:082731ede69f | 611 | |
JMF | 0:082731ede69f | 612 | _sockets[i].socket = i; //save index later |
JMF | 0:082731ede69f | 613 | _sockets[i].opened = true; |
JMF | 0:082731ede69f | 614 | _sockets[i].connected=false; |
JMF | 0:082731ede69f | 615 | _sockets[i].proto = (proto==NSAPI_UDP)?0:1; |
JMF | 0:082731ede69f | 616 | _sockets[i]._callback = NULL; |
JMF | 0:082731ede69f | 617 | _sockets[i]._cb_data = NULL; |
JMF | 0:082731ede69f | 618 | |
JMF | 0:082731ede69f | 619 | _socRxS[i].m_rx_wnc_state = READ_START; |
JMF | 0:082731ede69f | 620 | _socRxS[i].m_rx_disTO = false; |
JMF | 0:082731ede69f | 621 | _socTxS[i].m_tx_wnc_state = TX_IDLE; |
JMF | 0:082731ede69f | 622 | |
JMF | 0:082731ede69f | 623 | *handle = &_sockets[i]; |
JMF | 0:082731ede69f | 624 | |
JMF | 0:082731ede69f | 625 | debugOutput("EXIT socket_open; Socket=%d, OPEN=%s, protocol =%s", |
JMF | 0:082731ede69f | 626 | i, _sockets[i].opened?"YES":"NO", (!_sockets[i].proto)?"UDP":"TCP"); |
JMF | 0:082731ede69f | 627 | |
JMF | 0:082731ede69f | 628 | return (m_errors = NSAPI_ERROR_OK); |
JMF | 0:082731ede69f | 629 | } |
JMF | 0:082731ede69f | 630 | |
JMF | 0:082731ede69f | 631 | int WNC14A2AInterface::socket_connect(void *handle, const SocketAddress &address) |
JMF | 0:082731ede69f | 632 | { |
JMF | 0:082731ede69f | 633 | WNCSOCKET *wnc = (WNCSOCKET *)handle; |
JMF | 0:082731ede69f | 634 | int err = 0; |
JMF | 0:082731ede69f | 635 | |
JMF | 0:082731ede69f | 636 | debugOutput("ENTER socket_connect(); Socket=%d; IP=%s; PORT=%d;", wnc->socket, address.get_ip_address(), address.get_port()); |
JMF | 0:082731ede69f | 637 | |
JMF | 0:082731ede69f | 638 | if (!wnc->opened ) |
JMF | 0:082731ede69f | 639 | return (m_errors = NSAPI_ERROR_NO_SOCKET); |
JMF | 0:082731ede69f | 640 | |
JMF | 0:082731ede69f | 641 | wnc->addr = address; |
JMF | 0:082731ede69f | 642 | |
JMF | 0:082731ede69f | 643 | _pwnc_mutex.lock(); |
JMF | 0:082731ede69f | 644 | if( wnc->url.empty() ) |
JMF | 0:082731ede69f | 645 | err = !m_pwnc->openSocketIpAddr(wnc->socket, address.get_ip_address(), address.get_port(), wnc->proto, WNC14A2A_COMMUNICATION_TIMEOUT); |
JMF | 0:082731ede69f | 646 | else |
JMF | 0:082731ede69f | 647 | err = !m_pwnc->openSocketUrl(wnc->socket, wnc->url.c_str(), wnc->addr.get_port(), wnc->proto); |
JMF | 0:082731ede69f | 648 | _pwnc_mutex.unlock(); |
JMF | 0:082731ede69f | 649 | |
JMF | 0:082731ede69f | 650 | if( !err ) { |
JMF | 0:082731ede69f | 651 | wnc->connected = true; |
JMF | 0:082731ede69f | 652 | _socRxS[wnc->socket].m_rx_wnc_state = READ_START; |
JMF | 0:082731ede69f | 653 | _socTxS[wnc->socket].m_tx_wnc_state = TX_IDLE; |
JMF | 0:082731ede69f | 654 | |
JMF | 0:082731ede69f | 655 | if( wnc->_callback != NULL ) |
JMF | 0:082731ede69f | 656 | wnc->_callback( wnc->_cb_data ); |
JMF | 0:082731ede69f | 657 | } |
JMF | 0:082731ede69f | 658 | |
JMF | 0:082731ede69f | 659 | return err; |
JMF | 0:082731ede69f | 660 | } |
JMF | 0:082731ede69f | 661 | |
JMF | 0:082731ede69f | 662 | int WNC14A2AInterface::socket_close(void *handle) |
JMF | 0:082731ede69f | 663 | { |
JMF | 0:082731ede69f | 664 | WNCSOCKET *wnc = (WNCSOCKET*)handle; |
JMF | 0:082731ede69f | 665 | RXEVENT *rxsock; |
JMF | 0:082731ede69f | 666 | TXEVENT *txsock; |
JMF | 0:082731ede69f | 667 | bool err = false; |
JMF | 0:082731ede69f | 668 | |
JMF | 0:082731ede69f | 669 | debugOutput("ENTER socket_close()"); |
JMF | 0:082731ede69f | 670 | |
JMF | 0:082731ede69f | 671 | rxsock = &_socRxS[wnc->socket]; |
JMF | 0:082731ede69f | 672 | txsock = &_socTxS[wnc->socket]; |
JMF | 0:082731ede69f | 673 | |
JMF | 0:082731ede69f | 674 | txsock->m_tx_wnc_state = TX_IDLE; //reset TX state |
JMF | 0:082731ede69f | 675 | if( rxsock->m_rx_wnc_state != READ_START ) { //reset RX state |
JMF | 0:082731ede69f | 676 | rxsock->m_rx_disTO=false; |
JMF | 0:082731ede69f | 677 | while( rxsock->m_rx_wnc_state != DATA_AVAILABLE ) |
JMF | 0:082731ede69f | 678 | wait(1); //someone called close while a read was happening |
JMF | 0:082731ede69f | 679 | } |
JMF | 0:082731ede69f | 680 | |
JMF | 0:082731ede69f | 681 | _pwnc_mutex.lock(); |
JMF | 0:082731ede69f | 682 | if( !m_pwnc->closeSocket(wnc->socket) ) { |
JMF | 0:082731ede69f | 683 | m_errors = NSAPI_ERROR_DEVICE_ERROR; |
JMF | 0:082731ede69f | 684 | err = true; |
JMF | 0:082731ede69f | 685 | } |
JMF | 0:082731ede69f | 686 | _pwnc_mutex.unlock(); |
JMF | 0:082731ede69f | 687 | |
JMF | 0:082731ede69f | 688 | if( !err ) { |
JMF | 0:082731ede69f | 689 | wnc->opened = false; //no longer in use |
JMF | 0:082731ede69f | 690 | wnc->addr = NULL; //not open |
JMF | 0:082731ede69f | 691 | wnc->connected= false; |
JMF | 0:082731ede69f | 692 | wnc->proto = 1; //assume TCP for now |
JMF | 0:082731ede69f | 693 | m_errors = NSAPI_ERROR_OK; |
JMF | 0:082731ede69f | 694 | wnc->_cb_data = NULL; |
JMF | 0:082731ede69f | 695 | wnc->_callback= NULL; |
JMF | 0:082731ede69f | 696 | } |
JMF | 0:082731ede69f | 697 | |
JMF | 0:082731ede69f | 698 | debugOutput("EXIT socket_close()"); |
JMF | 0:082731ede69f | 699 | return err; |
JMF | 0:082731ede69f | 700 | } |
JMF | 0:082731ede69f | 701 | |
JMF | 0:082731ede69f | 702 | |
JMF | 0:082731ede69f | 703 | void WNC14A2AInterface::socket_attach(void *handle, void (*callback)(void *), void *data) |
JMF | 0:082731ede69f | 704 | { |
JMF | 0:082731ede69f | 705 | WNCSOCKET *wnc = (WNCSOCKET *)handle; |
JMF | 0:082731ede69f | 706 | |
JMF | 0:082731ede69f | 707 | debugOutput("ENTER/EXIT socket_attach()"); |
JMF | 0:082731ede69f | 708 | wnc->_callback = callback; |
JMF | 0:082731ede69f | 709 | wnc->_cb_data = data; |
JMF | 0:082731ede69f | 710 | } |
JMF | 0:082731ede69f | 711 | |
JMF | 0:082731ede69f | 712 | int WNC14A2AInterface::socket_sendto(void *handle, const SocketAddress &address, const void *data, unsigned size) |
JMF | 0:082731ede69f | 713 | { |
JMF | 0:082731ede69f | 714 | WNCSOCKET *wnc = (WNCSOCKET *)handle; |
JMF | 0:082731ede69f | 715 | |
JMF | 0:082731ede69f | 716 | debugOutput("ENTER socket_sendto()"); |
JMF | 0:082731ede69f | 717 | |
JMF | 0:082731ede69f | 718 | if (!wnc->connected) { |
JMF | 0:082731ede69f | 719 | int err = socket_connect(wnc, address); |
JMF | 0:082731ede69f | 720 | if (err < 0) |
JMF | 0:082731ede69f | 721 | return err; |
JMF | 0:082731ede69f | 722 | } |
JMF | 0:082731ede69f | 723 | wnc->addr = address; |
JMF | 0:082731ede69f | 724 | |
JMF | 0:082731ede69f | 725 | debugOutput("EXIT socket_sendto()"); |
JMF | 0:082731ede69f | 726 | return socket_send(wnc, data, size); |
JMF | 0:082731ede69f | 727 | } |
JMF | 0:082731ede69f | 728 | |
JMF | 0:082731ede69f | 729 | int WNC14A2AInterface::socket_recvfrom(void *handle, SocketAddress *address, void *buffer, unsigned size) |
JMF | 0:082731ede69f | 730 | { |
JMF | 0:082731ede69f | 731 | WNCSOCKET *wnc = (WNCSOCKET *)handle; |
JMF | 0:082731ede69f | 732 | debugOutput("ENTER socket_recvfrom()"); |
JMF | 0:082731ede69f | 733 | |
JMF | 0:082731ede69f | 734 | if (!wnc->connected) { |
JMF | 0:082731ede69f | 735 | debugOutput("need to open a WNC socket first"); |
JMF | 0:082731ede69f | 736 | int err = socket_connect(wnc, *address); |
JMF | 0:082731ede69f | 737 | if (err < 0) |
JMF | 0:082731ede69f | 738 | return err; |
JMF | 0:082731ede69f | 739 | } |
JMF | 0:082731ede69f | 740 | |
JMF | 0:082731ede69f | 741 | int ret = socket_recv(wnc, (char *)buffer, size); |
JMF | 0:082731ede69f | 742 | if (ret >= 0 && address) |
JMF | 0:082731ede69f | 743 | *address = wnc->addr; |
JMF | 0:082731ede69f | 744 | debugOutput("EXIT socket_recvfrom()"); |
JMF | 0:082731ede69f | 745 | return ret; |
JMF | 0:082731ede69f | 746 | } |
JMF | 0:082731ede69f | 747 | |
JMF | 0:082731ede69f | 748 | |
JMF | 0:082731ede69f | 749 | int inline WNC14A2AInterface::socket_accept(nsapi_socket_t server, nsapi_socket_t *handle, SocketAddress *address) |
JMF | 0:082731ede69f | 750 | { |
JMF | 0:082731ede69f | 751 | debugOutput("ENTER/EXIT socket_accept() -- not supported"); |
JMF | 0:082731ede69f | 752 | m_errors = NSAPI_ERROR_UNSUPPORTED; |
JMF | 0:082731ede69f | 753 | return -1; |
JMF | 0:082731ede69f | 754 | } |
JMF | 0:082731ede69f | 755 | |
JMF | 0:082731ede69f | 756 | int inline WNC14A2AInterface::socket_bind(void *handle, const SocketAddress &address) |
JMF | 0:082731ede69f | 757 | { |
JMF | 0:082731ede69f | 758 | WNCSOCKET *wnc = (WNCSOCKET *)handle; |
JMF | 0:082731ede69f | 759 | |
JMF | 0:082731ede69f | 760 | debugOutput("ENTER/EXIT socket_bind(), use address '%s', port %d", address.get_ip_address(),address.get_port()); |
JMF | 0:082731ede69f | 761 | _socRxS[wnc->socket].m_rx_disTO=true; //for us, simply disable the Rx timeout to keep monitoring for data |
JMF | 0:082731ede69f | 762 | return (m_errors = NSAPI_ERROR_OK); |
JMF | 0:082731ede69f | 763 | } |
JMF | 0:082731ede69f | 764 | |
JMF | 0:082731ede69f | 765 | |
JMF | 0:082731ede69f | 766 | int inline WNC14A2AInterface::socket_listen(void *handle, int backlog) |
JMF | 0:082731ede69f | 767 | { |
JMF | 0:082731ede69f | 768 | debugOutput("ENTER/EXIT socket_listen() -- not supported"); |
JMF | 0:082731ede69f | 769 | m_errors = NSAPI_ERROR_UNSUPPORTED; |
JMF | 0:082731ede69f | 770 | return -1; |
JMF | 0:082731ede69f | 771 | } |
JMF | 0:082731ede69f | 772 | |
JMF | 0:082731ede69f | 773 | |
JMF | 0:082731ede69f | 774 | int WNC14A2AInterface::socket_send(void *handle, const void *data, unsigned size) |
JMF | 0:082731ede69f | 775 | { |
JMF | 0:082731ede69f | 776 | WNCSOCKET *wnc = (WNCSOCKET *)handle; |
JMF | 0:082731ede69f | 777 | TXEVENT *txsock; |
JMF | 0:082731ede69f | 778 | |
JMF | 0:082731ede69f | 779 | debugOutput("ENTER socket_send() send %d bytes",size); |
JMF | 0:082731ede69f | 780 | txsock = &_socTxS[wnc->socket]; |
JMF | 0:082731ede69f | 781 | |
JMF | 0:082731ede69f | 782 | if( size < 1 || data == NULL ) // should never happen but have seen it |
JMF | 0:082731ede69f | 783 | return 0; |
JMF | 0:082731ede69f | 784 | |
JMF | 0:082731ede69f | 785 | switch( txsock->m_tx_wnc_state ) { |
JMF | 0:082731ede69f | 786 | case TX_IDLE: |
JMF | 0:082731ede69f | 787 | txsock->m_tx_wnc_state = TX_STARTING; |
JMF | 0:082731ede69f | 788 | debugDump_arry((const uint8_t*)data,size); |
JMF | 0:082731ede69f | 789 | txsock->m_tx_dptr = (uint8_t*)data; |
JMF | 0:082731ede69f | 790 | txsock->m_tx_orig_size = size; |
JMF | 0:082731ede69f | 791 | txsock->m_tx_req_size = (uint32_t)size; |
JMF | 0:082731ede69f | 792 | txsock->m_tx_total_sent= 0; |
JMF | 0:082731ede69f | 793 | txsock->m_tx_callback = wnc->_callback; |
JMF | 0:082731ede69f | 794 | txsock->m_tx_cb_data = wnc->_cb_data; |
JMF | 0:082731ede69f | 795 | |
JMF | 0:082731ede69f | 796 | if( txsock->m_tx_req_size > UART_BUFF_SIZE ) |
JMF | 0:082731ede69f | 797 | txsock->m_tx_req_size= UART_BUFF_SIZE; |
JMF | 0:082731ede69f | 798 | |
JMF | 0:082731ede69f | 799 | if( !tx_event(txsock) ) { //if we didn't sent all the data at once, continue in background |
JMF | 0:082731ede69f | 800 | txsock->m_tx_wnc_state = TX_ACTIVE; |
JMF | 0:082731ede69f | 801 | wnc_queue.call_in(EQ_FREQ,mbed::Callback<void()>((WNC14A2AInterface*)this,&WNC14A2AInterface::wnc_eq_event)); |
JMF | 0:082731ede69f | 802 | return NSAPI_ERROR_WOULD_BLOCK; |
JMF | 0:082731ede69f | 803 | } |
JMF | 0:082731ede69f | 804 | // fall through |
JMF | 0:082731ede69f | 805 | |
JMF | 0:082731ede69f | 806 | case TX_COMPLETE: |
JMF | 0:082731ede69f | 807 | debugOutput("EXIT socket_send(), sent %d bytes", txsock->m_tx_total_sent); |
JMF | 0:082731ede69f | 808 | txsock->m_tx_wnc_state = TX_IDLE; |
JMF | 0:082731ede69f | 809 | return txsock->m_tx_total_sent; |
JMF | 0:082731ede69f | 810 | |
JMF | 0:082731ede69f | 811 | case TX_ACTIVE: |
JMF | 0:082731ede69f | 812 | case TX_STARTING: |
JMF | 0:082731ede69f | 813 | return NSAPI_ERROR_WOULD_BLOCK; |
JMF | 0:082731ede69f | 814 | |
JMF | 0:082731ede69f | 815 | default: |
JMF | 0:082731ede69f | 816 | debugOutput("EXIT socket_send(), NSAPI_ERROR_DEVICE_ERROR"); |
JMF | 0:082731ede69f | 817 | return (m_errors = NSAPI_ERROR_DEVICE_ERROR); |
JMF | 0:082731ede69f | 818 | } |
JMF | 0:082731ede69f | 819 | } |
JMF | 0:082731ede69f | 820 | |
JMF | 0:082731ede69f | 821 | int WNC14A2AInterface::tx_event(TXEVENT *ptr) |
JMF | 0:082731ede69f | 822 | { |
JMF | 0:082731ede69f | 823 | debugOutput("ENTER tx_event(), socket %d",ptr->m_tx_socket); |
JMF | 0:082731ede69f | 824 | |
JMF | 0:082731ede69f | 825 | _pwnc_mutex.lock(); |
JMF | 0:082731ede69f | 826 | if( m_pwnc->write(ptr->m_tx_socket, ptr->m_tx_dptr, ptr->m_tx_req_size) ) |
JMF | 0:082731ede69f | 827 | ptr->m_tx_total_sent += ptr->m_tx_req_size; |
JMF | 0:082731ede69f | 828 | _pwnc_mutex.unlock(); |
JMF | 0:082731ede69f | 829 | |
JMF | 0:082731ede69f | 830 | if( ptr->m_tx_total_sent < ptr->m_tx_orig_size ) { |
JMF | 0:082731ede69f | 831 | ptr->m_tx_dptr += ptr->m_tx_req_size; |
JMF | 0:082731ede69f | 832 | ptr->m_tx_req_size = ptr->m_tx_orig_size-ptr->m_tx_total_sent; |
JMF | 0:082731ede69f | 833 | |
JMF | 0:082731ede69f | 834 | if( ptr->m_tx_req_size > UART_BUFF_SIZE) |
JMF | 0:082731ede69f | 835 | ptr->m_tx_req_size= UART_BUFF_SIZE; |
JMF | 0:082731ede69f | 836 | |
JMF | 0:082731ede69f | 837 | debugOutput("EXIT tx_event(), send %d more bytes.",ptr->m_tx_req_size); |
JMF | 0:082731ede69f | 838 | return 0; |
JMF | 0:082731ede69f | 839 | } |
JMF | 0:082731ede69f | 840 | debugOutput("EXIT tx_event, socket %d, data sent",ptr->m_tx_socket); |
JMF | 0:082731ede69f | 841 | ptr->m_tx_wnc_state = TX_COMPLETE; |
JMF | 0:082731ede69f | 842 | if( ptr->m_tx_callback != NULL ) |
JMF | 0:082731ede69f | 843 | ptr->m_tx_callback( ptr->m_tx_cb_data ); |
JMF | 0:082731ede69f | 844 | ptr->m_tx_cb_data = NULL; |
JMF | 0:082731ede69f | 845 | ptr->m_tx_callback = NULL; |
JMF | 0:082731ede69f | 846 | |
JMF | 0:082731ede69f | 847 | return 1; |
JMF | 0:082731ede69f | 848 | } |
JMF | 0:082731ede69f | 849 | |
JMF | 0:082731ede69f | 850 | int WNC14A2AInterface::socket_recv(void *handle, void *data, unsigned size) |
JMF | 0:082731ede69f | 851 | { |
JMF | 0:082731ede69f | 852 | WNCSOCKET *wnc = (WNCSOCKET *)handle; |
JMF | 0:082731ede69f | 853 | RXEVENT *rxsock; |
JMF | 0:082731ede69f | 854 | |
JMF | 0:082731ede69f | 855 | rxsock = &_socRxS[wnc->socket]; |
JMF | 0:082731ede69f | 856 | debugOutput("ENTER socket_recv(), socket %d, request %d bytes",wnc->socket, size); |
JMF | 0:082731ede69f | 857 | |
JMF | 0:082731ede69f | 858 | if( size < 1 || data == NULL ) { // should never happen |
JMF | 0:082731ede69f | 859 | return 0; |
JMF | 0:082731ede69f | 860 | } |
JMF | 0:082731ede69f | 861 | |
JMF | 0:082731ede69f | 862 | switch( rxsock->m_rx_wnc_state ) { |
JMF | 0:082731ede69f | 863 | case READ_START: //need to start a read sequence of events |
JMF | 0:082731ede69f | 864 | rxsock->m_rx_wnc_state= READ_INIT; |
JMF | 0:082731ede69f | 865 | rxsock->m_rx_dptr = (uint8_t*)data; |
JMF | 0:082731ede69f | 866 | rxsock->m_rx_req_size = (uint32_t)size; |
JMF | 0:082731ede69f | 867 | rxsock->m_rx_total_cnt= 0; |
JMF | 0:082731ede69f | 868 | rxsock->m_rx_timer = 0; |
JMF | 0:082731ede69f | 869 | rxsock->m_rx_return_cnt=0; |
JMF | 0:082731ede69f | 870 | |
JMF | 0:082731ede69f | 871 | if( rxsock->m_rx_req_size > WNC_BUFF_SIZE) |
JMF | 0:082731ede69f | 872 | rxsock->m_rx_req_size= WNC_BUFF_SIZE; |
JMF | 0:082731ede69f | 873 | |
JMF | 0:082731ede69f | 874 | rxsock->m_rx_callback = wnc->_callback; |
JMF | 0:082731ede69f | 875 | rxsock->m_rx_cb_data = wnc->_cb_data; |
JMF | 0:082731ede69f | 876 | |
JMF | 0:082731ede69f | 877 | if( !rx_event(rxsock) ){ |
JMF | 0:082731ede69f | 878 | rxsock->m_rx_wnc_state = READ_ACTIVE; |
JMF | 0:082731ede69f | 879 | wnc_queue.call_in(EQ_FREQ,mbed::Callback<void()>((WNC14A2AInterface*)this,&WNC14A2AInterface::wnc_eq_event)); |
JMF | 0:082731ede69f | 880 | return NSAPI_ERROR_WOULD_BLOCK; |
JMF | 0:082731ede69f | 881 | } |
JMF | 0:082731ede69f | 882 | // fall through |
JMF | 0:082731ede69f | 883 | |
JMF | 0:082731ede69f | 884 | case DATA_AVAILABLE: |
JMF | 0:082731ede69f | 885 | debugOutput("EXIT socket_recv(),socket %d, return %d bytes",wnc->socket, rxsock->m_rx_return_cnt); |
JMF | 0:082731ede69f | 886 | debugDump_arry((const uint8_t*)data,rxsock->m_rx_return_cnt); |
JMF | 0:082731ede69f | 887 | rxsock->m_rx_wnc_state = READ_START; |
JMF | 0:082731ede69f | 888 | return rxsock->m_rx_return_cnt; |
JMF | 0:082731ede69f | 889 | |
JMF | 0:082731ede69f | 890 | case READ_ACTIVE: |
JMF | 0:082731ede69f | 891 | case READ_INIT: |
JMF | 0:082731ede69f | 892 | rxsock->m_rx_timer = 0; //reset the time-out timer |
JMF | 0:082731ede69f | 893 | return NSAPI_ERROR_WOULD_BLOCK; |
JMF | 0:082731ede69f | 894 | |
JMF | 0:082731ede69f | 895 | default: |
JMF | 0:082731ede69f | 896 | debugOutput("EXIT socket_recv(), NSAPI_ERROR_DEVICE_ERROR"); |
JMF | 0:082731ede69f | 897 | return (m_errors = NSAPI_ERROR_DEVICE_ERROR); |
JMF | 0:082731ede69f | 898 | } |
JMF | 0:082731ede69f | 899 | } |
JMF | 0:082731ede69f | 900 | |
JMF | 0:082731ede69f | 901 | |
JMF | 0:082731ede69f | 902 | int WNC14A2AInterface::rx_event(RXEVENT *ptr) |
JMF | 0:082731ede69f | 903 | { |
JMF | 0:082731ede69f | 904 | debugOutput("ENTER rx_event() for socket %d", ptr->m_rx_socket); |
JMF | 0:082731ede69f | 905 | _pwnc_mutex.lock(); |
JMF | 0:082731ede69f | 906 | int cnt = m_pwnc->read(ptr->m_rx_socket, ptr->m_rx_dptr, ptr->m_rx_req_size); |
JMF | 0:082731ede69f | 907 | _pwnc_mutex.unlock(); |
JMF | 0:082731ede69f | 908 | |
JMF | 0:082731ede69f | 909 | if( cnt ) { //got data, return it to the caller |
JMF | 0:082731ede69f | 910 | debugOutput("data received on socket %d, cnt=%d", ptr->m_rx_socket,cnt); |
JMF | 0:082731ede69f | 911 | ptr->m_rx_wnc_state = DATA_AVAILABLE; |
JMF | 0:082731ede69f | 912 | ptr->m_rx_return_cnt = cnt; |
JMF | 0:082731ede69f | 913 | if( ptr->m_rx_callback != NULL ) |
JMF | 0:082731ede69f | 914 | ptr->m_rx_callback( ptr->m_rx_cb_data ); |
JMF | 0:082731ede69f | 915 | ptr->m_rx_cb_data = NULL; |
JMF | 0:082731ede69f | 916 | ptr->m_rx_callback = NULL; |
JMF | 0:082731ede69f | 917 | return 1; |
JMF | 0:082731ede69f | 918 | } |
JMF | 0:082731ede69f | 919 | if( ++ptr->m_rx_timer > (WNC14A2A_READ_TIMEOUTMS/EQ_FREQ) && !ptr->m_rx_disTO ) { //timed out waiting, return 0 to caller |
JMF | 0:082731ede69f | 920 | debugOutput("EXIT rx_event(), rx data TIME-OUT!"); |
JMF | 0:082731ede69f | 921 | ptr->m_rx_wnc_state = DATA_AVAILABLE; |
JMF | 0:082731ede69f | 922 | ptr->m_rx_return_cnt = 0; |
JMF | 0:082731ede69f | 923 | if( ptr->m_rx_callback != NULL ) |
JMF | 0:082731ede69f | 924 | ptr->m_rx_callback( ptr->m_rx_cb_data ); |
JMF | 0:082731ede69f | 925 | ptr->m_rx_cb_data = NULL; |
JMF | 0:082731ede69f | 926 | ptr->m_rx_callback = NULL; |
JMF | 0:082731ede69f | 927 | return 1; |
JMF | 0:082731ede69f | 928 | } |
JMF | 0:082731ede69f | 929 | |
JMF | 0:082731ede69f | 930 | debugOutput("EXIT rx_event(), socket %d, sechedule for more data.",ptr->m_rx_socket); |
JMF | 0:082731ede69f | 931 | return 0; |
JMF | 0:082731ede69f | 932 | } |
JMF | 0:082731ede69f | 933 | |
JMF | 0:082731ede69f | 934 | void WNC14A2AInterface::wnc_eq_event() |
JMF | 0:082731ede69f | 935 | { |
JMF | 0:082731ede69f | 936 | int done = 1; |
JMF | 0:082731ede69f | 937 | bool goSlow = true; |
JMF | 0:082731ede69f | 938 | |
JMF | 0:082731ede69f | 939 | for( unsigned int i=0; i<WNC14A2A_SOCKET_COUNT; i++ ) { |
JMF | 0:082731ede69f | 940 | if( _socRxS[i].m_rx_wnc_state == READ_ACTIVE || _socRxS[i].m_rx_disTO) { |
JMF | 0:082731ede69f | 941 | done &= rx_event(&_socRxS[i]); |
JMF | 0:082731ede69f | 942 | goSlow &= ( _socRxS[i].m_rx_timer > ((WNC14A2A_READ_TIMEOUTMS/EQ_FREQ)*(EQ_FREQ_SLOW/EQ_FREQ)) ); |
JMF | 0:082731ede69f | 943 | |
JMF | 0:082731ede69f | 944 | if( goSlow ) |
JMF | 0:082731ede69f | 945 | _socRxS[i].m_rx_timer = (WNC14A2A_READ_TIMEOUTMS/EQ_FREQ)*(EQ_FREQ_SLOW/EQ_FREQ); |
JMF | 0:082731ede69f | 946 | } |
JMF | 0:082731ede69f | 947 | |
JMF | 0:082731ede69f | 948 | if( _socTxS[i].m_tx_wnc_state == TX_ACTIVE ) { |
JMF | 0:082731ede69f | 949 | goSlow = false; |
JMF | 0:082731ede69f | 950 | debugOutput("CALL TX_event() for socket %d", i); |
JMF | 0:082731ede69f | 951 | done &= tx_event(&_socTxS[i]); |
JMF | 0:082731ede69f | 952 | } |
JMF | 0:082731ede69f | 953 | } |
JMF | 0:082731ede69f | 954 | |
JMF | 0:082731ede69f | 955 | if( !done ) |
JMF | 0:082731ede69f | 956 | wnc_queue.call_in((goSlow?EQ_FREQ_SLOW:EQ_FREQ),mbed::Callback<void()>((WNC14A2AInterface*)this,&WNC14A2AInterface::wnc_eq_event)); |
JMF | 0:082731ede69f | 957 | } |