-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnode.c
129 lines (100 loc) · 2.65 KB
/
node.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <stdint.h>
#include <stdio.h>
#include <common.h>
#include <message.h>
#include <hash.h>
#include <ipc.h>
#include <node.h>
#include <radio.h>
#include <logging/log.h>
#include <logging/log_ctrl.h>
#include <zephyr.h>
LOG_MODULE_REGISTER(node, GLOBAL_LOG_LEVEL);
/* Thread definitions */
#define THREAD_STACK_SIZE 2048
#define THREAD_PRIORITY 5
/* Queue of incoming messages waiting to be processed */
K_MSGQ_DEFINE(node_msgq, sizeof(struct message *), 10, 4);
#define MAX_HOP_COUNT 2
uint8_t msg_count = 0;
uint8_t node_send_buf[MAX_MESSAGE_SIZE];
uint8_t node_addr[MAC_LEN];
uint8_t node_broadcast_addr[MAC_LEN] = {[0 ... MAC_LEN - 1] = 0xff};
void node_enqueue(struct message *msg)
{
while (k_msgq_put(&node_msgq, &msg, K_NO_WAIT) != 0)
{
/* message queue is full: purge old data & try again */
k_msgq_purge(&node_msgq);
}
}
int node_radio_send(struct message *msg)
{
size_t size = message_to_buffer(node_send_buf, msg);
message_free(msg);
return radio_send(node_send_buf, size);
}
void node_process_packet()
{
struct message *msg;
k_msgq_get(&node_msgq, &msg, K_FOREVER);
uint32_t hash = hash_packet(msg);
if (hash_contains(hash))
{
message_free(msg);
return;
}
hash_add(hash);
if (memcmp(msg->dst_mac, node_addr, MAC_LEN) == 0)
{
node_receive(msg);
message_free(msg);
return;
}
if (memcmp(msg->dst_mac, node_broadcast_addr, MAC_LEN) == 0 &&
memcmp(msg->original_src_mac, node_addr, MAC_LEN) != 0)
{
node_receive(msg);
}
if (msg->ttl <= 0)
{
message_free(msg);
return;
}
msg->ttl--;
memcpy(msg->src_mac, node_addr, MAC_LEN);
LOG_HEXDUMP_DBG(msg->payload, msg->payload_len, "Forwarding");
node_radio_send(msg);
}
int node_send(struct message *msg)
{
if (msg->payload_len > MAX_PAYLOAD_SIZE)
{
return -1;
}
memcpy(msg->src_mac, node_addr, MAC_LEN);
memcpy(msg->original_src_mac, node_addr, MAC_LEN);
msg->msg_number = msg_count++;
msg->ttl = MAX_HOP_COUNT;
hash_add(hash_packet(msg));
return node_radio_send(msg);
}
void node_thread(void *p1, void *p2, void *p3)
{
LOG_INF("Node thread started with id %04x", (uint32_t)k_current_get());
k_msleep(500);
while (true)
{
node_process_packet();
}
}
void init_node()
{
for (size_t i = 0; i < MAC_LEN; i++)
{
node_addr[i] = NRF_FICR->DEVICEADDR[i / 4] >> ((i % 4) * 8);
}
LOG_HEXDUMP_INF(node_addr, MAC_LEN, "Node Address");
init_hash();
}
K_THREAD_DEFINE(node, THREAD_STACK_SIZE, node_thread, NULL, NULL, NULL, THREAD_PRIORITY, 0, 0);