23
23
using namespace mbed_cellular_util ;
24
24
using namespace mbed ;
25
25
26
- AT_CellularStack::AT_CellularStack (ATHandler &at, int cid, nsapi_ip_stack_t stack_type) : AT_CellularBase(at), _socket(NULL ), _socket_count(0 ), _cid(cid), _stack_type(stack_type)
26
+ AT_CellularStack::AT_CellularStack (ATHandler &at, int cid, nsapi_ip_stack_t stack_type) : AT_CellularBase(at), _socket(NULL ), _socket_count(0 ), _cid(cid), _stack_type(stack_type), _ip_ver_sendto(NSAPI_UNSPEC)
27
27
{
28
28
memset (_ip, 0 , PDP_IPV6_SIZE);
29
29
}
@@ -59,27 +59,43 @@ const char *AT_CellularStack::get_ip_address()
59
59
{
60
60
_at.lock ();
61
61
62
+ bool ipv4 = false , ipv6 = false ;
63
+
62
64
_at.cmd_start_stop (" +CGPADDR" , " =" , " %d" , _cid);
63
65
_at.resp_start (" +CGPADDR:" );
64
66
65
- int len = -1 ;
66
67
if (_at.info_resp ()) {
67
68
_at.skip_param ();
68
69
69
- len = _at.read_string (_ip, PDP_IPV6_SIZE);
70
-
71
- if (len != -1 && _stack_type != IPV4_STACK) {
72
- // in case stack type is not IPV4 only, try to look also for IPV6 address
73
- (void )_at.read_string (_ip, PDP_IPV6_SIZE);
70
+ if (_at.read_string (_ip, PDP_IPV6_SIZE) != -1 ) {
71
+ convert_ipv6 (_ip);
72
+ SocketAddress address;
73
+ address.set_ip_address (_ip);
74
+
75
+ ipv4 = (address.get_ip_version () == NSAPI_IPv4);
76
+ ipv6 = (address.get_ip_version () == NSAPI_IPv6);
77
+
78
+ // Try to look for second address ONLY if modem has support for dual stack(can handle both IPv4 and IPv6 simultaneously).
79
+ // Otherwise assumption is that second address is not reliable, even if network provides one.
80
+ if ((get_property (PROPERTY_IPV4V6_PDP_TYPE) && (_at.read_string (_ip, PDP_IPV6_SIZE) != -1 ))) {
81
+ convert_ipv6 (_ip);
82
+ address.set_ip_address (_ip);
83
+ ipv6 = (address.get_ip_version () == NSAPI_IPv6);
84
+ }
74
85
}
75
86
}
76
87
_at.resp_stop ();
77
88
_at.unlock ();
78
89
79
- // we have at least IPV4 address
80
- convert_ipv6 (_ip);
90
+ if (ipv4 && ipv6) {
91
+ _stack_type = IPV4V6_STACK;
92
+ } else if (ipv4) {
93
+ _stack_type = IPV4_STACK;
94
+ } else if (ipv6) {
95
+ _stack_type = IPV6_STACK;
96
+ }
81
97
82
- return len != - 1 ? _ip : NULL ;
98
+ return (ipv4 || ipv6) ? _ip : NULL ;
83
99
}
84
100
85
101
nsapi_error_t AT_CellularStack::socket_stack_init ()
@@ -256,6 +272,13 @@ nsapi_size_or_error_t AT_CellularStack::socket_sendto(nsapi_socket_t handle, con
256
272
nsapi_size_or_error_t ret_val = NSAPI_ERROR_OK;
257
273
258
274
if (socket->id == -1 ) {
275
+
276
+ /* Check that stack type supports sendto address type*/
277
+ if (!is_addr_stack_compatible (addr)) {
278
+ return NSAPI_ERROR_PARAMETER;
279
+ }
280
+
281
+ _ip_ver_sendto = addr.get_ip_version ();
259
282
_at.lock ();
260
283
261
284
ret_val = create_socket_impl (socket);
@@ -267,9 +290,9 @@ nsapi_size_or_error_t AT_CellularStack::socket_sendto(nsapi_socket_t handle, con
267
290
}
268
291
}
269
292
270
- /* Check parameters */
271
- if (addr. get_ip_version () == NSAPI_UNSPEC ) {
272
- return NSAPI_ERROR_DEVICE_ERROR ;
293
+ /* Check parameters - sendto address is valid and stack type supports sending to that address type */
294
+ if (! is_addr_stack_compatible (addr) ) {
295
+ return NSAPI_ERROR_PARAMETER ;
273
296
}
274
297
275
298
_at.lock ();
@@ -377,3 +400,14 @@ AT_CellularStack::CellularSocket *AT_CellularStack::find_socket(int sock_id)
377
400
}
378
401
return sock;
379
402
}
403
+
404
+ bool AT_CellularStack::is_addr_stack_compatible (const SocketAddress &addr)
405
+ {
406
+ if ((addr.get_ip_version () == NSAPI_UNSPEC) ||
407
+ (addr.get_ip_version () == NSAPI_IPv4 && _stack_type == IPV6_STACK) ||
408
+ (addr.get_ip_version () == NSAPI_IPv6 && _stack_type == IPV4_STACK)) {
409
+ return false ;
410
+ }
411
+ return true ;
412
+ }
413
+
0 commit comments