Contiki-NG
simple-udp.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011, Swedish Institute of Computer Science.
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 copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  */
31 
32 /**
33  * \file
34  * Code for the simple-udp module.
35  * \author
36  * Adam Dunkels <adam@sics.se>
37  *
38  */
39 
40 /**
41  * \addtogroup simple-udp
42  * @{
43  */
44 
45 #include "contiki-net.h"
46 #include "net/ipv6/simple-udp.h"
47 
48 #include <string.h>
49 
50 
51 PROCESS(simple_udp_process, "Simple UDP process");
52 static uint8_t started = 0;
53 static uint8_t databuffer[UIP_BUFSIZE];
54 
55 #define UIP_IP_BUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
56 
57 /*---------------------------------------------------------------------------*/
58 static void
59 init_simple_udp(void)
60 {
61  if(started == 0) {
62  process_start(&simple_udp_process, NULL);
63  started = 1;
64  }
65 }
66 /*---------------------------------------------------------------------------*/
67 int
69  const void *data, uint16_t datalen)
70 {
71  if(c->udp_conn != NULL) {
72  uip_udp_packet_sendto(c->udp_conn, data, datalen,
73  &c->remote_addr, UIP_HTONS(c->remote_port));
74  }
75  return 0;
76 }
77 /*---------------------------------------------------------------------------*/
78 int
80  const void *data, uint16_t datalen,
81  const uip_ipaddr_t *to)
82 {
83  if(c->udp_conn != NULL) {
84  uip_udp_packet_sendto(c->udp_conn, data, datalen,
85  to, UIP_HTONS(c->remote_port));
86  }
87  return 0;
88 }
89 /*---------------------------------------------------------------------------*/
90 int
92  const void *data, uint16_t datalen,
93  const uip_ipaddr_t *to,
94  uint16_t port)
95 {
96  if(c->udp_conn != NULL) {
97  uip_udp_packet_sendto(c->udp_conn, data, datalen,
98  to, UIP_HTONS(port));
99  }
100  return 0;
101 }
102 /*---------------------------------------------------------------------------*/
103 int
105  uint16_t local_port,
106  uip_ipaddr_t *remote_addr,
107  uint16_t remote_port,
108  simple_udp_callback receive_callback)
109 {
110 
111  init_simple_udp();
112 
113  c->local_port = local_port;
114  c->remote_port = remote_port;
115  if(remote_addr != NULL) {
116  uip_ipaddr_copy(&c->remote_addr, remote_addr);
117  }
118  c->receive_callback = receive_callback;
119 
120  PROCESS_CONTEXT_BEGIN(&simple_udp_process);
121  c->udp_conn = udp_new(remote_addr, UIP_HTONS(remote_port), c);
122  if(c->udp_conn != NULL && local_port) {
123  udp_bind(c->udp_conn, UIP_HTONS(local_port));
124  }
126 
127  if(c->udp_conn == NULL) {
128  return 0;
129  }
130  return 1;
131 }
132 /*---------------------------------------------------------------------------*/
133 PROCESS_THREAD(simple_udp_process, ev, data)
134 {
135  struct simple_udp_connection *c;
136  PROCESS_BEGIN();
137 
138  while(1) {
140  if(ev == tcpip_event) {
141 
142  /* An appstate pointer is passed to use from the IP stack
143  through the 'data' pointer. We registered this appstate when
144  we did the udp_new() call in simple_udp_register() as the
145  struct simple_udp_connection pointer. So we extract this
146  pointer and use it when calling the reception callback. */
147  c = (struct simple_udp_connection *)data;
148 
149  /* Defensive coding: although the appstate *should* be non-null
150  here, we make sure to avoid the program crashing on us. */
151  if(c != NULL) {
152 
153  /* If we were called because of incoming data, we should call
154  the reception callback. */
155  if(uip_newdata()) {
156  /* Copy the data from the uIP data buffer into our own
157  buffer to avoid the uIP buffer being messed with by the
158  callee. */
159  memcpy(databuffer, uip_appdata, uip_datalen());
160 
161  /* Call the client process. We use the PROCESS_CONTEXT
162  mechanism to temporarily switch process context to the
163  client process. */
164  if(c->receive_callback != NULL) {
165  PROCESS_CONTEXT_BEGIN(c->client_process);
166  c->receive_callback(c,
167  &(UIP_IP_BUF->srcipaddr),
168  UIP_HTONS(UIP_IP_BUF->srcport),
169  &(UIP_IP_BUF->destipaddr),
170  UIP_HTONS(UIP_IP_BUF->destport),
171  databuffer, uip_datalen());
173  }
174  }
175  }
176  }
177 
178  }
179 
180  PROCESS_END();
181 }
182 /*---------------------------------------------------------------------------*/
183 /** @} */
#define UIP_IP_BUF
Pointer to IP header.
Definition: uip-nd6.c:97
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
#define PROCESS_CONTEXT_END(p)
End a context switch.
Definition: process.h:440
int simple_udp_sendto_port(struct simple_udp_connection *c, const void *data, uint16_t datalen, const uip_ipaddr_t *to, uint16_t port)
Send a UDP packet to a specified IP address and UDP port.
Definition: simple-udp.c:91
#define PROCESS_WAIT_EVENT()
Wait for an event to be posted to the process.
Definition: process.h:141
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
process_event_t tcpip_event
The uIP event.
Definition: tcpip.c:66
#define UIP_BUFSIZE
The size of the uIP packet buffer.
Definition: uipopt.h:154
void(* simple_udp_callback)(struct simple_udp_connection *c, const uip_ipaddr_t *source_addr, uint16_t source_port, const uip_ipaddr_t *dest_addr, uint16_t dest_port, const uint8_t *data, uint16_t datalen)
Simple UDP Callback function type.
Definition: simple-udp.h:63
Header file for the simple-udp module.
Simple UDP connection.
Definition: simple-udp.h:71
int simple_udp_register(struct simple_udp_connection *c, uint16_t local_port, uip_ipaddr_t *remote_addr, uint16_t remote_port, simple_udp_callback receive_callback)
Register a UDP connection.
Definition: simple-udp.c:104
#define uip_newdata()
Is new incoming data available?
Definition: uip.h:729
struct uip_udp_conn * udp_new(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
Create a new UDP connection.
Definition: tcpip.c:265
#define uip_ipaddr_copy(dest, src)
Copy an IP address from one place to another.
Definition: uip.h:1018
#define UIP_HTONS(n)
Convert 16-bit quantity from host byte order to network byte order.
Definition: uip.h:1230
#define PROCESS_CONTEXT_BEGIN(p)
Switch context to another process.
Definition: process.h:426
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
Definition: cc2538-rf.c:1035
int simple_udp_sendto(struct simple_udp_connection *c, const void *data, uint16_t datalen, const uip_ipaddr_t *to)
Send a UDP packet to a specified IP address.
Definition: simple-udp.c:79
#define udp_bind(conn, port)
Bind a UDP connection to a local port.
Definition: tcpip.h:261
void * uip_appdata
Pointer to the application data in the packet buffer.
Definition: uip6.c:168
#define uip_datalen()
The length of any incoming data that is currently available (if available) in the uip_appdata buffer...
Definition: uip.h:642
int simple_udp_send(struct simple_udp_connection *c, const void *data, uint16_t datalen)
Send a UDP packet.
Definition: simple-udp.c:68
void process_start(struct process *p, process_data_t data)
Start a process.
Definition: process.c:99