Contiki 3.x
ipconfig.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  *
33  */
34 
35 #include "contiki-net.h"
36 #include "ctk/ctk.h"
37 #include "cfs/cfs.h"
38 #include "net/ip/dhcpc.h"
39 
40 static struct ctk_window window;
41 
42 static struct ctk_button requestbutton =
43  {CTK_BUTTON(4, 1, 18, "Request IP address")};
44 static struct ctk_label statuslabel =
45  {CTK_LABEL(0, 3, 14, 1, "")};
46 static struct ctk_label ipaddrlabel =
47  {CTK_LABEL(0, 5, 10, 1, "IP address")};
48 static char ipaddr[16];
49 static struct ctk_textentry ipaddrtextentry =
50  {CTK_TEXTENTRY(11, 5, 15, 1, ipaddr, 15)};
51 static struct ctk_label netmasklabel =
52  {CTK_LABEL(0, 7, 10, 1, "Netmask")};
53 static char netmask[16];
54 static struct ctk_textentry netmasktextentry =
55  {CTK_TEXTENTRY(11, 7, 15, 1, netmask, 15)};
56 static struct ctk_label gatewaylabel =
57  {CTK_LABEL(0, 9, 10, 1, "Gateway")};
58 static char gateway[16];
59 static struct ctk_textentry gatewaytextentry =
60  {CTK_TEXTENTRY(11, 9, 15, 1, gateway, 15)};
61 #if WITH_DNS
62 static struct ctk_label dnsserverlabel =
63  {CTK_LABEL(0, 11, 10, 1, "DNS server")};
64 static char dnsserver[16];
65 static struct ctk_textentry dnsservertextentry =
66  {CTK_TEXTENTRY(11, 11, 15, 1, dnsserver, 15)};
67 #endif /* WITH_DNS */
68 static struct ctk_button savebutton =
69  {CTK_BUTTON(0, 13, 12, "Save & close")};
70 static struct ctk_button cancelbutton =
71  {CTK_BUTTON(20, 13, 6, "Cancel")};
72 
73 PROCESS(ipconfig_process, "IP config");
74 
75 AUTOSTART_PROCESSES(&ipconfig_process);
76 
77 /*-----------------------------------------------------------------------------------*/
78 static char *
79 makebyte(uint8_t byte, char *str)
80 {
81  if(byte >= 100) {
82  *str++ = (byte / 100 ) % 10 + '0';
83  }
84  if(byte >= 10) {
85  *str++ = (byte / 10) % 10 + '0';
86  }
87  *str++ = (byte % 10) + '0';
88 
89  return str;
90 }
91 /*-----------------------------------------------------------------------------------*/
92 static void
93 makeaddr(uip_ipaddr_t *addr, char *str)
94 {
95  str = makebyte(addr->u8[0], str);
96  *str++ = '.';
97  str = makebyte(addr->u8[1], str);
98  *str++ = '.';
99  str = makebyte(addr->u8[2], str);
100  *str++ = '.';
101  str = makebyte(addr->u8[3], str);
102  *str++ = 0;
103 }
104 /*-----------------------------------------------------------------------------------*/
105 static void
106 makestrings(void)
107 {
108  uip_ipaddr_t addr, *addrptr;
109 
110  uip_gethostaddr(&addr);
111  makeaddr(&addr, ipaddr);
112 
113  uip_getnetmask(&addr);
114  makeaddr(&addr, netmask);
115 
116  uip_getdraddr(&addr);
117  makeaddr(&addr, gateway);
118 
119 #if WITH_DNS
120  addrptr = resolv_getserver();
121  if(addrptr != NULL) {
122  makeaddr(addrptr, dnsserver);
123  }
124 #endif /* WITH_DNS */
125 }
126 /*-----------------------------------------------------------------------------------*/
127 static void
128 nullterminate(char *cptr)
129 {
130  /* Find the first space character in the ipaddr and put a zero there
131  to end the string. */
132  for(; *cptr != ' ' && *cptr != 0; ++cptr);
133  *cptr = 0;
134 }
135 /*-----------------------------------------------------------------------------------*/
136 static void
137 apply_tcpipconfig(void)
138 {
139  int file = cfs_open("contiki.cfg", CFS_READ);
140  int size = cfs_read(file, uip_buf, 100);
141  cfs_close(file);
142 
143  nullterminate(ipaddr);
144  uiplib_ipaddrconv(ipaddr, (uip_ipaddr_t *)&uip_buf[0]);
145 
146  nullterminate(netmask);
147  uiplib_ipaddrconv(netmask, (uip_ipaddr_t *)&uip_buf[4]);
148 
149  nullterminate(gateway);
150  uiplib_ipaddrconv(gateway, (uip_ipaddr_t *)&uip_buf[8]);
151 
152 #if WITH_DNS
153  nullterminate(dnsserver);
154  uiplib_ipaddrconv(dnsserver, (uip_ipaddr_t *)&uip_buf[12]);
155 #endif /* WITH_DNS */
156 
157  file = cfs_open("contiki.cfg", CFS_WRITE);
158  cfs_write(file, uip_buf, size);
159  cfs_close(file);
160 }
161 /*-----------------------------------------------------------------------------------*/
162 static void
163 set_statustext(char *text)
164 {
165  ctk_label_set_text(&statuslabel, text);
166  CTK_WIDGET_REDRAW(&statuslabel);
167 }
168 /*-----------------------------------------------------------------------------------*/
169 static void
170 app_quit(void)
171 {
172  ctk_window_close(&window);
173  process_exit(&ipconfig_process);
174  LOADER_UNLOAD();
175 }
176 /*-----------------------------------------------------------------------------------*/
177 PROCESS_THREAD(ipconfig_process, ev, data)
178 {
179  PROCESS_BEGIN();
180 
181  ctk_window_new(&window, 29, 14, "IP config");
182 
183  CTK_WIDGET_ADD(&window, &requestbutton);
184  CTK_WIDGET_ADD(&window, &statuslabel);
185  CTK_WIDGET_ADD(&window, &ipaddrlabel);
186  CTK_WIDGET_ADD(&window, &ipaddrtextentry);
187  CTK_WIDGET_ADD(&window, &netmasklabel);
188  CTK_WIDGET_ADD(&window, &netmasktextentry);
189  CTK_WIDGET_ADD(&window, &gatewaylabel);
190  CTK_WIDGET_ADD(&window, &gatewaytextentry);
191 #if WITH_DNS
192  CTK_WIDGET_ADD(&window, &dnsserverlabel);
193  CTK_WIDGET_ADD(&window, &dnsservertextentry);
194 #endif /* WITH_DNS */
195  CTK_WIDGET_ADD(&window, &savebutton);
196  CTK_WIDGET_ADD(&window, &cancelbutton);
197 
198  CTK_WIDGET_FOCUS(&window, &requestbutton);
199 
200  makestrings();
201 
202  ctk_window_open(&window);
203 
204  /* Allow resolver to set DNS server address. */
205  PROCESS_PAUSE();
206 
207  dhcpc_init(uip_lladdr.addr, sizeof(uip_lladdr.addr));
208 
209  while(1) {
211 
212  if(ev == PROCESS_EVENT_MSG) {
213  makestrings();
214  ctk_window_redraw(&window);
215  } else if(ev == tcpip_event) {
216  dhcpc_appcall(ev, data);
217  } else if(ev == ctk_signal_button_activate) {
218  if(data == (process_data_t)&requestbutton) {
219  dhcpc_request();
220  set_statustext("Requesting...");
221  }
222  if(data == (process_data_t)&savebutton) {
223  apply_tcpipconfig();
224  app_quit();
225  }
226  if(data == (process_data_t)&cancelbutton) {
227  app_quit();
228  }
229  } else if(
230 #if CTK_CONF_WINDOWCLOSE
231  ev == ctk_signal_window_close ||
232 #endif
233  ev == PROCESS_EVENT_EXIT) {
234  app_quit();
235  }
236  }
237 
238  PROCESS_END();
239 }
240 /*-----------------------------------------------------------------------------------*/
241 void
242 dhcpc_configured(const struct dhcpc_state *s)
243 {
244  uip_sethostaddr(&s->ipaddr);
245  uip_setnetmask(&s->netmask);
246  uip_setdraddr(&s->default_router);
247 #if WITH_DNS
248  resolv_conf(&s->dnsaddr);
249 #endif /* WITH_DNS */
250 
251  set_statustext("Configured.");
252  process_post(PROCESS_CURRENT(), PROCESS_EVENT_MSG, NULL);
253 }
254 /*-----------------------------------------------------------------------------------*/
255 void
256 dhcpc_unconfigured(const struct dhcpc_state *s)
257 {
258  static uip_ipaddr_t nulladdr;
259 
260  uip_sethostaddr(&nulladdr);
261  uip_setnetmask(&nulladdr);
262  uip_setdraddr(&nulladdr);
263 #if WITH_DNS
264  resolv_conf(&nulladdr);
265 #endif /* WITH_DNS */
266 
267  set_statustext("Unconfigured.");
268  process_post(PROCESS_CURRENT(), PROCESS_EVENT_MSG, NULL);
269 }
270 /*-----------------------------------------------------------------------------------*/
#define PROCESS_CURRENT()
Get a pointer to the currently running process.
Definition: process.h:402
#define CTK_WIDGET_ADD(win, widg)
Add a widget to a window.
Definition: ctk.h:752
process_event_t ctk_signal_window_close
Emitted when a window is closed.
Definition: ctk.c:155
process_event_t ctk_signal_button_activate
Same as ctk_signal_widget_activate.
Definition: ctk.c:126
#define uip_sethostaddr(addr)
Set the IP address of this host.
Definition: uip.h:195
#define uip_gethostaddr(addr)
Get the IP address of this host.
Definition: uip.h:215
CCIF uip_lladdr_t uip_lladdr
Host L2 address.
Definition: uip6.c:115
void ctk_window_open(CC_REGISTER_ARG struct ctk_window *w)
Open a window, or bring window to front if already open.
Definition: ctk.c:347
int cfs_open(const char *name, int flags)
Open a file.
Definition: cfs-coffee.c:996
#define CTK_WIDGET_FOCUS(win, widg)
Set focus to a widget.
Definition: ctk.h:763
void ctk_window_close(struct ctk_window *w)
Close a window if it is open.
Definition: ctk.c:400
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
#define CFS_WRITE
Specify that cfs_open() should open a file for writing.
Definition: cfs.h:104
#define CTK_TEXTENTRY(x, y, w, h, text, len)
Instantiating macro for the ctk_textentry widget.
Definition: ctk.h:275
#define ctk_label_set_text(l, t)
Set the text of a label.
Definition: ctk.h:849
#define NULL
The null pointer.
void ctk_window_redraw(struct ctk_window *w)
Redraw a window.
Definition: ctk.c:652
#define CFS_READ
Specify that cfs_open() should open a file for reading.
Definition: cfs.h:90
#define uiplib_ipaddrconv
Convert a textual representation of an IP address to a numerical representation.
Definition: uiplib.h:71
#define uip_getdraddr(addr)
Get the default router's IP address.
Definition: uip.h:250
int process_post(struct process *p, process_event_t ev, process_data_t data)
Post an asynchronous event.
Definition: process.c:322
#define uip_setdraddr(addr)
Set the default router's IP address.
Definition: uip.h:227
#define CTK_LABEL(x, y, w, h, text)
Instantiating macro for the ctk_label widget.
Definition: ctk.h:171
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
Definition: process.h:273
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
void ctk_window_new(struct ctk_window *window, unsigned char w, unsigned char h, char *title)
Create a new window.
Definition: ctk.c:732
#define LOADER_UNLOAD()
Unload a program from memory.
Definition: loader.h:104
#define uip_getnetmask(addr)
Get the netmask.
Definition: uip.h:260
#define PROCESS_PAUSE()
Yield the process for a short while.
Definition: process.h:221
#define PROCESS_WAIT_EVENT()
Wait for an event to be posted to the process.
Definition: process.h:141
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
process_event_t tcpip_event
The uIP event.
Definition: tcpip.c:75
#define CTK_BUTTON(x, y, w, text)
Instantiating macro for the ctk_button widget.
Definition: ctk.h:140
Representation of a CTK window.
Definition: ctk.h:506
#define CTK_WIDGET_REDRAW(widg)
Add a widget to the redraw queue.
Definition: ctk.h:771
#define uip_setnetmask(addr)
Set the netmask.
Definition: uip.h:239
CTK header file.
void process_exit(struct process *p)
Cause a process to exit.
Definition: process.c:202
void cfs_close(int fd)
Close an open file.
Definition: cfs-coffee.c:1032
CFS header file.