Contiki 2.6

dhcp-client.c

00001 /*
00002  * Copyright (c) 2002, Adam Dunkels.
00003  * All rights reserved. 
00004  *
00005  * Redistribution and use in source and binary forms, with or without 
00006  * modification, are permitted provided that the following conditions 
00007  * are met: 
00008  * 1. Redistributions of source code must retain the above copyright 
00009  *    notice, this list of conditions and the following disclaimer. 
00010  * 2. Redistributions in binary form must reproduce the above
00011  *    copyright notice, this list of conditions and the following
00012  *    disclaimer in the documentation and/or other materials provided
00013  *    with the distribution. 
00014  * 3. The name of the author may not be used to endorse or promote
00015  *    products derived from this software without specific prior
00016  *    written permission.  
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
00019  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00020  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
00022  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00023  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00024  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00026  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00027  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
00029  *
00030  * This file is part of the Contiki desktop environment
00031  *
00032  * $Id: dhcp-client.c,v 1.5 2010/10/31 22:51:17 oliverschmidt Exp $
00033  *
00034  */
00035 
00036 #include "contiki-net.h"
00037 #include "ctk/ctk.h"
00038 #include "cfs/cfs.h"
00039 #include "net/dhcpc.h"
00040 
00041 static struct ctk_window window;
00042 
00043 static struct ctk_button requestbutton =
00044   {CTK_BUTTON(4, 1, 18, "Request IP address")};
00045 static struct ctk_label statuslabel =
00046   {CTK_LABEL(0, 3, 14, 1, "")};
00047 static struct ctk_label ipaddrlabel =
00048   {CTK_LABEL(0, 5, 10, 1, "IP address")};
00049 static char ipaddr[16];
00050 static struct ctk_textentry ipaddrtextentry =
00051   {CTK_TEXTENTRY(11, 5, 15, 1, ipaddr, 15)};
00052 static struct ctk_label netmasklabel =
00053   {CTK_LABEL(0, 7, 10, 1, "Netmask")};
00054 static char netmask[16];
00055 static struct ctk_textentry netmasktextentry =
00056   {CTK_TEXTENTRY(11, 7, 15, 1, netmask, 15)};
00057 static struct ctk_label gatewaylabel =
00058   {CTK_LABEL(0, 9, 10, 1, "Gateway")};
00059 static char gateway[16];
00060 static struct ctk_textentry gatewaytextentry =
00061   {CTK_TEXTENTRY(11, 9, 15, 1, gateway, 15)};
00062 #if WITH_DNS
00063 static struct ctk_label dnsserverlabel =
00064   {CTK_LABEL(0, 11, 10, 1, "DNS server")};
00065 static char dnsserver[16];
00066 static struct ctk_textentry dnsservertextentry =
00067   {CTK_TEXTENTRY(11, 11, 15, 1, dnsserver, 15)};
00068 #endif /* WITH_DNS */
00069 static struct ctk_button savebutton =
00070   {CTK_BUTTON(0, 13, 12, "Save & close")};
00071 static struct ctk_button cancelbutton =
00072   {CTK_BUTTON(20, 13, 6, "Cancel")};
00073 
00074 PROCESS(dhcp_process, "DHCP client");
00075 
00076 AUTOSTART_PROCESSES(&dhcp_process);
00077 
00078 /*-----------------------------------------------------------------------------------*/
00079 static char *
00080 makebyte(uint8_t byte, char *str)
00081 {
00082   if(byte >= 100) {
00083     *str++ = (byte / 100 ) % 10 + '0';
00084   }
00085   if(byte >= 10) {
00086     *str++ = (byte / 10) % 10 + '0';
00087   }
00088   *str++ = (byte % 10) + '0';
00089 
00090   return str;
00091 }
00092 /*-----------------------------------------------------------------------------------*/
00093 static void
00094 makeaddr(uip_ipaddr_t *addr, char *str)
00095 {
00096   str = makebyte(addr->u8[0], str);
00097   *str++ = '.';
00098   str = makebyte(addr->u8[1], str);
00099   *str++ = '.';
00100   str = makebyte(addr->u8[2], str);
00101   *str++ = '.';
00102   str = makebyte(addr->u8[3], str);
00103   *str++ = 0;
00104 }
00105 /*-----------------------------------------------------------------------------------*/
00106 static void
00107 makestrings(void)
00108 {
00109   uip_ipaddr_t addr, *addrptr;
00110 
00111   uip_gethostaddr(&addr);
00112   makeaddr(&addr, ipaddr);
00113   
00114   uip_getnetmask(&addr);
00115   makeaddr(&addr, netmask);
00116   
00117   uip_getdraddr(&addr);
00118   makeaddr(&addr, gateway);
00119 
00120 #if WITH_DNS
00121   addrptr = resolv_getserver();
00122   if(addrptr != NULL) {
00123     makeaddr(addrptr, dnsserver);
00124   }
00125 #endif /* WITH_DNS */
00126 }
00127 /*-----------------------------------------------------------------------------------*/
00128 static void
00129 nullterminate(char *cptr)
00130 {
00131   /* Find the first space character in the ipaddr and put a zero there
00132      to end the string. */
00133   for(; *cptr != ' ' && *cptr != 0; ++cptr);
00134   *cptr = 0;
00135 }
00136 /*-----------------------------------------------------------------------------------*/
00137 static void
00138 apply_tcpipconfig(void)
00139 {
00140   int file = cfs_open("contiki.cfg", CFS_READ);
00141   int size = cfs_read(file, uip_buf, 100);
00142   cfs_close(file);
00143 
00144   nullterminate(ipaddr);
00145   uiplib_ipaddrconv(ipaddr, (uip_ipaddr_t *)&uip_buf[0]);
00146 
00147   nullterminate(netmask);
00148   uiplib_ipaddrconv(netmask, (uip_ipaddr_t *)&uip_buf[4]);
00149 
00150   nullterminate(gateway);
00151   uiplib_ipaddrconv(gateway, (uip_ipaddr_t *)&uip_buf[8]);
00152   
00153 #if WITH_DNS
00154   nullterminate(dnsserver);
00155   uiplib_ipaddrconv(dnsserver, (uip_ipaddr_t *)&uip_buf[12]);
00156 #endif /* WITH_DNS */
00157 
00158   file = cfs_open("contiki.cfg", CFS_WRITE);
00159   cfs_write(file, uip_buf, size);
00160   cfs_close(file);
00161 }
00162 /*-----------------------------------------------------------------------------------*/
00163 static void
00164 set_statustext(char *text)
00165 {
00166   ctk_label_set_text(&statuslabel, text);
00167   CTK_WIDGET_REDRAW(&statuslabel);
00168 }
00169 /*-----------------------------------------------------------------------------------*/
00170 static void
00171 app_quit(void)
00172 {
00173   ctk_window_close(&window);
00174   process_exit(&dhcp_process);
00175   LOADER_UNLOAD();
00176 }
00177 /*-----------------------------------------------------------------------------------*/
00178 PROCESS_THREAD(dhcp_process, ev, data)
00179 {
00180   PROCESS_BEGIN();
00181   
00182   ctk_window_new(&window, 29, 14, "DHCP client");
00183   
00184   CTK_WIDGET_ADD(&window, &requestbutton);
00185   CTK_WIDGET_ADD(&window, &statuslabel);  
00186   CTK_WIDGET_ADD(&window, &ipaddrlabel);  
00187   CTK_WIDGET_ADD(&window, &ipaddrtextentry);
00188   CTK_WIDGET_ADD(&window, &netmasklabel);
00189   CTK_WIDGET_ADD(&window, &netmasktextentry);
00190   CTK_WIDGET_ADD(&window, &gatewaylabel);
00191   CTK_WIDGET_ADD(&window, &gatewaytextentry);
00192 #if WITH_DNS
00193   CTK_WIDGET_ADD(&window, &dnsserverlabel);
00194   CTK_WIDGET_ADD(&window, &dnsservertextentry);  
00195 #endif /* WITH_DNS */
00196   CTK_WIDGET_ADD(&window, &savebutton);
00197   CTK_WIDGET_ADD(&window, &cancelbutton);
00198 
00199   CTK_WIDGET_FOCUS(&window, &requestbutton);  
00200 
00201   ctk_window_open(&window);
00202 
00203   /* Allow resolver to set DNS server address. */
00204   process_post(PROCESS_CURRENT(), PROCESS_EVENT_MSG, NULL);
00205 
00206   dhcpc_init(uip_ethaddr.addr, sizeof(uip_ethaddr.addr));
00207 
00208   while(1) {
00209     PROCESS_WAIT_EVENT();
00210     
00211     if(ev == PROCESS_EVENT_MSG) {
00212       makestrings();
00213       ctk_window_redraw(&window);
00214     } else if(ev == tcpip_event) {
00215       dhcpc_appcall(ev, data);
00216     } else if(ev == ctk_signal_button_activate) {   
00217       if(data == (process_data_t)&requestbutton) {
00218         dhcpc_request();
00219         set_statustext("Requesting...");
00220       }
00221       if(data == (process_data_t)&savebutton) {
00222         apply_tcpipconfig();
00223         app_quit();
00224       }
00225       if(data == (process_data_t)&cancelbutton) {
00226         app_quit();
00227       }
00228     } else if(
00229 #if CTK_CONF_WINDOWCLOSE
00230               ev == ctk_signal_window_close ||
00231 #endif
00232               ev == PROCESS_EVENT_EXIT) {
00233       app_quit();
00234     }
00235   }
00236 
00237   PROCESS_END();
00238 }
00239 /*-----------------------------------------------------------------------------------*/
00240 void
00241 dhcpc_configured(const struct dhcpc_state *s)
00242 {
00243   uip_sethostaddr(&s->ipaddr);
00244   uip_setnetmask(&s->netmask);
00245   uip_setdraddr(&s->default_router);
00246 #if WITH_DNS
00247   resolv_conf(&s->dnsaddr);
00248 #endif /* WITH_DNS */
00249 
00250   set_statustext("Configured.");
00251   process_post(PROCESS_CURRENT(), PROCESS_EVENT_MSG, NULL);
00252 }
00253 /*-----------------------------------------------------------------------------------*/
00254 void
00255 dhcpc_unconfigured(const struct dhcpc_state *s)
00256 {
00257   static uip_ipaddr_t nulladdr;
00258 
00259   uip_sethostaddr(&nulladdr);
00260   uip_setnetmask(&nulladdr);
00261   uip_setdraddr(&nulladdr);
00262 #if WITH_DNS
00263   resolv_conf(&nulladdr);
00264 #endif /* WITH_DNS */
00265 
00266   set_statustext("Unconfigured.");
00267   process_post(PROCESS_CURRENT(), PROCESS_EVENT_MSG, NULL);
00268 }
00269 /*-----------------------------------------------------------------------------------*/