Skip to content

Commit 1f47a33

Browse files
author
Ari Parkkila
committed
Cellular: Fix BG96 AT driver for IPv6
1 parent 033fffe commit 1f47a33

File tree

3 files changed

+43
-8
lines changed

3 files changed

+43
-8
lines changed

features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ static const intptr_t cellular_properties[AT_CellularBase::PROPERTY_MAX] = {
5757
1, // AT_CMGF
5858
1, // AT_CSDH
5959
1, // PROPERTY_IPV4_STACK
60-
0, // PROPERTY_IPV6_STACK
61-
0, // PROPERTY_IPV4V6_STACK
60+
1, // PROPERTY_IPV6_STACK
61+
1, // PROPERTY_IPV4V6_STACK
6262
1, // PROPERTY_NON_IP_PDP_TYPE
6363
1, // PROPERTY_AT_CGEREP
6464
};

features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularStack.cpp

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
* limitations under the License.
1616
*/
1717

18+
#include <string.h>
1819
#include "QUECTEL/BG96/QUECTEL_BG96_CellularStack.h"
1920
#include "CellularLog.h"
2021

@@ -60,8 +61,10 @@ nsapi_error_t QUECTEL_BG96_CellularStack::socket_connect(nsapi_socket_t handle,
6061

6162
_at.lock();
6263
if (socket->proto == NSAPI_TCP) {
64+
char ipdot[NSAPI_IP_SIZE];
65+
ip2dot(address, ipdot);
6366
_at.at_cmd_discard("+QIOPEN", "=", "%d%d%s%s%d%d%d", _cid, request_connect_id, "TCP",
64-
address.get_ip_address(), address.get_port(), socket->localAddress.get_port(), 0);
67+
ipdot, address.get_port(), socket->localAddress.get_port(), 0);
6568

6669
handle_open_socket_response(modem_connect_id, err);
6770

@@ -74,7 +77,7 @@ nsapi_error_t QUECTEL_BG96_CellularStack::socket_connect(nsapi_socket_t handle,
7477
_at.at_cmd_discard("+QICLOSE", "=", "%d", modem_connect_id);
7578

7679
_at.at_cmd_discard("+QIOPEN", "=", "%d%d%s%s%d%d%d", _cid, request_connect_id, "TCP",
77-
address.get_ip_address(), address.get_port(), socket->localAddress.get_port(), 0);
80+
ipdot, address.get_port(), socket->localAddress.get_port(), 0);
7881

7982
handle_open_socket_response(modem_connect_id, err);
8083
}
@@ -228,8 +231,10 @@ nsapi_error_t QUECTEL_BG96_CellularStack::create_socket_impl(CellularSocket *soc
228231
handle_open_socket_response(modem_connect_id, err);
229232
}
230233
} else if (socket->proto == NSAPI_UDP && socket->connected) {
234+
char ipdot[NSAPI_IP_SIZE];
235+
ip2dot(socket->remoteAddress, ipdot);
231236
_at.at_cmd_discard("+QIOPEN", "=", "%d%d%s%s%d", _cid, request_connect_id, "UDP",
232-
socket->remoteAddress.get_ip_address(), socket->remoteAddress.get_port());
237+
ipdot, socket->remoteAddress.get_port());
233238

234239
handle_open_socket_response(modem_connect_id, err);
235240

@@ -241,7 +246,7 @@ nsapi_error_t QUECTEL_BG96_CellularStack::create_socket_impl(CellularSocket *soc
241246
socket_close_impl(modem_connect_id);
242247

243248
_at.at_cmd_discard("+QIOPEN", "=", "%d%d%s%s%d", _cid, request_connect_id, "UDP",
244-
socket->remoteAddress.get_ip_address(), socket->remoteAddress.get_port());
249+
ipdot, socket->remoteAddress.get_port());
245250

246251
handle_open_socket_response(modem_connect_id, err);
247252
}
@@ -264,7 +269,9 @@ nsapi_error_t QUECTEL_BG96_CellularStack::create_socket_impl(CellularSocket *soc
264269
nsapi_size_or_error_t QUECTEL_BG96_CellularStack::socket_sendto_impl(CellularSocket *socket, const SocketAddress &address,
265270
const void *data, nsapi_size_t size)
266271
{
267-
if (size > BG96_MAX_SEND_SIZE) {
272+
if (size > BG96_MAX_SEND_SIZE ||
273+
(_stack_type == IPV4_STACK && address.get_ip_version() != NSAPI_IPv4) ||
274+
(_stack_type == IPV6_STACK && address.get_ip_version() != NSAPI_IPv6)) {
268275
return NSAPI_ERROR_PARAMETER;
269276
}
270277

@@ -277,8 +284,10 @@ nsapi_size_or_error_t QUECTEL_BG96_CellularStack::socket_sendto_impl(CellularSoc
277284

278285
// Send
279286
if (socket->proto == NSAPI_UDP) {
287+
char ipdot[NSAPI_IP_SIZE];
288+
ip2dot(address, ipdot);
280289
_at.cmd_start_stop("+QISEND", "=", "%d%d%s%d", socket->id, size,
281-
address.get_ip_address(), address.get_port());
290+
ipdot, address.get_port());
282291
} else {
283292
_at.cmd_start_stop("+QISEND", "=", "%d%d", socket->id, size);
284293
}
@@ -401,3 +410,21 @@ nsapi_error_t QUECTEL_BG96_CellularStack::gethostbyname_async_cancel(int id)
401410
return NSAPI_ERROR_OK;
402411
}
403412
#endif
413+
414+
void QUECTEL_BG96_CellularStack::ip2dot(const SocketAddress &ip, char *dot)
415+
{
416+
if (ip.get_ip_version() == NSAPI_IPv6) {
417+
const uint8_t *bytes = (uint8_t *)ip.get_ip_bytes();
418+
char *p = dot;
419+
for (int i = 0; i < NSAPI_IPv6_BYTES; i += 2) {
420+
if (i != 0) {
421+
*dot++ = ':';
422+
}
423+
dot += sprintf(dot, "%x", (*(bytes + i) << 8 | *(bytes + i + 1)));
424+
}
425+
} else if (ip.get_ip_version() == NSAPI_IPv4) {
426+
strcpy(dot, ip.get_ip_address());
427+
} else {
428+
*dot = '\0';
429+
}
430+
}

features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularStack.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,14 @@ class QUECTEL_BG96_CellularStack : public AT_CellularStack {
8989
hostbyname_cb_t _dns_callback;
9090
nsapi_version_t _dns_version;
9191
#endif
92+
/** Convert IP address to dotted string representation
93+
*
94+
* BG96 requires consecutive zeros so can't use get_ip_address or ip6tos directly.
95+
*
96+
* @param ip address
97+
* @param dot buffer with size NSAPI_IPv6, where address is written zero terminated
98+
*/
99+
void ip2dot(const SocketAddress &ip, char *dot);
92100
};
93101
} // namespace mbed
94102
#endif /* QUECTEL_BG96_CELLULARSTACK_H_ */

0 commit comments

Comments
 (0)