From 3061ecca3d0fdfb87dabbf5f63c9e06c2a30f53a Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Thu, 23 Aug 2018 17:08:59 +0200 Subject: o Initial import. --- .../components/iot/ipv6_parse/ipv6_parse.c | 167 +++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_parse/ipv6_parse.c (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_parse/ipv6_parse.c') diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_parse/ipv6_parse.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_parse/ipv6_parse.c new file mode 100644 index 0000000..0581763 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_parse/ipv6_parse.c @@ -0,0 +1,167 @@ +/** + * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#include +#include +#include +#include +#include +#include "ipv6_parse.h" +#include "nrf_error.h" + +static uint16_t ascii_to_hex(char * p_str) +{ + uint16_t res = 0; + sscanf(p_str, "%hx", &res); + return res; +} + +static void reverse_string(char * p_str) +{ + uint32_t str_len = strlen(p_str); + for (uint32_t i = 0, j = str_len - 1; i < j; i++, j--) + { + char tmp = p_str[i]; + p_str[i] = p_str[j]; + p_str[j] = tmp; + } +} + +uint32_t ipv6_parse_addr(uint8_t * p_addr, const char * p_uri, uint8_t uri_len) +{ + bool is_compressed = false; + uint8_t block_1_len = uri_len; + + const char * compressed_position = strstr(&p_uri[0], "::"); + if (compressed_position != NULL) + { + is_compressed = true; + block_1_len = compressed_position - &p_uri[0]; + } + // Parse block 1. + uint8_t block_1_end = block_1_len; + char sub_addr_buf[5] = {'\0',}; + + uint8_t char_pos = 0; + uint8_t sub_addr_count_block_1 = 0; + + for (uint8_t i = 0; i < block_1_end; i++) + { + if (p_uri[i] != ':') + { + sub_addr_buf[char_pos++] = p_uri[i]; + } + else + { + // we have read all number bytes and hit a delimiter. Save the sub address. + uint16_t value = ascii_to_hex(sub_addr_buf); + p_addr[sub_addr_count_block_1++] = ((value & 0xFF00) >> 8); + p_addr[sub_addr_count_block_1++] = ((value & 0x00FF)); + + char_pos = 0; + memset(sub_addr_buf, '\0', 5); + + } + + // if we are at the end of block 1, save the last sub address. + if ((i + 1) == block_1_end) + { + uint16_t value = ascii_to_hex(sub_addr_buf); + p_addr[sub_addr_count_block_1++] = ((value & 0xFF00) >> 8); + p_addr[sub_addr_count_block_1++] = ((value & 0x00FF)); + + + char_pos = 0; + memset(sub_addr_buf, '\0', 5); + } + } + + if (is_compressed == true) + { + // NOTE: sub_addr_buf must be cleared in previous loop. + + // lets parse backwards for second block. + uint8_t block_2_start = block_1_end + 2; // skip the '::' delimiter. + uint8_t block_2_len = uri_len - (block_1_len + 2); + uint8_t block_2_end = block_2_start + block_2_len; + + uint8_t sub_addr_count_block_2 = 0; + uint8_t sub_addr_index = 15; + + for (uint8_t i = block_2_end - 1; i > block_2_start - 1; i--) + { + if (p_uri[i] != ':') + { + sub_addr_buf[char_pos++] = p_uri[i]; + } + else + { + // we have read all number bytes and hit a delimiter. Save the sub address. + reverse_string(sub_addr_buf); + + uint16_t value = ascii_to_hex(sub_addr_buf); + p_addr[sub_addr_index--] = ((value & 0x00FF)); + p_addr[sub_addr_index--] = ((value & 0xFF00) >> 8); + sub_addr_count_block_2 += 2; + char_pos = 0; + memset(sub_addr_buf, '\0', 5); + + } + + // if we are at the end of block 1, save the last sub address. + if (i == block_2_start) + { + reverse_string(sub_addr_buf); + + uint16_t value = ascii_to_hex(sub_addr_buf); + p_addr[sub_addr_index--] = ((value & 0x00FF)); + p_addr[sub_addr_index--] = ((value & 0xFF00) >> 8); + sub_addr_count_block_2 += 2; + char_pos = 0; + memset(sub_addr_buf, '\0', 5); + } + } + + for (uint8_t i = sub_addr_count_block_1; i < (16 - sub_addr_count_block_2); i++) + { + p_addr[i] = 0x00; + } + } + return NRF_SUCCESS; +} -- cgit v1.2.3