Contiki 2.5
dhcp-client.c
1 /*
2  * Copyright (c) 2002, Adam Dunkels.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following
12  * disclaimer in the documentation and/or other materials provided
13  * with the distribution.
14  * 3. The name of the author may not be used to endorse or promote
15  * products derived from this software without specific prior
16  * written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
24  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * This file is part of the Contiki desktop environment
31  *
32  * $Id: dhcp-client.c,v 1.5 2010/10/31 22:51:17 oliverschmidt Exp $
33  *
34  */
35 
36 #include "contiki-net.h"
37 #include "ctk/ctk.h"
38 #include "cfs/cfs.h"
39 #include "net/dhcpc.h"
40 
41 static struct ctk_window window;
42 
43 static struct ctk_button requestbutton =
44  {CTK_BUTTON(4, 1, 18, "Request IP address")};
45 static struct ctk_label statuslabel =
46  {CTK_LABEL(0, 3, 14, 1, "")};
47 static struct ctk_label ipaddrlabel =
48  {CTK_LABEL(0, 5, 10, 1, "IP address")};
49 static char ipaddr[16];
50 static struct ctk_textentry ipaddrtextentry =
51  {CTK_TEXTENTRY(11, 5, 15, 1, ipaddr, 15)};
52 static struct ctk_label netmasklabel =
53  {CTK_LABEL(0, 7, 10, 1, "Netmask")};
54 static char netmask[16];
55 static struct ctk_textentry netmasktextentry =
56  {CTK_TEXTENTRY(11, 7, 15, 1, netmask, 15)};
57 static struct ctk_label gatewaylabel =
58  {CTK_LABEL(0, 9, 10, 1, "Gateway")};
59 static char gateway[16];
60 static struct ctk_textentry gatewaytextentry =
61  {CTK_TEXTENTRY(11, 9, 15, 1, gateway, 15)};
62 #if WITH_DNS
63 static struct ctk_label dnsserverlabel =
64  {CTK_LABEL(0, 11, 10, 1, "DNS server")};
65 static char dnsserver[16];
66 static struct ctk_textentry dnsservertextentry =
67  {CTK_TEXTENTRY(11, 11, 15, 1, dnsserver, 15)};
68 #endif /* WITH_DNS */
69 static struct ctk_button savebutton =
70  {CTK_BUTTON(0, 13, 12, "Save & close")};
71 static struct ctk_button cancelbutton =
72  {CTK_BUTTON(20, 13, 6, "Cancel")};
73 
74 PROCESS(dhcp_process, "DHCP client");
75 
76 AUTOSTART_PROCESSES(&dhcp_process);
77 
78 /*-----------------------------------------------------------------------------------*/
79 static char *
80 makebyte(u8_t byte, char *str)
81 {
82  if(byte >= 100) {
83  *str++ = (byte / 100 ) % 10 + '0';
84  }
85  if(byte >= 10) {
86  *str++ = (byte / 10) % 10 + '0';
87  }
88  *str++ = (byte % 10) + '0';
89 
90  return str;
91 }
92 /*-----------------------------------------------------------------------------------*/
93 static void
94 makeaddr(uip_ipaddr_t *addr, char *str)
95 {
96  str = makebyte(addr->u8[0], str);
97  *str++ = '.';
98  str = makebyte(addr->u8[1], str);
99  *str++ = '.';
100  str = makebyte(addr->u8[2], str);
101  *str++ = '.';
102  str = makebyte(addr->u8[3], str);
103  *str++ = 0;
104 }
105 /*-----------------------------------------------------------------------------------*/
106 static void
107 makestrings(void)
108 {
109  uip_ipaddr_t addr, *addrptr;
110 
111  uip_gethostaddr(&addr);
112  makeaddr(&addr, ipaddr);
113 
114  uip_getnetmask(&addr);
115  makeaddr(&addr, netmask);
116 
117  uip_getdraddr(&addr);
118  makeaddr(&addr, gateway);
119 
120 #if WITH_DNS
121  addrptr = resolv_getserver();
122  if(addrptr != NULL) {
123  makeaddr(addrptr, dnsserver);
124  }
125 #endif /* WITH_DNS */
126 }
127 /*-----------------------------------------------------------------------------------*/
128 static void
129 nullterminate(char *cptr)
130 {
131  /* Find the first space character in the ipaddr and put a zero there
132  to end the string. */
133  for(; *cptr != ' ' && *cptr != 0; ++cptr);
134  *cptr = 0;
135 }
136 /*-----------------------------------------------------------------------------------*/
137 static void
138 apply_tcpipconfig(void)
139 {
140  int file = cfs_open("contiki.cfg", CFS_READ);
141  int size = cfs_read(file, uip_buf, 100);
142  cfs_close(file);
143 
144  nullterminate(ipaddr);
145  uiplib_ipaddrconv(ipaddr, (uip_ipaddr_t *)&uip_buf[0]);
146 
147  nullterminate(netmask);
148  uiplib_ipaddrconv(netmask, (uip_ipaddr_t *)&uip_buf[4]);
149 
150  nullterminate(gateway);
151  uiplib_ipaddrconv(gateway, (uip_ipaddr_t *)&uip_buf[8]);
152 
153 #if WITH_DNS
154  nullterminate(dnsserver);
155  uiplib_ipaddrconv(dnsserver, (uip_ipaddr_t *)&uip_buf[12]);
156 #endif /* WITH_DNS */
157 
158  file = cfs_open("contiki.cfg", CFS_WRITE);
159  cfs_write(file, uip_buf, size);
160  cfs_close(file);
161 }
162 /*-----------------------------------------------------------------------------------*/
163 static void
164 set_statustext(char *text)
165 {
166  ctk_label_set_text(&statuslabel, text);
167  CTK_WIDGET_REDRAW(&statuslabel);
168 }
169 /*-----------------------------------------------------------------------------------*/
170 static void
171 app_quit(void)
172 {
173  ctk_window_close(&window);
174  process_exit(&dhcp_process);
175  LOADER_UNLOAD();
176 }
177 /*-----------------------------------------------------------------------------------*/
178 PROCESS_THREAD(dhcp_process, ev, data)
179 {
180  PROCESS_BEGIN();
181 
182  ctk_window_new(&window, 29, 14, "DHCP client");
183 
184  CTK_WIDGET_ADD(&window, &requestbutton);
185  CTK_WIDGET_ADD(&window, &statuslabel);
186  CTK_WIDGET_ADD(&window, &ipaddrlabel);
187  CTK_WIDGET_ADD(&window, &ipaddrtextentry);
188  CTK_WIDGET_ADD(&window, &netmasklabel);
189  CTK_WIDGET_ADD(&window, &netmasktextentry);
190  CTK_WIDGET_ADD(&window, &gatewaylabel);
191  CTK_WIDGET_ADD(&window, &gatewaytextentry);
192 #if WITH_DNS
193  CTK_WIDGET_ADD(&window, &dnsserverlabel);
194  CTK_WIDGET_ADD(&window, &dnsservertextentry);
195 #endif /* WITH_DNS */
196  CTK_WIDGET_ADD(&window, &savebutton);
197  CTK_WIDGET_ADD(&window, &cancelbutton);
198 
199  CTK_WIDGET_FOCUS(&window, &requestbutton);
200 
201  ctk_window_open(&window);
202 
203  /* Allow resolver to set DNS server address. */
204  process_post(PROCESS_CURRENT(), PROCESS_EVENT_MSG, NULL);
205 
206  dhcpc_init(uip_ethaddr.addr, sizeof(uip_ethaddr.addr));
207 
208  while(1) {
210 
211  if(ev == PROCESS_EVENT_MSG) {
212  makestrings();
213  ctk_window_redraw(&window);
214  } else if(ev == tcpip_event) {
215  dhcpc_appcall(ev, data);
216  } else if(ev == ctk_signal_button_activate) {
217  if(data == (process_data_t)&requestbutton) {
218  dhcpc_request();
219  set_statustext("Requesting...");
220  }
221  if(data == (process_data_t)&savebutton) {
222  apply_tcpipconfig();
223  app_quit();
224  }
225  if(data == (process_data_t)&cancelbutton) {
226  app_quit();
227  }
228  } else if(
229 #if CTK_CONF_WINDOWCLOSE
230  ev == ctk_signal_window_close ||
231 #endif
232  ev == PROCESS_EVENT_EXIT) {
233  app_quit();
234  }
235  }
236 
237  PROCESS_END();
238 }
239 /*-----------------------------------------------------------------------------------*/
240 void
241 dhcpc_configured(const struct dhcpc_state *s)
242 {
243  uip_sethostaddr(&s->ipaddr);
244  uip_setnetmask(&s->netmask);
245  uip_setdraddr(&s->default_router);
246 #if WITH_DNS
247  resolv_conf(&s->dnsaddr);
248 #endif /* WITH_DNS */
249 
250  set_statustext("Configured.");
251  process_post(PROCESS_CURRENT(), PROCESS_EVENT_MSG, NULL);
252 }
253 /*-----------------------------------------------------------------------------------*/
254 void
255 dhcpc_unconfigured(const struct dhcpc_state *s)
256 {
257  static uip_ipaddr_t nulladdr;
258 
259  uip_sethostaddr(&nulladdr);
260  uip_setnetmask(&nulladdr);
261  uip_setdraddr(&nulladdr);
262 #if WITH_DNS
263  resolv_conf(&nulladdr);
264 #endif /* WITH_DNS */
265 
266  set_statustext("Unconfigured.");
267  process_post(PROCESS_CURRENT(), PROCESS_EVENT_MSG, NULL);
268 }
269 /*-----------------------------------------------------------------------------------*/