Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
lwipmgr.cpp
00001 ////////////////////////////////////////////////////////////////////////////// 00002 // Product: lwIP-Manager Active Object 00003 // Last Updated for Version: 4.1.06 00004 // Date of the Last Update: Feb 21, 2011 00005 // 00006 // Q u a n t u m L e a P s 00007 // --------------------------- 00008 // innovating embedded systems 00009 // 00010 // Copyright (C) 2002-2011 Quantum Leaps, LLC. All rights reserved. 00011 // 00012 // This software may be distributed and modified under the terms of the GNU 00013 // General Public License version 2 (GPL) as published by the Free Software 00014 // Foundation and appearing in the file GPL.TXT included in the packaging of 00015 // this file. Please note that GPL Section 2[b] requires that all works based 00016 // on this software must also be made publicly available under the terms of 00017 // the GPL ("Copyleft"). 00018 // 00019 // Alternatively, this software may be distributed and modified under the 00020 // terms of Quantum Leaps commercial licenses, which expressly supersede 00021 // the GPL and are specifically designed for licensees interested in 00022 // retaining the proprietary status of their code. 00023 // 00024 // Contact information: 00025 // Quantum Leaps Web site: http://www.quantum-leaps.com 00026 // e-mail: info@quantum-leaps.com 00027 ////////////////////////////////////////////////////////////////////////////// 00028 #include "qp_port.h" // QP-port 00029 #include "dpp.h" // application events and active objects 00030 #include "bsp.h" // Board Support Package 00031 00032 #include "lwip/opt.h" // lwIP options come first 00033 #include "lwip/stats.h" 00034 #include "lwip/tcp.h" 00035 #include "lwip/tcp_impl.h" 00036 #include "lwip/udp.h" 00037 #include "lwip/tcpip.h" 00038 #include "lwip/mem.h" 00039 #include "lwip/autoip.h" 00040 #include "lwip/dhcp.h" 00041 00042 #include "netif/etharp.h" 00043 #include "port/eth_driver.h" 00044 // utilities added by QL... 00045 #include "app/httpd.h" // application layer protocols 00046 00047 #include <string.h> 00048 #include <stdio.h> 00049 00050 Q_DEFINE_THIS_FILE 00051 00052 // application signals cannot overlap the device-driver signals 00053 Q_ASSERT_COMPILE(MAX_SIG < DEV_DRIVER_SIG); 00054 00055 #define LWIP_SLOW_TICK_MS TCP_TMR_INTERVAL 00056 00057 // Active object class ------------------------------------------------------- 00058 class LwIPMgr : public QActive { 00059 00060 QTimeEvt m_te_LWIP_SLOW_TICK; 00061 struct netif *m_netif; 00062 struct udp_pcb *m_upcb; 00063 uint32_t m_ip_addr; // IP address in the native host byte order 00064 00065 #if LWIP_TCP 00066 uint32_t m_tcp_tmr; 00067 #endif 00068 #if LWIP_ARP 00069 uint32_t m_arp_tmr; 00070 #endif 00071 #if LWIP_DHCP 00072 uint32_t m_dhcp_fine_tmr; 00073 uint32_t m_dhcp_coarse_tmr; 00074 #endif 00075 #if LWIP_AUTOIP 00076 uint32_t m_auto_ip_tmr; 00077 #endif 00078 00079 public: 00080 LwIPMgr(); // ctor 00081 00082 private: 00083 static QState initial(LwIPMgr *me, QEvent const *e); 00084 static QState running(LwIPMgr *me, QEvent const *e); 00085 }; 00086 00087 00088 // Local objects ------------------------------------------------------------- 00089 static LwIPMgr l_lwIPMgr; // the single instance of LwIPMgr AO 00090 00091 // Global-scope objects ------------------------------------------------------ 00092 QActive * const AO_LwIPMgr = (QActive *)&l_lwIPMgr; // "opaque" pointer 00093 00094 // Server-Side Include (SSI) demo ............................................ 00095 static char const * const ssi_tags[] = { 00096 "s_xmit", 00097 "s_recv", 00098 "s_fw", 00099 "s_drop", 00100 "s_chkerr", 00101 "s_lenerr", 00102 "s_memerr", 00103 "s_rterr", 00104 "s_proerr", 00105 "s_opterr", 00106 "s_err", 00107 }; 00108 static int ssi_handler(int iIndex, char *pcInsert, int iInsertLen); 00109 00110 // Common Gateway Iinterface (CG) demo ....................................... 00111 static char const *cgi_display(int index, int numParams, 00112 char const *param[], 00113 char const *value[]); 00114 static tCGI const cgi_handlers[] = { 00115 { "/display.cgi", &cgi_display }, 00116 }; 00117 00118 // UDP handler ............................................................... 00119 static void udp_rx_handler(void *arg, struct udp_pcb *upcb, 00120 struct pbuf *p, struct ip_addr *addr, u16_t port); 00121 //............................................................................ 00122 LwIPMgr::LwIPMgr() 00123 : QActive((QStateHandler)&LwIPMgr::initial), 00124 m_te_LWIP_SLOW_TICK(LWIP_SLOW_TICK_SIG) 00125 {} 00126 //............................................................................ 00127 QState LwIPMgr::initial(LwIPMgr *me, QEvent const * /*e*/) { 00128 // initialize the Ethernet Driver 00129 me->m_netif = eth_driver_init((QActive *)me, 0); 00130 00131 me->m_ip_addr = 0xFFFFFFFF; // initialize to impossible value 00132 00133 // initialize the lwIP applications... 00134 httpd_init(); // initialize the simple HTTP-Deamon (web server) 00135 http_set_ssi_handler(&ssi_handler, ssi_tags, Q_DIM(ssi_tags)); 00136 http_set_cgi_handlers(cgi_handlers, Q_DIM(cgi_handlers)); 00137 00138 me->m_upcb = udp_new(); 00139 udp_bind(me->m_upcb, IP_ADDR_ANY, 777); // use port 777 for UDP 00140 udp_recv(me->m_upcb, &udp_rx_handler, me); 00141 00142 QS_OBJ_DICTIONARY(&l_lwIPMgr); 00143 QS_OBJ_DICTIONARY(&l_lwIPMgr.m_te_LWIP_SLOW_TICK); 00144 QS_FUN_DICTIONARY(&QHsm::top); 00145 QS_FUN_DICTIONARY(&LwIPMgr::initial); 00146 QS_FUN_DICTIONARY(&LwIPMgr::running); 00147 00148 QS_SIG_DICTIONARY(SEND_UDP_SIG, me); 00149 QS_SIG_DICTIONARY(LWIP_SLOW_TICK_SIG, me); 00150 QS_SIG_DICTIONARY(LWIP_RX_READY_SIG, me); 00151 QS_SIG_DICTIONARY(LWIP_TX_READY_SIG, me); 00152 QS_SIG_DICTIONARY(LWIP_RX_OVERRUN_SIG, me); 00153 00154 return Q_TRAN(&LwIPMgr::running); 00155 } 00156 //............................................................................ 00157 QState LwIPMgr::running(LwIPMgr *me, QEvent const *e) { 00158 switch (e->sig) { 00159 case Q_ENTRY_SIG: { 00160 me->m_te_LWIP_SLOW_TICK.postEvery((QActive *)me, 00161 (LWIP_SLOW_TICK_MS * BSP_TICKS_PER_SEC) / 1000); 00162 return Q_HANDLED(); 00163 } 00164 case Q_EXIT_SIG: { 00165 me->m_te_LWIP_SLOW_TICK.disarm(); 00166 return Q_HANDLED(); 00167 } 00168 00169 case SEND_UDP_SIG: { 00170 if (me->m_upcb->remote_port != (uint16_t)0) { 00171 struct pbuf *p = pbuf_new((u8_t *)((TextEvt const *)e)->text, 00172 strlen(((TextEvt const *)e)->text) + 1); 00173 if (p != (struct pbuf *)0) { 00174 udp_send(me->m_upcb, p); 00175 pbuf_free(p); // don't leak the pbuf! 00176 00177 QS_BEGIN(LWIP_SEND_UDP, me) // app-specific record begin 00178 QS_STR(((TextEvt const *)e)->text); 00179 QS_END() 00180 } 00181 } 00182 return Q_HANDLED(); 00183 } 00184 00185 case LWIP_RX_READY_SIG: { 00186 eth_driver_read(); 00187 return Q_HANDLED(); 00188 } 00189 case LWIP_TX_READY_SIG: { 00190 eth_driver_write(); 00191 return Q_HANDLED(); 00192 } 00193 case LWIP_SLOW_TICK_SIG: { 00194 QS_BEGIN(LWIP_SLOW_TICK, me) // app-specific record begin 00195 QS_END() 00196 00197 if (me->m_ip_addr != me->m_netif->ip_addr.addr) { 00198 me->m_ip_addr = me->m_netif->ip_addr.addr; // save the IP addr 00199 uint32_t ip_net = ntohl(me->m_ip_addr);// IP in network order 00200 // publish the text event to display the new IP address 00201 QS_BEGIN(LWIP_IPADDR, me) // app-specific record begin 00202 QS_U8(3, (uint8_t)(ip_net >> 24)); 00203 QS_U8(3, (uint8_t)(ip_net >> 16)); 00204 QS_U8(3, (uint8_t)(ip_net >> 8)); 00205 QS_U8(3, (uint8_t)ip_net); 00206 QS_END() 00207 } 00208 00209 #if LWIP_TCP 00210 me->m_tcp_tmr += LWIP_SLOW_TICK_MS; 00211 if (me->m_tcp_tmr >= TCP_TMR_INTERVAL) { 00212 me->m_tcp_tmr = 0; 00213 tcp_tmr(); 00214 } 00215 #endif 00216 #if LWIP_ARP 00217 me->m_arp_tmr += LWIP_SLOW_TICK_MS; 00218 if (me->m_arp_tmr >= ARP_TMR_INTERVAL) { 00219 me->m_arp_tmr = 0; 00220 etharp_tmr(); 00221 } 00222 #endif 00223 #if LWIP_DHCP 00224 me->m_dhcp_fine_tmr += LWIP_SLOW_TICK_MS; 00225 if (me->m_dhcp_fine_tmr >= DHCP_FINE_TIMER_MSECS) { 00226 me->m_dhcp_fine_tmr = 0; 00227 dhcp_fine_tmr(); 00228 } 00229 me->m_dhcp_coarse_tmr += LWIP_SLOW_TICK_MS; 00230 if (me->m_dhcp_coarse_tmr >= DHCP_COARSE_TIMER_MSECS) { 00231 me->m_dhcp_coarse_tmr = 0; 00232 dhcp_coarse_tmr(); 00233 } 00234 #endif 00235 #if LWIP_AUTOIP 00236 me->auto_ip_tmr += LWIP_SLOW_TICK_MS; 00237 if (me->auto_ip_tmr >= AUTOIP_TMR_INTERVAL) { 00238 me->auto_ip_tmr = 0; 00239 autoip_tmr(); 00240 } 00241 #endif 00242 return Q_HANDLED(); 00243 } 00244 case LWIP_RX_OVERRUN_SIG: { 00245 LINK_STATS_INC(link.err); 00246 return Q_HANDLED(); 00247 } 00248 } 00249 return Q_SUPER(&QHsm::top); 00250 } 00251 00252 // HTTPD customizations ------------------------------------------------------ 00253 00254 // Server-Side Include (SSI) handler ......................................... 00255 static int ssi_handler(int iIndex, char *pcInsert, int iInsertLen) { 00256 struct stats_proto *stats = &lwip_stats.link; 00257 STAT_COUNTER value; 00258 00259 switch (iIndex) { 00260 case 0: // s_xmit 00261 value = stats->xmit; 00262 break; 00263 case 1: // s_recv 00264 value = stats->recv; 00265 break; 00266 case 2: // s_fw 00267 value = stats->fw; 00268 break; 00269 case 3: // s_drop 00270 value = stats->drop; 00271 break; 00272 case 4: // s_chkerr 00273 value = stats->chkerr; 00274 break; 00275 case 5: // s_lenerr 00276 value = stats->lenerr; 00277 break; 00278 case 6: // s_memerr 00279 value = stats->memerr; 00280 break; 00281 case 7: // s_rterr 00282 value = stats->rterr; 00283 break; 00284 case 8: // s_proerr 00285 value = stats->proterr; 00286 break; 00287 case 9: // s_opterr 00288 value = stats->opterr; 00289 break; 00290 case 10: // s_err 00291 value = stats->err; 00292 break; 00293 } 00294 00295 return snprintf(pcInsert, MAX_TAG_INSERT_LEN, "%d", value); 00296 } 00297 00298 // Common Gateway Iinterface (CG) handler .................................... 00299 static char const *cgi_display(int index, int numParams, 00300 char const *param[], 00301 char const *value[]) 00302 { 00303 for (int i = 0; i < numParams; ++i) { 00304 if (strstr(param[i], "text") != (char *)0) { // param text found? 00305 00306 00307 TextEvt *te = Q_NEW(TextEvt, DISPLAY_CGI_SIG); 00308 strncpy(te->text, value[i], Q_DIM(te->text)); 00309 QF::publish((QEvent *)te); 00310 return "/thank_you.htm"; 00311 } 00312 } 00313 return (char *)0; // no URI, HTTPD will send 404 error page to the browser 00314 } 00315 00316 // UDP receive handler ------------------------------------------------------- 00317 static void udp_rx_handler(void *arg, struct udp_pcb *upcb, 00318 struct pbuf *p, struct ip_addr *addr, u16_t port) 00319 { 00320 TextEvt *te = Q_NEW(TextEvt, DISPLAY_UDP_SIG); 00321 strncpy(te->text, (char *)p->payload, Q_DIM(te->text)); 00322 QF::publish(te); 00323 00324 udp_connect(upcb, addr, port); // connect to the remote host 00325 pbuf_free(p); // don't leak the pbuf! 00326 }
Generated on Tue Jul 19 2022 02:04:04 by
1.7.2