45 #include "contiki-net.h"
57 struct queuebuf *next;
63 enum {IN_RAM, IN_CFS} location;
66 struct queuebuf_data *ram_ptr;
74 struct queuebuf_data {
77 struct packetbuf_attr attrs[PACKETBUF_NUM_ATTRS];
78 struct packetbuf_addr addrs[PACKETBUF_NUM_ADDRS];
81 MEMB(bufmem,
struct queuebuf, QUEUEBUF_NUM);
82 MEMB(buframmem,
struct queuebuf_data, QUEUEBUFRAM_NUM);
91 #define NQBUF_PER_FILE 256
92 #define QBUF_FILE_SIZE (NQBUF_PER_FILE*sizeof(struct queuebuf_data))
93 #define NQBUF_ID (NQBUF_PER_FILE * NQBUF_FILES)
102 static struct queuebuf_data tmpdata;
104 static struct queuebuf *tmpdata_qbuf =
NULL;
106 static int next_swap_id = 0;
108 static struct qbuf_file qbuf_files[NQBUF_FILES];
110 static struct ctimer renew_timer;
122 #define PRINTF(...) printf(__VA_ARGS__)
127 #ifdef QUEUEBUF_CONF_STATS
128 #define QUEUEBUF_STATS QUEUEBUF_CONF_STATS
130 #define QUEUEBUF_STATS 0
134 uint8_t queuebuf_len, queuebuf_max_len;
140 qbuf_renew_file(
int file)
144 name[0] =
'a' + file;
146 if(qbuf_files[file].renewable == 1) {
147 PRINTF(
"qbuf_renew_file: removing file %d\n", file);
152 PRINTF(
"qbuf_renew_file: cfs open error\n");
154 qbuf_files[file].fd = ret;
155 qbuf_files[file].usage = 0;
156 qbuf_files[file].renewable = 0;
161 qbuf_renew_all(
void *unused)
164 for(i=0; i<NQBUF_FILES; i++) {
165 if(qbuf_files[i].renewable == 1) {
173 queuebuf_remove_from_file(
int swap_id)
177 fileid = swap_id / NQBUF_PER_FILE;
178 qbuf_files[fileid].usage--;
181 if(qbuf_files[fileid].usage == 0 && fileid != next_swap_id / NQBUF_PER_FILE) {
182 qbuf_files[fileid].renewable = 1;
187 if(tmpdata_qbuf->swap_id == swap_id) {
188 tmpdata_qbuf->swap_id = -1;
194 get_new_swap_id(
void)
197 int swap_id = next_swap_id;
198 fileid = swap_id / NQBUF_PER_FILE;
199 if(swap_id % NQBUF_PER_FILE == 0) {
200 if(qbuf_files[fileid].renewable) {
201 qbuf_renew_file(fileid);
203 if(qbuf_files[fileid].usage>0) {
207 qbuf_files[fileid].usage++;
208 next_swap_id = (next_swap_id+1) % NQBUF_ID;
214 queuebuf_flush_tmpdata(
void)
219 queuebuf_remove_from_file(tmpdata_qbuf->swap_id);
220 tmpdata_qbuf->swap_id = get_new_swap_id();
221 if(tmpdata_qbuf->swap_id == -1) {
224 fileid = tmpdata_qbuf->swap_id / NQBUF_PER_FILE;
225 offset = (tmpdata_qbuf->swap_id % NQBUF_PER_FILE) *
sizeof(
struct queuebuf_data);
226 fd = qbuf_files[fileid].fd;
229 PRINTF(
"queuebuf_flush_tmpdata: cfs seek error\n");
232 ret = cfs_write(fd, &tmpdata,
sizeof(
struct queuebuf_data));
234 PRINTF(
"queuebuf_flush_tmpdata: cfs write error\n");
242 static struct queuebuf_data *
243 queuebuf_load_to_ram(
struct queuebuf *b)
247 if(b->location == IN_RAM) {
250 if(tmpdata_qbuf && tmpdata_qbuf->swap_id == b->swap_id) {
255 fileid = b->swap_id / NQBUF_PER_FILE;
256 offset = (b->swap_id % NQBUF_PER_FILE) *
sizeof(
struct queuebuf_data);
257 fd = qbuf_files[fileid].fd;
260 PRINTF(
"queuebuf_load_to_ram: cfs seek error\n");
262 ret = cfs_read(fd, &tmpdata,
sizeof(
struct queuebuf_data));
264 PRINTF(
"queuebuf_load_to_ram: cfs read error\n");
272 static struct queuebuf_data *
273 queuebuf_load_to_ram(
struct queuebuf *b)
284 for(i=0; i<NQBUF_FILES; i++) {
285 qbuf_files[i].renewable = 1;
292 queuebuf_max_len = 0;
297 queuebuf_numfree(
void)
299 return memb_numfree(&bufmem);
304 queuebuf_new_from_packetbuf_debug(
const char *file,
int line)
307 queuebuf_new_from_packetbuf(
void)
310 struct queuebuf *buf;
312 struct queuebuf_data *buframptr;
324 if(buf->ram_ptr !=
NULL) {
325 buf->location = IN_RAM;
326 buframptr = buf->ram_ptr;
328 buf->location = IN_CFS;
331 buframptr = &tmpdata;
334 if(buf->ram_ptr ==
NULL) {
335 PRINTF(
"queuebuf_new_from_packetbuf: could not queuebuf data\n");
339 buframptr = buf->ram_ptr;
343 packetbuf_attr_copyto(buframptr->attrs, buframptr->addrs);
346 if(buf->location == IN_CFS) {
347 if(queuebuf_flush_tmpdata() == -1) {
357 PRINTF(
"#A q=%d\n", queuebuf_len);
358 if(queuebuf_len > queuebuf_max_len) {
359 queuebuf_max_len = queuebuf_len;
364 PRINTF(
"queuebuf_new_from_packetbuf: could not allocate a queuebuf\n");
370 queuebuf_update_attr_from_packetbuf(
struct queuebuf *buf)
372 struct queuebuf_data *buframptr = queuebuf_load_to_ram(buf);
373 packetbuf_attr_copyto(buframptr->attrs, buframptr->addrs);
375 if(buf->location == IN_CFS) {
376 queuebuf_flush_tmpdata();
382 queuebuf_update_from_packetbuf(
struct queuebuf *buf)
384 struct queuebuf_data *buframptr = queuebuf_load_to_ram(buf);
385 packetbuf_attr_copyto(buframptr->attrs, buframptr->addrs);
388 if(buf->location == IN_CFS) {
389 queuebuf_flush_tmpdata();
395 queuebuf_free(
struct queuebuf *buf)
397 if(memb_inmemb(&bufmem, buf)) {
399 if(buf->location == IN_RAM) {
402 queuebuf_remove_from_file(buf->swap_id);
410 PRINTF(
"#A q=%d\n", queuebuf_len);
419 queuebuf_to_packetbuf(
struct queuebuf *b)
421 if(memb_inmemb(&bufmem, b)) {
422 struct queuebuf_data *buframptr = queuebuf_load_to_ram(b);
424 packetbuf_attr_copyfrom(buframptr->attrs, buframptr->addrs);
429 queuebuf_dataptr(
struct queuebuf *b)
431 if(memb_inmemb(&bufmem, b)) {
432 struct queuebuf_data *buframptr = queuebuf_load_to_ram(b);
433 return buframptr->data;
439 queuebuf_datalen(
struct queuebuf *b)
441 struct queuebuf_data *buframptr = queuebuf_load_to_ram(b);
442 return buframptr->len;
446 queuebuf_addr(
struct queuebuf *b, uint8_t type)
448 struct queuebuf_data *buframptr = queuebuf_load_to_ram(b);
449 return &buframptr->addrs[type - PACKETBUF_ADDR_FIRST].addr;
453 queuebuf_attr(
struct queuebuf *b, uint8_t type)
455 struct queuebuf_data *buframptr = queuebuf_load_to_ram(b);
456 return buframptr->attrs[type].val;
460 queuebuf_debug_print(
void)
464 printf(
"queuebuf_list: ");
467 printf(
"%s,%d,%lu ", q->file, q->line, q->time);
int cfs_open(const char *name, int flags)
Open a file.
#define CFS_WRITE
Specify that cfs_open() should open a file for writing.
void list_remove(list_t list, void *item)
Remove a specific element from a list.
#define LIST(name)
Declare a linked list.
#define MEMB(name, structure, num)
Declare a memory block.
CCIF clock_time_t clock_time(void)
Get the current clock time.
#define CFS_SEEK_SET
Specify that cfs_seek() should compute the offset from the beginning of the file. ...
void * list_item_next(void *item)
Get the next item following this item.
#define CFS_READ
Specify that cfs_open() should open a file for reading.
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
void memb_init(struct memb *m)
Initialize a memory block that was declared with MEMB().
void * list_head(list_t list)
Get a pointer to the first element of a list.
#define NULL
The null pointer.
void list_add(list_t list, void *item)
Add an item at the end of a list.
Linked list manipulation routines.
int packetbuf_copyfrom(const void *from, uint16_t len)
Copy from external data into the packetbuf.
int cfs_remove(const char *name)
Remove a file.
void ctimer_set(struct ctimer *c, clock_time_t t, void(*f)(void *), void *ptr)
Set a callback timer.
cfs_offset_t cfs_seek(int fd, cfs_offset_t offset, int whence)
Seek to a specified position in an open file.
void * memb_alloc(struct memb *m)
Allocate a memory block from a block of memory declared with MEMB().
char memb_free(struct memb *m, void *ptr)
Deallocate a memory block from a memory block previously declared with MEMB().
int packetbuf_copyto(void *to)
Copy the entire packetbuf to an external buffer.