commit
115420a510
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup sys_ping Ping
|
||||
* @ingroup sys
|
||||
* @brief Ping
|
||||
*/
|
||||
|
||||
#include "radio/radio.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void init_payload(void);
|
||||
void ping_init(protocol_t protocol, uint8_t channr, radio_address_t addr);
|
||||
void ping(radio_address_t addr, uint8_t channr);
|
||||
void calc_rtt(void);
|
||||
void print_success(void);
|
||||
void print_failed(void);
|
||||
void gpio_n_timer_init(void);
|
||||
void adjust_timer(void);
|
||||
static void ping_handler(void *payload, int payload_size,
|
||||
packet_info_t *packet_info);
|
||||
static void pong_handler(void *payload, int payload_size,
|
||||
packet_info_t *packet_info);
|
||||
void pong(uint16_t src);
|
||||
|
||||
typedef struct pong {
|
||||
int hopcount;
|
||||
int ttl;
|
||||
radio_address_t radio_address;
|
||||
} ping_r;
|
||||
|
||||
typedef struct ping_payload {
|
||||
char *payload;
|
||||
} ping_payload;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (C) 2014, INRIA
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef L2_PING_H
|
||||
#define L2_PING_H
|
||||
|
||||
/**
|
||||
* @defgroup net_l2_ping Link Layer Ping
|
||||
* @ingroup net
|
||||
* @brief Link Layer Ping
|
||||
*
|
||||
* @{
|
||||
* @file
|
||||
* @brief Link Layer Ping public interface, data structs, and defines
|
||||
*
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
*/
|
||||
|
||||
#include "radio/radio.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief the bitmask of the first link layer payload byte defining the type
|
||||
*/
|
||||
#define L2_PAYLOAD_TYPE (0xF0)
|
||||
|
||||
/**
|
||||
* @brief link layer payload type
|
||||
*
|
||||
* @note assure not to interfere with valid network layer values like the
|
||||
* 6LoWPAN dispatch field
|
||||
*/
|
||||
#define L2_PAYLOAD_PING (0x10)
|
||||
|
||||
/**
|
||||
* @brief the bitmask for the payload identifier, defining the actual l2 ping type
|
||||
*
|
||||
* @see l2_ping_type_t
|
||||
*/
|
||||
#define L2_PING_TYPE (0x0F)
|
||||
|
||||
/**
|
||||
* @brief the default interval between two ping packets are sent in microseconds
|
||||
*/
|
||||
#define L2_PING_DEFAULT_INTERVAL (50 * 1000u)
|
||||
|
||||
/**
|
||||
* @brief maximum number of bytes for payload within a l2 ping packet
|
||||
*/
|
||||
#define L2_PING_PAYLOAD_SIZE (8)
|
||||
|
||||
/**
|
||||
* @brief data type for the l2 ping type
|
||||
*/
|
||||
typedef enum {
|
||||
L2_PING = 0x01, /**< ping request packet */
|
||||
L2_PONG = 0x02, /**< pong response packet */
|
||||
L2_PROBE = 0x04 /**< probe packet */
|
||||
} l2_ping_type_t;
|
||||
|
||||
/**
|
||||
* @brief l2 ping statistics data structure
|
||||
*/
|
||||
typedef struct {
|
||||
radio_address_t dst; /**< the destination address for the last ping request sent */
|
||||
uint16_t ping_count; /**< the amount of ping requests sent to this destination */
|
||||
uint16_t pong_count; /**< the amount of pong respnses received from this node */
|
||||
timex_t last_rtt; /**< the round trip time for the last received pong response */
|
||||
timex_t avg_rtt; /**< the average round trip time to this node */
|
||||
timex_t max_rtt; /**< the maximum round trip time to this node */
|
||||
timex_t min_rtt; /**< the minimum round trip time to this node */
|
||||
} l2_ping_stats_t;
|
||||
|
||||
/**
|
||||
* @brief l2 probe statistics entry
|
||||
*/
|
||||
typedef struct {
|
||||
radio_address_t src; /**< link layer address of the probe's origin */
|
||||
uint16_t count; /**< number of received probes from this node */
|
||||
} l2_probe_stat_entry_t;
|
||||
|
||||
/**
|
||||
* @brief payload data structure for l2 ping packets
|
||||
*/
|
||||
typedef struct ping_payload {
|
||||
uint8_t type; /**< the data type */
|
||||
uint16_t seq; /**< sequence number */
|
||||
/* cppcheck-suppress unusedStructMember */
|
||||
char payload[L2_PING_PAYLOAD_SIZE]; /**< the actual payload */
|
||||
uint8_t payload_len; /**< number of payload bytes */
|
||||
} l2_ping_payload_t;
|
||||
|
||||
/**
|
||||
* @brief the current l2 ping statistics about the current communication
|
||||
* partner
|
||||
*/
|
||||
extern l2_ping_stats_t l2_ping_stats;
|
||||
|
||||
/**
|
||||
* @brief initializes the l2 ping module
|
||||
*
|
||||
* @note this function gets usually called by auto_init
|
||||
*/
|
||||
void l2_ping_init(void);
|
||||
|
||||
/**
|
||||
* @brief send a ping request
|
||||
*
|
||||
* @param[in] addr the destination address
|
||||
* @param[in] count the number of requests to send, 0 means infinite
|
||||
* @param[in] interval the interval between sending ping requests,
|
||||
* if 0 the default interval (#L2_PING_DEFAULT_INTERVAL)
|
||||
* @param[in] payload optional payload data, may be NULL
|
||||
* @param[in] payload_len the length of the payload data, must be smaller than
|
||||
* #L2_PING_PAYLOAD_SIZE
|
||||
* @param[in] probe_only do not request a pong response
|
||||
*/
|
||||
void l2_ping(radio_address_t addr, uint16_t count, uint32_t interval,
|
||||
const char *payload, uint8_t payload_len, uint8_t probe_only);
|
||||
|
||||
/**
|
||||
* @brief get l2 probe statistics to check how many probes have been received
|
||||
*
|
||||
* @param[out] l2_probe_stats pointer to an array of ::l2_probe_stat_entry_t
|
||||
* @param[out] count pointer to the number of entries in l2_probe_stats
|
||||
*/
|
||||
void l2_probe_stats(l2_probe_stat_entry_t *l2_probe_stats[], uint16_t *count);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* L2_PING_H */
|
@ -1 +1,3 @@
|
||||
MODULE := l2_ping
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
@ -0,0 +1,279 @@
|
||||
/*
|
||||
* Copyright (C) 2013, Igor Merkulow <igor.merkulow@gmail.com>
|
||||
* Copyright (C) 2014, Oliver Hahm <oliver.hahm@inria.fr>
|
||||
*
|
||||
* 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 Igor Merkulow <igor.merkulow@gmail.com>
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "thread.h"
|
||||
#include "msg.h"
|
||||
#include "mutex.h"
|
||||
|
||||
#include "transceiver.h"
|
||||
#include "radio/types.h"
|
||||
#include "vtimer.h"
|
||||
#include "timex.h"
|
||||
#include "l2_ping.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* interal defines */
|
||||
#define RCV_BUFFER_SIZE (64)
|
||||
#define RADIO_STACK_SIZE (KERNEL_CONF_STACKSIZE_DEFAULT)
|
||||
#define MAX_PROB_STATS (64)
|
||||
|
||||
/* internal prototypes */
|
||||
/* link layer send function for l2_pings */
|
||||
static int8_t send_l2_packet(radio_address_t dst, l2_ping_type_t type, uint16_t seq, const char *payload, uint8_t payload_len);
|
||||
/* handler for incoming packets from transceiver */
|
||||
static void *l2_pkt_handler(void *unused);
|
||||
/* handles l2 ping requests */
|
||||
static void ping_handler(radio_address_t addr, uint16_t seq);
|
||||
/* handles l2 pong responses */
|
||||
static void pong_handler(void);
|
||||
/* handle l2 probes */
|
||||
static void probe_handler(radio_address_t src);
|
||||
/* calculates the round trip time for a ping-pong exchange */
|
||||
static void calc_rtt(void);
|
||||
|
||||
/* internal buffers and variables */
|
||||
static char l2_pkt_handler_stack_buffer[RADIO_STACK_SIZE];
|
||||
static msg_t msg_q[RCV_BUFFER_SIZE];
|
||||
|
||||
#ifndef DISABLE_PROB_STATS
|
||||
static l2_probe_stat_entry_t probe_stats[MAX_PROB_STATS];
|
||||
#endif
|
||||
|
||||
static timex_t start, end, rtt_sum;
|
||||
static uint8_t ping_sent;
|
||||
static struct mutex_t ping_sender_mutex;
|
||||
l2_ping_stats_t l2_ping_stats;
|
||||
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* public interface functions */
|
||||
void l2_ping_init(void)
|
||||
{
|
||||
mutex_init(&ping_sender_mutex);
|
||||
kernel_pid_t l2_pkt_handler_pid = thread_create(l2_pkt_handler_stack_buffer,
|
||||
RADIO_STACK_SIZE,
|
||||
PRIORITY_MAIN - 2,
|
||||
CREATE_STACKTEST,
|
||||
l2_pkt_handler, NULL,
|
||||
"l2_pkt_handler");
|
||||
uint16_t transceivers = TRANSCEIVER_DEFAULT;
|
||||
|
||||
#ifndef MODULE_NET_IF
|
||||
transceiver_init(transceivers);
|
||||
(void) transceiver_start();
|
||||
#endif
|
||||
transceiver_register(transceivers, l2_pkt_handler_pid);
|
||||
}
|
||||
|
||||
void l2_ping(radio_address_t addr, uint16_t count, uint32_t interval,
|
||||
const char *payload, uint8_t payload_len, uint8_t probe_only)
|
||||
{
|
||||
l2_ping_type_t pt;
|
||||
|
||||
probe_only ? (pt = L2_PROBE) : (pt = L2_PING);
|
||||
|
||||
if (!interval) {
|
||||
interval = L2_PING_DEFAULT_INTERVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&ping_sender_mutex);
|
||||
l2_ping_stats.dst = addr;
|
||||
l2_ping_stats.ping_count = 0;
|
||||
l2_ping_stats.pong_count = 0;
|
||||
l2_ping_stats.last_rtt = timex_set(0, 0);
|
||||
l2_ping_stats.avg_rtt = timex_set(0, 0);
|
||||
l2_ping_stats.max_rtt = timex_set(0, 0);
|
||||
l2_ping_stats.min_rtt = timex_set(UINT32_MAX, UINT32_MAX);
|
||||
|
||||
for (unsigned i = 1; (count == 0) || (i <= count); i++) {
|
||||
vtimer_now(&start);
|
||||
|
||||
if (send_l2_packet(addr, pt, i, payload, payload_len)) {
|
||||
ping_sent = 1;
|
||||
l2_ping_stats.ping_count++;
|
||||
}
|
||||
if ((!count) || (i <= count)) {
|
||||
vtimer_usleep(interval);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&ping_sender_mutex);
|
||||
}
|
||||
|
||||
void l2_probe_stats(l2_probe_stat_entry_t *l2_probe_stats[], uint16_t *count)
|
||||
{
|
||||
unsigned i;
|
||||
*l2_probe_stats = probe_stats;
|
||||
for (i = 0; i < MAX_PROB_STATS; i++) {
|
||||
if (!(probe_stats[i]).src) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
*count = i;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* internal functions */
|
||||
static void *l2_pkt_handler(void *unused)
|
||||
{
|
||||
(void) unused;
|
||||
|
||||
msg_t m;
|
||||
radio_packet_t *p;
|
||||
l2_ping_payload_t *pp;
|
||||
|
||||
msg_init_queue(msg_q, sizeof(msg_q));
|
||||
|
||||
while (1) {
|
||||
msg_receive(&m);
|
||||
|
||||
if (m.type == PKT_PENDING) {
|
||||
vtimer_now(&end);
|
||||
p = (radio_packet_t *) m.content.ptr;
|
||||
pp = (l2_ping_payload_t *) p->data;
|
||||
|
||||
if ((pp->type & L2_PAYLOAD_TYPE) == L2_PAYLOAD_PING) {
|
||||
DEBUGF("INFO: received l2_ping_packet number %d from %d with payload(%d) %.*s.\n",
|
||||
pp->seq, p->src, pp->payload_len, pp->payload_len, pp->payload);
|
||||
switch (pp->type & L2_PING_TYPE) {
|
||||
case L2_PING:
|
||||
ping_handler(p->src, pp->seq);
|
||||
break;
|
||||
case L2_PONG:
|
||||
pong_handler();
|
||||
break;
|
||||
case L2_PROBE:
|
||||
probe_handler(p->src);
|
||||
break;
|
||||
default:
|
||||
DEBUGF("ERROR: Unknown L2 PING type\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
DEBUGF("WARN: no L2 ping packet, type is %02X\n", pp->type);
|
||||
}
|
||||
|
||||
p->processing--;
|
||||
}
|
||||
else if (m.type == ENOBUFFER) {
|
||||
DEBUGF("ERROR: Transceiver buffer full\n");
|
||||
}
|
||||
else {
|
||||
DEBUGF("ERROR: Unknown messagereceived\n");
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void calc_rtt(void)
|
||||
{
|
||||
timex_t rtt = timex_sub(end, start);
|
||||
rtt_sum = timex_add(rtt_sum, rtt);
|
||||
|
||||
l2_ping_stats.last_rtt = rtt;
|
||||
l2_ping_stats.avg_rtt = timex_from_uint64(timex_uint64(rtt_sum) / l2_ping_stats.pong_count);
|
||||
if (timex_cmp(rtt, l2_ping_stats.max_rtt) > 0) {
|
||||
l2_ping_stats.max_rtt = rtt;
|
||||
}
|
||||
if (timex_cmp(rtt, l2_ping_stats.min_rtt) < 0) {
|
||||
l2_ping_stats.min_rtt = rtt;
|
||||
}
|
||||
}
|
||||
|
||||
static int8_t send_l2_packet(radio_address_t dst, l2_ping_type_t type, uint16_t seq, const char *payload, uint8_t payload_len)
|
||||
{
|
||||
radio_packet_t p;
|
||||
l2_ping_payload_t pp;
|
||||
|
||||
if (payload_len > L2_PING_PAYLOAD_SIZE) {
|
||||
DEBUGF("ERROR: payload too big for l2 ping packet of type %u\n", type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
transceiver_command_t tcmd;
|
||||
tcmd.transceivers = TRANSCEIVER_DEFAULT;
|
||||
tcmd.data = &p;
|
||||
|
||||
pp.type = type | L2_PAYLOAD_PING;
|
||||
pp.seq = seq;
|
||||
|
||||
memset(pp.payload, 0, L2_PING_PAYLOAD_SIZE);
|
||||
memcpy(pp.payload, payload, payload_len);
|
||||
pp.payload_len = payload_len;
|
||||
|
||||
p.data = (uint8_t*) &pp;
|
||||
p.length = sizeof(pp);
|
||||
p.dst = dst;
|
||||
|
||||
msg_t mesg;
|
||||
mesg.type = SND_PKT;
|
||||
mesg.content.ptr = (char *) &tcmd;
|
||||
|
||||
msg_send_receive(&mesg, &mesg, transceiver_pid);
|
||||
int8_t response = mesg.content.value;
|
||||
|
||||
if (response <= 0) {
|
||||
DEBUGF("ERROR: sending L2 packet of type %x failed.\n", type);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
static void ping_handler(radio_address_t addr, uint16_t seq)
|
||||
{
|
||||
send_l2_packet(addr, L2_PONG, seq, NULL, 0);
|
||||
}
|
||||
|
||||
static void pong_handler(void)
|
||||
{
|
||||
if (ping_sent) {
|
||||
ping_sent = 0;
|
||||
l2_ping_stats.pong_count++;
|
||||
calc_rtt();
|
||||
}
|
||||
else {
|
||||
DEBUGF("ERROR: received pong without a sent ping\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void probe_handler(radio_address_t src)
|
||||
{
|
||||
#ifdef DISABLE_PROB_STATS
|
||||
DEBUGF("WARN: L2 probe statistics are disabled, not handling probe packet.\n");
|
||||
#else
|
||||
unsigned i;
|
||||
for (i = 0; i < MAX_PROB_STATS; i++) {
|
||||
/* found entry for this source address */
|
||||
if (probe_stats[i].src == src) {
|
||||
probe_stats[i].count++;
|
||||
return;
|
||||
}
|
||||
/* found empty entry */
|
||||
else if (!(probe_stats[i].src)) {
|
||||
probe_stats[i].src = src;
|
||||
probe_stats[i].count++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
DEBUGF("ERROR: L2 probe statistics full! Probe data from %u not stored.\n", src);
|
||||
#endif
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
/**
|
||||
* Ping: low level ping pong
|
||||
*
|
||||
* Copyright (C) 2013, Igor Merkulow <igor.merkulow@gmail.com>
|
||||
*
|
||||
* 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 Igor Merkulow <igor.merkulow@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "thread.h"
|
||||
#include "msg.h"
|
||||
|
||||
#include "cc110x_legacy_csma/cc1100.h"
|
||||
#include "lpc2387.h"
|
||||
|
||||
#include "vtimer.h"
|
||||
#include "timex.h"
|
||||
#include "gpioint.h"
|
||||
#include "ping.h"
|
||||
|
||||
ping_payload *pipa;
|
||||
protocol_t protocol_id = 0;
|
||||
radio_address_t r_address = 0;
|
||||
timex_t start = 0;
|
||||
float rtt = 0;
|
||||
|
||||
void ping_handler(void *payload, int payload_size,
|
||||
packet_info_t *packet_info)
|
||||
{
|
||||
pong(packet_info->phy_src);
|
||||
}
|
||||
|
||||
void pong_handler(void *payload, int payload_size,
|
||||
packet_info_t *packet_info)
|
||||
{
|
||||
calc_rtt();
|
||||
print_success();
|
||||
}
|
||||
|
||||
void pong(uint16_t src)
|
||||
{
|
||||
int trans_ok = cc1100_send_csmaca(src, protocol_id, 2, pipa->payload,
|
||||
sizeof(pipa->payload));
|
||||
|
||||
if (trans_ok < 0) {
|
||||
print_failed();
|
||||
}
|
||||
}
|
||||
|
||||
void ping_init(protocol_t protocol, uint8_t channr, radio_address_t addr)
|
||||
{
|
||||
protocol_id = protocol;
|
||||
r_address = addr;
|
||||
cc1100_set_packet_handler(protocol, ping_handler);
|
||||
cc1100_set_channel(channr);
|
||||
cc1100_set_address(r_address);
|
||||
init_payload();
|
||||
}
|
||||
|
||||
void ping(radio_address_t addr, uint8_t channr)
|
||||
{
|
||||
cc1100_set_packet_handler(protocol_id, pong_handler);
|
||||
cc1100_set_channel(channr);
|
||||
cc1100_set_address(r_address);
|
||||
|
||||
while (1) {
|
||||
vtimer_now(&start);
|
||||
int trans_ok = cc1100_send_csmaca(addr,
|
||||
protocol_id, 2, pipa->payload, sizeof(pipa->payload));
|
||||
|
||||
if (trans_ok < 0) {
|
||||
print_failed();
|
||||
}
|
||||
|
||||
hwtimer_wait(HWTIMER_TICKS(500 * 1000));
|
||||
}
|
||||
}
|
||||
|
||||
void calc_rtt(void)
|
||||
{
|
||||
timex_t end;
|
||||
vtimer_now(&end);
|
||||
timex_t result = timex_sub(end, start);
|
||||
|
||||
rtt = result.seconds + (float)result.microseconds / (1000.0 * 1000.0);
|
||||
}
|
||||
|
||||
void print_success(void)
|
||||
{
|
||||
printf("%s%f%s\n", "time=", rtt, "ms");
|
||||
}
|
||||
|
||||
void print_failed(void)
|
||||
{
|
||||
printf("%s\n", "ping failed");
|
||||
}
|
||||
|
||||
void init_payload(void)
|
||||
{
|
||||
pipa = malloc(sizeof(*pipa));
|
||||
pipa->payload = NULL;
|
||||
}
|
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Shell commands for l2_ping module
|
||||
*
|
||||
* Copyright (C) 2014, INRIA
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @ingroup shell_commands
|
||||
* @{
|
||||
* @file
|
||||
* @brief provides shell commands use link layer ping functionality
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "l2_ping.h"
|
||||
#include "transceiver.h"
|
||||
#include "timex.h"
|
||||
#include "vtimer.h"
|
||||
|
||||
void _l2_ping_req_handler(int argc, char **argv)
|
||||
{
|
||||
size_t payload_strlen;
|
||||
uint16_t count = 5;
|
||||
timex_t start, end, period;
|
||||
|
||||
if (transceiver_pid == KERNEL_PID_UNDEF) {
|
||||
puts("Transceiver not initialized");
|
||||
return;
|
||||
}
|
||||
if (argc < 2) {
|
||||
printf("Usage:\t%s <ADDR> [COUNT] [MSG]\n", argv[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
char l2_payload[L2_PING_PAYLOAD_SIZE];
|
||||
if (argc > 3) {
|
||||
payload_strlen = strlen(argv[3]);
|
||||
if (payload_strlen > L2_PING_PAYLOAD_SIZE) {
|
||||
printf("[l2_ping] Your input is too long and will be truncated to \"%.*s\".\n", L2_PING_PAYLOAD_SIZE, argv[3]);
|
||||
payload_strlen = L2_PING_PAYLOAD_SIZE;
|
||||
}
|
||||
memset(l2_payload, 0, L2_PING_PAYLOAD_SIZE);
|
||||
strncpy(l2_payload, argv[3], payload_strlen);
|
||||
}
|
||||
else {
|
||||
payload_strlen = 0;
|
||||
}
|
||||
|
||||
if (argc > 2) {
|
||||
count = atoi(argv[2]);
|
||||
}
|
||||
|
||||
printf("[l2_ping] Send %" PRIu8 " ping requests to %" PRIu16 " with interval %" PRIu32 ".%" PRIu32 "s and payload %s\n",
|
||||
count, atoi(argv[1]),
|
||||
timex_from_uint64(L2_PING_DEFAULT_INTERVAL).seconds,
|
||||
timex_from_uint64(L2_PING_DEFAULT_INTERVAL).microseconds,
|
||||
(argc > 3) ? l2_payload : "NULL");
|
||||
vtimer_now(&start);
|
||||
l2_ping((radio_address_t) atoi(argv[1]), count, L2_PING_DEFAULT_INTERVAL,
|
||||
l2_payload, payload_strlen, 0);
|
||||
vtimer_now(&end);
|
||||
period = timex_sub(end, start);
|
||||
|
||||
printf(" --- ping statistics for host %" PRIu16 " ---\n", l2_ping_stats.dst);
|
||||
printf(" %" PRIu16 " packets transmitted, %" PRIu16 " received, %" PRIu16 "%% packet loss, time %" PRIu32 ".%06" PRIu32 "s\n",
|
||||
l2_ping_stats.ping_count,
|
||||
l2_ping_stats.pong_count,
|
||||
100 - ((l2_ping_stats.pong_count * 100) / l2_ping_stats.ping_count),
|
||||
period.seconds,
|
||||
period.microseconds);
|
||||
printf(" rtt min/avg/max = %" PRIu32 ".%06" PRIu32 "/%" PRIu32 ".%06" PRIu32 "/%" PRIu32 ".%06" PRIu32 " s\n",
|
||||
l2_ping_stats.min_rtt.seconds, l2_ping_stats.min_rtt.microseconds,
|
||||
l2_ping_stats.avg_rtt.seconds, l2_ping_stats.avg_rtt.microseconds,
|
||||
l2_ping_stats.max_rtt.seconds, l2_ping_stats.max_rtt.microseconds);
|
||||
}
|
||||
|
||||
void _l2_ping_probe_handler(int argc, char **argv)
|
||||
{
|
||||
size_t payload_strlen;
|
||||
uint16_t count = 5;
|
||||
timex_t start, end, period;
|
||||
|
||||
if (transceiver_pid == KERNEL_PID_UNDEF) {
|
||||
puts("Transceiver not initialized");
|
||||
return;
|
||||
}
|
||||
if (argc < 2) {
|
||||
printf("Usage:\t%s <ADDR> [COUNT] [MSG]\n", argv[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
char l2_payload[L2_PING_PAYLOAD_SIZE];
|
||||
if (argc > 3) {
|
||||
payload_strlen = strlen(argv[3]);
|
||||
if (payload_strlen > L2_PING_PAYLOAD_SIZE) {
|
||||
printf("[l2_ping] Your input is too long and will be truncated to \"%.*s\".\n", L2_PING_PAYLOAD_SIZE, argv[3]);
|
||||
payload_strlen = L2_PING_PAYLOAD_SIZE;
|
||||
}
|
||||
memset(l2_payload, 0, L2_PING_PAYLOAD_SIZE);
|
||||
strncpy(l2_payload, argv[3], payload_strlen);
|
||||
}
|
||||
else {
|
||||
payload_strlen = 0;
|
||||
}
|
||||
|
||||
if (argc > 2) {
|
||||
count = atoi(argv[2]);
|
||||
}
|
||||
|
||||
printf("[l2_ping] Send %" PRIu16 " probes to %" PRIu16 " with interval %u and payload %s\n",
|
||||
count, atoi(argv[1]), L2_PING_DEFAULT_INTERVAL, (argc > 3) ? l2_payload : "NULL");
|
||||
vtimer_now(&start);
|
||||
l2_ping((radio_address_t) atoi(argv[1]), count, L2_PING_DEFAULT_INTERVAL,
|
||||
l2_payload, payload_strlen, 1);
|
||||
vtimer_now(&end);
|
||||
period = timex_sub(end, start);
|
||||
|
||||
printf(" --- ping statistics for host %" PRIu16 " ---\n", l2_ping_stats.dst);
|
||||
printf(" %" PRIu16 " packets transmitted in %" PRIu32 ".%06" PRIu32 "s\n", l2_ping_stats.ping_count,
|
||||
period.seconds, period.microseconds);
|
||||
}
|
||||
|
||||
void _l2_ping_get_probe_handler(int argc, char **argv)
|
||||
{
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
|
||||
l2_probe_stat_entry_t *stats;
|
||||
uint16_t count;
|
||||
|
||||
l2_probe_stats(&stats, &count);
|
||||
|
||||
printf("[l2_ping] Getting link layer probe statistics:\n");
|
||||
for (uint16_t i = 0; i < count; i++) {
|
||||
printf("...received %" PRIu16 " probes from node %" PRIu16 ".\n", stats[i].count, stats[i].src);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue