@@ -65,8 +65,6 @@ void GEMALTO_CINTERION_CellularStack::urc_sis()
65
65
int urc_code = _at.read_int ();
66
66
CellularSocket *sock = find_socket (sock_id);
67
67
if (sock) {
68
- // Currently only UDP is supported so there is need to handle only some error codes here,
69
- // and others are detected on sendto/recvfrom responses.
70
68
if (urc_code == 5 ) { // The service is ready to use (ELS61 and EMS31).
71
69
if (sock->_cb ) {
72
70
sock->started = true ;
@@ -81,12 +79,17 @@ void GEMALTO_CINTERION_CellularStack::urc_sisw()
81
79
{
82
80
int sock_id = _at.read_int ();
83
81
int urc_code = _at.read_int ();
82
+ sisw_urc_handler (sock_id, urc_code);
83
+ }
84
+
85
+ void GEMALTO_CINTERION_CellularStack::sisw_urc_handler (int sock_id, int urc_code)
86
+ {
84
87
CellularSocket *sock = find_socket (sock_id);
85
88
if (sock) {
86
89
if (urc_code == 1 ) { // ready
87
90
if (sock->_cb ) {
88
91
sock->tx_ready = true ;
89
- if (GEMALTO_CINTERION_Module::get_model () == GEMALTO_CINTERION_Module::ModelBGS2) {
92
+ if (sock-> proto == NSAPI_TCP || GEMALTO_CINTERION_Module::get_model () == GEMALTO_CINTERION_Module::ModelBGS2) {
90
93
sock->started = true ;
91
94
}
92
95
sock->_cb (sock->_data );
@@ -99,6 +102,11 @@ void GEMALTO_CINTERION_CellularStack::urc_sisr()
99
102
{
100
103
int sock_id = _at.read_int ();
101
104
int urc_code = _at.read_int ();
105
+ sisr_urc_handler (sock_id, urc_code);
106
+ }
107
+
108
+ void GEMALTO_CINTERION_CellularStack::sisr_urc_handler (int sock_id, int urc_code)
109
+ {
102
110
CellularSocket *sock = find_socket (sock_id);
103
111
if (sock) {
104
112
if (urc_code == 1 ) { // data available
@@ -139,7 +147,7 @@ int GEMALTO_CINTERION_CellularStack::get_max_socket_count()
139
147
140
148
bool GEMALTO_CINTERION_CellularStack::is_protocol_supported (nsapi_protocol_t protocol)
141
149
{
142
- return (protocol == NSAPI_UDP);
150
+ return (protocol == NSAPI_UDP || protocol == NSAPI_TCP );
143
151
}
144
152
145
153
nsapi_error_t GEMALTO_CINTERION_CellularStack::socket_close_impl (int sock_id)
@@ -170,11 +178,20 @@ nsapi_error_t GEMALTO_CINTERION_CellularStack::socket_close_impl(int sock_id)
170
178
nsapi_error_t GEMALTO_CINTERION_CellularStack::socket_open_defer (CellularSocket *socket, const SocketAddress *address)
171
179
{
172
180
// host address (IPv4) and local+remote port is needed only for BGS2 which does not support UDP server socket
173
- char sock_addr[sizeof (" sockudp://" ) - 1 + NSAPI_IPv4_SIZE + sizeof (" :12345;port=12345" ) - 1 + 1 ];
174
- if (GEMALTO_CINTERION_Module::get_model () != GEMALTO_CINTERION_Module::ModelBGS2) {
175
- std::sprintf (sock_addr, " sockudp://%s:%u" , address ? address->get_ip_address () : " " , socket->localAddress .get_port ());
181
+ char sock_addr[sizeof (" sockudp://" ) - 1 + NSAPI_IPv6_SIZE + sizeof (" []:12345;port=12345" ) - 1 + 1 ];
182
+
183
+ if (socket->proto == NSAPI_UDP) {
184
+ if (GEMALTO_CINTERION_Module::get_model () != GEMALTO_CINTERION_Module::ModelBGS2) {
185
+ std::sprintf (sock_addr, " sockudp://%s:%u" , address ? address->get_ip_address () : " " , socket->localAddress .get_port ());
186
+ } else {
187
+ std::sprintf (sock_addr, " sockudp://%s:%u;port=%u" , address->get_ip_address (), address->get_port (), socket->localAddress .get_port ());
188
+ }
176
189
} else {
177
- std::sprintf (sock_addr, " sockudp://%s:%u;port=%u" , address->get_ip_address (), address->get_port (), socket->localAddress .get_port ());
190
+ if (address->get_ip_version () == NSAPI_IPv4) {
191
+ std::sprintf (sock_addr, " socktcp://%s:%u" , address->get_ip_address (), address->get_port ());
192
+ } else {
193
+ std::sprintf (sock_addr, " socktcp://[%s]:%u" , address->get_ip_address (), address->get_port ());
194
+ }
178
195
}
179
196
180
197
_at.cmd_start (" AT^SISS=" );
@@ -281,9 +298,12 @@ nsapi_error_t GEMALTO_CINTERION_CellularStack::create_socket_impl(CellularSocket
281
298
282
299
tr_debug (" Internet service %d (err %d)" , internet_service_id, _at.get_last_error ());
283
300
284
- if (GEMALTO_CINTERION_Module::get_model () != GEMALTO_CINTERION_Module::ModelBGS2) {
285
- return socket_open_defer (socket);
301
+ if (socket->proto == NSAPI_UDP) {
302
+ if (GEMALTO_CINTERION_Module::get_model () != GEMALTO_CINTERION_Module::ModelBGS2) {
303
+ return socket_open_defer (socket);
304
+ }
286
305
}
306
+
287
307
return _at.get_last_error ();
288
308
}
289
309
@@ -292,13 +312,16 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_sendto_impl(Cellul
292
312
{
293
313
tr_debug (" Socket %d, sendto %s, len %d" , socket->id , address.get_ip_address (), size);
294
314
295
- int ip_version = address.get_ip_version ();
296
- if ((ip_version == NSAPI_IPv4 && _stack_type != IPV4_STACK) ||
297
- (ip_version == NSAPI_IPv6 && _stack_type != IPV6_STACK)) {
298
- tr_warn (" No IP route for %s" , address.get_ip_address ());
299
- return NSAPI_ERROR_NO_SOCKET;
315
+ if (socket->proto == NSAPI_UDP) {
316
+ const int ip_version = address.get_ip_version ();
317
+ if ((ip_version == NSAPI_IPv4 && _stack_type != IPV4_STACK) ||
318
+ (ip_version == NSAPI_IPv6 && _stack_type != IPV6_STACK)) {
319
+ tr_warn (" No IP route for %s" , address.get_ip_address ());
320
+ return NSAPI_ERROR_NO_SOCKET;
321
+ }
300
322
}
301
- if (GEMALTO_CINTERION_Module::get_model () == GEMALTO_CINTERION_Module::ModelBGS2) {
323
+
324
+ if (socket->proto == NSAPI_UDP && GEMALTO_CINTERION_Module::get_model () == GEMALTO_CINTERION_Module::ModelBGS2) {
302
325
tr_debug (" Send addr %s, prev addr %s" , address.get_ip_address (), socket->remoteAddress .get_ip_address ());
303
326
if (address != socket->remoteAddress ) {
304
327
if (socket->started ) {
@@ -340,16 +363,22 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_sendto_impl(Cellul
340
363
_at.cmd_start (" AT^SISW=" );
341
364
_at.write_int (socket->id );
342
365
_at.write_int (size);
366
+
343
367
if (GEMALTO_CINTERION_Module::get_model () != GEMALTO_CINTERION_Module::ModelBGS2) {
344
368
_at.write_int (0 );
345
- char socket_address[NSAPI_IPv6_SIZE + sizeof (" []:12345" ) - 1 + 1 ];
346
- if (address.get_ip_version () == NSAPI_IPv4) {
347
- std::sprintf (socket_address, " %s:%u" , address.get_ip_address (), address.get_port ());
348
- } else {
349
- std::sprintf (socket_address, " [%s]:%u" , address.get_ip_address (), address.get_port ());
369
+
370
+ // UDP requires Udp_RemClient
371
+ if (socket->proto == NSAPI_UDP) {
372
+ char socket_address[NSAPI_IPv6_SIZE + sizeof (" []:12345" ) - 1 + 1 ];
373
+ if (address.get_ip_version () == NSAPI_IPv4) {
374
+ std::sprintf (socket_address, " %s:%u" , address.get_ip_address (), address.get_port ());
375
+ } else {
376
+ std::sprintf (socket_address, " [%s]:%u" , address.get_ip_address (), address.get_port ());
377
+ }
378
+ _at.write_string (socket_address);
350
379
}
351
- _at.write_string (socket_address);
352
380
}
381
+
353
382
_at.cmd_stop ();
354
383
355
384
sisw_retry:
@@ -359,29 +388,30 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_sendto_impl(Cellul
359
388
_at.restore_at_timeout ();
360
389
return NSAPI_ERROR_DEVICE_ERROR;
361
390
}
362
- _at.restore_at_timeout ();
363
391
int socket_id = _at.read_int ();
364
392
if (socket_id != socket->id ) {
393
+ // We might have read the SISW URC so let's try to handle it
394
+ const int urc_code = _at.read_int ();
395
+ const int extra = _at.read_int ();
396
+ if (urc_code != -1 && extra == -1 ) {
397
+ sisw_urc_handler (socket_id, urc_code);
398
+ goto sisw_retry;
399
+ }
400
+ _at.restore_at_timeout ();
365
401
tr_error (" Socket id %d != %d" , socket_id, socket->id );
366
402
return NSAPI_ERROR_DEVICE_ERROR;
367
403
}
368
404
int accept_len = _at.read_int ();
369
405
if (accept_len == -1 ) {
370
406
tr_error (" Socket %d send failed" , socket->id );
407
+ _at.restore_at_timeout ();
371
408
return NSAPI_ERROR_DEVICE_ERROR;
372
409
}
373
- int unack_len = _at.read_int ();
374
- if (unack_len != 0 ) {
375
- tr_warn (" Socket %d unack_len %d" , socket->id , unack_len);
376
- if (GEMALTO_CINTERION_Module::get_model () != GEMALTO_CINTERION_Module::ModelBGS2) {
377
- // assume that an URC was received when unackData is not received
378
- _at.resp_stop ();
379
- goto sisw_retry;
380
- }
381
- }
410
+ _at.skip_param (); // unackData
382
411
383
412
_at.write_bytes ((uint8_t *)data, accept_len);
384
413
_at.resp_stop ();
414
+ _at.restore_at_timeout ();
385
415
386
416
tr_debug (" Socket %d sendto %s, %d bytes (err %d)" , socket->id , address.get_ip_address (), accept_len, _at.get_last_error ());
387
417
@@ -417,16 +447,25 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_recvfrom_impl(Cell
417
447
_at.write_int (size);
418
448
_at.cmd_stop ();
419
449
450
+ sisr_retry:
420
451
_at.resp_start (" ^SISR:" );
421
452
if (!_at.info_resp ()) {
422
453
tr_error (" Socket %d not responding" , socket->id );
423
454
return NSAPI_ERROR_DEVICE_ERROR;
424
455
}
456
+
425
457
int socket_id = _at.read_int ();
426
458
if (socket_id != socket->id ) {
459
+ const int urc_code = _at.read_int ();
460
+ const int extra = _at.read_int (); // should be -1 if URC
461
+ if (urc_code != -1 && extra == -1 ) {
462
+ sisr_urc_handler (socket_id, urc_code);
463
+ goto sisr_retry;
464
+ }
427
465
tr_error (" Socket recvfrom id %d != %d" , socket_id, socket->id );
428
466
return NSAPI_ERROR_DEVICE_ERROR;
429
467
}
468
+
430
469
nsapi_size_or_error_t len = _at.read_int ();
431
470
if (len == 0 ) {
432
471
tr_warn (" Socket %d no data" , socket->id );
@@ -444,7 +483,9 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_recvfrom_impl(Cell
444
483
socket->rx_avail = true ;
445
484
}
446
485
}
447
- if (GEMALTO_CINTERION_Module::get_model () != GEMALTO_CINTERION_Module::ModelBGS2) {
486
+
487
+ // UDP Udp_RemClient
488
+ if (socket->proto == NSAPI_UDP && GEMALTO_CINTERION_Module::get_model () != GEMALTO_CINTERION_Module::ModelBGS2) {
448
489
char ip_address[NSAPI_IPv6_SIZE + sizeof (" []:12345" ) - 1 + 1 ];
449
490
int ip_len = _at.read_string (ip_address, sizeof (ip_address));
450
491
if (ip_len <= 0 ) {
@@ -472,7 +513,7 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_recvfrom_impl(Cell
472
513
port_start++; // skip ':'
473
514
int port = std::strtol (port_start, NULL , 10 );
474
515
address->set_port (port);
475
- tr_debug (" IP address %s: %d" , address->get_ip_address (), address->get_port ());
516
+ tr_debug (" IP address %s, port %d" , address->get_ip_address (), address->get_port ());
476
517
*ip_stop = tmp_ch; // restore original IP string
477
518
}
478
519
}
@@ -592,3 +633,29 @@ void GEMALTO_CINTERION_CellularStack::close_connection_profile(int connection_pr
592
633
593
634
_at.clear_error ();
594
635
}
636
+
637
+ nsapi_error_t GEMALTO_CINTERION_CellularStack::socket_connect (nsapi_socket_t handle, const SocketAddress &address)
638
+ {
639
+ int err = NSAPI_ERROR_DEVICE_ERROR;
640
+
641
+ struct CellularSocket *socket = (struct CellularSocket *)handle;
642
+ if (!socket) {
643
+ return err;
644
+ }
645
+
646
+ _at.lock ();
647
+ err = create_socket_impl (socket);
648
+ if (err != NSAPI_ERROR_OK) {
649
+ _at.unlock ();
650
+ return err;
651
+ }
652
+ err = socket_open_defer (socket, &address);
653
+ _at.unlock ();
654
+
655
+ if (err == NSAPI_ERROR_OK) {
656
+ socket->remoteAddress = address;
657
+ socket->connected = true ;
658
+ }
659
+
660
+ return err;
661
+ }
0 commit comments