Skip to content

Commit 605a42d

Browse files
author
Ari Parkkila
committed
Cellular: Fix Gemalto/Cinterion socket open defer
1 parent cdc28b5 commit 605a42d

File tree

3 files changed

+60
-73
lines changed

3 files changed

+60
-73
lines changed

UNITTESTS/features/cellular/framework/AT/at_cellularcontext/at_cellularcontexttest.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ TEST_F(TestAT_CellularContext, connect_disconnect_sync)
473473
network_cb_count = 0;
474474
// connect in sync mode, semaphore will return 0 so timeout is returned
475475
ASSERT_EQ(ctx.connect(), NSAPI_ERROR_TIMEOUT);
476-
ASSERT_EQ(network_cb_count, 0);
476+
ASSERT_EQ(network_cb_count, 1);
477477

478478
my_AT_CTX ctx1(at, &dev);
479479
ctx1.attach(&network_cb);
@@ -486,7 +486,7 @@ TEST_F(TestAT_CellularContext, connect_disconnect_sync)
486486

487487
ASSERT_EQ(ctx1.connect(), NSAPI_ERROR_OK);
488488

489-
ASSERT_EQ(network_cb_count, 4);
489+
ASSERT_EQ(network_cb_count, 5);
490490

491491
ASSERT_EQ(ctx1.connect(), NSAPI_ERROR_IS_CONNECTED);
492492

features/cellular/framework/targets/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp

Lines changed: 58 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,6 @@ GEMALTO_CINTERION_CellularStack::~GEMALTO_CINTERION_CellularStack()
4444
_at.set_urc_handler("^SISR:", 0);
4545
}
4646

47-
GEMALTO_CINTERION_CellularStack::CellularSocket *GEMALTO_CINTERION_CellularStack::find_socket(int sock_id)
48-
{
49-
CellularSocket *sock = NULL;
50-
for (int i = 0; i < SOCKET_MAX; i++) {
51-
if (_socket[i] && _socket[i]->id == sock_id) {
52-
sock = _socket[i];
53-
break;
54-
}
55-
}
56-
if (!sock) {
57-
tr_error("Socket not found %d", sock_id);
58-
}
59-
return sock;
60-
}
61-
6247
void GEMALTO_CINTERION_CellularStack::urc_sis()
6348
{
6449
int sock_id = _at.read_int();
@@ -175,56 +160,11 @@ nsapi_error_t GEMALTO_CINTERION_CellularStack::socket_close_impl(int sock_id)
175160
}
176161

177162
nsapi_error_t GEMALTO_CINTERION_CellularStack::socket_open_defer(CellularSocket *socket, const SocketAddress *address)
178-
{
179-
// host address (IPv4) and local+remote port is needed only for BGS2 which does not support UDP server socket
180-
char sock_addr[sizeof("sockudp://") - 1 + NSAPI_IPv6_SIZE + sizeof("[]:12345;port=12345") - 1 + 1];
181-
182-
if (socket->proto == NSAPI_UDP) {
183-
if (GEMALTO_CINTERION::get_module() != GEMALTO_CINTERION::ModuleBGS2) {
184-
std::sprintf(sock_addr, "sockudp://%s:%u", address ? address->get_ip_address() : "", socket->localAddress.get_port());
185-
} else {
186-
std::sprintf(sock_addr, "sockudp://%s:%u;port=%u", address->get_ip_address(), address->get_port(), socket->localAddress.get_port());
187-
}
188-
} else {
189-
if (address->get_ip_version() == NSAPI_IPv4) {
190-
std::sprintf(sock_addr, "socktcp://%s:%u", address->get_ip_address(), address->get_port());
191-
} else {
192-
std::sprintf(sock_addr, "socktcp://[%s]:%u", address->get_ip_address(), address->get_port());
193-
}
194-
}
195-
196-
_at.cmd_start("AT^SISS=");
197-
_at.write_int(socket->id);
198-
_at.write_string("address", false);
199-
_at.write_string(sock_addr);
200-
_at.cmd_stop_read_resp();
201-
202-
_at.cmd_start("AT^SISO=");
203-
_at.write_int(socket->id);
204-
_at.cmd_stop_read_resp();
205-
206-
if (_at.get_last_error()) {
207-
tr_error("Socket %d open failed!", socket->id);
208-
_at.clear_error();
209-
socket_close_impl(socket->id); // socket may already be open on modem if app and modem are not in sync, as a recovery, try to close the socket so open succeeds the next time
210-
return NSAPI_ERROR_NO_SOCKET;
211-
}
212-
213-
socket->created = true;
214-
tr_debug("Cinterion open %d (err %d)", socket->id, _at.get_last_error());
215-
216-
return _at.get_last_error();
217-
}
218-
219-
// To open socket:
220-
// 1. Select URC mode or polling mode with AT^SCFG
221-
// 2. create a GPRS connection profile with AT^SICS (must have PDP)
222-
// 3. create service profile with AT^SISS and map connectionID to serviceID
223-
// 4. open internet session with AT^SISO (ELS61 tries to attach to a packet domain)
224-
nsapi_error_t GEMALTO_CINTERION_CellularStack::create_socket_impl(CellularSocket *socket)
225163
{
226164
int connection_profile_id = CONNECTION_PROFILE_ID;
227165

166+
int retry_open = 1;
167+
retry_open:
228168
// setup internet session profile
229169
int internet_service_id = socket->id;
230170
bool foundSrvType = false;
@@ -285,6 +225,56 @@ nsapi_error_t GEMALTO_CINTERION_CellularStack::create_socket_impl(CellularSocket
285225
_at.cmd_stop_read_resp();
286226
}
287227

228+
// host address (IPv4) and local+remote port is needed only for BGS2 which does not support UDP server socket
229+
char sock_addr[sizeof("sockudp://") - 1 + NSAPI_IPv6_SIZE + sizeof("[]:12345;port=12345") - 1 + 1];
230+
231+
if (socket->proto == NSAPI_UDP) {
232+
if (GEMALTO_CINTERION::get_module() != GEMALTO_CINTERION::ModuleBGS2) {
233+
std::sprintf(sock_addr, "sockudp://%s:%u", address ? address->get_ip_address() : "", socket->localAddress.get_port());
234+
} else {
235+
std::sprintf(sock_addr, "sockudp://%s:%u;port=%u", address->get_ip_address(), address->get_port(), socket->localAddress.get_port());
236+
}
237+
} else {
238+
if (address->get_ip_version() == NSAPI_IPv4) {
239+
std::sprintf(sock_addr, "socktcp://%s:%u", address->get_ip_address(), address->get_port());
240+
} else {
241+
std::sprintf(sock_addr, "socktcp://[%s]:%u", address->get_ip_address(), address->get_port());
242+
}
243+
}
244+
245+
_at.cmd_start("AT^SISS=");
246+
_at.write_int(socket->id);
247+
_at.write_string("address", false);
248+
_at.write_string(sock_addr);
249+
_at.cmd_stop_read_resp();
250+
251+
_at.cmd_start("AT^SISO=");
252+
_at.write_int(socket->id);
253+
_at.cmd_stop_read_resp();
254+
255+
if (_at.get_last_error()) {
256+
tr_error("Socket %d open failed!", socket->id);
257+
_at.clear_error();
258+
socket_close_impl(socket->id); // socket may already be open on modem if app and modem are not in sync, as a recovery, try to close the socket so open succeeds the next time
259+
if (retry_open--) {
260+
goto retry_open;
261+
}
262+
return NSAPI_ERROR_NO_SOCKET;
263+
}
264+
265+
socket->created = true;
266+
tr_debug("Cinterion open %d (err %d)", socket->id, _at.get_last_error());
267+
268+
return _at.get_last_error();
269+
}
270+
271+
// To open socket:
272+
// 1. Select URC mode or polling mode with AT^SCFG
273+
// 2. create a GPRS connection profile with AT^SICS (must have PDP)
274+
// 3. create service profile with AT^SISS and map connectionID to serviceID
275+
// 4. open internet session with AT^SISO (ELS61 tries to attach to a packet domain)
276+
nsapi_error_t GEMALTO_CINTERION_CellularStack::create_socket_impl(CellularSocket *socket)
277+
{
288278
if (socket->proto == NSAPI_UDP) {
289279
if (GEMALTO_CINTERION::get_module() != GEMALTO_CINTERION::ModuleBGS2) {
290280
return socket_open_defer(socket);
@@ -335,13 +325,13 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_sendto_impl(Cellul
335325
}
336326
}
337327
if (!socket->started || !socket->tx_ready) {
338-
tr_debug("Socket %d would block (started %d, tx %d)", socket->id, socket->started, socket->tx_ready);
328+
tr_debug("Socket %d send would block (started %d, tx %d)", socket->id, socket->started, socket->tx_ready);
339329
return NSAPI_ERROR_WOULD_BLOCK;
340330
}
341331

342332
if (size > UDP_PACKET_SIZE) {
343-
tr_warn("Sending UDP packet size %d (max %d)", size, UDP_PACKET_SIZE);
344-
size = UDP_PACKET_SIZE;
333+
tr_error("sendto size %d (max %d)", size, UDP_PACKET_SIZE);
334+
return NSAPI_ERROR_PARAMETER;
345335
}
346336

347337
_at.set_at_timeout(FAILURE_TIMEOUT);
@@ -413,13 +403,12 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_recvfrom_impl(Cell
413403
if (!socket->rx_avail) {
414404
_at.process_oob(); // check for ^SISR URC
415405
if (!socket->rx_avail) {
416-
tr_debug("Socket %d would block", socket->id);
406+
tr_debug("Socekt %d recv would block", socket->id);
417407
return NSAPI_ERROR_WOULD_BLOCK;
418408
}
419409
}
420410

421411
if (size > UDP_PACKET_SIZE) {
422-
tr_debug("Socket recvfrom size %d > %d", size, UDP_PACKET_SIZE);
423412
size = UDP_PACKET_SIZE;
424413
}
425414

@@ -459,6 +448,7 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_recvfrom_impl(Cell
459448
}
460449
socket->rx_avail = false;
461450
if (len >= (nsapi_size_or_error_t)size) {
451+
len = (nsapi_size_or_error_t)size;
462452
int remain_len = _at.read_int();
463453
if (remain_len > 0) {
464454
socket->rx_avail = true;
@@ -470,7 +460,7 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_recvfrom_impl(Cell
470460
char ip_address[NSAPI_IPv6_SIZE + sizeof("[]:12345") - 1 + 1];
471461
int ip_len = _at.read_string(ip_address, sizeof(ip_address));
472462
if (ip_len <= 0) {
473-
tr_error("Socket %d recvfrom addr!", socket->id);
463+
tr_error("Socket %d recvfrom addr (len %d)", socket->id, ip_len);
474464
return NSAPI_ERROR_DEVICE_ERROR;
475465
}
476466
if (address) {

features/cellular/framework/targets/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,6 @@ class GEMALTO_CINTERION_CellularStack : public AT_CellularStack {
4848
virtual nsapi_error_t socket_connect(nsapi_socket_t handle, const SocketAddress &address);
4949

5050
private:
51-
// find the socket handle based on socket identifier
52-
CellularSocket *find_socket(int sock_id);
53-
5451
// socket URC handlers as per Cinterion AT manuals
5552
void urc_sis();
5653
void urc_sisw();

0 commit comments

Comments
 (0)