00001 /** 00002 * \addtogroup packetqueue 00003 * @{ 00004 */ 00005 /* 00006 * Copyright (c) 2009, Swedish Institute of Computer Science. 00007 * All rights reserved. 00008 * 00009 * Redistribution and use in source and binary forms, with or without 00010 * modification, are permitted provided that the following conditions 00011 * are met: 00012 * 1. Redistributions of source code must retain the above copyright 00013 * notice, this list of conditions and the following disclaimer. 00014 * 2. Redistributions in binary form must reproduce the above copyright 00015 * notice, this list of conditions and the following disclaimer in the 00016 * documentation and/or other materials provided with the distribution. 00017 * 3. Neither the name of the Institute nor the names of its contributors 00018 * may be used to endorse or promote products derived from this software 00019 * without specific prior written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00022 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00023 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00024 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00025 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00026 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00027 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00028 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00029 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00030 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00031 * SUCH DAMAGE. 00032 * 00033 * This file is part of the Contiki operating system. 00034 * 00035 * $Id: packetqueue.c,v 1.1 2010/06/14 19:19:16 adamdunkels Exp $ 00036 */ 00037 00038 /** 00039 * \file 00040 * Packet queue management 00041 * \author 00042 * Adam Dunkels <adam@sics.se> 00043 */ 00044 00045 #include "sys/ctimer.h" 00046 #include "net/packetqueue.h" 00047 00048 /*---------------------------------------------------------------------------*/ 00049 void 00050 packetqueue_init(struct packetqueue *q) 00051 { 00052 list_init(*q->list); 00053 memb_init(q->memb); 00054 } 00055 /*---------------------------------------------------------------------------*/ 00056 static void 00057 remove_queued_packet(void *item) 00058 { 00059 struct packetqueue_item *i = item; 00060 struct packetqueue *q = i->queue; 00061 00062 list_remove(*q->list, i); 00063 queuebuf_free(i->buf); 00064 ctimer_stop(&i->lifetimer); 00065 memb_free(q->memb, i); 00066 /* printf("removing queued packet due to timeout\n");*/ 00067 } 00068 /*---------------------------------------------------------------------------*/ 00069 int 00070 packetqueue_enqueue_packetbuf(struct packetqueue *q, clock_time_t lifetime, 00071 void *ptr) 00072 { 00073 struct packetqueue_item *i; 00074 00075 /* Allocate a memory block to hold the packet queue item. */ 00076 i = memb_alloc(q->memb); 00077 00078 if(i == NULL) { 00079 return 0; 00080 } 00081 00082 /* Allocate a queuebuf and copy the contents of the packetbuf into it. */ 00083 i->buf = queuebuf_new_from_packetbuf(); 00084 00085 if(i->buf == NULL) { 00086 memb_free(q->memb, i); 00087 return 0; 00088 } 00089 00090 i->queue = q; 00091 i->ptr = ptr; 00092 00093 /* Setup a ctimer that removes the packet from the queue when its 00094 lifetime expires. If the lifetime is zero, we do not set a 00095 lifetimer. */ 00096 if(lifetime > 0) { 00097 ctimer_set(&i->lifetimer, lifetime, remove_queued_packet, i); 00098 } 00099 00100 /* Add the item to the queue. */ 00101 list_add(*q->list, i); 00102 00103 return 1; 00104 } 00105 /*---------------------------------------------------------------------------*/ 00106 struct packetqueue_item * 00107 packetqueue_first(struct packetqueue *q) 00108 { 00109 return list_head(*q->list); 00110 } 00111 /*---------------------------------------------------------------------------*/ 00112 void 00113 packetqueue_dequeue(struct packetqueue *q) 00114 { 00115 struct packetqueue_item *i; 00116 00117 i = list_head(*q->list); 00118 if(i != NULL) { 00119 list_remove(*q->list, i); 00120 queuebuf_free(i->buf); 00121 ctimer_stop(&i->lifetimer); 00122 memb_free(q->memb, i); 00123 } 00124 } 00125 /*---------------------------------------------------------------------------*/ 00126 int 00127 packetqueue_len(struct packetqueue *q) 00128 { 00129 return list_length(*q->list); 00130 } 00131 /*---------------------------------------------------------------------------*/ 00132 struct queuebuf * 00133 packetqueue_queuebuf(struct packetqueue_item *i) 00134 { 00135 if(i != NULL) { 00136 return i->buf; 00137 } else { 00138 return NULL; 00139 } 00140 } 00141 /*---------------------------------------------------------------------------*/ 00142 void * 00143 packetqueue_ptr(struct packetqueue_item *i) 00144 { 00145 if(i != NULL) { 00146 return i->ptr; 00147 } else { 00148 return NULL; 00149 } 00150 } 00151 /*---------------------------------------------------------------------------*/ 00152 /** @} */