Contiki 3.x
packetbuf.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2006, Swedish Institute of Computer Science.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  *
31  */
32 
33 /**
34  * \file
35  * Rime buffer (packetbuf) management
36  * \author
37  * Adam Dunkels <adam@sics.se>
38  */
39 
40 /**
41  * \addtogroup packetbuf
42  * @{
43  */
44 
45 #include <string.h>
46 
47 #include "contiki-net.h"
48 #include "net/packetbuf.h"
49 #include "net/rime/rime.h"
50 
51 struct packetbuf_attr packetbuf_attrs[PACKETBUF_NUM_ATTRS];
52 struct packetbuf_addr packetbuf_addrs[PACKETBUF_NUM_ADDRS];
53 
54 
55 static uint16_t buflen, bufptr;
56 static uint8_t hdrptr;
57 
58 /* The declarations below ensure that the packet buffer is aligned on
59  an even 16-bit boundary. On some platforms (most notably the
60  msp430), having apotentially misaligned packet buffer may lead to
61  problems when accessing 16-bit values. */
62 static uint16_t packetbuf_aligned[(PACKETBUF_SIZE + PACKETBUF_HDR_SIZE) / 2 + 1];
63 static uint8_t *packetbuf = (uint8_t *)packetbuf_aligned;
64 
65 static uint8_t *packetbufptr;
66 
67 #define DEBUG 0
68 #if DEBUG
69 #include <stdio.h>
70 #define PRINTF(...) printf(__VA_ARGS__)
71 #else
72 #define PRINTF(...)
73 #endif
74 
75 /*---------------------------------------------------------------------------*/
76 void
78 {
79  buflen = bufptr = 0;
80  hdrptr = PACKETBUF_HDR_SIZE;
81 
82  packetbufptr = &packetbuf[PACKETBUF_HDR_SIZE];
83  packetbuf_attr_clear();
84 }
85 /*---------------------------------------------------------------------------*/
86 void
88 {
89  hdrptr = PACKETBUF_HDR_SIZE;
90 }
91 /*---------------------------------------------------------------------------*/
92 int
93 packetbuf_copyfrom(const void *from, uint16_t len)
94 {
95  uint16_t l;
96 
98  l = len > PACKETBUF_SIZE? PACKETBUF_SIZE: len;
99  memcpy(packetbufptr, from, l);
100  buflen = l;
101  return l;
102 }
103 /*---------------------------------------------------------------------------*/
104 void
106 {
107  int i, len;
108 
109  if(packetbuf_is_reference()) {
110  memcpy(&packetbuf[PACKETBUF_HDR_SIZE], packetbuf_reference_ptr(),
112  } else if(bufptr > 0) {
114  for(i = PACKETBUF_HDR_SIZE; i < len; i++) {
115  packetbuf[i] = packetbuf[bufptr + i];
116  }
117 
118  bufptr = 0;
119  }
120 }
121 /*---------------------------------------------------------------------------*/
122 int
124 {
125 #if DEBUG_LEVEL > 0
126  {
127  int i;
128  PRINTF("packetbuf_write_hdr: header:\n");
129  for(i = hdrptr; i < PACKETBUF_HDR_SIZE; ++i) {
130  PRINTF("0x%02x, ", packetbuf[i]);
131  }
132  PRINTF("\n");
133  }
134 #endif /* DEBUG_LEVEL */
135  memcpy(to, packetbuf + hdrptr, PACKETBUF_HDR_SIZE - hdrptr);
136  return PACKETBUF_HDR_SIZE - hdrptr;
137 }
138 /*---------------------------------------------------------------------------*/
139 int
141 {
142 #if DEBUG_LEVEL > 0
143  {
144  int i;
145  char buffer[1000];
146  char *bufferptr = buffer;
147 
148  bufferptr[0] = 0;
149  for(i = hdrptr; i < PACKETBUF_HDR_SIZE; ++i) {
150  bufferptr += sprintf(bufferptr, "0x%02x, ", packetbuf[i]);
151  }
152  PRINTF("packetbuf_write: header: %s\n", buffer);
153  bufferptr = buffer;
154  bufferptr[0] = 0;
155  for(i = bufptr; i < buflen + bufptr; ++i) {
156  bufferptr += sprintf(bufferptr, "0x%02x, ", packetbufptr[i]);
157  }
158  PRINTF("packetbuf_write: data: %s\n", buffer);
159  }
160 #endif /* DEBUG_LEVEL */
161  if(PACKETBUF_HDR_SIZE - hdrptr + buflen > PACKETBUF_SIZE) {
162  /* Too large packet */
163  return 0;
164  }
165  memcpy(to, packetbuf + hdrptr, PACKETBUF_HDR_SIZE - hdrptr);
166  memcpy((uint8_t *)to + PACKETBUF_HDR_SIZE - hdrptr, packetbufptr + bufptr,
167  buflen);
168  return PACKETBUF_HDR_SIZE - hdrptr + buflen;
169 }
170 /*---------------------------------------------------------------------------*/
171 int
173 {
174  if(hdrptr >= size && packetbuf_totlen() + size <= PACKETBUF_SIZE) {
175  hdrptr -= size;
176  return 1;
177  }
178  return 0;
179 }
180 /*---------------------------------------------------------------------------*/
181 void
182 packetbuf_hdr_remove(int size)
183 {
184  hdrptr += size;
185 }
186 /*---------------------------------------------------------------------------*/
187 int
189 {
190  if(buflen < size) {
191  return 0;
192  }
193 
194  bufptr += size;
195  buflen -= size;
196  return 1;
197 }
198 /*---------------------------------------------------------------------------*/
199 void
201 {
202  PRINTF("packetbuf_set_len: len %d\n", len);
203  buflen = len;
204 }
205 /*---------------------------------------------------------------------------*/
206 void *
208 {
209  return (void *)(&packetbuf[bufptr + PACKETBUF_HDR_SIZE]);
210 }
211 /*---------------------------------------------------------------------------*/
212 void *
214 {
215  return (void *)(&packetbuf[hdrptr]);
216 }
217 /*---------------------------------------------------------------------------*/
218 void
219 packetbuf_reference(void *ptr, uint16_t len)
220 {
221  packetbuf_clear();
222  packetbufptr = ptr;
223  buflen = len;
224 }
225 /*---------------------------------------------------------------------------*/
226 int
228 {
229  return packetbufptr != &packetbuf[PACKETBUF_HDR_SIZE];
230 }
231 /*---------------------------------------------------------------------------*/
232 void *
234 {
235  return packetbufptr;
236 }
237 /*---------------------------------------------------------------------------*/
238 uint16_t
240 {
241  return buflen;
242 }
243 /*---------------------------------------------------------------------------*/
244 uint8_t
246 {
247  uint8_t hdrlen;
248 
249  hdrlen = PACKETBUF_HDR_SIZE - hdrptr;
250  if(hdrlen) {
251  /* outbound packet */
252  return hdrlen;
253  } else {
254  /* inbound packet */
255  return bufptr;
256  }
257 }
258 /*---------------------------------------------------------------------------*/
259 uint16_t
261 {
262  return packetbuf_hdrlen() + packetbuf_datalen();
263 }
264 /*---------------------------------------------------------------------------*/
265 void
266 packetbuf_attr_clear(void)
267 {
268  int i;
269  for(i = 0; i < PACKETBUF_NUM_ATTRS; ++i) {
270  packetbuf_attrs[i].val = 0;
271  }
272  for(i = 0; i < PACKETBUF_NUM_ADDRS; ++i) {
273  linkaddr_copy(&packetbuf_addrs[i].addr, &linkaddr_null);
274  }
275 }
276 /*---------------------------------------------------------------------------*/
277 void
278 packetbuf_attr_copyto(struct packetbuf_attr *attrs,
279  struct packetbuf_addr *addrs)
280 {
281  memcpy(attrs, packetbuf_attrs, sizeof(packetbuf_attrs));
282  memcpy(addrs, packetbuf_addrs, sizeof(packetbuf_addrs));
283 }
284 /*---------------------------------------------------------------------------*/
285 void
286 packetbuf_attr_copyfrom(struct packetbuf_attr *attrs,
287  struct packetbuf_addr *addrs)
288 {
289  memcpy(packetbuf_attrs, attrs, sizeof(packetbuf_attrs));
290  memcpy(packetbuf_addrs, addrs, sizeof(packetbuf_addrs));
291 }
292 /*---------------------------------------------------------------------------*/
293 #if !PACKETBUF_CONF_ATTRS_INLINE
294 int
295 packetbuf_set_attr(uint8_t type, const packetbuf_attr_t val)
296 {
297 /* packetbuf_attrs[type].type = type; */
298  packetbuf_attrs[type].val = val;
299  return 1;
300 }
301 /*---------------------------------------------------------------------------*/
302 packetbuf_attr_t
303 packetbuf_attr(uint8_t type)
304 {
305  return packetbuf_attrs[type].val;
306 }
307 /*---------------------------------------------------------------------------*/
308 int
309 packetbuf_set_addr(uint8_t type, const linkaddr_t *addr)
310 {
311 /* packetbuf_addrs[type - PACKETBUF_ADDR_FIRST].type = type; */
312  linkaddr_copy(&packetbuf_addrs[type - PACKETBUF_ADDR_FIRST].addr, addr);
313  return 1;
314 }
315 /*---------------------------------------------------------------------------*/
316 const linkaddr_t *
317 packetbuf_addr(uint8_t type)
318 {
319  return &packetbuf_addrs[type - PACKETBUF_ADDR_FIRST].addr;
320 }
321 /*---------------------------------------------------------------------------*/
322 #endif /* PACKETBUF_CONF_ATTRS_INLINE */
323 /** @} */
int packetbuf_hdralloc(int size)
Extend the header of the packetbuf, for outbound packets.
Definition: packetbuf.c:172
int packetbuf_copyfrom(const void *from, uint16_t len)
Copy from external data into the packetbuf.
Definition: packetbuf.c:93
const linkaddr_t linkaddr_null
The null Rime address.
Header file for the Rime buffer (packetbuf) management
uint8_t packetbuf_hdrlen(void)
Get the length of the header in the packetbuf.
Definition: packetbuf.c:245
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
Definition: packetbuf.c:200
uint16_t packetbuf_totlen(void)
Get the total length of the header and data in the packetbuf.
Definition: packetbuf.c:260
Header file for the Rime stack
uint16_t packetbuf_datalen(void)
Get the length of the data in the packetbuf.
Definition: packetbuf.c:239
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
Copy a Rime address.
Definition: linkaddr.c:60
void * packetbuf_hdrptr(void)
Get a pointer to the header in the packetbuf, for outbound packets.
Definition: packetbuf.c:213
void * packetbuf_reference_ptr(void)
Get a pointer to external data referenced by the packetbuf.
Definition: packetbuf.c:233
#define PACKETBUF_HDR_SIZE
The size of the packetbuf header, in bytes.
Definition: packetbuf.h:74
int packetbuf_copyto(void *to)
Copy the entire packetbuf to an external buffer.
Definition: packetbuf.c:140
void packetbuf_compact(void)
Compact the packetbuf.
Definition: packetbuf.c:105
void packetbuf_clear_hdr(void)
Clear and reset the header of the packetbuf.
Definition: packetbuf.c:87
int packetbuf_copyto_hdr(uint8_t *to)
Copy the header portion of the packetbuf to an external buffer.
Definition: packetbuf.c:123
void packetbuf_clear(void)
Clear and reset the packetbuf.
Definition: packetbuf.c:77
void packetbuf_reference(void *ptr, uint16_t len)
Point the packetbuf to external data.
Definition: packetbuf.c:219
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
Definition: packetbuf.h:65
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
Definition: packetbuf.c:207
int packetbuf_is_reference(void)
Check if the packetbuf references external data.
Definition: packetbuf.c:227
int packetbuf_hdrreduce(int size)
Reduce the header in the packetbuf, for incoming packets.
Definition: packetbuf.c:188