-
Notifications
You must be signed in to change notification settings - Fork 0
/
net.c
133 lines (106 loc) · 2.4 KB
/
net.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
130
131
132
133
/* net.c - KNoT Application Client */
/*
* Copyright (c) 2018, CESAR. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* The knot client application is acting as a client that is run in Zephyr OS,
* The client sends sensor data encapsulated using KNoT netcol.
*/
#include <zephyr.h>
#include <net/net_core.h>
#include <net/net_pkt.h>
#include <net/buf.h>
#include <logging/log.h>
#include "net.h"
#include "tcp6.h"
LOG_MODULE_DECLARE(knot, LOG_LEVEL_DBG);
static struct k_thread rx_thread_data;
static K_THREAD_STACK_DEFINE(rx_stack, 1024);
static struct k_pipe *proto2net;
static struct k_pipe *net2proto;
static bool connected;
K_ALERT_DEFINE(connection_lost, NULL, 1);
K_ALERT_DEFINE(connection_established, NULL, 1);
static void close_cb(void)
{
if (connected) {
connected = false;
k_alert_send(&connection_lost);
}
}
static bool recv_cb(struct net_buf *netbuf)
{
u8_t opdu[128];
struct net_buf *frag = netbuf;
size_t olen = 0;
size_t frag_len = 0;
u16_t pos = 0;
memset(opdu, 0, sizeof(opdu));
while (frag) {
/* Data comming from network */
if ((olen + frag->len) > sizeof(opdu)) {
LOG_ERR("Small MTU");
return true;
}
frag_len = frag->len;
frag = net_frag_read(frag, pos, &pos, frag_len,
(u8_t *) (opdu + olen));
olen += frag_len;
}
/* Sending recv data to PROTO thread */
k_pipe_put(net2proto, opdu, olen, &olen, olen, K_NO_WAIT);
return true;
}
static void connection_start(void)
{
int ret;
ret = tcp6_start(recv_cb, close_cb);
if (ret < 0) {
LOG_DBG("NET: TCP start failure");
tcp6_stop();
return;
}
connected = true;
k_alert_send(&connection_established);
}
static void net_thread(void)
{
u8_t ipdu[128];
size_t ilen;
int ret;
memset(ipdu, 0, sizeof(ipdu));
connection_start();
while (1) {
if (!connected) {
connection_start();
goto done;
}
ilen = 0;
/* Reading data from PROTO thread */
ret = k_pipe_get(proto2net, ipdu, sizeof(ipdu),
&ilen, 0U, K_NO_WAIT);
if (ret == 0 && ilen)
ret = tcp6_send(ipdu, ilen);
done:
k_yield();
}
tcp6_stop();
}
int net_start(struct k_pipe *p2n, struct k_pipe *n2p)
{
LOG_DBG("NET: Start");
proto2net = p2n;
net2proto = n2p;
connected = false;
k_thread_create(&rx_thread_data, rx_stack,
K_THREAD_STACK_SIZEOF(rx_stack),
(k_thread_entry_t) net_thread,
NULL, NULL, NULL, K_PRIO_COOP(10), 0, K_NO_WAIT);
return 0;
}
void net_stop(void)
{
LOG_DBG("NET: Stop");
}