Skip to content

Commit 2ca8487

Browse files
author
Seppo Takalo
authored
Merge pull request #11082 from AriParkkila/cell-bg96-dns
Cellular: Add BG96 AT driver with DNS support
2 parents 4a1f00a + 71c7ed2 commit 2ca8487

File tree

6 files changed

+148
-8
lines changed

6 files changed

+148
-8
lines changed

TESTS/netsocket/dns/asynchronous_dns_cancel.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,15 @@ void ASYNCHRONOUS_DNS_CANCEL()
3535
data[i].semaphore = &semaphore;
3636
data[i].req_result = get_interface()->gethostbyname_async(dns_test_hosts[i],
3737
mbed::Callback<void(nsapi_error_t, SocketAddress *)>(hostbyname_cb, (void *) &data[i]));
38-
TEST_ASSERT(data[i].req_result >= 0 || data[i].req_result == NSAPI_ERROR_NO_MEMORY);
38+
TEST_ASSERT(data[i].req_result >= 0 || data[i].req_result == NSAPI_ERROR_NO_MEMORY || data[i].req_result == NSAPI_ERROR_BUSY);
3939

4040
if (data[i].req_result >= 0) {
4141
// Callback will be called
4242
count++;
4343
} else {
4444
// No memory to initiate DNS query, callback will not be called
45-
printf("Error: No memory to initiate DNS query for %s\n", dns_test_hosts[i]);
46-
data[i].result = NSAPI_ERROR_NO_MEMORY;
45+
printf("Error: No resources to initiate DNS query for %s\n", dns_test_hosts[i]);
46+
data[i].result = data[i].req_result;
4747
data[i].value_set = true;
4848
}
4949
}
@@ -66,7 +66,7 @@ void ASYNCHRONOUS_DNS_CANCEL()
6666
printf("DNS: query \"%s\" => cancel\n", dns_test_hosts[i]);
6767
continue;
6868
}
69-
TEST_ASSERT(data[i].result == NSAPI_ERROR_OK || data[i].result == NSAPI_ERROR_NO_MEMORY || data[i].result == NSAPI_ERROR_DNS_FAILURE || data[i].result == NSAPI_ERROR_TIMEOUT);
69+
TEST_ASSERT(data[i].result == NSAPI_ERROR_OK || data[i].result == NSAPI_ERROR_NO_MEMORY || data[i].result == NSAPI_ERROR_BUSY || data[i].result == NSAPI_ERROR_DNS_FAILURE || data[i].result == NSAPI_ERROR_TIMEOUT);
7070
if (data[i].result == NSAPI_ERROR_OK) {
7171
printf("DNS: query \"%s\" => \"%s\"\n",
7272
dns_test_hosts[i], data[i].addr.get_ip_address());
@@ -76,6 +76,8 @@ void ASYNCHRONOUS_DNS_CANCEL()
7676
printf("DNS: query \"%s\" => timeout\n", dns_test_hosts[i]);
7777
} else if (data[i].result == NSAPI_ERROR_NO_MEMORY) {
7878
printf("DNS: query \"%s\" => no memory\n", dns_test_hosts[i]);
79+
} else if (data[i].result == NSAPI_ERROR_BUSY) {
80+
printf("DNS: query \"%s\" => busy\n", dns_test_hosts[i]);
7981
}
8082
}
8183

TESTS/netsocket/dns/dns_tests.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,12 @@
1919
#define DNS_TESTS_H
2020

2121
#ifndef MBED_CONF_APP_DNS_SIMULT_QUERIES
22+
#ifdef MBED_CONF_CELLULAR_OFFLOAD_DNS_QUERIES
23+
#define MBED_CONF_APP_DNS_SIMULT_QUERIES MBED_CONF_CELLULAR_OFFLOAD_DNS_QUERIES
24+
#else
2225
#define MBED_CONF_APP_DNS_SIMULT_QUERIES 5
2326
#endif
27+
#endif
2428

2529
#ifndef MBED_CONF_NSAPI_DNS_CACHE_SIZE
2630
#define MBED_CONF_NSAPI_DNS_CACHE_SIZE 3

TESTS/netsocket/dns/main.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,13 @@ void do_asynchronous_gethostbyname(const char hosts[][DNS_TEST_HOST_LEN], unsign
7070
for (unsigned int i = 0; i < op_count; i++) {
7171
data[i].semaphore = &semaphore;
7272
nsapi_error_t err = net->gethostbyname_async(hosts[i], mbed::Callback<void(nsapi_error_t, SocketAddress *)>(hostbyname_cb, (void *) &data[i]));
73-
TEST_ASSERT(err >= 0 || err == NSAPI_ERROR_NO_MEMORY);
73+
TEST_ASSERT(err >= 0 || err == NSAPI_ERROR_NO_MEMORY || err == NSAPI_ERROR_BUSY);
7474
if (err >= 0) {
7575
// Callback will be called
7676
count++;
7777
} else {
7878
// No memory to initiate DNS query, callback will not be called
79-
data[i].result = NSAPI_ERROR_NO_MEMORY;
79+
data[i].result = err;
8080
}
8181
}
8282

@@ -87,7 +87,7 @@ void do_asynchronous_gethostbyname(const char hosts[][DNS_TEST_HOST_LEN], unsign
8787

8888
// Print result
8989
for (unsigned int i = 0; i < op_count; i++) {
90-
TEST_ASSERT(data[i].result == NSAPI_ERROR_OK || data[i].result == NSAPI_ERROR_NO_MEMORY || data[i].result == NSAPI_ERROR_DNS_FAILURE || data[i].result == NSAPI_ERROR_TIMEOUT);
90+
TEST_ASSERT(data[i].result == NSAPI_ERROR_OK || data[i].result == NSAPI_ERROR_NO_MEMORY || data[i].result == NSAPI_ERROR_BUSY || data[i].result == NSAPI_ERROR_DNS_FAILURE || data[i].result == NSAPI_ERROR_TIMEOUT);
9191
if (data[i].result == NSAPI_ERROR_OK) {
9292
(*exp_ok)++;
9393
printf("DNS: query \"%s\" => \"%s\"\n",
@@ -101,6 +101,9 @@ void do_asynchronous_gethostbyname(const char hosts[][DNS_TEST_HOST_LEN], unsign
101101
} else if (data[i].result == NSAPI_ERROR_NO_MEMORY) {
102102
(*exp_no_mem)++;
103103
printf("DNS: query \"%s\" => no memory\n", hosts[i]);
104+
} else if (data[i].result == NSAPI_ERROR_BUSY) {
105+
(*exp_no_mem)++;
106+
printf("DNS: query \"%s\" => busy\n", hosts[i]);
104107
}
105108
}
106109

@@ -135,9 +138,12 @@ void do_gethostbyname(const char hosts[][DNS_TEST_HOST_LEN], unsigned int op_cou
135138
} else if (err == NSAPI_ERROR_NO_MEMORY) {
136139
(*exp_no_mem)++;
137140
printf("DNS: query \"%s\" => no memory\n", hosts[i]);
141+
} else if (err == NSAPI_ERROR_BUSY) {
142+
(*exp_no_mem)++;
143+
printf("DNS: query \"%s\" => busy\n", hosts[i]);
138144
} else {
139145
printf("DNS: query \"%s\" => %d, unexpected answer\n", hosts[i], err);
140-
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_NO_MEMORY || err == NSAPI_ERROR_DNS_FAILURE || err == NSAPI_ERROR_TIMEOUT);
146+
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_NO_MEMORY || err == NSAPI_ERROR_BUSY || err == NSAPI_ERROR_DNS_FAILURE || err == NSAPI_ERROR_TIMEOUT);
141147
}
142148
}
143149
}
@@ -181,12 +187,18 @@ Case cases[] = {
181187
Case("ASYNCHRONOUS_DNS", ASYNCHRONOUS_DNS),
182188
Case("ASYNCHRONOUS_DNS_SIMULTANEOUS", ASYNCHRONOUS_DNS_SIMULTANEOUS),
183189
Case("ASYNCHRONOUS_DNS_SIMULTANEOUS_CACHE", ASYNCHRONOUS_DNS_SIMULTANEOUS_CACHE),
190+
#ifndef MBED_CONF_CELLULAR_OFFLOAD_DNS_QUERIES
184191
Case("ASYNCHRONOUS_DNS_CACHE", ASYNCHRONOUS_DNS_CACHE),
192+
#endif
193+
#if !defined MBED_CONF_CELLULAR_OFFLOAD_DNS_QUERIES || MBED_CONF_CELLULAR_OFFLOAD_DNS_QUERIES > MBED_CONF_APP_DNS_TEST_HOSTS_NUM
185194
Case("ASYNCHRONOUS_DNS_NON_ASYNC_AND_ASYNC", ASYNCHRONOUS_DNS_NON_ASYNC_AND_ASYNC),
195+
#endif
186196
Case("ASYNCHRONOUS_DNS_CANCEL", ASYNCHRONOUS_DNS_CANCEL),
197+
#ifndef MBED_CONF_CELLULAR_OFFLOAD_DNS_QUERIES
187198
Case("ASYNCHRONOUS_DNS_EXTERNAL_EVENT_QUEUE", ASYNCHRONOUS_DNS_EXTERNAL_EVENT_QUEUE),
188199
Case("ASYNCHRONOUS_DNS_INVALID_HOST", ASYNCHRONOUS_DNS_INVALID_HOST),
189200
Case("ASYNCHRONOUS_DNS_TIMEOUTS", ASYNCHRONOUS_DNS_TIMEOUTS),
201+
#endif
190202
Case("ASYNCHRONOUS_DNS_SIMULTANEOUS_REPEAT", ASYNCHRONOUS_DNS_SIMULTANEOUS_REPEAT),
191203
Case("SYNCHRONOUS_DNS", SYNCHRONOUS_DNS),
192204
Case("SYNCHRONOUS_DNS_MULTIPLE", SYNCHRONOUS_DNS_MULTIPLE),

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

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,15 @@
2121
using namespace mbed;
2222

2323
QUECTEL_BG96_CellularStack::QUECTEL_BG96_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type) : AT_CellularStack(atHandler, cid, stack_type)
24+
#ifdef MBED_CONF_CELLULAR_OFFLOAD_DNS_QUERIES
25+
, _dns_callback(NULL), _dns_version(NSAPI_UNSPEC)
26+
#endif
2427
{
2528
_at.set_urc_handler("+QIURC: \"recv", mbed::Callback<void()>(this, &QUECTEL_BG96_CellularStack::urc_qiurc_recv));
2629
_at.set_urc_handler("+QIURC: \"close", mbed::Callback<void()>(this, &QUECTEL_BG96_CellularStack::urc_qiurc_closed));
30+
#ifdef MBED_CONF_CELLULAR_OFFLOAD_DNS_QUERIES
31+
_at.set_urc_handler("+QIURC: \"dnsgip\",", mbed::Callback<void()>(this, &QUECTEL_BG96_CellularStack::urc_qiurc_dnsgip));
32+
#endif
2733
}
2834

2935
QUECTEL_BG96_CellularStack::~QUECTEL_BG96_CellularStack()
@@ -102,6 +108,41 @@ void QUECTEL_BG96_CellularStack::urc_qiurc_closed()
102108
urc_qiurc(URC_CLOSED);
103109
}
104110

111+
#ifdef MBED_CONF_CELLULAR_OFFLOAD_DNS_QUERIES
112+
bool QUECTEL_BG96_CellularStack::read_dnsgip(SocketAddress &address, nsapi_version_t _dns_version)
113+
{
114+
if (_at.read_int() == 0) {
115+
int count = _at.read_int();
116+
_at.skip_param();
117+
for (; count > 0; count--) {
118+
_at.resp_start("+QIURC: \"dnsgip\",");
119+
char ipAddress[NSAPI_IP_SIZE];
120+
_at.read_string(ipAddress, sizeof(ipAddress));
121+
if (address.set_ip_address(ipAddress)) {
122+
if (_dns_version == NSAPI_UNSPEC || _dns_version == address.get_ip_version()) {
123+
return true;
124+
}
125+
}
126+
}
127+
}
128+
return false;
129+
}
130+
131+
void QUECTEL_BG96_CellularStack::urc_qiurc_dnsgip()
132+
{
133+
if (!_dns_callback) {
134+
return;
135+
}
136+
SocketAddress address;
137+
if (read_dnsgip(address, _dns_version)) {
138+
_dns_callback(NSAPI_ERROR_OK, &address);
139+
} else {
140+
_dns_callback(NSAPI_ERROR_DNS_FAILURE, NULL);
141+
}
142+
_dns_callback = NULL;
143+
}
144+
#endif
145+
105146
void QUECTEL_BG96_CellularStack::urc_qiurc(urc_type_t urc_type)
106147
{
107148
_at.lock();
@@ -299,3 +340,64 @@ nsapi_size_or_error_t QUECTEL_BG96_CellularStack::socket_recvfrom_impl(CellularS
299340

300341
return recv_len;
301342
}
343+
344+
#ifdef MBED_CONF_CELLULAR_OFFLOAD_DNS_QUERIES
345+
nsapi_error_t QUECTEL_BG96_CellularStack::gethostbyname(const char *host, SocketAddress *address,
346+
nsapi_version_t version, const char *interface_name)
347+
{
348+
(void) interface_name;
349+
MBED_ASSERT(host);
350+
MBED_ASSERT(address);
351+
352+
_at.lock();
353+
354+
if (_dns_callback) {
355+
_at.unlock();
356+
return NSAPI_ERROR_BUSY;
357+
}
358+
359+
if (!address->set_ip_address(host)) {
360+
_at.set_at_timeout(60 * 1000); // from BG96_TCP/IP_AT_Commands_Manual_V1.0
361+
_at.at_cmd_discard("+QIDNSGIP", "=", "%d%s", _cid, host);
362+
_at.resp_start("+QIURC: \"dnsgip\",");
363+
_at.restore_at_timeout();
364+
if (!read_dnsgip(*address, version)) {
365+
_at.unlock();
366+
return NSAPI_ERROR_DNS_FAILURE;
367+
}
368+
}
369+
370+
return _at.unlock_return_error();
371+
}
372+
373+
nsapi_value_or_error_t QUECTEL_BG96_CellularStack::gethostbyname_async(const char *host, hostbyname_cb_t callback,
374+
nsapi_version_t version, const char *interface_name)
375+
{
376+
(void) interface_name;
377+
MBED_ASSERT(host);
378+
MBED_ASSERT(callback);
379+
380+
_at.lock();
381+
382+
if (_dns_callback) {
383+
_at.unlock();
384+
return NSAPI_ERROR_BUSY;
385+
}
386+
387+
_at.at_cmd_discard("+QIDNSGIP", "=", "%d%s", _cid, host);
388+
if (!_at.get_last_error()) {
389+
_dns_callback = callback;
390+
_dns_version = version;
391+
}
392+
393+
return _at.unlock_return_error() ? NSAPI_ERROR_DNS_FAILURE : NSAPI_ERROR_OK;
394+
}
395+
396+
nsapi_error_t QUECTEL_BG96_CellularStack::gethostbyname_async_cancel(int id)
397+
{
398+
_at.lock();
399+
_dns_callback = NULL;
400+
_at.unlock();
401+
return NSAPI_ERROR_OK;
402+
}
403+
#endif

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ class QUECTEL_BG96_CellularStack : public AT_CellularStack {
4848

4949
virtual nsapi_error_t socket_connect(nsapi_socket_t handle, const SocketAddress &address);
5050

51+
#ifdef MBED_CONF_CELLULAR_OFFLOAD_DNS_QUERIES
52+
virtual nsapi_error_t gethostbyname(const char *host, SocketAddress *address, nsapi_version_t version, const char *interface_name);
53+
virtual nsapi_value_or_error_t gethostbyname_async(const char *host, hostbyname_cb_t callback, nsapi_version_t version = NSAPI_UNSPEC,
54+
const char *interface_name = NULL);
55+
virtual nsapi_error_t gethostbyname_async_cancel(int id);
56+
#endif
57+
5158
protected: // AT_CellularStack
5259

5360
virtual int get_max_socket_count();
@@ -73,6 +80,15 @@ class QUECTEL_BG96_CellularStack : public AT_CellularStack {
7380
void urc_qiurc_closed();
7481

7582
void handle_open_socket_response(int &modem_connect_id, int &err);
83+
84+
#ifdef MBED_CONF_CELLULAR_OFFLOAD_DNS_QUERIES
85+
// URC handler for DNS query
86+
void urc_qiurc_dnsgip();
87+
// read DNS query result
88+
bool read_dnsgip(SocketAddress &address, nsapi_version_t _dns_version);
89+
hostbyname_cb_t _dns_callback;
90+
nsapi_version_t _dns_version;
91+
#endif
7692
};
7793
} // namespace mbed
7894
#endif /* QUECTEL_BG96_CELLULARSTACK_H_ */

features/cellular/mbed_lib.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
"control-plane-opt": {
2121
"help": "Enables control plane CIoT EPS optimization",
2222
"value": false
23+
},
24+
"offload-dns-queries" : {
25+
"help": "Use modem IP stack for DNS queries, null or numeric simultaneous queries",
26+
"value": null
2327
}
2428
}
2529
}

0 commit comments

Comments
 (0)