Used in Live Traffic Update Nokia LCD Display Project

Fork of NetServices by Segundo Equipo

Committer:
rrajan8
Date:
Wed Mar 06 19:07:23 2013 +0000
Revision:
8:92b57208ab99
Parent:
3:5a6792c147c0
This project utilizes mbed's networking features to display live traffic updates on the Nokia LCD using the MapQuest API's Traffic Web Service.

Who changed what in which revision?

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