15
15
* limitations under the License.
16
16
*/
17
17
18
+ #include " rtos/ThisThread.h"
19
+ #include " mbed_error.h"
20
+ #include " platform/mbed_atomic.h"
21
+ #include " events/EventQueue.h"
22
+ #include " events/mbed_shared_queues.h"
23
+
18
24
#include " QUECTEL_BC95_CellularStack.h"
19
25
#include " CellularUtil.h"
20
26
#include " CellularLog.h"
21
27
22
28
#define PACKET_SIZE_MAX 1358
29
+ #define TXFULL_EVENT_TIMEOUT (1 * 1000 ) // ms
30
+
31
+ #define AT_UPLINK_BUSY 159
32
+ #define AT_UART_BUFFER_ERROR 536
33
+ #define AT_BACK_OFF_TIMER 537
23
34
24
35
using namespace mbed ;
25
36
using namespace mbed_cellular_util ;
26
37
27
38
QUECTEL_BC95_CellularStack::QUECTEL_BC95_CellularStack (ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type, AT_CellularDevice &device) :
28
- AT_CellularStack(atHandler, cid, stack_type, device)
39
+ AT_CellularStack(atHandler, cid, stack_type, device), _event_queue(mbed_event_queue()), _txfull_event_id( 0 )
29
40
{
30
41
_at.set_urc_handler (" +NSONMI:" , mbed::Callback<void ()>(this , &QUECTEL_BC95_CellularStack::urc_nsonmi));
31
42
_at.set_urc_handler (" +NSOCLI:" , mbed::Callback<void ()>(this , &QUECTEL_BC95_CellularStack::urc_nsocli));
32
43
}
33
44
34
45
QUECTEL_BC95_CellularStack::~QUECTEL_BC95_CellularStack ()
35
46
{
47
+ if (_txfull_event_id) {
48
+ _event_queue->cancel (_txfull_event_id);
49
+ }
50
+
36
51
_at.set_urc_handler (" +NSONMI:" , NULL );
37
52
_at.set_urc_handler (" +NSOCLI:" , NULL );
38
53
}
@@ -130,6 +145,9 @@ nsapi_error_t QUECTEL_BC95_CellularStack::socket_close_impl(int sock_id)
130
145
if (sock && sock->closed ) {
131
146
return NSAPI_ERROR_OK;
132
147
}
148
+
149
+ sock->txfull_event = false ;
150
+
133
151
nsapi_error_t err = _at.at_cmd_discard (" +NSOCL" , " =" , " %d" , sock_id);
134
152
135
153
tr_info (" Close socket: %d error: %d" , sock_id, err);
@@ -186,6 +204,8 @@ nsapi_size_or_error_t QUECTEL_BC95_CellularStack::socket_sendto_impl(CellularSoc
186
204
return NSAPI_ERROR_PARAMETER;
187
205
}
188
206
207
+ int retry = 0 ;
208
+ retry_send:
189
209
if (socket->proto == NSAPI_UDP) {
190
210
_at.cmd_start (" AT+NSOST=" );
191
211
_at.write_int (socket->id );
@@ -212,6 +232,36 @@ nsapi_size_or_error_t QUECTEL_BC95_CellularStack::socket_sendto_impl(CellularSoc
212
232
return sent_len;
213
233
}
214
234
235
+ // check for network congestion
236
+ device_err_t err = _at.get_last_device_error ();
237
+ if (err.errType == DeviceErrorTypeErrorCME &&
238
+ (err.errCode == AT_UART_BUFFER_ERROR || err.errCode == AT_BACK_OFF_TIMER) || err.errCode == AT_UPLINK_BUSY) {
239
+ if (socket->proto == NSAPI_UDP) {
240
+ if (retry < 3 ) {
241
+ retry++;
242
+ tr_warn (" Socket %d sendto EAGAIN" , socket->id );
243
+ rtos::ThisThread::sleep_for (30 );
244
+ _at.clear_error ();
245
+ goto retry_send;
246
+ }
247
+ return NSAPI_ERROR_NO_MEMORY;
248
+ }
249
+ _socket_mutex.lock ();
250
+ if (!socket->txfull_event && !_txfull_event_id) {
251
+ tr_warn (" socket %d tx full" , socket->id );
252
+ socket->txfull_event = true ;
253
+ _txfull_event_id = _event_queue->call_in (TXFULL_EVENT_TIMEOUT, callback (this , &QUECTEL_BC95_CellularStack::txfull_event_timeout));
254
+ if (!_txfull_event_id) {
255
+ MBED_ERROR (MBED_MAKE_ERROR (MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENOMEM), \
256
+ " QUECTEL_BC95_CellularStack::socket_sendto_impl(): unable to add event to queue. Increase \" events.shared-eventsize\"\n " );
257
+ _socket_mutex.unlock ();
258
+ return NSAPI_ERROR_NO_MEMORY;
259
+ }
260
+ }
261
+ _socket_mutex.unlock ();
262
+ return NSAPI_ERROR_WOULD_BLOCK;
263
+ }
264
+
215
265
return _at.get_last_error ();
216
266
}
217
267
@@ -234,7 +284,7 @@ nsapi_size_or_error_t QUECTEL_BC95_CellularStack::socket_recvfrom_impl(CellularS
234
284
_at.read_string (ip_address, sizeof (ip_address));
235
285
port = _at.read_int ();
236
286
recv_len = _at.read_int ();
237
- int hexlen = _at.read_hex_string ((char *)buffer, size );
287
+ int hexlen = _at.read_hex_string ((char *)buffer, recv_len );
238
288
// remaining length
239
289
_at.skip_param ();
240
290
_at.resp_stop ();
@@ -253,3 +303,17 @@ nsapi_size_or_error_t QUECTEL_BC95_CellularStack::socket_recvfrom_impl(CellularS
253
303
}
254
304
return recv_len;
255
305
}
306
+
307
+ void QUECTEL_BC95_CellularStack::txfull_event_timeout ()
308
+ {
309
+ _socket_mutex.lock ();
310
+ _txfull_event_id = 0 ;
311
+ for (int i = 0 ; i < get_max_socket_count (); i++) {
312
+ CellularSocket *sock = _socket[i];
313
+ if (sock && sock->_cb && sock->txfull_event ) {
314
+ sock->txfull_event = false ;
315
+ sock->_cb (sock->_data );
316
+ }
317
+ }
318
+ _socket_mutex.unlock ();
319
+ }
0 commit comments