In this article, I will explain the collect-view example that I added today. A few days ago I had the opportunity to explain this in detail. I will only show the changes on makefile and udp-server, udp-client. The letters in red indicate the additions on the Makefile.
hello friends in this video I will show you the use of collect-view on cooja. First of all, let me state that, measurements are made using the samples available on the internet and the files udp-sender.c udp-sink.c.
I will prepare a new project that works on udp-server udp-client from scratch. I received a lot of questions on this subject via e-mail, so I decided to shoot this video. I hope it helps you all. Thank you from now.
DEFINES+=PROJECT_CONF_H=\”project-conf.h\”
CONTIKI_PROJECT=udp-client udp-server
PROJECT_SOURCEFILES += collect-common.call: $(CONTIKI_PROJECT)
CONTIKI=../../../..#linker optimizations
SMALL=1# battery consumption I added
APPS += serial-shell collect-view
Now let’s look at the libraries that will be added to the udp-server and udp-client instances.
/**/
#include “collect-common.h”
#include “collect-view.h”
#include “dev/serial-line.h”
/**/
The above plug-ins will be added to the server and client. We can use the include files together with other files. We came to the most important part: First, we need to call collect_common_process. The added part is written in red. Those who know the subject understood that processes can be used in this way.
PROCESS(udp_server_process, “UDP server process”);
AUTOSTART_PROCESSES(&udp_server_process, &collect_common_process);
/**
* \file
* Common code between collect client and server
* \author
* Niclas Finne <nfi@sics.se>
*/#ifndef COLLECT_COMMON_H_
#define COLLECT_COMMON_H_#include “contiki.h”
#include “net/linkaddr.h”void collect_common_net_init(void);
void collect_common_net_print(void);
void collect_common_set_sink(void);
void collect_common_send(void);
void collect_common_recv(const linkaddr_t *originator, uint8_t seqno,
uint8_t hops,
uint8_t *payload,
uint16_t payload_len);
void collect_common_set_send_active(int active);PROCESS_NAME(collect_common_process);
#endif /* COLLECT_COMMON_H_ */
PROCESS(udp_server_process, “UDP server process”);
AUTOSTART_PROCESSES(&udp_server_process, &collect_common_process);
#if 1
/*—————————————————————————*/
void
collect_common_set_sink(void)
{
}
/*—————————————————————————*/
void
collect_common_net_print(void)
{
PRINTF(“I am sink!\n”);
}
/*—————————————————————————*/
void
collect_common_send(void)
{
/* Server never sends */
}
/*—————————————————————————*/
void
collect_common_net_init(void)
{uart1_set_input(serial_line_input_byte);
serial_line_init();PRINTF(“I am sink!\n”);
}
#endif
I have made tcpip_handler compatible with us. The new code snippet is written in red. #If 0 means that it is no longer compiled.
static void
tcpip_handler(void)
{#if 0
char *appdata;
if(uip_newdata()) {
appdata = (char *)uip_appdata;
appdata[uip_datalen()] = 0;
PRINTF(“DATA recv from “);
PRINTF(“%d”,
UIP_IP_BUF->srcipaddr.u8[sizeof(UIP_IP_BUF->srcipaddr.u8) – 1]);
#if RPL_ADD_ROUTE_ENABLED
uint16_t seq_no = (uint16_t)(appdata[34] << 8 | appdata[33]); PRINTF(” Seq No: %u\n”, seq_no); #else PRINTF(” ‘%s’\n”, appdata); #endif //PRINTF(“RSSI : %d\n”, packetbuf_attr(PACKETBUF_ATTR_RSSI)); #if SERVER_REPLY PRINTF(“DATA sending reply\n”); uip_ipaddr_copy(&server_conn->ripaddr, &UIP_IP_BUF->srcipaddr);
uip_udp_packet_send(server_conn, “Reply”, sizeof(“Reply”));
uip_create_unspecified(&server_conn->ripaddr);
#endif
}
#endif#if 1
uint8_t *appdata;
linkaddr_t sender;
uint8_t seqno;
uint8_t hops;if(uip_newdata()) {
appdata = (uint8_t *)uip_appdata;appdata[uip_datalen()] = 0;
//PRINTF(“%d”,
// UIP_IP_BUF->srcipaddr.u8[sizeof(UIP_IP_BUF->srcipaddr.u8) – 1]);
//PRINTF(” ‘%s’\n”, appdata);sender.u8[0] = UIP_IP_BUF->srcipaddr.u8[15];
sender.u8[1] = UIP_IP_BUF->srcipaddr.u8[14];
seqno = *appdata;
hops = uip_ds6_if.cur_hop_limit – UIP_IP_BUF->ttl + 1;
collect_common_recv(&sender, seqno, hops,
appdata + 2, uip_datalen() – 2);
}
#endif}
Let’s go to the udp-client.c section here, the changes are similar to the server side.
/*—————————————————————————*/
PROCESS(udp_client_process, “UDP client process”);
AUTOSTART_PROCESSES(&udp_client_process, &collect_common_process);#if 1
/*—————————————————————————*/
void
collect_common_set_sink(void)
{
/* A udp client can never become sink */
}/*—————————————————————————*/
void
collect_common_net_print(void)
{
rpl_dag_t *dag;
uip_ds6_route_t *r;/* Let’s suppose we have only one instance */
dag = rpl_get_any_dag();
if(dag->preferred_parent != NULL) {
PRINTF(“Preferred parent: “);
PRINT6ADDR(rpl_get_parent_ipaddr(dag->preferred_parent));
PRINTF(“\n”);
}
for(r = uip_ds6_route_head();
r != NULL;
r = uip_ds6_route_next(r)) {
PRINT6ADDR(&r->ipaddr);
}
PRINTF(“—\n”);
}/*—————————————————————————*/
void
collect_common_net_init(void)
{
uart1_set_input(serial_line_input_byte);
serial_line_init();
}/*—————————————————————————*/
void
collect_common_send(void)
{
static uip_ipaddr_t server_ipaddr;
uip_ip6addr(&server_ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0x200, 0, 0, 1); // parent ip adressprintf(“collect_common_send\n”);
static uint8_t seqno;
struct {
uint8_t seqno;
uint8_t for_alignment;
struct collect_view_data_msg msg;
} msg;
/* struct collect_neighbor *n; */
uint16_t parent_etx;
uint16_t rtmetric;
uint16_t num_neighbors;
uint16_t beacon_interval;
rpl_parent_t *preferred_parent;
linkaddr_t parent;
rpl_dag_t *dag;if(client_conn == NULL) {
/* Not setup yet */
return;
}
memset(&msg, 0, sizeof(msg));
seqno++;
if(seqno == 0) {
/* Wrap to 128 to identify restarts */
seqno = 128;
}
msg.seqno = seqno;linkaddr_copy(&parent, &linkaddr_null);
parent_etx = 0;/* Let’s suppose we have only one instance */
dag = rpl_get_any_dag();
if(dag != NULL) {
preferred_parent = dag->preferred_parent;
if(preferred_parent != NULL) {
uip_ds6_nbr_t *nbr;
nbr = uip_ds6_nbr_lookup(rpl_get_parent_ipaddr(preferred_parent));
if(nbr != NULL) {
/* Use parts of the IPv6 address as the parent address, in reversed byte order. */
parent.u8[LINKADDR_SIZE – 1] = nbr->ipaddr.u8[sizeof(uip_ipaddr_t) – 2];
parent.u8[LINKADDR_SIZE – 2] = nbr->ipaddr.u8[sizeof(uip_ipaddr_t) – 1];
parent_etx = rpl_get_parent_rank((uip_lladdr_t *) uip_ds6_nbr_get_ll(nbr)) / 2;
}
}
rtmetric = dag->rank;
beacon_interval = (uint16_t) ((2L << dag->instance->dio_intcurrent) / 1000);
num_neighbors = uip_ds6_nbr_num();
} else {
rtmetric = 0;
beacon_interval = 0;
num_neighbors = 0;
}/* num_neighbors = collect_neighbor_list_num(&tc.neighbor_list); */
collect_view_construct_message(&msg.msg, &parent,
parent_etx, rtmetric,
num_neighbors, beacon_interval);uip_udp_packet_sendto(client_conn, &msg, sizeof(msg),
&server_ipaddr, UIP_HTONS(JOIN_PORT));
}
#endif
#define JOIN_PORT 5678
general information.
if UDP_CLIENT_PORT = 3000, UDP_SERVER_PORT = 3001, thus udp-server.c server_conn = udp_new(NULL, UIP_HTONS(3000), NULL); <<== listening to port 3000 udp_bind(server_conn, UIP_HTONS(3001)); udp-client.c client_conn = udp_new(NULL, UIP_HTONS(3001), NULL); <<== send packet to port 3001 udp_bind(client_conn, UIP_HTONS(3000));
(fd) 16 = (253) 10
(fe) 16 = (254) 10
31 node powerview screenshots: