forked from contiki-os/contiki
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexample-psock-server.c
166 lines (147 loc) · 4.75 KB
/
example-psock-server.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*
* This is a small example of how to write a TCP server using
* Contiki's protosockets. It is a simple server that accepts one line
* of text from the TCP connection, and echoes back the first 10 bytes
* of the string, and then closes the connection.
*
* The server only handles one connection at a time.
*
*/
#include <string.h>
/*
* We include "contiki-net.h" to get all network definitions and
* declarations.
*/
#include "contiki-net.h"
/*
* We define one protosocket since we've decided to only handle one
* connection at a time. If we want to be able to handle more than one
* connection at a time, each parallell connection needs its own
* protosocket.
*/
static struct psock ps;
/*
* We must have somewhere to put incoming data, and we use a 10 byte
* buffer for this purpose.
*/
static uint8_t buffer[10];
/*---------------------------------------------------------------------------*/
/*
* A protosocket always requires a protothread. The protothread
* contains the code that uses the protosocket. We define the
* protothread here.
*/
static
PT_THREAD(handle_connection(struct psock *p))
{
/*
* A protosocket's protothread must start with a PSOCK_BEGIN(), with
* the protosocket as argument.
*
* Remember that the same rules as for protothreads apply: do NOT
* use local variables unless you are very sure what you are doing!
* Local (stack) variables are not preserved when the protothread
* blocks.
*/
PSOCK_BEGIN(p);
/*
* We start by sending out a welcoming message. The message is sent
* using the PSOCK_SEND_STR() function that sends a null-terminated
* string.
*/
PSOCK_SEND_STR(p, "Welcome, please type something and press return.\n");
/*
* Next, we use the PSOCK_READTO() function to read incoming data
* from the TCP connection until we get a newline character. The
* number of bytes that we actually keep is dependant of the length
* of the input buffer that we use. Since we only have a 10 byte
* buffer here (the buffer[] array), we can only remember the first
* 10 bytes received. The rest of the line up to the newline simply
* is discarded.
*/
PSOCK_READTO(p, '\n');
/*
* And we send back the contents of the buffer. The PSOCK_DATALEN()
* function provides us with the length of the data that we've
* received. Note that this length will not be longer than the input
* buffer we're using.
*/
PSOCK_SEND_STR(p, "Got the following data: ");
PSOCK_SEND(p, buffer, PSOCK_DATALEN(p));
PSOCK_SEND_STR(p, "Good bye!\r\n");
/*
* We close the protosocket.
*/
PSOCK_CLOSE(p);
/*
* And end the protosocket's protothread.
*/
PSOCK_END(p);
}
/*---------------------------------------------------------------------------*/
/*
* We declare the process and specify that it should be automatically started.
*/
PROCESS(example_psock_server_process, "Example protosocket server");
AUTOSTART_PROCESSES(&example_psock_server_process);
/*---------------------------------------------------------------------------*/
/*
* The definition of the process.
*/
PROCESS_THREAD(example_psock_server_process, ev, data)
{
/*
* The process begins here.
*/
PROCESS_BEGIN();
/*
* We start with setting up a listening TCP port. Note how we're
* using the UIP_HTONS() macro to convert the port number (1010) to
* network byte order as required by the tcp_listen() function.
*/
tcp_listen(UIP_HTONS(1010));
/*
* We loop for ever, accepting new connections.
*/
while(1) {
/*
* We wait until we get the first TCP/IP event, which probably
* comes because someone connected to us.
*/
PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event);
/*
* If a peer connected with us, we'll initialize the protosocket
* with PSOCK_INIT().
*/
if(uip_connected()) {
/*
* The PSOCK_INIT() function initializes the protosocket and
* binds the input buffer to the protosocket.
*/
PSOCK_INIT(&ps, buffer, sizeof(buffer));
/*
* We loop until the connection is aborted, closed, or times out.
*/
while(!(uip_aborted() || uip_closed() || uip_timedout())) {
/*
* We wait until we get a TCP/IP event. Remember that we
* always need to wait for events inside a process, to let
* other processes run while we are waiting.
*/
PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event);
/*
* Here is where the real work is taking place: we call the
* handle_connection() protothread that we defined above. This
* protothread uses the protosocket to receive the data that
* we want it to.
*/
handle_connection(&ps);
}
}
}
/*
* We must always declare the end of a process.
*/
PROCESS_END();
}
/*---------------------------------------------------------------------------*/