forked from RIOT-OS/RIOT
-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
examples/watrli_rpl_udp: initial commit [DO NOT MERGE, just 4 testing] #5
Open
BytesGalore
wants to merge
7
commits into
watr-li:master
Choose a base branch
from
BytesGalore:watrli_rpl_udp_example
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
8e4798e
examples/watrli_rpl_udp: initial commit
8331cd1
[SQUASH ME] removed unnecessary address binding
ba7de3e
[SQUASH ME] made it less error prone
daa439f
[SQUASH ME] made payload more dynamic
fc23b25
[SQUASH ME] adjusted `rpl_init()` call to the API change providing th…
6d82ec1
[SQUASH ME] added comment pointing the API change
df3c31a
[SQUASH ME] added option to let the node act as RPL root
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# name of your application | ||
APPLICATION = watrli_rpl_udp | ||
|
||
# If no BOARD is found in the environment, use this default: | ||
BOARD ?= native | ||
|
||
# This has to be the absolute path to the RIOT base directory: | ||
RIOTBASE ?= $(CURDIR)/../.. | ||
|
||
# Comment this out to disable code in RIOT that does safety checking | ||
# which is not needed in a production environment but helps in the | ||
# development process: | ||
CFLAGS += -DDEVELHELP | ||
|
||
# Change this to 0 show compiler invocation lines by default: | ||
QUIET ?= 1 | ||
|
||
# Modules to include | ||
USEMODULE += defaulttransceiver | ||
USEMODULE += rpl | ||
USEMODULE += udp | ||
|
||
include $(RIOTBASE)/Makefile.include |
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,290 @@ | ||
/* | ||
* Copyright (C) 2015 | ||
* | ||
* 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 examples | ||
* @{ | ||
* | ||
* @file | ||
* @brief watr.li rpl udp application | ||
* | ||
* @author | ||
* | ||
* @} | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <unistd.h> | ||
#include "udp.h" | ||
#include "rpl.h" | ||
|
||
#define WATR_LI_CHANNEL (26) /**< The used channel */ | ||
#define WATR_LI_PAN (0x03e9) /**< The used PAN ID */ | ||
#define WATR_LI_IFACE (0) /**< The used Trasmssion device */ | ||
#define WATR_LI_UDP_PORT (12345) /**< The UDP port to listen */ | ||
#define WATR_LI_UDP_BUFFER_SIZE (1024) /**< The buffer size for receiving UDPs */ | ||
|
||
/** The UDP server thread stack */ | ||
char udp_server_stack_buffer[KERNEL_CONF_STACKSIZE_MAIN]; | ||
/** The node IPv6 address */ | ||
ipv6_addr_t myaddr; | ||
|
||
/** | ||
* @brief the sample UDP server that expects receiving strings | ||
* @param[in] arg unused parameter pointer | ||
*/ | ||
static void *watr_li_udp_server(void *arg) | ||
{ | ||
(void) arg; | ||
|
||
sockaddr6_t sa; | ||
char buffer_main[WATR_LI_UDP_BUFFER_SIZE]; | ||
uint32_t fromlen; | ||
int sock = socket_base_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); | ||
|
||
memset(&sa, 0, sizeof(sa)); | ||
|
||
sa.sin6_family = AF_INET; | ||
sa.sin6_port = HTONS(WATR_LI_UDP_PORT); | ||
|
||
fromlen = sizeof(sa); | ||
|
||
if (-1 == socket_base_bind(sock, &sa, sizeof(sa))) { | ||
puts("[watr_li_udp_server] Error bind failed!"); | ||
socket_base_close(sock); | ||
return NULL; | ||
} | ||
|
||
while (1) { | ||
int32_t recsize = socket_base_recvfrom(sock, (void *)buffer_main, | ||
WATR_LI_UDP_BUFFER_SIZE, 0, | ||
&sa, &fromlen); | ||
|
||
if (recsize < 0) { | ||
puts("[watr_li_udp_server] ERROR: recsize < 0!"); | ||
} else { | ||
/* if we received a string print it */ | ||
if (buffer_main[recsize-1] == '\0' ) { | ||
printf("UDP packet received, payload:\n%s\n", buffer_main); | ||
} else { | ||
/* print the buffer bytes in hex */ | ||
printf("UDP packet received, payload (%d bytes):\n", (int)recsize); | ||
for(int i = 0; i < recsize; ++i) { | ||
|
||
if ( (i%8) == 0 ) { | ||
/* newline after 8 bytes */ | ||
puts(""); | ||
} | ||
|
||
printf("%02x ", buffer_main[i]); | ||
} | ||
puts(""); | ||
} | ||
} | ||
|
||
} | ||
|
||
socket_base_close(sock); | ||
|
||
return NULL; | ||
} | ||
|
||
/** | ||
* @brief sends a packet to the DODAG ID (should be the root node IPv6 address) | ||
* @param[in] payload pointer to the payload to be sent | ||
* @param[in] size number of bytes of the payload | ||
*/ | ||
static void watr_li_udp_send(char* payload, size_t payload_size) | ||
{ | ||
int sock; | ||
sockaddr6_t sa; | ||
int bytes_sent; | ||
sock = socket_base_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); | ||
char addr_str[IPV6_MAX_ADDR_STR_LEN]; | ||
|
||
if (-1 == sock) { | ||
puts("[watr_li_udp_send] Error Creating Socket!"); | ||
return; | ||
} | ||
rpl_dodag_t *mydodag = rpl_get_my_dodag(); | ||
|
||
if(mydodag != NULL) { | ||
memset(&sa, 0, sizeof(sa)); | ||
sa.sin6_family = AF_INET; | ||
memcpy(&sa.sin6_addr, &(mydodag->dodag_id), 16); | ||
sa.sin6_port = HTONS(WATR_LI_UDP_PORT); | ||
|
||
bytes_sent = socket_base_sendto(sock, | ||
payload, | ||
payload_size, | ||
0, &sa, sizeof(sa)); | ||
|
||
if (bytes_sent < 0) { | ||
puts("[watr_li_udp_send] Error sending packet!"); | ||
} | ||
|
||
printf("[watr_li_udp_send] Successful deliverd %i bytes over UDP to %s to 6LoWPAN\n", | ||
bytes_sent, ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, | ||
&(sa.sin6_addr))); | ||
} else { | ||
puts("[watr_li_udp_send] not joined a DODAG (yet), so payload will not be sent."); | ||
} | ||
socket_base_close(sock); | ||
} | ||
|
||
/** | ||
* @brief setup the readio interface | ||
* @retrun radio_address_t of the set interface | ||
*/ | ||
static radio_address_t set_watr_li_if(void) | ||
{ | ||
net_if_set_src_address_mode(WATR_LI_IFACE, NET_IF_TRANS_ADDR_M_SHORT); | ||
radio_address_t iface_id = net_if_get_hardware_address(WATR_LI_IFACE); | ||
return iface_id; | ||
} | ||
|
||
/** | ||
* @brief set the channel for this watr.li node | ||
* @param[in] chan the channel to use | ||
* @return 0 on success | ||
*/ | ||
static int set_watr_li_channel(int32_t chan) | ||
{ | ||
transceiver_command_t tcmd; | ||
msg_t m; | ||
|
||
tcmd.transceivers = TRANSCEIVER_DEFAULT; | ||
tcmd.data = &chan; | ||
m.type = SET_CHANNEL; | ||
m.content.ptr = (void *) &tcmd; | ||
|
||
msg_send_receive(&m, &m, transceiver_pid); | ||
return 0; | ||
} | ||
|
||
/** | ||
* @brief set the PAN ID for this watr.li node | ||
* @param[in] pan the PAN ID to use | ||
* @return 0 on success | ||
*/ | ||
static int set_watr_li_pan(int32_t pan) | ||
{ | ||
transceiver_command_t tcmd; | ||
msg_t m; | ||
|
||
tcmd.transceivers = TRANSCEIVER_DEFAULT; | ||
tcmd.data = &pan; | ||
m.type = SET_PAN; | ||
m.content.ptr = (void *) &tcmd; | ||
|
||
msg_send_receive(&m, &m, transceiver_pid); | ||
return 0; | ||
} | ||
|
||
/** | ||
* @brief set a desire address for this watr.li node | ||
* @return 0 on success | ||
*/ | ||
static int set_watr_li_address(ipv6_addr_t* node_addr) | ||
{ | ||
ipv6_net_if_add_addr(WATR_LI_IFACE, node_addr, NDP_ADDR_STATE_PREFERRED, 0, 0, 0); | ||
return 0; | ||
} | ||
|
||
/** | ||
* @brief prepares this node to join the watr.li DODAG | ||
* @return 0 on success | ||
*/ | ||
static int watr_li_setup_node(void) | ||
{ | ||
radio_address_t iface_id = 0xffff; | ||
|
||
set_watr_li_channel(WATR_LI_CHANNEL); | ||
set_watr_li_pan(WATR_LI_PAN); | ||
iface_id = set_watr_li_if(); | ||
|
||
/* choose addresses */ | ||
ipv6_addr_init(&myaddr, 0x2015, 0x3, 0x18, 0x1111, 0x0, 0x0, 0x0, iface_id); | ||
|
||
/* and set it */ | ||
/* set_watr_li_address(&myaddr); // this is done by RPL now automatically */ | ||
|
||
return 0; | ||
} | ||
|
||
/** | ||
* @brief initialize RPL on this watr.li node | ||
* @return 0 on success | ||
*/ | ||
static int watr_li_init_rpl(bool is_root) | ||
{ | ||
/* use specific global address */ | ||
rpl_init(WATR_LI_IFACE, &myaddr); | ||
|
||
if(is_root) { | ||
ipv6_addr_t prefix; | ||
ipv6_addr_init(&prefix, 0x2015, 0x3, 0x18, 0x1111, 0x0, 0x0, 0x0, 0x0); | ||
|
||
rpl_options_t rpl_opts = { | ||
.instance_id = 0, | ||
.prefix = prefix, | ||
.prefix_len = 64, | ||
.prefix_flags = RPL_PREFIX_INFO_AUTO_ADDR_CONF, | ||
/* autonomous address-configuration */ | ||
}; | ||
rpl_init_root(&rpl_opts); | ||
} | ||
|
||
ipv6_iface_set_routing_provider(rpl_get_next_hop); | ||
return 0; | ||
} | ||
|
||
/** | ||
* @brief create a thread to receive UDP messages | ||
*/ | ||
static void watr_li_start_udp_server(void) | ||
{ | ||
thread_create(udp_server_stack_buffer,sizeof(udp_server_stack_buffer), | ||
PRIORITY_MAIN, CREATE_STACKTEST, watr_li_udp_server, NULL, | ||
"watr.li udp_server"); | ||
} | ||
|
||
int main(void) | ||
{ | ||
puts("Hello watr.li!"); | ||
|
||
printf("You are running RIOT on a(n) %s board.\n", RIOT_BOARD); | ||
printf("This board features a(n) %s MCU.\n", RIOT_MCU); | ||
|
||
char payload[80]; | ||
int msgnum = 0; | ||
bool is_root = false; | ||
|
||
watr_li_setup_node(); | ||
watr_li_init_rpl(is_root); | ||
watr_li_start_udp_server(); | ||
|
||
if(is_root) { | ||
puts("I'am the RPL root."); | ||
} else { | ||
puts("I'am a RPL node."); | ||
} | ||
|
||
while(1){ | ||
sleep(30); | ||
if(is_root) { | ||
snprintf(payload, 80, "watr.li root(%x) msg: %d", HTONS(myaddr.uint16[7]), msgnum++); | ||
} else { | ||
snprintf(payload, 80, "watr.li node(%x) msg: %d", HTONS(myaddr.uint16[7]), msgnum++); | ||
} | ||
watr_li_udp_send(payload, (strlen(payload) + 1)); | ||
thread_yield(); | ||
} | ||
|
||
return 0; | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I'm not mistaken, this creates a new socket every time is is used to send a packet... Is this intentional? If so, why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup every-time a new socket.
There's no real reason for that. My initial intention was to use this function only once for testing purposes.
So the function prototype could be changed to e.g.
static void watr_li_udp_send(int sock, char* payload, size_t payload_size)
and the
socket_base_close(sock);
at the end of this function should be removed then.The socket then can be created for instance here and provided as parameter here (with the new prototype).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main has changed a bit in the plant_node master anyway.. ;) I'd create the socket in watr_li_setup_node() and close it at the end of my new main. Thanks for the quick response!