Michael Spencer / Mbed 2 deprecated LaOS

Dependencies:   mbed

Committer:
Michael J. Spencer
Date:
Wed Mar 05 06:14:02 2014 -0800
Revision:
1:f5ac63519541
Initial commit.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Michael J. Spencer 1:f5ac63519541 1 /**
Michael J. Spencer 1:f5ac63519541 2 * @file
Michael J. Spencer 1:f5ac63519541 3 * Stack-internal timers implementation.
Michael J. Spencer 1:f5ac63519541 4 * This file includes timer callbacks for stack-internal timers as well as
Michael J. Spencer 1:f5ac63519541 5 * functions to set up or stop timers and check for expired timers.
Michael J. Spencer 1:f5ac63519541 6 *
Michael J. Spencer 1:f5ac63519541 7 */
Michael J. Spencer 1:f5ac63519541 8
Michael J. Spencer 1:f5ac63519541 9 /*
Michael J. Spencer 1:f5ac63519541 10 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
Michael J. Spencer 1:f5ac63519541 11 * All rights reserved.
Michael J. Spencer 1:f5ac63519541 12 *
Michael J. Spencer 1:f5ac63519541 13 * Redistribution and use in source and binary forms, with or without modification,
Michael J. Spencer 1:f5ac63519541 14 * are permitted provided that the following conditions are met:
Michael J. Spencer 1:f5ac63519541 15 *
Michael J. Spencer 1:f5ac63519541 16 * 1. Redistributions of source code must retain the above copyright notice,
Michael J. Spencer 1:f5ac63519541 17 * this list of conditions and the following disclaimer.
Michael J. Spencer 1:f5ac63519541 18 * 2. Redistributions in binary form must reproduce the above copyright notice,
Michael J. Spencer 1:f5ac63519541 19 * this list of conditions and the following disclaimer in the documentation
Michael J. Spencer 1:f5ac63519541 20 * and/or other materials provided with the distribution.
Michael J. Spencer 1:f5ac63519541 21 * 3. The name of the author may not be used to endorse or promote products
Michael J. Spencer 1:f5ac63519541 22 * derived from this software without specific prior written permission.
Michael J. Spencer 1:f5ac63519541 23 *
Michael J. Spencer 1:f5ac63519541 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
Michael J. Spencer 1:f5ac63519541 25 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
Michael J. Spencer 1:f5ac63519541 26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
Michael J. Spencer 1:f5ac63519541 27 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
Michael J. Spencer 1:f5ac63519541 28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
Michael J. Spencer 1:f5ac63519541 29 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
Michael J. Spencer 1:f5ac63519541 30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
Michael J. Spencer 1:f5ac63519541 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
Michael J. Spencer 1:f5ac63519541 32 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
Michael J. Spencer 1:f5ac63519541 33 * OF SUCH DAMAGE.
Michael J. Spencer 1:f5ac63519541 34 *
Michael J. Spencer 1:f5ac63519541 35 * This file is part of the lwIP TCP/IP stack.
Michael J. Spencer 1:f5ac63519541 36 *
Michael J. Spencer 1:f5ac63519541 37 * Author: Adam Dunkels <adam@sics.se>
Michael J. Spencer 1:f5ac63519541 38 * Simon Goldschmidt
Michael J. Spencer 1:f5ac63519541 39 *
Michael J. Spencer 1:f5ac63519541 40 */
Michael J. Spencer 1:f5ac63519541 41
Michael J. Spencer 1:f5ac63519541 42 #include "lwip/opt.h"
Michael J. Spencer 1:f5ac63519541 43
Michael J. Spencer 1:f5ac63519541 44 #include "lwip/timers.h"
Michael J. Spencer 1:f5ac63519541 45
Michael J. Spencer 1:f5ac63519541 46 #if LWIP_TIMERS
Michael J. Spencer 1:f5ac63519541 47
Michael J. Spencer 1:f5ac63519541 48 #include "lwip/def.h"
Michael J. Spencer 1:f5ac63519541 49 #include "lwip/memp.h"
Michael J. Spencer 1:f5ac63519541 50 #include "lwip/tcpip.h"
Michael J. Spencer 1:f5ac63519541 51
Michael J. Spencer 1:f5ac63519541 52 #include "lwip/tcp_impl.h"
Michael J. Spencer 1:f5ac63519541 53 #include "lwip/ip_frag.h"
Michael J. Spencer 1:f5ac63519541 54 #include "netif/etharp.h"
Michael J. Spencer 1:f5ac63519541 55 #include "lwip/dhcp.h"
Michael J. Spencer 1:f5ac63519541 56 #include "lwip/autoip.h"
Michael J. Spencer 1:f5ac63519541 57 #include "lwip/igmp.h"
Michael J. Spencer 1:f5ac63519541 58 #include "lwip/dns.h"
Michael J. Spencer 1:f5ac63519541 59
Michael J. Spencer 1:f5ac63519541 60
Michael J. Spencer 1:f5ac63519541 61 /** The one and only timeout list */
Michael J. Spencer 1:f5ac63519541 62 static struct sys_timeo *next_timeout;
Michael J. Spencer 1:f5ac63519541 63 #if NO_SYS
Michael J. Spencer 1:f5ac63519541 64 static u32_t timeouts_last_time;
Michael J. Spencer 1:f5ac63519541 65 #endif /* NO_SYS */
Michael J. Spencer 1:f5ac63519541 66
Michael J. Spencer 1:f5ac63519541 67 #if LWIP_TCP
Michael J. Spencer 1:f5ac63519541 68 /** global variable that shows if the tcp timer is currently scheduled or not */
Michael J. Spencer 1:f5ac63519541 69 static int tcpip_tcp_timer_active;
Michael J. Spencer 1:f5ac63519541 70
Michael J. Spencer 1:f5ac63519541 71 /**
Michael J. Spencer 1:f5ac63519541 72 * Timer callback function that calls tcp_tmr() and reschedules itself.
Michael J. Spencer 1:f5ac63519541 73 *
Michael J. Spencer 1:f5ac63519541 74 * @param arg unused argument
Michael J. Spencer 1:f5ac63519541 75 */
Michael J. Spencer 1:f5ac63519541 76 static void
Michael J. Spencer 1:f5ac63519541 77 tcpip_tcp_timer(void *arg)
Michael J. Spencer 1:f5ac63519541 78 {
Michael J. Spencer 1:f5ac63519541 79 LWIP_UNUSED_ARG(arg);
Michael J. Spencer 1:f5ac63519541 80
Michael J. Spencer 1:f5ac63519541 81 /* call TCP timer handler */
Michael J. Spencer 1:f5ac63519541 82 tcp_tmr();
Michael J. Spencer 1:f5ac63519541 83 /* timer still needed? */
Michael J. Spencer 1:f5ac63519541 84 if (tcp_active_pcbs || tcp_tw_pcbs) {
Michael J. Spencer 1:f5ac63519541 85 /* restart timer */
Michael J. Spencer 1:f5ac63519541 86 sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);
Michael J. Spencer 1:f5ac63519541 87 } else {
Michael J. Spencer 1:f5ac63519541 88 /* disable timer */
Michael J. Spencer 1:f5ac63519541 89 tcpip_tcp_timer_active = 0;
Michael J. Spencer 1:f5ac63519541 90 }
Michael J. Spencer 1:f5ac63519541 91 }
Michael J. Spencer 1:f5ac63519541 92
Michael J. Spencer 1:f5ac63519541 93 /**
Michael J. Spencer 1:f5ac63519541 94 * Called from TCP_REG when registering a new PCB:
Michael J. Spencer 1:f5ac63519541 95 * the reason is to have the TCP timer only running when
Michael J. Spencer 1:f5ac63519541 96 * there are active (or time-wait) PCBs.
Michael J. Spencer 1:f5ac63519541 97 */
Michael J. Spencer 1:f5ac63519541 98 void
Michael J. Spencer 1:f5ac63519541 99 tcp_timer_needed(void)
Michael J. Spencer 1:f5ac63519541 100 {
Michael J. Spencer 1:f5ac63519541 101 /* timer is off but needed again? */
Michael J. Spencer 1:f5ac63519541 102 if (!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) {
Michael J. Spencer 1:f5ac63519541 103 /* enable and start timer */
Michael J. Spencer 1:f5ac63519541 104 tcpip_tcp_timer_active = 1;
Michael J. Spencer 1:f5ac63519541 105 sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);
Michael J. Spencer 1:f5ac63519541 106 }
Michael J. Spencer 1:f5ac63519541 107 }
Michael J. Spencer 1:f5ac63519541 108 #endif /* LWIP_TCP */
Michael J. Spencer 1:f5ac63519541 109
Michael J. Spencer 1:f5ac63519541 110 #if IP_REASSEMBLY
Michael J. Spencer 1:f5ac63519541 111 /**
Michael J. Spencer 1:f5ac63519541 112 * Timer callback function that calls ip_reass_tmr() and reschedules itself.
Michael J. Spencer 1:f5ac63519541 113 *
Michael J. Spencer 1:f5ac63519541 114 * @param arg unused argument
Michael J. Spencer 1:f5ac63519541 115 */
Michael J. Spencer 1:f5ac63519541 116 static void
Michael J. Spencer 1:f5ac63519541 117 ip_reass_timer(void *arg)
Michael J. Spencer 1:f5ac63519541 118 {
Michael J. Spencer 1:f5ac63519541 119 LWIP_UNUSED_ARG(arg);
Michael J. Spencer 1:f5ac63519541 120 LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: ip_reass_tmr()\n"));
Michael J. Spencer 1:f5ac63519541 121 ip_reass_tmr();
Michael J. Spencer 1:f5ac63519541 122 sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL);
Michael J. Spencer 1:f5ac63519541 123 }
Michael J. Spencer 1:f5ac63519541 124 #endif /* IP_REASSEMBLY */
Michael J. Spencer 1:f5ac63519541 125
Michael J. Spencer 1:f5ac63519541 126 #if LWIP_ARP
Michael J. Spencer 1:f5ac63519541 127 /**
Michael J. Spencer 1:f5ac63519541 128 * Timer callback function that calls etharp_tmr() and reschedules itself.
Michael J. Spencer 1:f5ac63519541 129 *
Michael J. Spencer 1:f5ac63519541 130 * @param arg unused argument
Michael J. Spencer 1:f5ac63519541 131 */
Michael J. Spencer 1:f5ac63519541 132 static void
Michael J. Spencer 1:f5ac63519541 133 arp_timer(void *arg)
Michael J. Spencer 1:f5ac63519541 134 {
Michael J. Spencer 1:f5ac63519541 135 LWIP_UNUSED_ARG(arg);
Michael J. Spencer 1:f5ac63519541 136 LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: etharp_tmr()\n"));
Michael J. Spencer 1:f5ac63519541 137 etharp_tmr();
Michael J. Spencer 1:f5ac63519541 138 sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
Michael J. Spencer 1:f5ac63519541 139 }
Michael J. Spencer 1:f5ac63519541 140 #endif /* LWIP_ARP */
Michael J. Spencer 1:f5ac63519541 141
Michael J. Spencer 1:f5ac63519541 142 #if LWIP_DHCP
Michael J. Spencer 1:f5ac63519541 143 /**
Michael J. Spencer 1:f5ac63519541 144 * Timer callback function that calls dhcp_coarse_tmr() and reschedules itself.
Michael J. Spencer 1:f5ac63519541 145 *
Michael J. Spencer 1:f5ac63519541 146 * @param arg unused argument
Michael J. Spencer 1:f5ac63519541 147 */
Michael J. Spencer 1:f5ac63519541 148 static void
Michael J. Spencer 1:f5ac63519541 149 dhcp_timer_coarse(void *arg)
Michael J. Spencer 1:f5ac63519541 150 {
Michael J. Spencer 1:f5ac63519541 151 LWIP_UNUSED_ARG(arg);
Michael J. Spencer 1:f5ac63519541 152 LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: dhcp_coarse_tmr()\n"));
Michael J. Spencer 1:f5ac63519541 153 dhcp_coarse_tmr();
Michael J. Spencer 1:f5ac63519541 154 sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcp_timer_coarse, NULL);
Michael J. Spencer 1:f5ac63519541 155 }
Michael J. Spencer 1:f5ac63519541 156
Michael J. Spencer 1:f5ac63519541 157 /**
Michael J. Spencer 1:f5ac63519541 158 * Timer callback function that calls dhcp_fine_tmr() and reschedules itself.
Michael J. Spencer 1:f5ac63519541 159 *
Michael J. Spencer 1:f5ac63519541 160 * @param arg unused argument
Michael J. Spencer 1:f5ac63519541 161 */
Michael J. Spencer 1:f5ac63519541 162 static void
Michael J. Spencer 1:f5ac63519541 163 dhcp_timer_fine(void *arg)
Michael J. Spencer 1:f5ac63519541 164 {
Michael J. Spencer 1:f5ac63519541 165 LWIP_UNUSED_ARG(arg);
Michael J. Spencer 1:f5ac63519541 166 LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: dhcp_fine_tmr()\n"));
Michael J. Spencer 1:f5ac63519541 167 dhcp_fine_tmr();
Michael J. Spencer 1:f5ac63519541 168 sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL);
Michael J. Spencer 1:f5ac63519541 169 }
Michael J. Spencer 1:f5ac63519541 170 #endif /* LWIP_DHCP */
Michael J. Spencer 1:f5ac63519541 171
Michael J. Spencer 1:f5ac63519541 172 #if LWIP_AUTOIP
Michael J. Spencer 1:f5ac63519541 173 /**
Michael J. Spencer 1:f5ac63519541 174 * Timer callback function that calls autoip_tmr() and reschedules itself.
Michael J. Spencer 1:f5ac63519541 175 *
Michael J. Spencer 1:f5ac63519541 176 * @param arg unused argument
Michael J. Spencer 1:f5ac63519541 177 */
Michael J. Spencer 1:f5ac63519541 178 static void
Michael J. Spencer 1:f5ac63519541 179 autoip_timer(void *arg)
Michael J. Spencer 1:f5ac63519541 180 {
Michael J. Spencer 1:f5ac63519541 181 LWIP_UNUSED_ARG(arg);
Michael J. Spencer 1:f5ac63519541 182 LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: autoip_tmr()\n"));
Michael J. Spencer 1:f5ac63519541 183 autoip_tmr();
Michael J. Spencer 1:f5ac63519541 184 sys_timeout(AUTOIP_TMR_INTERVAL, autoip_timer, NULL);
Michael J. Spencer 1:f5ac63519541 185 }
Michael J. Spencer 1:f5ac63519541 186 #endif /* LWIP_AUTOIP */
Michael J. Spencer 1:f5ac63519541 187
Michael J. Spencer 1:f5ac63519541 188 #if LWIP_IGMP
Michael J. Spencer 1:f5ac63519541 189 /**
Michael J. Spencer 1:f5ac63519541 190 * Timer callback function that calls igmp_tmr() and reschedules itself.
Michael J. Spencer 1:f5ac63519541 191 *
Michael J. Spencer 1:f5ac63519541 192 * @param arg unused argument
Michael J. Spencer 1:f5ac63519541 193 */
Michael J. Spencer 1:f5ac63519541 194 static void
Michael J. Spencer 1:f5ac63519541 195 igmp_timer(void *arg)
Michael J. Spencer 1:f5ac63519541 196 {
Michael J. Spencer 1:f5ac63519541 197 LWIP_UNUSED_ARG(arg);
Michael J. Spencer 1:f5ac63519541 198 LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: igmp_tmr()\n"));
Michael J. Spencer 1:f5ac63519541 199 igmp_tmr();
Michael J. Spencer 1:f5ac63519541 200 sys_timeout(IGMP_TMR_INTERVAL, igmp_timer, NULL);
Michael J. Spencer 1:f5ac63519541 201 }
Michael J. Spencer 1:f5ac63519541 202 #endif /* LWIP_IGMP */
Michael J. Spencer 1:f5ac63519541 203
Michael J. Spencer 1:f5ac63519541 204 #if LWIP_DNS
Michael J. Spencer 1:f5ac63519541 205 /**
Michael J. Spencer 1:f5ac63519541 206 * Timer callback function that calls dns_tmr() and reschedules itself.
Michael J. Spencer 1:f5ac63519541 207 *
Michael J. Spencer 1:f5ac63519541 208 * @param arg unused argument
Michael J. Spencer 1:f5ac63519541 209 */
Michael J. Spencer 1:f5ac63519541 210 static void
Michael J. Spencer 1:f5ac63519541 211 dns_timer(void *arg)
Michael J. Spencer 1:f5ac63519541 212 {
Michael J. Spencer 1:f5ac63519541 213 LWIP_UNUSED_ARG(arg);
Michael J. Spencer 1:f5ac63519541 214 LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: dns_tmr()\n"));
Michael J. Spencer 1:f5ac63519541 215 dns_tmr();
Michael J. Spencer 1:f5ac63519541 216 sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL);
Michael J. Spencer 1:f5ac63519541 217 }
Michael J. Spencer 1:f5ac63519541 218 #endif /* LWIP_DNS */
Michael J. Spencer 1:f5ac63519541 219
Michael J. Spencer 1:f5ac63519541 220 /** Initialize this module */
Michael J. Spencer 1:f5ac63519541 221 void sys_timeouts_init(void)
Michael J. Spencer 1:f5ac63519541 222 {
Michael J. Spencer 1:f5ac63519541 223 next_timeout = NULL;
Michael J. Spencer 1:f5ac63519541 224 #if IP_REASSEMBLY
Michael J. Spencer 1:f5ac63519541 225 sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL);
Michael J. Spencer 1:f5ac63519541 226 #endif /* IP_REASSEMBLY */
Michael J. Spencer 1:f5ac63519541 227 #if LWIP_ARP
Michael J. Spencer 1:f5ac63519541 228 sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
Michael J. Spencer 1:f5ac63519541 229 #endif /* LWIP_ARP */
Michael J. Spencer 1:f5ac63519541 230 #if LWIP_DHCP
Michael J. Spencer 1:f5ac63519541 231 sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcp_timer_coarse, NULL);
Michael J. Spencer 1:f5ac63519541 232 sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL);
Michael J. Spencer 1:f5ac63519541 233 #endif /* LWIP_DHCP */
Michael J. Spencer 1:f5ac63519541 234 #if LWIP_AUTOIP
Michael J. Spencer 1:f5ac63519541 235 sys_timeout(AUTOIP_TMR_INTERVAL, autoip_timer, NULL);
Michael J. Spencer 1:f5ac63519541 236 #endif /* LWIP_AUTOIP */
Michael J. Spencer 1:f5ac63519541 237 #if LWIP_IGMP
Michael J. Spencer 1:f5ac63519541 238 sys_timeout(IGMP_TMR_INTERVAL, igmp_timer, NULL);
Michael J. Spencer 1:f5ac63519541 239 #endif /* LWIP_IGMP */
Michael J. Spencer 1:f5ac63519541 240 #if LWIP_DNS
Michael J. Spencer 1:f5ac63519541 241 sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL);
Michael J. Spencer 1:f5ac63519541 242 #endif /* LWIP_DNS */
Michael J. Spencer 1:f5ac63519541 243
Michael J. Spencer 1:f5ac63519541 244 #if NO_SYS
Michael J. Spencer 1:f5ac63519541 245 /* Initialise timestamp for sys_check_timeouts */
Michael J. Spencer 1:f5ac63519541 246 timeouts_last_time = sys_now();
Michael J. Spencer 1:f5ac63519541 247 #endif
Michael J. Spencer 1:f5ac63519541 248 }
Michael J. Spencer 1:f5ac63519541 249
Michael J. Spencer 1:f5ac63519541 250 /**
Michael J. Spencer 1:f5ac63519541 251 * Create a one-shot timer (aka timeout). Timeouts are processed in the
Michael J. Spencer 1:f5ac63519541 252 * following cases:
Michael J. Spencer 1:f5ac63519541 253 * - while waiting for a message using sys_timeouts_mbox_fetch()
Michael J. Spencer 1:f5ac63519541 254 * - by calling sys_check_timeouts() (NO_SYS==1 only)
Michael J. Spencer 1:f5ac63519541 255 *
Michael J. Spencer 1:f5ac63519541 256 * @param msecs time in milliseconds after that the timer should expire
Michael J. Spencer 1:f5ac63519541 257 * @param handler callback function to call when msecs have elapsed
Michael J. Spencer 1:f5ac63519541 258 * @param arg argument to pass to the callback function
Michael J. Spencer 1:f5ac63519541 259 */
Michael J. Spencer 1:f5ac63519541 260 #if LWIP_DEBUG_TIMERNAMES
Michael J. Spencer 1:f5ac63519541 261 void
Michael J. Spencer 1:f5ac63519541 262 sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char* handler_name)
Michael J. Spencer 1:f5ac63519541 263 #else /* LWIP_DEBUG_TIMERNAMES */
Michael J. Spencer 1:f5ac63519541 264 void
Michael J. Spencer 1:f5ac63519541 265 sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg)
Michael J. Spencer 1:f5ac63519541 266 #endif /* LWIP_DEBUG_TIMERNAMES */
Michael J. Spencer 1:f5ac63519541 267 {
Michael J. Spencer 1:f5ac63519541 268 struct sys_timeo *timeout, *t;
Michael J. Spencer 1:f5ac63519541 269
Michael J. Spencer 1:f5ac63519541 270 timeout = (struct sys_timeo *)memp_malloc(MEMP_SYS_TIMEOUT);
Michael J. Spencer 1:f5ac63519541 271 if (timeout == NULL) {
Michael J. Spencer 1:f5ac63519541 272 LWIP_ASSERT("sys_timeout: timeout != NULL, pool MEMP_SYS_TIMEOUT is empty", timeout != NULL);
Michael J. Spencer 1:f5ac63519541 273 return;
Michael J. Spencer 1:f5ac63519541 274 }
Michael J. Spencer 1:f5ac63519541 275 timeout->next = NULL;
Michael J. Spencer 1:f5ac63519541 276 timeout->h = handler;
Michael J. Spencer 1:f5ac63519541 277 timeout->arg = arg;
Michael J. Spencer 1:f5ac63519541 278 timeout->time = msecs;
Michael J. Spencer 1:f5ac63519541 279 #if LWIP_DEBUG_TIMERNAMES
Michael J. Spencer 1:f5ac63519541 280 timeout->handler_name = handler_name;
Michael J. Spencer 1:f5ac63519541 281 LWIP_DEBUGF(TIMERS_DEBUG, ("sys_timeout: %p msecs=%"U32_F" handler=%s arg=%p\n",
Michael J. Spencer 1:f5ac63519541 282 (void *)timeout, msecs, handler_name, (void *)arg));
Michael J. Spencer 1:f5ac63519541 283 #endif /* LWIP_DEBUG_TIMERNAMES */
Michael J. Spencer 1:f5ac63519541 284
Michael J. Spencer 1:f5ac63519541 285 if (next_timeout == NULL) {
Michael J. Spencer 1:f5ac63519541 286 next_timeout = timeout;
Michael J. Spencer 1:f5ac63519541 287 return;
Michael J. Spencer 1:f5ac63519541 288 }
Michael J. Spencer 1:f5ac63519541 289
Michael J. Spencer 1:f5ac63519541 290 if (next_timeout->time > msecs) {
Michael J. Spencer 1:f5ac63519541 291 next_timeout->time -= msecs;
Michael J. Spencer 1:f5ac63519541 292 timeout->next = next_timeout;
Michael J. Spencer 1:f5ac63519541 293 next_timeout = timeout;
Michael J. Spencer 1:f5ac63519541 294 } else {
Michael J. Spencer 1:f5ac63519541 295 for(t = next_timeout; t != NULL; t = t->next) {
Michael J. Spencer 1:f5ac63519541 296 timeout->time -= t->time;
Michael J. Spencer 1:f5ac63519541 297 if (t->next == NULL || t->next->time > timeout->time) {
Michael J. Spencer 1:f5ac63519541 298 if (t->next != NULL) {
Michael J. Spencer 1:f5ac63519541 299 t->next->time -= timeout->time;
Michael J. Spencer 1:f5ac63519541 300 }
Michael J. Spencer 1:f5ac63519541 301 timeout->next = t->next;
Michael J. Spencer 1:f5ac63519541 302 t->next = timeout;
Michael J. Spencer 1:f5ac63519541 303 break;
Michael J. Spencer 1:f5ac63519541 304 }
Michael J. Spencer 1:f5ac63519541 305 }
Michael J. Spencer 1:f5ac63519541 306 }
Michael J. Spencer 1:f5ac63519541 307 }
Michael J. Spencer 1:f5ac63519541 308
Michael J. Spencer 1:f5ac63519541 309 /**
Michael J. Spencer 1:f5ac63519541 310 * Go through timeout list (for this task only) and remove the first matching
Michael J. Spencer 1:f5ac63519541 311 * entry, even though the timeout has not triggered yet.
Michael J. Spencer 1:f5ac63519541 312 *
Michael J. Spencer 1:f5ac63519541 313 * @note This function only works as expected if there is only one timeout
Michael J. Spencer 1:f5ac63519541 314 * calling 'handler' in the list of timeouts.
Michael J. Spencer 1:f5ac63519541 315 *
Michael J. Spencer 1:f5ac63519541 316 * @param handler callback function that would be called by the timeout
Michael J. Spencer 1:f5ac63519541 317 * @param arg callback argument that would be passed to handler
Michael J. Spencer 1:f5ac63519541 318 */
Michael J. Spencer 1:f5ac63519541 319 void
Michael J. Spencer 1:f5ac63519541 320 sys_untimeout(sys_timeout_handler handler, void *arg)
Michael J. Spencer 1:f5ac63519541 321 {
Michael J. Spencer 1:f5ac63519541 322 struct sys_timeo *prev_t, *t;
Michael J. Spencer 1:f5ac63519541 323
Michael J. Spencer 1:f5ac63519541 324 if (next_timeout == NULL) {
Michael J. Spencer 1:f5ac63519541 325 return;
Michael J. Spencer 1:f5ac63519541 326 }
Michael J. Spencer 1:f5ac63519541 327
Michael J. Spencer 1:f5ac63519541 328 for (t = next_timeout, prev_t = NULL; t != NULL; prev_t = t, t = t->next) {
Michael J. Spencer 1:f5ac63519541 329 if ((t->h == handler) && (t->arg == arg)) {
Michael J. Spencer 1:f5ac63519541 330 /* We have a match */
Michael J. Spencer 1:f5ac63519541 331 /* Unlink from previous in list */
Michael J. Spencer 1:f5ac63519541 332 if (prev_t == NULL) {
Michael J. Spencer 1:f5ac63519541 333 next_timeout = t->next;
Michael J. Spencer 1:f5ac63519541 334 } else {
Michael J. Spencer 1:f5ac63519541 335 prev_t->next = t->next;
Michael J. Spencer 1:f5ac63519541 336 }
Michael J. Spencer 1:f5ac63519541 337 /* If not the last one, add time of this one back to next */
Michael J. Spencer 1:f5ac63519541 338 if (t->next != NULL) {
Michael J. Spencer 1:f5ac63519541 339 t->next->time += t->time;
Michael J. Spencer 1:f5ac63519541 340 }
Michael J. Spencer 1:f5ac63519541 341 memp_free(MEMP_SYS_TIMEOUT, t);
Michael J. Spencer 1:f5ac63519541 342 return;
Michael J. Spencer 1:f5ac63519541 343 }
Michael J. Spencer 1:f5ac63519541 344 }
Michael J. Spencer 1:f5ac63519541 345 return;
Michael J. Spencer 1:f5ac63519541 346 }
Michael J. Spencer 1:f5ac63519541 347
Michael J. Spencer 1:f5ac63519541 348 #if NO_SYS
Michael J. Spencer 1:f5ac63519541 349
Michael J. Spencer 1:f5ac63519541 350 /** Handle timeouts for NO_SYS==1 (i.e. without using
Michael J. Spencer 1:f5ac63519541 351 * tcpip_thread/sys_timeouts_mbox_fetch(). Uses sys_now() to call timeout
Michael J. Spencer 1:f5ac63519541 352 * handler functions when timeouts expire.
Michael J. Spencer 1:f5ac63519541 353 *
Michael J. Spencer 1:f5ac63519541 354 * Must be called periodically from your main loop.
Michael J. Spencer 1:f5ac63519541 355 */
Michael J. Spencer 1:f5ac63519541 356 void
Michael J. Spencer 1:f5ac63519541 357 sys_check_timeouts(void)
Michael J. Spencer 1:f5ac63519541 358 {
Michael J. Spencer 1:f5ac63519541 359 struct sys_timeo *tmptimeout;
Michael J. Spencer 1:f5ac63519541 360 u32_t diff;
Michael J. Spencer 1:f5ac63519541 361 sys_timeout_handler handler;
Michael J. Spencer 1:f5ac63519541 362 void *arg;
Michael J. Spencer 1:f5ac63519541 363 int had_one;
Michael J. Spencer 1:f5ac63519541 364 u32_t now;
Michael J. Spencer 1:f5ac63519541 365
Michael J. Spencer 1:f5ac63519541 366 now = sys_now();
Michael J. Spencer 1:f5ac63519541 367 if (next_timeout) {
Michael J. Spencer 1:f5ac63519541 368 /* this cares for wraparounds */
Michael J. Spencer 1:f5ac63519541 369 diff = LWIP_U32_DIFF(now, timeouts_last_time);
Michael J. Spencer 1:f5ac63519541 370 do
Michael J. Spencer 1:f5ac63519541 371 {
Michael J. Spencer 1:f5ac63519541 372 had_one = 0;
Michael J. Spencer 1:f5ac63519541 373 tmptimeout = next_timeout;
Michael J. Spencer 1:f5ac63519541 374 if (tmptimeout->time <= diff) {
Michael J. Spencer 1:f5ac63519541 375 /* timeout has expired */
Michael J. Spencer 1:f5ac63519541 376 had_one = 1;
Michael J. Spencer 1:f5ac63519541 377 timeouts_last_time = now;
Michael J. Spencer 1:f5ac63519541 378 diff -= tmptimeout->time;
Michael J. Spencer 1:f5ac63519541 379 next_timeout = tmptimeout->next;
Michael J. Spencer 1:f5ac63519541 380 handler = tmptimeout->h;
Michael J. Spencer 1:f5ac63519541 381 arg = tmptimeout->arg;
Michael J. Spencer 1:f5ac63519541 382 #if LWIP_DEBUG_TIMERNAMES
Michael J. Spencer 1:f5ac63519541 383 if (handler != NULL) {
Michael J. Spencer 1:f5ac63519541 384 LWIP_DEBUGF(TIMERS_DEBUG, ("sct calling h=%s arg=%p\n",
Michael J. Spencer 1:f5ac63519541 385 tmptimeout->handler_name, arg));
Michael J. Spencer 1:f5ac63519541 386 }
Michael J. Spencer 1:f5ac63519541 387 #endif /* LWIP_DEBUG_TIMERNAMES */
Michael J. Spencer 1:f5ac63519541 388 memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
Michael J. Spencer 1:f5ac63519541 389 if (handler != NULL) {
Michael J. Spencer 1:f5ac63519541 390 handler(arg);
Michael J. Spencer 1:f5ac63519541 391 }
Michael J. Spencer 1:f5ac63519541 392 }
Michael J. Spencer 1:f5ac63519541 393 /* repeat until all expired timers have been called */
Michael J. Spencer 1:f5ac63519541 394 }while(had_one);
Michael J. Spencer 1:f5ac63519541 395 }
Michael J. Spencer 1:f5ac63519541 396 }
Michael J. Spencer 1:f5ac63519541 397
Michael J. Spencer 1:f5ac63519541 398 /** Set back the timestamp of the last call to sys_check_timeouts()
Michael J. Spencer 1:f5ac63519541 399 * This is necessary if sys_check_timeouts() hasn't been called for a long
Michael J. Spencer 1:f5ac63519541 400 * time (e.g. while saving energy) to prevent all timer functions of that
Michael J. Spencer 1:f5ac63519541 401 * period being called.
Michael J. Spencer 1:f5ac63519541 402 */
Michael J. Spencer 1:f5ac63519541 403 void
Michael J. Spencer 1:f5ac63519541 404 sys_restart_timeouts(void)
Michael J. Spencer 1:f5ac63519541 405 {
Michael J. Spencer 1:f5ac63519541 406 timeouts_last_time = sys_now();
Michael J. Spencer 1:f5ac63519541 407 }
Michael J. Spencer 1:f5ac63519541 408
Michael J. Spencer 1:f5ac63519541 409 #else /* NO_SYS */
Michael J. Spencer 1:f5ac63519541 410
Michael J. Spencer 1:f5ac63519541 411 /**
Michael J. Spencer 1:f5ac63519541 412 * Wait (forever) for a message to arrive in an mbox.
Michael J. Spencer 1:f5ac63519541 413 * While waiting, timeouts are processed.
Michael J. Spencer 1:f5ac63519541 414 *
Michael J. Spencer 1:f5ac63519541 415 * @param mbox the mbox to fetch the message from
Michael J. Spencer 1:f5ac63519541 416 * @param msg the place to store the message
Michael J. Spencer 1:f5ac63519541 417 */
Michael J. Spencer 1:f5ac63519541 418 void
Michael J. Spencer 1:f5ac63519541 419 sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg)
Michael J. Spencer 1:f5ac63519541 420 {
Michael J. Spencer 1:f5ac63519541 421 u32_t time_needed;
Michael J. Spencer 1:f5ac63519541 422 struct sys_timeo *tmptimeout;
Michael J. Spencer 1:f5ac63519541 423 sys_timeout_handler handler;
Michael J. Spencer 1:f5ac63519541 424 void *arg;
Michael J. Spencer 1:f5ac63519541 425
Michael J. Spencer 1:f5ac63519541 426 again:
Michael J. Spencer 1:f5ac63519541 427 if (!next_timeout) {
Michael J. Spencer 1:f5ac63519541 428 time_needed = sys_arch_mbox_fetch(mbox, msg, 0);
Michael J. Spencer 1:f5ac63519541 429 } else {
Michael J. Spencer 1:f5ac63519541 430 if (next_timeout->time > 0) {
Michael J. Spencer 1:f5ac63519541 431 time_needed = sys_arch_mbox_fetch(mbox, msg, next_timeout->time);
Michael J. Spencer 1:f5ac63519541 432 } else {
Michael J. Spencer 1:f5ac63519541 433 time_needed = SYS_ARCH_TIMEOUT;
Michael J. Spencer 1:f5ac63519541 434 }
Michael J. Spencer 1:f5ac63519541 435
Michael J. Spencer 1:f5ac63519541 436 if (time_needed == SYS_ARCH_TIMEOUT) {
Michael J. Spencer 1:f5ac63519541 437 /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message
Michael J. Spencer 1:f5ac63519541 438 could be fetched. We should now call the timeout handler and
Michael J. Spencer 1:f5ac63519541 439 deallocate the memory allocated for the timeout. */
Michael J. Spencer 1:f5ac63519541 440 tmptimeout = next_timeout;
Michael J. Spencer 1:f5ac63519541 441 next_timeout = tmptimeout->next;
Michael J. Spencer 1:f5ac63519541 442 handler = tmptimeout->h;
Michael J. Spencer 1:f5ac63519541 443 arg = tmptimeout->arg;
Michael J. Spencer 1:f5ac63519541 444 #if LWIP_DEBUG_TIMERNAMES
Michael J. Spencer 1:f5ac63519541 445 if (handler != NULL) {
Michael J. Spencer 1:f5ac63519541 446 LWIP_DEBUGF(TIMERS_DEBUG, ("stmf calling h=%s arg=%p\n",
Michael J. Spencer 1:f5ac63519541 447 tmptimeout->handler_name, arg));
Michael J. Spencer 1:f5ac63519541 448 }
Michael J. Spencer 1:f5ac63519541 449 #endif /* LWIP_DEBUG_TIMERNAMES */
Michael J. Spencer 1:f5ac63519541 450 memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
Michael J. Spencer 1:f5ac63519541 451 if (handler != NULL) {
Michael J. Spencer 1:f5ac63519541 452 /* For LWIP_TCPIP_CORE_LOCKING, lock the core before calling the
Michael J. Spencer 1:f5ac63519541 453 timeout handler function. */
Michael J. Spencer 1:f5ac63519541 454 LOCK_TCPIP_CORE();
Michael J. Spencer 1:f5ac63519541 455 handler(arg);
Michael J. Spencer 1:f5ac63519541 456 UNLOCK_TCPIP_CORE();
Michael J. Spencer 1:f5ac63519541 457 }
Michael J. Spencer 1:f5ac63519541 458 LWIP_TCPIP_THREAD_ALIVE();
Michael J. Spencer 1:f5ac63519541 459
Michael J. Spencer 1:f5ac63519541 460 /* We try again to fetch a message from the mbox. */
Michael J. Spencer 1:f5ac63519541 461 goto again;
Michael J. Spencer 1:f5ac63519541 462 } else {
Michael J. Spencer 1:f5ac63519541 463 /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout
Michael J. Spencer 1:f5ac63519541 464 occured. The time variable is set to the number of
Michael J. Spencer 1:f5ac63519541 465 milliseconds we waited for the message. */
Michael J. Spencer 1:f5ac63519541 466 if (time_needed < next_timeout->time) {
Michael J. Spencer 1:f5ac63519541 467 next_timeout->time -= time_needed;
Michael J. Spencer 1:f5ac63519541 468 } else {
Michael J. Spencer 1:f5ac63519541 469 next_timeout->time = 0;
Michael J. Spencer 1:f5ac63519541 470 }
Michael J. Spencer 1:f5ac63519541 471 }
Michael J. Spencer 1:f5ac63519541 472 }
Michael J. Spencer 1:f5ac63519541 473 }
Michael J. Spencer 1:f5ac63519541 474
Michael J. Spencer 1:f5ac63519541 475 #endif /* NO_SYS */
Michael J. Spencer 1:f5ac63519541 476
Michael J. Spencer 1:f5ac63519541 477 #else /* LWIP_TIMERS */
Michael J. Spencer 1:f5ac63519541 478 /* Satisfy the TCP code which calls this function */
Michael J. Spencer 1:f5ac63519541 479 void
Michael J. Spencer 1:f5ac63519541 480 tcp_timer_needed(void)
Michael J. Spencer 1:f5ac63519541 481 {
Michael J. Spencer 1:f5ac63519541 482 }
Michael J. Spencer 1:f5ac63519541 483 #endif /* LWIP_TIMERS */