@@ -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)
@@ -168,11 +176,20 @@ nsapi_error_t GEMALTO_CINTERION_CellularStack::socket_close_impl(int sock_id)
168
176
nsapi_error_t GEMALTO_CINTERION_CellularStack::socket_open_defer (CellularSocket *socket, const SocketAddress *address)
169
177
{
170
178
// host address (IPv4) and local+remote port is needed only for BGS2 which does not support UDP server socket
171
- char sock_addr[sizeof (" sockudp://" ) - 1 + NSAPI_IPv4_SIZE + sizeof (" :12345;port=12345" ) - 1 + 1 ];
172
- if (GEMALTO_CINTERION_Module::get_model () != GEMALTO_CINTERION_Module::ModelBGS2) {
173
- std::sprintf (sock_addr, " sockudp://%s:%u" , address ? address->get_ip_address () : " " , socket->localAddress .get_port ());
179
+ char sock_addr[sizeof (" sockudp://" ) - 1 + NSAPI_IPv6_SIZE + sizeof (" []:12345;port=12345" ) - 1 + 1 ];
180
+
181
+ if (socket->proto == NSAPI_UDP) {
182
+ if (GEMALTO_CINTERION_Module::get_model () != GEMALTO_CINTERION_Module::ModelBGS2) {
183
+ std::sprintf (sock_addr, " sockudp://%s:%u" , address ? address->get_ip_address () : " " , socket->localAddress .get_port ());
184
+ } else {
185
+ std::sprintf (sock_addr, " sockudp://%s:%u;port=%u" , address->get_ip_address (), address->get_port (), socket->localAddress .get_port ());
186
+ }
174
187
} else {
175
- std::sprintf (sock_addr, " sockudp://%s:%u;port=%u" , address->get_ip_address (), address->get_port (), socket->localAddress .get_port ());
188
+ if (address->get_ip_version () == NSAPI_IPv4) {
189
+ std::sprintf (sock_addr, " socktcp://%s:%u" , address->get_ip_address (), address->get_port ());
190
+ } else {
191
+ std::sprintf (sock_addr, " socktcp://[%s]:%u" , address->get_ip_address (), address->get_port ());
192
+ }
176
193
}
177
194
178
195
_at.cmd_start (" AT^SISS=" );
@@ -272,9 +289,12 @@ nsapi_error_t GEMALTO_CINTERION_CellularStack::create_socket_impl(CellularSocket
272
289
273
290
tr_debug (" Internet service %d (err %d)" , internet_service_id, _at.get_last_error ());
274
291
275
- if (GEMALTO_CINTERION_Module::get_model () != GEMALTO_CINTERION_Module::ModelBGS2) {
276
- return socket_open_defer (socket);
292
+ if (socket->proto == NSAPI_UDP) {
293
+ if (GEMALTO_CINTERION_Module::get_model () != GEMALTO_CINTERION_Module::ModelBGS2) {
294
+ return socket_open_defer (socket);
295
+ }
277
296
}
297
+
278
298
return _at.get_last_error ();
279
299
}
280
300
@@ -283,13 +303,16 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_sendto_impl(Cellul
283
303
{
284
304
tr_debug (" Socket %d, sendto %s, len %d" , socket->id , address.get_ip_address (), size);
285
305
286
- int ip_version = address.get_ip_version ();
287
- if ((ip_version == NSAPI_IPv4 && _stack_type != IPV4_STACK) ||
288
- (ip_version == NSAPI_IPv6 && _stack_type != IPV6_STACK)) {
289
- tr_warn (" No IP route for %s" , address.get_ip_address ());
290
- return NSAPI_ERROR_NO_SOCKET;
306
+ if (socket->proto == NSAPI_UDP) {
307
+ const int ip_version = address.get_ip_version ();
308
+ if ((ip_version == NSAPI_IPv4 && _stack_type != IPV4_STACK) ||
309
+ (ip_version == NSAPI_IPv6 && _stack_type != IPV6_STACK)) {
310
+ tr_warn (" No IP route for %s" , address.get_ip_address ());
311
+ return NSAPI_ERROR_NO_SOCKET;
312
+ }
291
313
}
292
- if (GEMALTO_CINTERION_Module::get_model () == GEMALTO_CINTERION_Module::ModelBGS2) {
314
+
315
+ if (socket->proto == NSAPI_UDP && GEMALTO_CINTERION_Module::get_model () == GEMALTO_CINTERION_Module::ModelBGS2) {
293
316
tr_debug (" Send addr %s, prev addr %s" , address.get_ip_address (), socket->remoteAddress .get_ip_address ());
294
317
if (address != socket->remoteAddress ) {
295
318
if (socket->started ) {
@@ -331,16 +354,22 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_sendto_impl(Cellul
331
354
_at.cmd_start (" AT^SISW=" );
332
355
_at.write_int (socket->id );
333
356
_at.write_int (size);
357
+
334
358
if (GEMALTO_CINTERION_Module::get_model () != GEMALTO_CINTERION_Module::ModelBGS2) {
335
359
_at.write_int (0 );
336
- char socket_address[NSAPI_IPv6_SIZE + sizeof (" []:12345" ) - 1 + 1 ];
337
- if (address.get_ip_version () == NSAPI_IPv4) {
338
- std::sprintf (socket_address, " %s:%u" , address.get_ip_address (), address.get_port ());
339
- } else {
340
- std::sprintf (socket_address, " [%s]:%u" , address.get_ip_address (), address.get_port ());
360
+
361
+ // UDP requires Udp_RemClient
362
+ if (socket->proto == NSAPI_UDP) {
363
+ char socket_address[NSAPI_IPv6_SIZE + sizeof (" []:12345" ) - 1 + 1 ];
364
+ if (address.get_ip_version () == NSAPI_IPv4) {
365
+ std::sprintf (socket_address, " %s:%u" , address.get_ip_address (), address.get_port ());
366
+ } else {
367
+ std::sprintf (socket_address, " [%s]:%u" , address.get_ip_address (), address.get_port ());
368
+ }
369
+ _at.write_string (socket_address);
341
370
}
342
- _at.write_string (socket_address);
343
371
}
372
+
344
373
_at.cmd_stop ();
345
374
346
375
sisw_retry:
@@ -350,29 +379,30 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_sendto_impl(Cellul
350
379
_at.restore_at_timeout ();
351
380
return NSAPI_ERROR_DEVICE_ERROR;
352
381
}
353
- _at.restore_at_timeout ();
354
382
int socket_id = _at.read_int ();
355
383
if (socket_id != socket->id ) {
384
+ // We might have read the SISW URC so let's try to handle it
385
+ const int urc_code = _at.read_int ();
386
+ const int extra = _at.read_int ();
387
+ if (urc_code != -1 && extra == -1 ) {
388
+ sisw_urc_handler (socket_id, urc_code);
389
+ goto sisw_retry;
390
+ }
391
+ _at.restore_at_timeout ();
356
392
tr_error (" Socket id %d != %d" , socket_id, socket->id );
357
393
return NSAPI_ERROR_DEVICE_ERROR;
358
394
}
359
395
int accept_len = _at.read_int ();
360
396
if (accept_len == -1 ) {
361
397
tr_error (" Socket %d send failed" , socket->id );
398
+ _at.restore_at_timeout ();
362
399
return NSAPI_ERROR_DEVICE_ERROR;
363
400
}
364
- int unack_len = _at.read_int ();
365
- if (unack_len != 0 ) {
366
- tr_warn (" Socket %d unack_len %d" , socket->id , unack_len);
367
- if (GEMALTO_CINTERION_Module::get_model () != GEMALTO_CINTERION_Module::ModelBGS2) {
368
- // assume that an URC was received when unackData is not received
369
- _at.resp_stop ();
370
- goto sisw_retry;
371
- }
372
- }
401
+ _at.skip_param (); // unackData
373
402
374
403
_at.write_bytes ((uint8_t *)data, accept_len);
375
404
_at.resp_stop ();
405
+ _at.restore_at_timeout ();
376
406
377
407
tr_debug (" Socket %d sendto %s, %d bytes (err %d)" , socket->id , address.get_ip_address (), accept_len, _at.get_last_error ());
378
408
@@ -408,16 +438,25 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_recvfrom_impl(Cell
408
438
_at.write_int (size);
409
439
_at.cmd_stop ();
410
440
441
+ sisr_retry:
411
442
_at.resp_start (" ^SISR:" );
412
443
if (!_at.info_resp ()) {
413
444
tr_error (" Socket %d not responding" , socket->id );
414
445
return NSAPI_ERROR_DEVICE_ERROR;
415
446
}
447
+
416
448
int socket_id = _at.read_int ();
417
449
if (socket_id != socket->id ) {
450
+ const int urc_code = _at.read_int ();
451
+ const int extra = _at.read_int (); // should be -1 if URC
452
+ if (urc_code != -1 && extra == -1 ) {
453
+ sisr_urc_handler (socket_id, urc_code);
454
+ goto sisr_retry;
455
+ }
418
456
tr_error (" Socket recvfrom id %d != %d" , socket_id, socket->id );
419
457
return NSAPI_ERROR_DEVICE_ERROR;
420
458
}
459
+
421
460
nsapi_size_or_error_t len = _at.read_int ();
422
461
if (len == 0 ) {
423
462
tr_warn (" Socket %d no data" , socket->id );
@@ -435,7 +474,9 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_recvfrom_impl(Cell
435
474
socket->rx_avail = true ;
436
475
}
437
476
}
438
- if (GEMALTO_CINTERION_Module::get_model () != GEMALTO_CINTERION_Module::ModelBGS2) {
477
+
478
+ // UDP Udp_RemClient
479
+ if (socket->proto == NSAPI_UDP && GEMALTO_CINTERION_Module::get_model () != GEMALTO_CINTERION_Module::ModelBGS2) {
439
480
char ip_address[NSAPI_IPv6_SIZE + sizeof (" []:12345" ) - 1 + 1 ];
440
481
int ip_len = _at.read_string (ip_address, sizeof (ip_address));
441
482
if (ip_len <= 0 ) {
@@ -463,7 +504,7 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_recvfrom_impl(Cell
463
504
port_start++; // skip ':'
464
505
int port = std::strtol (port_start, NULL , 10 );
465
506
address->set_port (port);
466
- tr_debug (" IP address %s: %d" , address->get_ip_address (), address->get_port ());
507
+ tr_debug (" IP address %s, port %d" , address->get_ip_address (), address->get_port ());
467
508
*ip_stop = tmp_ch; // restore original IP string
468
509
}
469
510
}
@@ -571,3 +612,29 @@ void GEMALTO_CINTERION_CellularStack::close_connection_profile(int connection_pr
571
612
572
613
_at.clear_error ();
573
614
}
615
+
616
+ nsapi_error_t GEMALTO_CINTERION_CellularStack::socket_connect (nsapi_socket_t handle, const SocketAddress &address)
617
+ {
618
+ int err = NSAPI_ERROR_DEVICE_ERROR;
619
+
620
+ struct CellularSocket *socket = (struct CellularSocket *)handle;
621
+ if (!socket) {
622
+ return err;
623
+ }
624
+
625
+ _at.lock ();
626
+ err = create_socket_impl (socket);
627
+ if (err != NSAPI_ERROR_OK) {
628
+ _at.unlock ();
629
+ return err;
630
+ }
631
+ err = socket_open_defer (socket, &address);
632
+ _at.unlock ();
633
+
634
+ if (err == NSAPI_ERROR_OK) {
635
+ socket->remoteAddress = address;
636
+ socket->connected = true ;
637
+ }
638
+
639
+ return err;
640
+ }
0 commit comments