Contiki-NG
Loading...
Searching...
No Matches
platform.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 OS
31 *
32 */
33
34/**
35 * \ingroup platform
36 *
37 * \defgroup native_platform Native platform
38 *
39 * Platform running in the host (Windows or Linux) environment.
40 *
41 * Used mainly for development and debugging.
42 * @{
43 */
44
45#include <stdio.h>
46#include <string.h>
47#include <unistd.h>
48#include <sys/select.h>
49#include <errno.h>
50
51#include "contiki.h"
52#include "net/netstack.h"
53
54#include "dev/serial-line.h"
55#include "dev/button-hal.h"
56#include "dev/gpio-hal.h"
57#include "dev/leds.h"
58
59#include "net/ipv6/uip.h"
60#include "net/ipv6/uip-debug.h"
61#include "net/queuebuf.h"
62
63#if NETSTACK_CONF_WITH_IPV6
64#include "net/ipv6/uip-ds6.h"
65#endif /* NETSTACK_CONF_WITH_IPV6 */
66
67#include "lib/assert.h"
68#include "lib/csprng.h"
69#ifdef __APPLE__
70#include <Security/Security.h>
71#include <Security/SecRandom.h>
72#else /* __APPLE__ */
73#include <sys/random.h>
74#endif /* __APPLE__ */
75
76/* Log configuration */
77#include "sys/log.h"
78#define LOG_MODULE "Native"
79#define LOG_LEVEL LOG_LEVEL_MAIN
80
81/*---------------------------------------------------------------------------*/
82/**
83 * \name Native Platform Configuration
84 *
85 * @{
86 */
87
88/*
89 * Defines the maximum number of file descriptors monitored by the platform
90 * main loop.
91 */
92#ifdef SELECT_CONF_MAX
93#define SELECT_MAX SELECT_CONF_MAX
94#else
95#define SELECT_MAX 8
96#endif
97
98/*
99 * Defines the timeout (in msec) of the select operation if no monitored file
100 * descriptors becomes ready.
101 */
102#ifdef SELECT_CONF_TIMEOUT
103#define SELECT_TIMEOUT SELECT_CONF_TIMEOUT
104#else
105#define SELECT_TIMEOUT 1000
106#endif
107
108/*
109 * Adds the STDIN file descriptor to the list of monitored file descriptors.
110 */
111#ifdef SELECT_CONF_STDIN
112#define SELECT_STDIN SELECT_CONF_STDIN
113#else
114#define SELECT_STDIN 1
115#endif
116/** @} */
117/*---------------------------------------------------------------------------*/
118
119static const struct select_callback *select_callback[SELECT_MAX];
120static int select_max = 0;
121
122#ifdef PLATFORM_CONF_MAC_ADDR
123static uint8_t mac_addr[] = PLATFORM_CONF_MAC_ADDR;
124#else /* PLATFORM_CONF_MAC_ADDR */
125static uint8_t mac_addr[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
126#endif /* PLATFORM_CONF_MAC_ADDR */
127
128/*---------------------------------------------------------------------------*/
129int
130select_set_callback(int fd, const struct select_callback *callback)
131{
132 int i;
133 if(fd >= 0 && fd < SELECT_MAX) {
134 /* Check that the callback functions are set */
135 if(callback != NULL &&
136 (callback->set_fd == NULL || callback->handle_fd == NULL)) {
137 callback = NULL;
138 }
139
140 select_callback[fd] = callback;
141
142 /* Update fd max */
143 if(callback != NULL) {
144 if(fd > select_max) {
145 select_max = fd;
146 }
147 } else {
148 select_max = 0;
149 for(i = SELECT_MAX - 1; i > 0; i--) {
150 if(select_callback[i] != NULL) {
151 select_max = i;
152 break;
153 }
154 }
155 }
156 return 1;
157 }
158 return 0;
159}
160/*---------------------------------------------------------------------------*/
161#if SELECT_STDIN
162static int
163stdin_set_fd(fd_set *rset, fd_set *wset)
164{
165 FD_SET(STDIN_FILENO, rset);
166 return 1;
167}
168static int (*input_handler)(unsigned char c);
169
170void
171native_uart_set_input(int (*input)(unsigned char c))
172{
173 input_handler = input;
174}
175static void
176stdin_handle_fd(fd_set *rset, fd_set *wset)
177{
178 char c;
179 if(FD_ISSET(STDIN_FILENO, rset)) {
180 if(read(STDIN_FILENO, &c, 1) > 0) {
181 input_handler(c);
182 }
183 }
184}
185const static struct select_callback stdin_fd = {
186 stdin_set_fd, stdin_handle_fd
187};
188#endif /* SELECT_STDIN */
189/*---------------------------------------------------------------------------*/
190static void
191set_lladdr(void)
192{
193 linkaddr_t addr;
194
195 memset(&addr, 0, sizeof(linkaddr_t));
196#if NETSTACK_CONF_WITH_IPV6
197 memcpy(addr.u8, mac_addr, sizeof(addr.u8));
198#else
199 int i;
200 for(i = 0; i < sizeof(linkaddr_t); ++i) {
201 addr.u8[i] = mac_addr[7 - i];
202 }
203#endif
205}
206/*---------------------------------------------------------------------------*/
207#if NETSTACK_CONF_WITH_IPV6
208static void
209set_global_address(void)
210{
211 uip_ipaddr_t ipaddr;
212 const uip_ipaddr_t *default_prefix = uip_ds6_default_prefix();
213
214 /* Assign a unique local address (RFC4193,
215 http://tools.ietf.org/html/rfc4193). */
216 uip_ip6addr_copy(&ipaddr, default_prefix);
217
218 /* Assumes that the uip_lladdr is set */
220 uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF);
221
222 LOG_INFO("Added global IPv6 address ");
223 LOG_INFO_6ADDR(&ipaddr);
224 LOG_INFO_("\n");
225
226 /* set the PREFIX::1 address to the IF */
227 uip_ip6addr_copy(&ipaddr, default_prefix);
228 ipaddr.u8[15] = 1;
229 uip_ds6_defrt_add(&ipaddr, 0);
230}
231#endif
232/*---------------------------------------------------------------------------*/
233int contiki_argc = 0;
234char **contiki_argv;
235/*---------------------------------------------------------------------------*/
236void
237platform_process_args(int argc, char **argv)
238{
239 /* crappy way of remembering and accessing argc/v */
240 contiki_argc = argc;
241 contiki_argv = argv;
242}
243/*---------------------------------------------------------------------------*/
244void
246{
249 leds_init();
250 struct csprng_seed seed;
251#ifdef __APPLE__
252 if(SecRandomCopyBytes(kSecRandomDefault, CSPRNG_SEED_LEN, seed.u8)
253 == errSecSuccess) {
254#else /* __APPLE__ */
255 if(getrandom(seed.u8, CSPRNG_SEED_LEN, GRND_RANDOM) == CSPRNG_SEED_LEN) {
256#endif /* __APPLE__ */
257 csprng_feed(&seed);
258 }
259}
260/*---------------------------------------------------------------------------*/
261void
263{
264 set_lladdr();
265 serial_line_init();
266
267#if SELECT_STDIN
268 if(NULL == input_handler) {
269 native_uart_set_input(serial_line_input_byte);
270 }
271#endif
272}
273/*---------------------------------------------------------------------------*/
274void
276{
277#if NETSTACK_CONF_WITH_IPV6
278 set_global_address();
279#endif /* NETSTACK_CONF_WITH_IPV6 */
280
281 /* Make standard output unbuffered. */
282 setvbuf(stdout, (char *)NULL, _IONBF, 0);
283}
284/*---------------------------------------------------------------------------*/
285void
287{
288#if SELECT_STDIN
289 select_set_callback(STDIN_FILENO, &stdin_fd);
290#endif /* SELECT_STDIN */
291 while(1) {
292 fd_set fdr;
293 fd_set fdw;
294 int maxfd;
295 int i;
296 int retval;
297 struct timeval tv;
298
299 retval = process_run();
300
301 tv.tv_sec = retval ? 0 : SELECT_TIMEOUT / 1000;
302 tv.tv_usec = retval ? 1 : (SELECT_TIMEOUT * 1000) % 1000000;
303
304 FD_ZERO(&fdr);
305 FD_ZERO(&fdw);
306 maxfd = 0;
307 for(i = 0; i <= select_max; i++) {
308 if(select_callback[i] != NULL && select_callback[i]->set_fd(&fdr, &fdw)) {
309 maxfd = i;
310 }
311 }
312
313 retval = select(maxfd + 1, &fdr, &fdw, NULL, &tv);
314 if(retval < 0) {
315 if(errno != EINTR) {
316 perror("select");
317 }
318 } else if(retval > 0) {
319 /* timeout => retval == 0 */
320 for(i = 0; i <= maxfd; i++) {
321 if(select_callback[i] != NULL) {
322 select_callback[i]->handle_fd(&fdr, &fdw);
323 }
324 }
325 }
326
328 }
329}
330/*---------------------------------------------------------------------------*/
331void
332log_message(char *m1, char *m2)
333{
334 fprintf(stderr, "%s%s\n", m1, m2);
335}
336/*---------------------------------------------------------------------------*/
337void
338uip_log(char *m)
339{
340 fprintf(stderr, "%s\n", m);
341}
342/*---------------------------------------------------------------------------*/
343/** @} */
Header file for the button HAL.
An OFB-AES-128-based CSPRNG.
Header file for the GPIO HAL.
void button_hal_init()
Initialise the button HAL.
Definition button-hal.c:213
void platform_init_stage_three()
Final stage of platform driver initialisation.
Definition platform.c:169
void platform_init_stage_one(void)
Basic (Stage 1) platform driver initialisation.
Definition platform.c:114
void platform_init_stage_two()
Stage 2 of platform driver initialisation.
Definition platform.c:123
void csprng_feed(struct csprng_seed *new_seed)
Mixes a new seed with the current one.
Definition csprng.c:61
void leds_init(void)
Initialise the LED HAL.
Definition minileds.c:44
void etimer_request_poll(void)
Make the event timer aware that the clock has changed.
Definition etimer.c:145
void gpio_hal_init()
Initialise the GPIO HAL.
Definition gpio-hal.c:95
static void linkaddr_set_node_addr(linkaddr_t *addr)
Set the address of the current node.
Definition linkaddr.h:124
void platform_main_loop()
The platform's main loop, if provided.
Definition platform.c:124
void uip_log(char *m)
Print out a uIP log message.
Definition platform.c:338
void platform_process_args(int argc, char **argv)
Allow the platform to process main's command line arguments.
Definition platform.c:237
process_num_events_t process_run(void)
Run the system once - call poll handlers and process one event.
Definition process.c:305
const uip_ip6addr_t * uip_ds6_default_prefix()
Retrieve the Default IPv6 prefix.
Definition uip-ds6.c:104
uip_lladdr_t uip_lladdr
Host L2 address.
Definition uip6.c:107
uip_ds6_addr_t * uip_ds6_addr_add(uip_ipaddr_t *ipaddr, unsigned long vlifetime, uint8_t type)
Add a unicast address to the interface.
Definition uip-ds6.c:352
void uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr)
set the last 64 bits of an IP address based on the MAC address
Definition uip-ds6.c:568
Header file for the LED HAL.
Header file for the logging system.
Include file for the Contiki low-layer network stack (NETSTACK)
Header file for the Packet queue buffer management.
Generic serial I/O process header filer.
This is the structure of a seed.
Definition csprng.h:76
uint8_t u8[(AES_128_KEY_LENGTH+AES_128_BLOCK_SIZE)]
for convenience
Definition csprng.h:83
A set of debugging macros for the IP stack.
Header file for IPv6-related data structures.
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
Definition uip-nd6.c:116
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
Definition uip-nd6.c:107
Header file for the uIP TCP/IP stack.