45#include "contiki-net.h"
58 struct queuebuf *next;
64 enum {IN_RAM, IN_CFS} location;
67 struct queuebuf_data *ram_ptr;
78 struct packetbuf_attr attrs[PACKETBUF_NUM_ATTRS];
79 struct packetbuf_addr addrs[PACKETBUF_NUM_ADDRS];
82MEMB(bufmem,
struct queuebuf, QUEUEBUF_NUM);
83MEMB(buframmem,
struct queuebuf_data, QUEUEBUFRAM_NUM);
92#define NQBUF_PER_FILE 256
93#define QBUF_FILE_SIZE (NQBUF_PER_FILE*sizeof(struct queuebuf_data))
94#define NQBUF_ID (NQBUF_PER_FILE * NQBUF_FILES)
103static struct queuebuf_data tmpdata;
105static struct queuebuf *tmpdata_qbuf = NULL;
107static int next_swap_id = 0;
109static struct qbuf_file qbuf_files[NQBUF_FILES];
111static struct ctimer renew_timer;
123#define PRINTF(...) printf(__VA_ARGS__)
128#ifdef QUEUEBUF_CONF_STATS
129#define QUEUEBUF_STATS QUEUEBUF_CONF_STATS
131#define QUEUEBUF_STATS 0
135uint8_t queuebuf_len, queuebuf_max_len;
141qbuf_renew_file(
int file)
145 name[0] =
'a' + file;
147 if(qbuf_files[file].renewable == 1) {
148 PRINTF(
"qbuf_renew_file: removing file %d\n", file);
153 PRINTF(
"qbuf_renew_file: cfs open error\n");
155 qbuf_files[file].fd = ret;
156 qbuf_files[file].usage = 0;
157 qbuf_files[file].renewable = 0;
162qbuf_renew_all(
void *unused)
165 for(i=0; i<NQBUF_FILES; i++) {
166 if(qbuf_files[i].renewable == 1) {
174queuebuf_remove_from_file(
int swap_id)
178 fileid = swap_id / NQBUF_PER_FILE;
179 qbuf_files[fileid].usage--;
182 if(qbuf_files[fileid].usage == 0 && fileid != next_swap_id / NQBUF_PER_FILE) {
183 qbuf_files[fileid].renewable = 1;
185 ctimer_set(&renew_timer, 0, qbuf_renew_all, NULL);
188 if(tmpdata_qbuf->swap_id == swap_id) {
189 tmpdata_qbuf->swap_id = -1;
198 int swap_id = next_swap_id;
199 fileid = swap_id / NQBUF_PER_FILE;
200 if(swap_id % NQBUF_PER_FILE == 0) {
201 if(qbuf_files[fileid].renewable) {
202 qbuf_renew_file(fileid);
204 if(qbuf_files[fileid].usage>0) {
208 qbuf_files[fileid].usage++;
209 next_swap_id = (next_swap_id+1) % NQBUF_ID;
215queuebuf_flush_tmpdata(
void)
220 queuebuf_remove_from_file(tmpdata_qbuf->swap_id);
221 tmpdata_qbuf->swap_id = get_new_swap_id();
222 if(tmpdata_qbuf->swap_id == -1) {
225 fileid = tmpdata_qbuf->swap_id / NQBUF_PER_FILE;
226 offset = (tmpdata_qbuf->swap_id % NQBUF_PER_FILE) *
sizeof(
struct queuebuf_data);
227 fd = qbuf_files[fileid].fd;
230 PRINTF(
"queuebuf_flush_tmpdata: cfs seek error\n");
233 ret =
cfs_write(fd, &tmpdata,
sizeof(
struct queuebuf_data));
235 PRINTF(
"queuebuf_flush_tmpdata: cfs write error\n");
243static struct queuebuf_data *
244queuebuf_load_to_ram(
struct queuebuf *b)
248 if(b->location == IN_RAM) {
251 if(tmpdata_qbuf && tmpdata_qbuf->swap_id == b->swap_id) {
256 fileid = b->swap_id / NQBUF_PER_FILE;
257 offset = (b->swap_id % NQBUF_PER_FILE) *
sizeof(
struct queuebuf_data);
258 fd = qbuf_files[fileid].fd;
261 PRINTF(
"queuebuf_load_to_ram: cfs seek error\n");
263 ret =
cfs_read(fd, &tmpdata,
sizeof(
struct queuebuf_data));
265 PRINTF(
"queuebuf_load_to_ram: cfs read error\n");
273static struct queuebuf_data *
274queuebuf_load_to_ram(
struct queuebuf *b)
285 for(i=0; i<NQBUF_FILES; i++) {
286 qbuf_files[i].renewable = 1;
293 queuebuf_max_len = 0;
298queuebuf_numfree(
void)
305queuebuf_new_from_packetbuf_debug(
const char *file,
int line)
308queuebuf_new_from_packetbuf(
void)
311 struct queuebuf *buf;
313 struct queuebuf_data *buframptr;
325 if(buf->ram_ptr != NULL) {
326 buf->location = IN_RAM;
327 buframptr = buf->ram_ptr;
329 buf->location = IN_CFS;
332 buframptr = &tmpdata;
335 if(buf->ram_ptr == NULL) {
336 PRINTF(
"queuebuf_new_from_packetbuf: could not queuebuf data\n");
340 buframptr = buf->ram_ptr;
344 packetbuf_attr_copyto(buframptr->attrs, buframptr->addrs);
347 if(buf->location == IN_CFS) {
348 if(queuebuf_flush_tmpdata() == -1) {
358 PRINTF(
"#A q=%d\n", queuebuf_len);
359 if(queuebuf_len > queuebuf_max_len) {
360 queuebuf_max_len = queuebuf_len;
365 PRINTF(
"queuebuf_new_from_packetbuf: could not allocate a queuebuf\n");
371queuebuf_update_attr_from_packetbuf(
struct queuebuf *buf)
373 struct queuebuf_data *buframptr = queuebuf_load_to_ram(buf);
374 packetbuf_attr_copyto(buframptr->attrs, buframptr->addrs);
376 if(buf->location == IN_CFS) {
377 queuebuf_flush_tmpdata();
383queuebuf_update_from_packetbuf(
struct queuebuf *buf)
385 struct queuebuf_data *buframptr = queuebuf_load_to_ram(buf);
386 packetbuf_attr_copyto(buframptr->attrs, buframptr->addrs);
389 if(buf->location == IN_CFS) {
390 queuebuf_flush_tmpdata();
396queuebuf_free(
struct queuebuf *buf)
400 if(buf->location == IN_RAM) {
403 queuebuf_remove_from_file(buf->swap_id);
411 PRINTF(
"#A q=%d\n", queuebuf_len);
420queuebuf_to_packetbuf(
struct queuebuf *b)
423 struct queuebuf_data *buframptr = queuebuf_load_to_ram(b);
425 packetbuf_attr_copyfrom(buframptr->attrs, buframptr->addrs);
430queuebuf_dataptr(
struct queuebuf *b)
433 struct queuebuf_data *buframptr = queuebuf_load_to_ram(b);
434 return buframptr->data;
440queuebuf_datalen(
struct queuebuf *b)
442 struct queuebuf_data *buframptr = queuebuf_load_to_ram(b);
443 return buframptr->len;
447queuebuf_addr(
struct queuebuf *b, uint8_t type)
449 struct queuebuf_data *buframptr = queuebuf_load_to_ram(b);
450 return &buframptr->addrs[type - PACKETBUF_ADDR_FIRST].addr;
454queuebuf_attr(
struct queuebuf *b, uint8_t type)
456 struct queuebuf_data *buframptr = queuebuf_load_to_ram(b);
457 return buframptr->attrs[type].val;
461queuebuf_debug_print(
void)
465 printf(
"queuebuf_list: ");
466 for(q =
list_head(queuebuf_list); q != NULL;
468 printf(
"%s,%d,%lu ", q->file, q->line, q->time);
clock_time_t clock_time(void)
Get the current clock time.
#define CFS_READ
Specify that cfs_open() should open a file for reading.
int cfs_read(int f, void *buf, unsigned int len)
Read data from an open file.
int cfs_remove(const char *name)
Remove a file.
int cfs_open(const char *n, int f)
Open a file.
#define CFS_SEEK_SET
Specify that cfs_seek() should compute the offset from the beginning of the file.
#define CFS_WRITE
Specify that cfs_open() should open a file for writing.
cfs_offset_t cfs_seek(int f, cfs_offset_t o, int w)
Seek to a specified position in an open file.
int cfs_write(int f, const void *buf, unsigned int len)
Write data to an open file.
int cfs_offset_t
CFS directory entry name length.
static void ctimer_set(struct ctimer *c, clock_time_t t, void(*f)(void *), void *ptr)
Set a callback timer.
#define LIST(name)
Declare a linked list.
static void * list_item_next(const void *item)
Get the next item following this item.
void list_add(list_t list, void *item)
Add an item at the end of a list.
void list_remove(list_t list, const void *item)
Remove a specific element from a list.
static void * list_head(const_list_t list)
Get a pointer to the first element of a list.
int memb_free(struct memb *m, void *ptr)
Deallocate a memory block from a memory block previously declared with MEMB().
size_t memb_numfree(struct memb *m)
Count free memory blocks.
int memb_inmemb(struct memb *m, void *ptr)
Check if a given address is within a memory area previously declared with MEMB().
void * memb_alloc(struct memb *m)
Allocate a memory block from a block of memory declared with MEMB().
void memb_init(struct memb *m)
Initialize a memory block that was declared with MEMB().
#define MEMB(name, structure, num)
Declare a memory block.
int packetbuf_copyfrom(const void *from, uint16_t len)
Copy from external data into the packetbuf.
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
int packetbuf_copyto(void *to)
Copy the entire packetbuf to an external buffer.
Linked list manipulation routines.
Header file for the Packet queue buffer management.