2323using namespace mbed_cellular_util ;
2424using namespace mbed ;
2525
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)
2727{
2828 memset (_ip, 0 , PDP_IPV6_SIZE);
2929}
@@ -59,27 +59,43 @@ const char *AT_CellularStack::get_ip_address()
5959{
6060 _at.lock ();
6161
62+ bool ipv4 = false , ipv6 = false ;
63+
6264 _at.cmd_start_stop (" +CGPADDR" , " =" , " %d" , _cid);
6365 _at.resp_start (" +CGPADDR:" );
6466
65- int len = -1 ;
6667 if (_at.info_resp ()) {
6768 _at.skip_param ();
6869
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+ }
7485 }
7586 }
7687 _at.resp_stop ();
7788 _at.unlock ();
7889
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+ }
8197
82- return len != - 1 ? _ip : NULL ;
98+ return (ipv4 || ipv6) ? _ip : NULL ;
8399}
84100
85101nsapi_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
256272 nsapi_size_or_error_t ret_val = NSAPI_ERROR_OK;
257273
258274 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 ();
259282 _at.lock ();
260283
261284 ret_val = create_socket_impl (socket);
@@ -267,9 +290,9 @@ nsapi_size_or_error_t AT_CellularStack::socket_sendto(nsapi_socket_t handle, con
267290 }
268291 }
269292
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 ;
273296 }
274297
275298 _at.lock ();
@@ -377,3 +400,14 @@ AT_CellularStack::CellularSocket *AT_CellularStack::find_socket(int sock_id)
377400 }
378401 return sock;
379402}
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