Contiki 3.x
linuxradio-drv.c
1 /*
2  * Copyright (c) 2013, Google
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  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * 3. Neither the name of the Institute nor the names of its contributors
17  * may be used to endorse or promote products derived from this software
18  * without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * Author: Vladimir Pouzanov <farcaller@gmail.com>
33  *
34  */
35 
36 #include "contiki.h"
37 #include "contiki-conf.h"
38 
39 #if defined(linux) && NETSTACK_CONF_WITH_IPV6
40 
41 #include "linuxradio-drv.h"
42 
43 #include "net/packetbuf.h"
44 #include "net/netstack.h"
45 
46 #include <stdlib.h>
47 #include <stdio.h>
48 #include <sys/ioctl.h>
49 #include <string.h>
50 #include <sys/types.h>
51 #include <sys/socket.h>
52 #include <netinet/in.h>
53 #include <unistd.h>
54 #include <netinet/if_ether.h>
55 #include <netpacket/packet.h>
56 #include <net/if.h>
57 #include <linux/sockios.h>
58 
59 #define DEBUG 0
60 #if DEBUG
61 #include <stdio.h>
62 #define PRINTF(...) printf(__VA_ARGS__)
63 #else
64 #define PRINTF(...)
65 #endif
66 
67 static int sockfd = -1;
68 static char *sockbuf;
69 static int buflen;
70 
71 #define MAX_PACKET_SIZE 256
72 
73 static int
74 init(void)
75 {
76  sockbuf = malloc(MAX_PACKET_SIZE);
77  if(sockbuf == 0) {
78  return 1;
79  }
80  return 0;
81 }
82 static int
83 prepare(const void *payload, unsigned short payload_len)
84 {
85  if(payload_len > MAX_PACKET_SIZE) {
86  return 0;
87  }
88  memcpy(sockbuf, payload, payload_len);
89  buflen = payload_len;
90 
91  return 0;
92 }
93 static int
94 transmit(unsigned short transmit_len)
95 {
96  int sent = 0;
97  sent = send(sockfd, sockbuf, buflen, 0);
98  if(sent < 0) {
99  perror("linuxradio send()");
100  return RADIO_TX_ERR;
101  }
102  buflen = 0;
103  return RADIO_TX_OK;
104 }
105 static int
106 my_send(const void *payload, unsigned short payload_len)
107 {
108  int ret = -1;
109 
110  if(prepare(payload, payload_len)) {
111  return ret;
112  }
113 
114  ret = transmit(payload_len);
115 
116  return ret;
117 }
118 static int
119 my_read(void *buf, unsigned short buf_len)
120 {
121  return 0;
122 }
123 static int
124 channel_clear(void)
125 {
126  return 1;
127 }
128 static int
129 receiving_packet(void)
130 {
131  return 0;
132 }
133 static int
134 pending_packet(void)
135 {
136  return 0;
137 }
138 static int
139 set_fd(fd_set *rset, fd_set *wset)
140 {
141  FD_SET(sockfd, rset);
142  return 1;
143 }
144 static void
145 handle_fd(fd_set *rset, fd_set *wset)
146 {
147  if(FD_ISSET(sockfd, rset)) {
148  int bytes = read(sockfd, sockbuf, MAX_PACKET_SIZE);
149  buflen = bytes;
150  memcpy(packetbuf_dataptr(), sockbuf, bytes);
151  packetbuf_set_datalen(bytes);
152  NETSTACK_RDC.input();
153  }
154 }
155 
156 static const struct select_callback linuxradio_sock_callback = { set_fd, handle_fd };
157 
158 static int
159 on(void)
160 {
161  struct ifreq ifr;
162  int err;
163  struct sockaddr_ll sll;
164 
165  sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IEEE802154));
166  if(sockfd < 0) {
167  perror("linuxradio socket()");
168  return 0;
169  } else {
170  strncpy((char *)ifr.ifr_name, NETSTACK_CONF_LINUXRADIO_DEV, IFNAMSIZ);
171  err = ioctl(sockfd, SIOCGIFINDEX, &ifr);
172  if(err == -1) {
173  perror("linuxradio ioctl()");
174  return 0;
175  }
176  sll.sll_family = AF_PACKET;
177  sll.sll_ifindex = ifr.ifr_ifindex;
178  sll.sll_protocol = htons(ETH_P_IEEE802154);
179 
180  if(bind(sockfd, (struct sockaddr *)&sll, sizeof(sll)) < 0) {
181  perror("linuxradio bind()");
182  return 0;
183  }
184 
185  select_set_callback(sockfd, &linuxradio_sock_callback);
186  return 1;
187  }
188 }
189 static int
190 off(void)
191 {
192  close(sockfd);
193  sockfd = -1;
194  return 1;
195 }
196 const struct radio_driver linuxradio_driver =
197 {
198  init,
199  prepare,
200  transmit,
201  my_send,
202  my_read,
206  on,
207  off,
208 };
209 
210 #endif
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
Definition: packetbuf.c:158
int(* channel_clear)(void)
Perform a Clear-Channel Assessment (CCA) to find out if there is a packet in the air or not...
Definition: radio.h:255
int(* prepare)(const void *payload, unsigned short payload_len)
Prepare the radio with a packet to be sent.
Definition: radio.h:242
int(* receiving_packet)(void)
Check if the radio driver is currently receiving a packet.
Definition: radio.h:258
The structure of a device driver for a radio in Contiki.
Definition: radio.h:237
int(* pending_packet)(void)
Check if the radio driver has just received a packet.
Definition: radio.h:261
Header file for the Rime buffer (packetbuf) management
int(* off)(void)
Turn the radio off.
Definition: radio.h:267
int(* on)(void)
Turn the radio on.
Definition: radio.h:264
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
Definition: packetbuf.c:151
int(* transmit)(unsigned short transmit_len)
Send the packet that has previously been prepared.
Definition: radio.h:245
Include file for the Contiki low-layer network stack (NETSTACK)