1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-18 12:52:44 +01:00

Merge pull request #2889 from Kijewski/issue-2887

ng_netif: non-destructive ng_netif_addr_to_str
This commit is contained in:
Martine Lenders 2015-06-13 13:53:09 +02:00
commit 456b0fdd54
5 changed files with 133 additions and 51 deletions

View File

@ -107,7 +107,7 @@ size_t ng_netif_get(kernel_pid_t *netifs);
* @return Copy of @p out on success.
* @return NULL, if @p out_len < 3 * @p addr_len.
*/
char *ng_netif_addr_to_str(char *out, size_t out_len, uint8_t *addr,
char *ng_netif_addr_to_str(char *out, size_t out_len, const uint8_t *addr,
size_t addr_len);
/**
@ -116,8 +116,6 @@ char *ng_netif_addr_to_str(char *out, size_t out_len, uint8_t *addr,
*
* @details The input format must be like `xx:xx:xx:xx` where `xx` will be the
* bytes of @p addr in hexadecimal representation.
* Changes @p str for simple parsing purposes. Make a copy if you
* need it later.
*
* @param[out] out The resulting hardware address.
* @param[out] out_len Length of @p out.
@ -126,7 +124,7 @@ char *ng_netif_addr_to_str(char *out, size_t out_len, uint8_t *addr,
* @return Actual length of @p out on success.
* @return 0, on failure.
*/
size_t ng_netif_addr_from_str(uint8_t *out, size_t out_len, char *str);
size_t ng_netif_addr_from_str(uint8_t *out, size_t out_len, const char *str);
#ifdef __cplusplus
}

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
* Copyright (C) 2015 René Kijewski <rene.kijewski@fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
@ -14,47 +15,76 @@
#include "net/ng_netif.h"
static uint8_t _parse_byte(char *str)
static inline int _dehex(char c, int default_)
{
uint8_t res = 0;
for (int i = 0; i < 2; i++) { /* iterate over half-bytes */
if ((str[i] >= '0') && (str[i] <= '9')) { /* if '0'-'9' */
res |= (str[i] - '0') << (4 * (1 - i)); /* set half-byte to 0-9 */
}
else if ((str[i] >= 'a') && (str[i] <= 'f')) { /* if 'a'-'f' */
res |= (str[i] - 'a' + 10) << (4 * (1 - i));/* set half-byte to 10-15 */
}
/* interpret any other character as 0 */
if ('0' <= c && c <= '9') {
return c - '0';
}
else if ('A' <= c && c <= 'F') {
return c - 'A' + 10;
}
else if ('a' <= c && c <= 'f') {
return c - 'a' + 10;
}
else {
return default_;
}
return res;
}
size_t ng_netif_addr_from_str(uint8_t *out, size_t out_len, char *str)
size_t ng_netif_addr_from_str(uint8_t *out, size_t out_len, const char *str)
{
size_t res = 0;
char *byte_str = str;
int end = 0;
/* Walk over str from the end. */
/* Take two chars a time as one hex value (%hhx). */
/* Leading zeros can be omitted. */
/* Every non-hexadimal character is a delimiter. */
/* Leading, tailing and adjacent delimiters are forbidden. */
while (end == 0) {
str++;
const char *end_str = str;
uint8_t *out_end = out;
size_t count = 0;
int assert_cell = 1;
if ((res >= out_len) || ((str - byte_str) > 2)) {
/* no space left or byte_str has become > 2 chars */
return 0;
}
if ((*str == ':') || (*str == '\0')) {
end = (*str == '\0');
*str = '\0';
out[res++] = _parse_byte(byte_str);
byte_str = ++str;
}
if (!str || !*str) {
return 0;
}
while (end_str[1]) {
++end_str;
}
return res;
while (end_str >= str) {
int a = 0, b = _dehex(*end_str--, -1);
if (b < 0) {
if (assert_cell) {
return 0;
}
else {
assert_cell = 1;
continue;
}
}
assert_cell = 0;
if (end_str >= str) {
a = _dehex(*end_str--, 0);
}
if (++count > out_len) {
return 0;
}
*out_end++ = (a << 4) | b;
}
if (assert_cell) {
return 0;
}
/* out is reversed */
while (out < --out_end) {
uint8_t tmp = *out_end;
*out_end = *out;
*out++ = tmp;
}
return count;
}
/** @} */

View File

@ -19,7 +19,7 @@ static inline char _half_byte_to_char(uint8_t half_byte)
return (half_byte < 10) ? ('0' + half_byte) : ('a' + (half_byte - 10));
}
char *ng_netif_addr_to_str(char *out, size_t out_len, uint8_t *addr,
char *ng_netif_addr_to_str(char *out, size_t out_len, const uint8_t *addr,
size_t addr_len)
{
size_t i;

View File

@ -4,7 +4,7 @@ include ../Makefile.tests_common
BOARD_INSUFFICIENT_RAM := airfy-beacon chronos msb-430 msb-430h pca10000 \
pca10005 redbee-econotag spark-core stm32f0discovery \
telosb wsn430-v1_3b wsn430-v1_4 z1 nucleo-f334 \
yunjia-nrf51822 samr21-xpro
yunjia-nrf51822 samr21-xpro arduino-mega2560
USEMODULE += embunit

View File

@ -161,7 +161,7 @@ static void test_ng_netif_get__full(void)
static void test_ng_netif_addr_to_str__out_too_short(void)
{
uint8_t addr[] = {0x05, 0xcd};
static const uint8_t addr[] = {0x05, 0xcd};
char out[2];
TEST_ASSERT_NULL(ng_netif_addr_to_str(out, sizeof(out), addr, sizeof(addr)));
@ -169,7 +169,7 @@ static void test_ng_netif_addr_to_str__out_too_short(void)
static void test_ng_netif_addr_to_str__success(void)
{
uint8_t addr[] = {0x05, 0xcd};
static const uint8_t addr[] = {0x05, 0xcd};
char out[3 * sizeof(addr)];
TEST_ASSERT_EQUAL_STRING("05:cd", ng_netif_addr_to_str(out, sizeof(out),
@ -178,31 +178,80 @@ static void test_ng_netif_addr_to_str__success(void)
static void test_ng_netif_addr_from_str__out_too_short(void)
{
char str[] = "05:cd";
static const char str[] = "05:cd";
uint8_t out[1];
TEST_ASSERT_EQUAL_INT(0, ng_netif_addr_from_str(out, sizeof(out), str));
}
static void test_ng_netif_addr_from_str__ill_formated1(void)
static void test_ng_netif_addr_from_str__omitted_delimitter(void)
{
char str[] = "576:cd";
uint8_t out[sizeof(str)];
static const char str[] = "4567:cd";
uint8_t out[3];
TEST_ASSERT_EQUAL_INT(0, ng_netif_addr_from_str(out, sizeof(out), str));
TEST_ASSERT_EQUAL_INT(3, ng_netif_addr_from_str(out, sizeof(out), str));
TEST_ASSERT_EQUAL_INT(0x45, out[0]);
TEST_ASSERT_EQUAL_INT(0x67, out[1]);
TEST_ASSERT_EQUAL_INT(0xcd, out[2]);
}
static void test_ng_netif_addr_from_str__ill_formated2(void)
{
char str[] = TEST_STRING8;
static const char str[] = TEST_STRING8;
uint8_t out[sizeof(str)];
TEST_ASSERT_EQUAL_INT(0, ng_netif_addr_from_str(out, sizeof(out), str));
}
static void test_ng_netif_addr_from_str__ill_formated3(void)
static void test_ng_netif_addr_from_str__dash_delimitter(void)
{
char str[] = "05-cd";
static const char str[] = "05-cd";
uint8_t out[2];
TEST_ASSERT_EQUAL_INT(2, ng_netif_addr_from_str(out, sizeof(out), str));
TEST_ASSERT_EQUAL_INT(0x05, out[0]);
TEST_ASSERT_EQUAL_INT(0xcd, out[1]);
}
static void test_ng_netif_addr_from_str__zero_omitted_back(void)
{
static const char str[] = "05:c";
uint8_t out[2];
TEST_ASSERT_EQUAL_INT(2, ng_netif_addr_from_str(out, sizeof(out), str));
TEST_ASSERT_EQUAL_INT(0x05, out[0]);
TEST_ASSERT_EQUAL_INT(0x0c, out[1]);
}
static void test_ng_netif_addr_from_str__zero_omitted_front(void)
{
static const char str[] = "5:cd";
uint8_t out[2];
TEST_ASSERT_EQUAL_INT(2, ng_netif_addr_from_str(out, sizeof(out), str));
TEST_ASSERT_EQUAL_INT(0x05, out[0]);
TEST_ASSERT_EQUAL_INT(0xcd, out[1]);
}
static void test_ng_netif_addr_from_str__ill_trailing_delimitter(void)
{
static const char str[] = "05:cd:";
uint8_t out[sizeof(str)];
TEST_ASSERT_EQUAL_INT(0, ng_netif_addr_from_str(out, sizeof(out), str));
}
static void test_ng_netif_addr_from_str__ill_leading_delimitter(void)
{
static const char str[] = ":05:cd";
uint8_t out[sizeof(str)];
TEST_ASSERT_EQUAL_INT(0, ng_netif_addr_from_str(out, sizeof(out), str));
}
static void test_ng_netif_addr_from_str__ill_extra_delimitter(void)
{
static const char str[] = "05::cd";
uint8_t out[sizeof(str)];
TEST_ASSERT_EQUAL_INT(0, ng_netif_addr_from_str(out, sizeof(out), str));
@ -210,7 +259,7 @@ static void test_ng_netif_addr_from_str__ill_formated3(void)
static void test_ng_netif_addr_from_str__success(void)
{
char str[] = "05:cd";
static const char str[] = "05:cd";
uint8_t out[2];
TEST_ASSERT_EQUAL_INT(2, ng_netif_addr_from_str(out, sizeof(out), str));
@ -234,9 +283,14 @@ Test *tests_netif_tests(void)
new_TestFixture(test_ng_netif_addr_to_str__out_too_short),
new_TestFixture(test_ng_netif_addr_to_str__success),
new_TestFixture(test_ng_netif_addr_from_str__out_too_short),
new_TestFixture(test_ng_netif_addr_from_str__ill_formated1),
new_TestFixture(test_ng_netif_addr_from_str__omitted_delimitter),
new_TestFixture(test_ng_netif_addr_from_str__ill_formated2),
new_TestFixture(test_ng_netif_addr_from_str__ill_formated3),
new_TestFixture(test_ng_netif_addr_from_str__dash_delimitter),
new_TestFixture(test_ng_netif_addr_from_str__zero_omitted_back),
new_TestFixture(test_ng_netif_addr_from_str__zero_omitted_front),
new_TestFixture(test_ng_netif_addr_from_str__ill_trailing_delimitter),
new_TestFixture(test_ng_netif_addr_from_str__ill_leading_delimitter),
new_TestFixture(test_ng_netif_addr_from_str__ill_extra_delimitter),
new_TestFixture(test_ng_netif_addr_from_str__success),
};