45 #include "contiki-net.h" 58 struct queuebuf *next;
64 enum {IN_RAM, IN_CFS} location;
67 struct queuebuf_data *ram_ptr;
75 struct queuebuf_data {
78 struct packetbuf_attr attrs[PACKETBUF_NUM_ATTRS];
79 struct packetbuf_addr addrs[PACKETBUF_NUM_ADDRS];
82 MEMB(bufmem,
struct queuebuf, QUEUEBUF_NUM);
83 MEMB(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) 103 static struct queuebuf_data tmpdata;
105 static struct queuebuf *tmpdata_qbuf = NULL;
107 static int next_swap_id = 0;
109 static struct qbuf_file qbuf_files[NQBUF_FILES];
111 static 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 135 uint8_t queuebuf_len, queuebuf_max_len;
141 qbuf_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;
162 qbuf_renew_all(
void *unused)
165 for(i=0; i<NQBUF_FILES; i++) {
166 if(qbuf_files[i].renewable == 1) {
174 queuebuf_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;
195 get_new_swap_id(
void)
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;
215 queuebuf_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");
243 static struct queuebuf_data *
244 queuebuf_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");
273 static struct queuebuf_data *
274 queuebuf_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;
298 queuebuf_numfree(
void)
300 return memb_numfree(&bufmem);
305 queuebuf_new_from_packetbuf_debug(
const char *file,
int line)
308 queuebuf_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");
371 queuebuf_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();
383 queuebuf_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();
396 queuebuf_free(
struct queuebuf *buf)
398 if(memb_inmemb(&bufmem, buf)) {
400 if(buf->location == IN_RAM) {
403 queuebuf_remove_from_file(buf->swap_id);
411 PRINTF(
"#A q=%d\n", queuebuf_len);
420 queuebuf_to_packetbuf(
struct queuebuf *b)
422 if(memb_inmemb(&bufmem, b)) {
423 struct queuebuf_data *buframptr = queuebuf_load_to_ram(b);
425 packetbuf_attr_copyfrom(buframptr->attrs, buframptr->addrs);
430 queuebuf_dataptr(
struct queuebuf *b)
432 if(memb_inmemb(&bufmem, b)) {
433 struct queuebuf_data *buframptr = queuebuf_load_to_ram(b);
434 return buframptr->data;
440 queuebuf_datalen(
struct queuebuf *b)
442 struct queuebuf_data *buframptr = queuebuf_load_to_ram(b);
443 return buframptr->len;
447 queuebuf_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;
454 queuebuf_attr(
struct queuebuf *b, uint8_t type)
456 struct queuebuf_data *buframptr = queuebuf_load_to_ram(b);
457 return buframptr->attrs[type].val;
461 queuebuf_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);
int cfs_open(const char *name, int flags)
Open a file.
int packetbuf_copyto(void *to)
Copy the entire packetbuf to an external buffer.
int cfs_remove(const char *name)
Remove a file.
cfs_offset_t cfs_seek(int fd, cfs_offset_t offset, int whence)
Seek to a specified position in an open file.
Header file for the Packet queue buffer management
Linked list manipulation routines.
int cfs_write(int fd, const void *buf, unsigned int len)
Write data to an open file.
void * list_head(list_t list)
Get a pointer to the first element of a list.
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
void ctimer_set(struct ctimer *c, clock_time_t t, void(*f)(void *), void *ptr)
Set a callback timer.
int packetbuf_copyfrom(const void *from, uint16_t len)
Copy from external data into the packetbuf.
clock_time_t clock_time(void)
Get the current clock time.
void list_add(list_t list, void *item)
Add an item at the end of a list.
int cfs_read(int fd, void *buf, unsigned int len)
Read data from an open file.
#define CFS_READ
Specify that cfs_open() should open a file for reading.
#define LIST(name)
Declare a linked list.
void * memb_alloc(struct memb *m)
Allocate a memory block from a block of memory declared with MEMB().
#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.
void memb_init(struct memb *m)
Initialize a memory block that was declared with MEMB().
char memb_free(struct memb *m, void *ptr)
Deallocate a memory block from a memory block previously declared with MEMB().
void list_remove(list_t list, void *item)
Remove a specific element from a list.
void * list_item_next(void *item)
Get the next item following this item.
#define MEMB(name, structure, num)
Declare a memory block.