Skip to content

Commit

Permalink
Cellular: Fix BG96 AT driver for IPv6
Browse files Browse the repository at this point in the history
  • Loading branch information
Ari Parkkila committed Aug 16, 2019
1 parent 033fffe commit 1f47a33
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ static const intptr_t cellular_properties[AT_CellularBase::PROPERTY_MAX] = {
1, // AT_CMGF
1, // AT_CSDH
1, // PROPERTY_IPV4_STACK
0, // PROPERTY_IPV6_STACK
0, // PROPERTY_IPV4V6_STACK
1, // PROPERTY_IPV6_STACK
1, // PROPERTY_IPV4V6_STACK
1, // PROPERTY_NON_IP_PDP_TYPE
1, // PROPERTY_AT_CGEREP
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* limitations under the License.
*/

#include <string.h>
#include "QUECTEL/BG96/QUECTEL_BG96_CellularStack.h"
#include "CellularLog.h"

Expand Down Expand Up @@ -60,8 +61,10 @@ nsapi_error_t QUECTEL_BG96_CellularStack::socket_connect(nsapi_socket_t handle,

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

handle_open_socket_response(modem_connect_id, err);

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

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

handle_open_socket_response(modem_connect_id, err);
}
Expand Down Expand Up @@ -228,8 +231,10 @@ nsapi_error_t QUECTEL_BG96_CellularStack::create_socket_impl(CellularSocket *soc
handle_open_socket_response(modem_connect_id, err);
}
} else if (socket->proto == NSAPI_UDP && socket->connected) {
char ipdot[NSAPI_IP_SIZE];
ip2dot(socket->remoteAddress, ipdot);
_at.at_cmd_discard("+QIOPEN", "=", "%d%d%s%s%d", _cid, request_connect_id, "UDP",
socket->remoteAddress.get_ip_address(), socket->remoteAddress.get_port());
ipdot, socket->remoteAddress.get_port());

handle_open_socket_response(modem_connect_id, err);

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

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

handle_open_socket_response(modem_connect_id, err);
}
Expand All @@ -264,7 +269,9 @@ nsapi_error_t QUECTEL_BG96_CellularStack::create_socket_impl(CellularSocket *soc
nsapi_size_or_error_t QUECTEL_BG96_CellularStack::socket_sendto_impl(CellularSocket *socket, const SocketAddress &address,
const void *data, nsapi_size_t size)
{
if (size > BG96_MAX_SEND_SIZE) {
if (size > BG96_MAX_SEND_SIZE ||
(_stack_type == IPV4_STACK && address.get_ip_version() != NSAPI_IPv4) ||
(_stack_type == IPV6_STACK && address.get_ip_version() != NSAPI_IPv6)) {
return NSAPI_ERROR_PARAMETER;
}

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

// Send
if (socket->proto == NSAPI_UDP) {
char ipdot[NSAPI_IP_SIZE];
ip2dot(address, ipdot);
_at.cmd_start_stop("+QISEND", "=", "%d%d%s%d", socket->id, size,
address.get_ip_address(), address.get_port());
ipdot, address.get_port());
} else {
_at.cmd_start_stop("+QISEND", "=", "%d%d", socket->id, size);
}
Expand Down Expand Up @@ -401,3 +410,21 @@ nsapi_error_t QUECTEL_BG96_CellularStack::gethostbyname_async_cancel(int id)
return NSAPI_ERROR_OK;
}
#endif

void QUECTEL_BG96_CellularStack::ip2dot(const SocketAddress &ip, char *dot)
{
if (ip.get_ip_version() == NSAPI_IPv6) {
const uint8_t *bytes = (uint8_t *)ip.get_ip_bytes();
char *p = dot;
for (int i = 0; i < NSAPI_IPv6_BYTES; i += 2) {
if (i != 0) {
*dot++ = ':';
}
dot += sprintf(dot, "%x", (*(bytes + i) << 8 | *(bytes + i + 1)));
}
} else if (ip.get_ip_version() == NSAPI_IPv4) {
strcpy(dot, ip.get_ip_address());
} else {
*dot = '\0';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ class QUECTEL_BG96_CellularStack : public AT_CellularStack {
hostbyname_cb_t _dns_callback;
nsapi_version_t _dns_version;
#endif
/** Convert IP address to dotted string representation
*
* BG96 requires consecutive zeros so can't use get_ip_address or ip6tos directly.
*
* @param ip address
* @param dot buffer with size NSAPI_IPv6, where address is written zero terminated
*/
void ip2dot(const SocketAddress &ip, char *dot);
};
} // namespace mbed
#endif /* QUECTEL_BG96_CELLULARSTACK_H_ */

0 comments on commit 1f47a33

Please sign in to comment.