mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			Merge pull request #11424 from mirelachirica/stack_type_ip_versions
Stack type ip versionspull/11480/head
						commit
						66c39e0bca
					
				| 
						 | 
				
			
			@ -51,9 +51,9 @@ uint16_t char_str_to_hex(const char *str, uint16_t len, char *buf, bool omit_lea
 | 
			
		|||
    return CellularUtil_stub::uint16_value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void convert_ipv6(char *ip)
 | 
			
		||||
nsapi_version_t convert_ipv6(char *ip)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    return NSAPI_UNSPEC;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *find_dot_number(char *str, int dot_number)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,7 +60,7 @@ public:
 | 
			
		|||
        PROPERTY_AT_CSDH,           // 0 = not supported, 1 = supported. Show text mode AT command
 | 
			
		||||
        PROPERTY_IPV4_PDP_TYPE,     // 0 = not supported, 1 = supported. Does modem support IPV4?
 | 
			
		||||
        PROPERTY_IPV6_PDP_TYPE,     // 0 = not supported, 1 = supported. Does modem support IPV6?
 | 
			
		||||
        PROPERTY_IPV4V6_PDP_TYPE,   // 0 = not supported, 1 = supported. Does modem support dual stack IPV4V6?
 | 
			
		||||
        PROPERTY_IPV4V6_PDP_TYPE,   // 0 = not supported, 1 = supported. Does modem support IPV4 and IPV6 simultaneously?
 | 
			
		||||
        PROPERTY_NON_IP_PDP_TYPE,   // 0 = not supported, 1 = supported. Does modem support Non-IP?
 | 
			
		||||
        PROPERTY_AT_CGEREP,         // 0 = not supported, 1 = supported. Does modem support AT command AT+CGEREP.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -369,8 +369,9 @@ bool AT_CellularContext::get_context()
 | 
			
		|||
                // APN matched -> Check PDP type
 | 
			
		||||
                pdp_type_t pdp_type = string_to_pdp_type(pdp_type_from_context);
 | 
			
		||||
 | 
			
		||||
                // Accept exact matching PDP context type
 | 
			
		||||
                if (get_property(pdp_type_t_to_cellular_property(pdp_type))) {
 | 
			
		||||
                // Accept exact matching PDP context type or dual PDP context for modems that support both IPv4 and IPv6 stacks
 | 
			
		||||
                if (get_property(pdp_type_t_to_cellular_property(pdp_type)) ||
 | 
			
		||||
                        ((pdp_type == IPV4V6_PDP_TYPE && (get_property(PROPERTY_IPV4_PDP_TYPE) && get_property(PROPERTY_IPV6_PDP_TYPE))) && !_nonip_req)) {
 | 
			
		||||
                    _pdp_type = pdp_type;
 | 
			
		||||
                    _cid = cid;
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -403,7 +404,7 @@ bool AT_CellularContext::set_new_context(int cid)
 | 
			
		|||
    if (_nonip_req && _cp_in_use && get_property(PROPERTY_NON_IP_PDP_TYPE)) {
 | 
			
		||||
        strncpy(pdp_type_str, "Non-IP", sizeof(pdp_type_str));
 | 
			
		||||
        pdp_type = NON_IP_PDP_TYPE;
 | 
			
		||||
    } else if (get_property(PROPERTY_IPV4V6_PDP_TYPE)) {
 | 
			
		||||
    } else if (get_property(PROPERTY_IPV4V6_PDP_TYPE) || (get_property(PROPERTY_IPV4_PDP_TYPE) && get_property(PROPERTY_IPV6_PDP_TYPE))) {
 | 
			
		||||
        strncpy(pdp_type_str, "IPV4V6", sizeof(pdp_type_str));
 | 
			
		||||
        pdp_type = IPV4V6_PDP_TYPE;
 | 
			
		||||
    } else if (get_property(PROPERTY_IPV6_PDP_TYPE)) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,7 +23,7 @@
 | 
			
		|||
using namespace mbed_cellular_util;
 | 
			
		||||
using namespace mbed;
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
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)
 | 
			
		||||
{
 | 
			
		||||
    memset(_ip, 0, PDP_IPV6_SIZE);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -59,27 +59,43 @@ const char *AT_CellularStack::get_ip_address()
 | 
			
		|||
{
 | 
			
		||||
    _at.lock();
 | 
			
		||||
 | 
			
		||||
    bool ipv4 = false, ipv6 = false;
 | 
			
		||||
 | 
			
		||||
    _at.cmd_start_stop("+CGPADDR", "=", "%d", _cid);
 | 
			
		||||
    _at.resp_start("+CGPADDR:");
 | 
			
		||||
 | 
			
		||||
    int len = -1;
 | 
			
		||||
    if (_at.info_resp()) {
 | 
			
		||||
        _at.skip_param();
 | 
			
		||||
 | 
			
		||||
        len = _at.read_string(_ip, PDP_IPV6_SIZE);
 | 
			
		||||
        if (_at.read_string(_ip, PDP_IPV6_SIZE) != -1) {
 | 
			
		||||
            convert_ipv6(_ip);
 | 
			
		||||
            SocketAddress address;
 | 
			
		||||
            address.set_ip_address(_ip);
 | 
			
		||||
 | 
			
		||||
        if (len != -1 && _stack_type != IPV4_STACK) {
 | 
			
		||||
            // in case stack type is not IPV4 only, try to look also for IPV6 address
 | 
			
		||||
            (void)_at.read_string(_ip, PDP_IPV6_SIZE);
 | 
			
		||||
            ipv4 = (address.get_ip_version() == NSAPI_IPv4);
 | 
			
		||||
            ipv6 = (address.get_ip_version() == NSAPI_IPv6);
 | 
			
		||||
 | 
			
		||||
            // Try to look for second address ONLY if modem has support for dual stack(can handle both IPv4 and IPv6 simultaneously).
 | 
			
		||||
            // Otherwise assumption is that second address is not reliable, even if network provides one.
 | 
			
		||||
            if ((get_property(PROPERTY_IPV4V6_PDP_TYPE) && (_at.read_string(_ip, PDP_IPV6_SIZE) != -1))) {
 | 
			
		||||
                convert_ipv6(_ip);
 | 
			
		||||
                address.set_ip_address(_ip);
 | 
			
		||||
                ipv6 = (address.get_ip_version() == NSAPI_IPv6);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    _at.resp_stop();
 | 
			
		||||
    _at.unlock();
 | 
			
		||||
 | 
			
		||||
    // we have at least IPV4 address
 | 
			
		||||
    convert_ipv6(_ip);
 | 
			
		||||
    if (ipv4 && ipv6) {
 | 
			
		||||
        _stack_type = IPV4V6_STACK;
 | 
			
		||||
    } else if (ipv4) {
 | 
			
		||||
        _stack_type = IPV4_STACK;
 | 
			
		||||
    } else if (ipv6) {
 | 
			
		||||
        _stack_type = IPV6_STACK;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return len != -1 ? _ip : NULL;
 | 
			
		||||
    return (ipv4 || ipv6) ? _ip : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		|||
    nsapi_size_or_error_t ret_val = NSAPI_ERROR_OK;
 | 
			
		||||
 | 
			
		||||
    if (socket->id == -1) {
 | 
			
		||||
 | 
			
		||||
        /* Check that stack type supports sendto address type*/
 | 
			
		||||
        if (!is_addr_stack_compatible(addr)) {
 | 
			
		||||
            return NSAPI_ERROR_PARAMETER;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        _ip_ver_sendto = addr.get_ip_version();
 | 
			
		||||
        _at.lock();
 | 
			
		||||
 | 
			
		||||
        ret_val = create_socket_impl(socket);
 | 
			
		||||
| 
						 | 
				
			
			@ -267,9 +290,9 @@ nsapi_size_or_error_t AT_CellularStack::socket_sendto(nsapi_socket_t handle, con
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Check parameters */
 | 
			
		||||
    if (addr.get_ip_version() == NSAPI_UNSPEC) {
 | 
			
		||||
        return NSAPI_ERROR_DEVICE_ERROR;
 | 
			
		||||
    /* Check parameters - sendto address is valid and stack type supports sending to that address type*/
 | 
			
		||||
    if (!is_addr_stack_compatible(addr)) {
 | 
			
		||||
        return NSAPI_ERROR_PARAMETER;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _at.lock();
 | 
			
		||||
| 
						 | 
				
			
			@ -377,3 +400,14 @@ AT_CellularStack::CellularSocket *AT_CellularStack::find_socket(int sock_id)
 | 
			
		|||
    }
 | 
			
		||||
    return sock;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool AT_CellularStack::is_addr_stack_compatible(const SocketAddress &addr)
 | 
			
		||||
{
 | 
			
		||||
    if ((addr.get_ip_version() == NSAPI_UNSPEC) ||
 | 
			
		||||
            (addr.get_ip_version() == NSAPI_IPv4 && _stack_type == IPV6_STACK) ||
 | 
			
		||||
            (addr.get_ip_version() == NSAPI_IPv6 && _stack_type == IPV4_STACK)) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -192,6 +192,11 @@ protected:
 | 
			
		|||
     */
 | 
			
		||||
    int find_socket_index(nsapi_socket_t handle);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     *  Checks if send to address is valid and if current stack type supports sending to that address type
 | 
			
		||||
     */
 | 
			
		||||
    bool is_addr_stack_compatible(const SocketAddress &addr);
 | 
			
		||||
 | 
			
		||||
    // socket container
 | 
			
		||||
    CellularSocket **_socket;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -204,9 +209,12 @@ protected:
 | 
			
		|||
    // PDP context id
 | 
			
		||||
    int _cid;
 | 
			
		||||
 | 
			
		||||
    // stack type from PDP context
 | 
			
		||||
    // stack type - initialised as PDP type and set accordingly after CGPADDR checked
 | 
			
		||||
    nsapi_ip_stack_t _stack_type;
 | 
			
		||||
 | 
			
		||||
    // IP version of send to address
 | 
			
		||||
    nsapi_version_t _ip_ver_sendto;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    int get_socket_index_by_port(uint16_t port);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,10 +28,10 @@
 | 
			
		|||
using namespace mbed;
 | 
			
		||||
namespace mbed_cellular_util {
 | 
			
		||||
 | 
			
		||||
void convert_ipv6(char *ip)
 | 
			
		||||
nsapi_version_t convert_ipv6(char *ip)
 | 
			
		||||
{
 | 
			
		||||
    if (!ip) {
 | 
			
		||||
        return;
 | 
			
		||||
        return NSAPI_UNSPEC;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int len = strlen(ip);
 | 
			
		||||
| 
						 | 
				
			
			@ -49,7 +49,11 @@ void convert_ipv6(char *ip)
 | 
			
		|||
 | 
			
		||||
    // more that 3 periods mean that it was ipv6 but in format of a1.a2.a3.a4.a5.a6.a7.a8.a9.a10.a11.a12.a13.a14.a15.a16
 | 
			
		||||
    // we need to convert it to hexadecimal format separated with colons
 | 
			
		||||
    if (pos > 3) {
 | 
			
		||||
    if (pos == 3) {
 | 
			
		||||
 | 
			
		||||
        return NSAPI_IPv4;
 | 
			
		||||
 | 
			
		||||
    } else if (pos > 3) {
 | 
			
		||||
        pos = 0;
 | 
			
		||||
        int ip_pos = 0;
 | 
			
		||||
        char b;
 | 
			
		||||
| 
						 | 
				
			
			@ -74,7 +78,11 @@ void convert_ipv6(char *ip)
 | 
			
		|||
                ip[pos] = '\0';
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return NSAPI_IPv6;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return NSAPI_UNSPEC;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// For example "32.1.13.184.0.0.205.48.0.0.0.0.0.0.0.0"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,8 +48,9 @@ static const char hex_values[] = "0123456789ABCDEF";
 | 
			
		|||
 *  where ax are in decimal format. In this case, function converts decimals to hex with separated with colons.
 | 
			
		||||
 *
 | 
			
		||||
 *  @param ip       IP address that can be IPv4 or IPv6 in different formats from AT command +CGPADDR. Converted result uses same buffer.
 | 
			
		||||
 *  @return         IP version of the address or NSAPI_UNSPEC if param ip empty or if IPv4 or IPv6 version could not be concluded.
 | 
			
		||||
 */
 | 
			
		||||
void convert_ipv6(char *ip);
 | 
			
		||||
nsapi_version_t convert_ipv6(char *ip);
 | 
			
		||||
 | 
			
		||||
/** Separates IP addresses from the given 'orig' string. 'orig' may contain zero, one or two IP addresses in various formats.
 | 
			
		||||
 *  See AT command +CGPIAF from 3GPP TS 27.007 for details. Does also needed conversions for IPv6 addresses.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,7 +57,7 @@ static const intptr_t cellular_properties[AT_CellularBase::PROPERTY_MAX] = {
 | 
			
		|||
    1,  // AT_CMGF
 | 
			
		||||
    1,  // AT_CSDH
 | 
			
		||||
    1,  // PROPERTY_IPV4_STACK
 | 
			
		||||
    0,  // PROPERTY_IPV6_STACK
 | 
			
		||||
    1,  // PROPERTY_IPV6_STACK
 | 
			
		||||
    0,  // PROPERTY_IPV4V6_STACK
 | 
			
		||||
    1,  // PROPERTY_NON_IP_PDP_TYPE
 | 
			
		||||
    1,  // PROPERTY_AT_CGEREP
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -212,7 +212,7 @@ nsapi_error_t QUECTEL_BG96_CellularStack::create_socket_impl(CellularSocket *soc
 | 
			
		|||
 | 
			
		||||
    if (socket->proto == NSAPI_UDP && !socket->connected) {
 | 
			
		||||
        _at.at_cmd_discard("+QIOPEN", "=", "%d%d%s%s%d%d%d", _cid, request_connect_id, "UDP SERVICE",
 | 
			
		||||
                           (_stack_type == IPV4_STACK) ? "127.0.0.1" : "0:0:0:0:0:0:0:1",
 | 
			
		||||
                           (_ip_ver_sendto == NSAPI_IPv4) ? "127.0.0.1" : "0:0:0:0:0:0:0:1",
 | 
			
		||||
                           remote_port, socket->localAddress.get_port(), 0);
 | 
			
		||||
 | 
			
		||||
        handle_open_socket_response(modem_connect_id, err);
 | 
			
		||||
| 
						 | 
				
			
			@ -225,7 +225,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%d%d", _cid, request_connect_id, "UDP SERVICE",
 | 
			
		||||
                               (_stack_type == IPV4_STACK) ? "127.0.0.1" : "0:0:0:0:0:0:0:1",
 | 
			
		||||
                               (_ip_ver_sendto == NSAPI_IPv4) ? "127.0.0.1" : "0:0:0:0:0:0:0:1",
 | 
			
		||||
                               remote_port, socket->localAddress.get_port(), 0);
 | 
			
		||||
 | 
			
		||||
            handle_open_socket_response(modem_connect_id, err);
 | 
			
		||||
| 
						 | 
				
			
			@ -273,6 +273,12 @@ nsapi_size_or_error_t QUECTEL_BG96_CellularStack::socket_sendto_impl(CellularSoc
 | 
			
		|||
        return NSAPI_ERROR_PARAMETER;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (_ip_ver_sendto != address.get_ip_version()) {
 | 
			
		||||
        _ip_ver_sendto =  address.get_ip_version();
 | 
			
		||||
        socket_close_impl(socket->id);
 | 
			
		||||
        create_socket_impl(socket);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int sent_len = 0;
 | 
			
		||||
    int sent_len_before = 0;
 | 
			
		||||
    int sent_len_after = 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue