HTTPClient using static IP

Dependencies:   mbed

Committer:
mr_q
Date:
Mon May 30 11:53:37 2011 +0000
Revision:
0:d8f2f7d5f31b
v0.01 Draft

Who changed what in which revision?

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