-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tests: modify driver_at86rf2xx for pure netdev2
- Loading branch information
Showing
6 changed files
with
593 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/* | ||
* Copyright (C) Freie Universität Berlin | ||
* | ||
* 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 | ||
* directory for more details. | ||
*/ | ||
|
||
/** | ||
* @{ | ||
* | ||
* @file | ||
* @author Martine Lenders <mlenders@inf.fu-berlin.de> | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <stdint.h> | ||
|
||
#include "common.h" | ||
|
||
void print_addr(uint8_t *addr, size_t addr_len) | ||
{ | ||
for (int i = 0; i < addr_len; i++) { | ||
if (i != 0) { | ||
printf(":"); | ||
} | ||
printf("%02x", (unsigned)addr[i]); | ||
} | ||
} | ||
|
||
/** @} */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,306 @@ | ||
/* | ||
* Copyright (C) 2016 Freie Universität Berlin | ||
* | ||
* 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 | ||
* directory for more details. | ||
*/ | ||
|
||
/** | ||
* @{ | ||
* | ||
* @file | ||
* @author Martine Lenders <mlenders@inf.fu-berlin.de> | ||
*/ | ||
|
||
#include <errno.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
|
||
#include "net/netdev2/ieee802154.h" | ||
#include "net/ieee802154.h" | ||
|
||
#include "common.h" | ||
|
||
#include "od.h" | ||
|
||
#define _MAX_ADDR_LEN (8) | ||
|
||
static int _parse_addr(uint8_t *out, size_t out_len, const char *in); | ||
static int send(int iface, le_uint16_t dst_pan, uint8_t *dst_addr, | ||
size_t dst_len, char *data); | ||
|
||
int ifconfig_list(int idx) | ||
{ | ||
int res; | ||
uint8_t array_val[_MAX_ADDR_LEN]; | ||
netdev2_ieee802154_t *dev = (netdev2_ieee802154_t *)(&devs[idx]); | ||
|
||
int (*get)(netdev2_t *, netopt_t, void *, size_t) = dev->netdev.driver->get; | ||
netopt_enable_t enable_val; | ||
uint16_t u16_val; | ||
|
||
printf("Iface %3d HWaddr: ", idx); | ||
print_addr(dev->short_addr, IEEE802154_SHORT_ADDRESS_LEN); | ||
printf(", Long HWaddr: "); | ||
print_addr(dev->long_addr, IEEE802154_LONG_ADDRESS_LEN); | ||
printf(", PAN: 0x%04x", dev->pan); | ||
|
||
res = get((netdev2_t *)dev, NETOPT_ADDR_LEN, &u16_val, sizeof(u16_val)); | ||
if (res < 0) { | ||
puts("(err)"); | ||
return 1; | ||
} | ||
printf("\n Address length: %u", (unsigned)u16_val); | ||
|
||
res = get((netdev2_t *)dev, NETOPT_SRC_LEN, &u16_val, sizeof(u16_val)); | ||
if (res < 0) { | ||
puts("(err)"); | ||
return 1; | ||
} | ||
printf(", Source address length: %u", (unsigned)u16_val); | ||
|
||
res = get((netdev2_t *)dev, NETOPT_MAX_PACKET_SIZE, &u16_val, | ||
sizeof(u16_val)); | ||
if (res < 0) { | ||
puts("(err)"); | ||
return 1; | ||
} | ||
printf(", Max.Payload: %u", (unsigned)u16_val); | ||
|
||
res = get((netdev2_t *)dev, NETOPT_IPV6_IID, array_val, sizeof(array_val)); | ||
if (res > 0) { | ||
printf("\n IPv6 IID: "); | ||
print_addr(array_val, res); | ||
} | ||
|
||
printf("\n Channel: %u", dev->chan); | ||
|
||
res = get((netdev2_t *)dev, NETOPT_CHANNEL_PAGE, &u16_val, sizeof(u16_val)); | ||
if (res < 0) { | ||
puts("(err)"); | ||
return 1; | ||
} | ||
printf(", Ch.page: %u", (unsigned)u16_val); | ||
|
||
res = get((netdev2_t *)dev, NETOPT_TX_POWER, &u16_val, sizeof(u16_val)); | ||
if (res < 0) { | ||
puts("(err)"); | ||
return 1; | ||
} | ||
printf(", TXPower: %d dBm", (int)u16_val); | ||
res = get((netdev2_t *)dev, NETOPT_IS_WIRED, &u16_val, sizeof(u16_val)); | ||
if (res < 0) { | ||
puts(", wireless"); | ||
} | ||
else { | ||
puts(", wired"); | ||
} | ||
|
||
printf(" "); | ||
res = get((netdev2_t *)dev, NETOPT_PRELOADING, &enable_val, | ||
sizeof(netopt_enable_t)); | ||
if ((res > 0) && (enable_val == NETOPT_ENABLE)) { | ||
printf(" PRELOAD"); | ||
} | ||
res = get((netdev2_t *)dev, NETOPT_AUTOACK, &enable_val, | ||
sizeof(netopt_enable_t)); | ||
if ((res > 0) && (enable_val == NETOPT_ENABLE)) { | ||
printf(" AUTOACK"); | ||
} | ||
res = get((netdev2_t *)dev, NETOPT_RAWMODE, &enable_val, | ||
sizeof(netopt_enable_t)); | ||
if ((res > 0) && (enable_val == NETOPT_ENABLE)) { | ||
printf(" RAW"); | ||
} | ||
res = get((netdev2_t *)dev, NETOPT_AUTOCCA, &enable_val, | ||
sizeof(netopt_enable_t)); | ||
if ((res > 0) && (enable_val == NETOPT_ENABLE)) { | ||
printf(" AUTOCCA"); | ||
} | ||
res = get((netdev2_t *)dev, NETOPT_CSMA, &enable_val, | ||
sizeof(netopt_enable_t)); | ||
if ((res > 0) && (enable_val == NETOPT_ENABLE)) { | ||
printf(" CSMA"); | ||
} | ||
puts(""); | ||
|
||
return 0; | ||
} | ||
|
||
int ifconfig(int argc, char **argv) | ||
{ | ||
(void)argc; | ||
(void)argv; | ||
for (int i = 0; i < AT86RF2XX_NUM; i++) { | ||
ifconfig_list(i); | ||
} | ||
return 0; | ||
} | ||
|
||
static void txtsnd_usage(char *cmd_name) | ||
{ | ||
printf("usage: %s <iface> [<pan>] <addr> <text>\n", cmd_name); | ||
} | ||
|
||
int txtsnd(int argc, char **argv) | ||
{ | ||
char *text; | ||
uint8_t addr[_MAX_ADDR_LEN]; | ||
int iface, idx = 2, res; | ||
le_uint16_t pan = { 0 }; | ||
|
||
switch (argc) { | ||
case 4: | ||
break; | ||
case 5: | ||
res = _parse_addr((uint8_t *)&pan, sizeof(pan), argv[idx++]); | ||
if ((res <= 0) || (res > sizeof(pan))) { | ||
txtsnd_usage(argv[0]); | ||
return 1; | ||
} | ||
pan.u16 = byteorder_swaps(pan.u16); | ||
break; | ||
default: | ||
txtsnd_usage(argv[0]); | ||
return 1; | ||
} | ||
|
||
iface = atoi(argv[1]); | ||
res = _parse_addr(addr, sizeof(addr), argv[idx++]); | ||
if (res <= 0) { | ||
txtsnd_usage(argv[0]); | ||
return 1; | ||
} | ||
text = argv[idx++]; | ||
return send(iface, pan, addr, (size_t)res, text); | ||
} | ||
|
||
static inline int _dehex(char c, int default_) | ||
{ | ||
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_; | ||
} | ||
} | ||
|
||
static int _parse_addr(uint8_t *out, size_t out_len, const char *in) | ||
{ | ||
const char *end_str = in; | ||
uint8_t *out_end = out; | ||
size_t count = 0; | ||
int assert_cell = 1; | ||
|
||
if (!in || !*in) { | ||
return 0; | ||
} | ||
while (end_str[1]) { | ||
++end_str; | ||
} | ||
|
||
while (end_str >= in) { | ||
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 >= in) { | ||
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; | ||
} | ||
|
||
static int send(int iface, le_uint16_t dst_pan, uint8_t *dst, size_t dst_len, | ||
char *data) | ||
{ | ||
int res; | ||
netdev2_ieee802154_t *dev; | ||
const size_t count = 2; /* mhr + payload */ | ||
struct iovec vector[count]; | ||
uint8_t *src; | ||
size_t src_len; | ||
uint8_t mhr[IEEE802154_MAX_HDR_LEN]; | ||
uint8_t flags; | ||
le_uint16_t src_pan; | ||
|
||
if (((unsigned)iface) > (AT86RF2XX_NUM - 1)) { | ||
printf("txtsnd: %d is not an interface\n", iface); | ||
return 1; | ||
} | ||
|
||
dev = (netdev2_ieee802154_t *)&devs[iface]; | ||
flags = (uint8_t)(dev->flags & NETDEV2_IEEE802154_SEND_MASK); | ||
flags |= IEEE802154_FCF_TYPE_DATA; | ||
vector[1].iov_base = data; | ||
vector[1].iov_len = strlen(data); | ||
src_pan = byteorder_btols(byteorder_htons(dev->pan)); | ||
if (dst_pan.u16 == 0) { | ||
dst_pan = src_pan; | ||
} | ||
if (dev->flags & NETDEV2_IEEE802154_SRC_MODE_LONG) { | ||
src_len = 8; | ||
src = dev->long_addr; | ||
} | ||
else { | ||
src_len = 2; | ||
src = dev->short_addr; | ||
} | ||
/* fill MAC header, seq should be set by device */ | ||
if ((res = ieee802154_set_frame_hdr(mhr, src, src_len, | ||
dst, dst_len, | ||
src_pan, dst_pan, | ||
flags, dev->seq++)) < 0) { | ||
puts("txtsnd: Error preperaring frame"); | ||
return 1; | ||
} | ||
vector[0].iov_base = mhr; | ||
vector[0].iov_len = (size_t)res; | ||
res = dev->netdev.driver->send((netdev2_t *)dev, vector, count); | ||
if (res < 0) { | ||
puts("txtsnd: Error on sending"); | ||
return 1; | ||
} | ||
else { | ||
printf("txtsnd: send %u bytes to ", (unsigned)vector[1].iov_len); | ||
print_addr(dst, dst_len); | ||
printf(" (PAN: "); | ||
print_addr((uint8_t *)&dst_pan, sizeof(dst_pan)); | ||
puts(")"); | ||
} | ||
return 0; | ||
} | ||
|
||
/** @} */ |
Oops, something went wrong.