]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_LPC1768_GCC_RedSuite/src/webserver/psock.h
Add FreeRTOS-Plus directory.
[freertos] / FreeRTOS / Demo / CORTEX_LPC1768_GCC_RedSuite / src / webserver / psock.h
1 /*\r
2  * Copyright (c) 2004, Swedish Institute of Computer Science.\r
3  * All rights reserved.\r
4  *\r
5  * Redistribution and use in source and binary forms, with or without\r
6  * modification, are permitted provided that the following conditions\r
7  * are met:\r
8  * 1. Redistributions of source code must retain the above copyright\r
9  *    notice, this list of conditions and the following disclaimer.\r
10  * 2. Redistributions in binary form must reproduce the above copyright\r
11  *    notice, this list of conditions and the following disclaimer in the\r
12  *    documentation and/or other materials provided with the distribution.\r
13  * 3. Neither the name of the Institute nor the names of its contributors\r
14  *    may be used to endorse or promote products derived from this software\r
15  *    without specific prior written permission.\r
16  *\r
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND\r
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE\r
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
27  * SUCH DAMAGE.\r
28  *\r
29  * This file is part of the uIP TCP/IP stack\r
30  *\r
31  * Author: Adam Dunkels <adam@sics.se>\r
32  *\r
33  * $Id: psock.h,v 1.3 2006/06/12 08:00:30 adam Exp $\r
34  */\r
35 \r
36 /**\r
37  * \defgroup psock Protosockets library\r
38  * @{\r
39  *\r
40  * The protosocket library provides an interface to the uIP stack that is\r
41  * similar to the traditional BSD socket interface. Unlike programs\r
42  * written for the ordinary uIP event-driven interface, programs\r
43  * written with the protosocket library are executed in a sequential\r
44  * fashion and does not have to be implemented as explicit state\r
45  * machines.\r
46  *\r
47  * Protosockets only work with TCP connections.\r
48  *\r
49  * The protosocket library uses \ref pt protothreads to provide\r
50  * sequential control flow. This makes the protosockets lightweight in\r
51  * terms of memory, but also means that protosockets inherits the\r
52  * functional limitations of protothreads. Each protosocket lives only\r
53  * within a single function. Automatic variables (stack variables) are\r
54  * not retained across a protosocket library function call.\r
55  *\r
56  * \note Because the protosocket library uses protothreads, local\r
57  * variables will not always be saved across a call to a protosocket\r
58  * library function. It is therefore advised that local variables are\r
59  * used with extreme care.\r
60  *\r
61  * The protosocket library provides functions for sending data without\r
62  * having to deal with retransmissions and acknowledgements, as well\r
63  * as functions for reading data without having to deal with data\r
64  * being split across more than one TCP segment.\r
65  *\r
66  * Because each protosocket runs as a protothread, the protosocket has to be\r
67  * started with a call to PSOCK_BEGIN() at the start of the function\r
68  * in which the protosocket is used. Similarly, the protosocket protothread can\r
69  * be terminated by a call to PSOCK_EXIT().\r
70  *\r
71  */\r
72 \r
73 /**\r
74  * \file\r
75  * Protosocket library header file\r
76  * \author\r
77  * Adam Dunkels <adam@sics.se>\r
78  *\r
79  */\r
80 \r
81 #ifndef __PSOCK_H__\r
82 #define __PSOCK_H__\r
83 \r
84 #include "uipopt.h"\r
85 #include "pt.h"\r
86 \r
87  /*\r
88  * The structure that holds the state of a buffer.\r
89  *\r
90  * This structure holds the state of a uIP buffer. The structure has\r
91  * no user-visible elements, but is used through the functions\r
92  * provided by the library.\r
93  *\r
94  */\r
95 struct psock_buf {\r
96   u8_t *ptr;\r
97   unsigned short left;\r
98 };\r
99 \r
100 /**\r
101  * The representation of a protosocket.\r
102  *\r
103  * The protosocket structrure is an opaque structure with no user-visible\r
104  * elements.\r
105  */\r
106 struct psock {\r
107   struct pt pt, psockpt; /* Protothreads - one that's using the psock\r
108                             functions, and one that runs inside the\r
109                             psock functions. */\r
110   const u8_t *sendptr;   /* Pointer to the next data to be sent. */\r
111   u8_t *readptr;         /* Pointer to the next data to be read. */\r
112   \r
113   char *bufptr;          /* Pointer to the buffer used for buffering\r
114                             incoming data. */\r
115   \r
116   u16_t sendlen;         /* The number of bytes left to be sent. */\r
117   u16_t readlen;         /* The number of bytes left to be read. */\r
118 \r
119   struct psock_buf buf;  /* The structure holding the state of the\r
120                             input buffer. */\r
121   unsigned int bufsize;  /* The size of the input buffer. */\r
122   \r
123   unsigned char state;   /* The state of the protosocket. */\r
124 };\r
125 \r
126 void psock_init(struct psock *psock, char *buffer, unsigned int buffersize);\r
127 /**\r
128  * Initialize a protosocket.\r
129  *\r
130  * This macro initializes a protosocket and must be called before the\r
131  * protosocket is used. The initialization also specifies the input buffer\r
132  * for the protosocket.\r
133  *\r
134  * \param psock (struct psock *) A pointer to the protosocket to be\r
135  * initialized\r
136  *\r
137  * \param buffer (char *) A pointer to the input buffer for the\r
138  * protosocket.\r
139  *\r
140  * \param buffersize (unsigned int) The size of the input buffer.\r
141  *\r
142  * \hideinitializer\r
143  */\r
144 #define PSOCK_INIT(psock, buffer, buffersize) \\r
145   psock_init(psock, buffer, buffersize)\r
146 \r
147 /**\r
148  * Start the protosocket protothread in a function.\r
149  *\r
150  * This macro starts the protothread associated with the protosocket and\r
151  * must come before other protosocket calls in the function it is used.\r
152  *\r
153  * \param psock (struct psock *) A pointer to the protosocket to be\r
154  * started.\r
155  *\r
156  * \hideinitializer\r
157  */\r
158 #define PSOCK_BEGIN(psock) PT_BEGIN(&((psock)->pt))\r
159 \r
160 PT_THREAD(psock_send(struct psock *psock, const char *buf, unsigned int len));\r
161 /**\r
162  * Send data.\r
163  *\r
164  * This macro sends data over a protosocket. The protosocket protothread blocks\r
165  * until all data has been sent and is known to have been received by\r
166  * the remote end of the TCP connection.\r
167  *\r
168  * \param psock (struct psock *) A pointer to the protosocket over which\r
169  * data is to be sent.\r
170  *\r
171  * \param data (char *) A pointer to the data that is to be sent.\r
172  *\r
173  * \param datalen (unsigned int) The length of the data that is to be\r
174  * sent.\r
175  *\r
176  * \hideinitializer\r
177  */\r
178 #define PSOCK_SEND(psock, data, datalen)                \\r
179     PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, data, datalen))\r
180 \r
181 /**\r
182  * \brief      Send a null-terminated string.\r
183  * \param psock Pointer to the protosocket.\r
184  * \param str  The string to be sent.\r
185  *\r
186  *             This function sends a null-terminated string over the\r
187  *             protosocket.\r
188  *\r
189  * \hideinitializer\r
190  */\r
191 #define PSOCK_SEND_STR(psock, str)                      \\r
192     PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, str, strlen(str)))\r
193 \r
194 PT_THREAD(psock_generator_send(struct psock *psock,\r
195                                 unsigned short (*f)(void *), void *arg));\r
196 \r
197 /**\r
198  * \brief      Generate data with a function and send it\r
199  * \param psock Pointer to the protosocket.\r
200  * \param generator Pointer to the generator function\r
201  * \param arg   Argument to the generator function\r
202  *\r
203  *             This function generates data and sends it over the\r
204  *             protosocket. This can be used to dynamically generate\r
205  *             data for a transmission, instead of generating the data\r
206  *             in a buffer beforehand. This function reduces the need for\r
207  *             buffer memory. The generator function is implemented by\r
208  *             the application, and a pointer to the function is given\r
209  *             as an argument with the call to PSOCK_GENERATOR_SEND().\r
210  *\r
211  *             The generator function should place the generated data\r
212  *             directly in the uip_appdata buffer, and return the\r
213  *             length of the generated data. The generator function is\r
214  *             called by the protosocket layer when the data first is\r
215  *             sent, and once for every retransmission that is needed.\r
216  *\r
217  * \hideinitializer\r
218  */\r
219 #define PSOCK_GENERATOR_SEND(psock, generator, arg)     \\r
220     PT_WAIT_THREAD(&((psock)->pt),                                      \\r
221                    psock_generator_send(psock, generator, arg))\r
222 \r
223 \r
224 /**\r
225  * Close a protosocket.\r
226  *\r
227  * This macro closes a protosocket and can only be called from within the\r
228  * protothread in which the protosocket lives.\r
229  *\r
230  * \param psock (struct psock *) A pointer to the protosocket that is to\r
231  * be closed.\r
232  *\r
233  * \hideinitializer\r
234  */\r
235 #define PSOCK_CLOSE(psock) uip_close()\r
236 \r
237 PT_THREAD(psock_readbuf(struct psock *psock));\r
238 /**\r
239  * Read data until the buffer is full.\r
240  *\r
241  * This macro will block waiting for data and read the data into the\r
242  * input buffer specified with the call to PSOCK_INIT(). Data is read\r
243  * until the buffer is full..\r
244  *\r
245  * \param psock (struct psock *) A pointer to the protosocket from which\r
246  * data should be read.\r
247  *\r
248  * \hideinitializer\r
249  */\r
250 #define PSOCK_READBUF(psock)                            \\r
251   PT_WAIT_THREAD(&((psock)->pt), psock_readbuf(psock))\r
252 \r
253 PT_THREAD(psock_readto(struct psock *psock, unsigned char c));\r
254 /**\r
255  * Read data up to a specified character.\r
256  *\r
257  * This macro will block waiting for data and read the data into the\r
258  * input buffer specified with the call to PSOCK_INIT(). Data is only\r
259  * read until the specifieed character appears in the data stream.\r
260  *\r
261  * \param psock (struct psock *) A pointer to the protosocket from which\r
262  * data should be read.\r
263  *\r
264  * \param c (char) The character at which to stop reading.\r
265  *\r
266  * \hideinitializer\r
267  */\r
268 #define PSOCK_READTO(psock, c)                          \\r
269   PT_WAIT_THREAD(&((psock)->pt), psock_readto(psock, c))\r
270 \r
271 /**\r
272  * The length of the data that was previously read.\r
273  *\r
274  * This macro returns the length of the data that was previously read\r
275  * using PSOCK_READTO() or PSOCK_READ().\r
276  *\r
277  * \param psock (struct psock *) A pointer to the protosocket holding the data.\r
278  *\r
279  * \hideinitializer\r
280  */\r
281 #define PSOCK_DATALEN(psock) psock_datalen(psock)\r
282 \r
283 u16_t psock_datalen(struct psock *psock);\r
284 \r
285 /**\r
286  * Exit the protosocket's protothread.\r
287  *\r
288  * This macro terminates the protothread of the protosocket and should\r
289  * almost always be used in conjunction with PSOCK_CLOSE().\r
290  *\r
291  * \sa PSOCK_CLOSE_EXIT()\r
292  *\r
293  * \param psock (struct psock *) A pointer to the protosocket.\r
294  *\r
295  * \hideinitializer\r
296  */\r
297 #define PSOCK_EXIT(psock) PT_EXIT(&((psock)->pt))\r
298 \r
299 /**\r
300  * Close a protosocket and exit the protosocket's protothread.\r
301  *\r
302  * This macro closes a protosocket and exits the protosocket's protothread.\r
303  *\r
304  * \param psock (struct psock *) A pointer to the protosocket.\r
305  *\r
306  * \hideinitializer\r
307  */\r
308 #define PSOCK_CLOSE_EXIT(psock)         \\r
309   do {                                          \\r
310     PSOCK_CLOSE(psock);                 \\r
311     PSOCK_EXIT(psock);                  \\r
312   } while(0)\r
313 \r
314 /**\r
315  * Declare the end of a protosocket's protothread.\r
316  *\r
317  * This macro is used for declaring that the protosocket's protothread\r
318  * ends. It must always be used together with a matching PSOCK_BEGIN()\r
319  * macro.\r
320  *\r
321  * \param psock (struct psock *) A pointer to the protosocket.\r
322  *\r
323  * \hideinitializer\r
324  */\r
325 #define PSOCK_END(psock) PT_END(&((psock)->pt))\r
326 \r
327 char psock_newdata(struct psock *s);\r
328 \r
329 /**\r
330  * Check if new data has arrived on a protosocket.\r
331  *\r
332  * This macro is used in conjunction with the PSOCK_WAIT_UNTIL()\r
333  * macro to check if data has arrived on a protosocket.\r
334  *\r
335  * \param psock (struct psock *) A pointer to the protosocket.\r
336  *\r
337  * \hideinitializer\r
338  */\r
339 #define PSOCK_NEWDATA(psock) psock_newdata(psock)\r
340 \r
341 /**\r
342  * Wait until a condition is true.\r
343  *\r
344  * This macro blocks the protothread until the specified condition is\r
345  * true. The macro PSOCK_NEWDATA() can be used to check if new data\r
346  * arrives when the protosocket is waiting.\r
347  *\r
348  * Typically, this macro is used as follows:\r
349  *\r
350  \code\r
351  PT_THREAD(thread(struct psock *s, struct timer *t))\r
352  {\r
353    PSOCK_BEGIN(s);\r
354 \r
355    PSOCK_WAIT_UNTIL(s, PSOCK_NEWADATA(s) || timer_expired(t));\r
356    \r
357    if(PSOCK_NEWDATA(s)) {\r
358      PSOCK_READTO(s, '\n');\r
359    } else {\r
360      handle_timed_out(s);\r
361    }\r
362    \r
363    PSOCK_END(s);\r
364  }\r
365  \endcode\r
366  *\r
367  * \param psock (struct psock *) A pointer to the protosocket.\r
368  * \param condition The condition to wait for.\r
369  *\r
370  * \hideinitializer\r
371  */\r
372 #define PSOCK_WAIT_UNTIL(psock, condition)    \\r
373   PT_WAIT_UNTIL(&((psock)->pt), (condition));\r
374 \r
375 #define PSOCK_WAIT_THREAD(psock, condition)   \\r
376   PT_WAIT_THREAD(&((psock)->pt), (condition))\r
377 \r
378 #endif /* __PSOCK_H__ */\r
379 \r
380 /** @} */\r