Contiki 2.6
|
00001 /** 00002 * \addtogroup simple-udp 00003 * @{ 00004 */ 00005 00006 00007 /* 00008 * Copyright (c) 2011, Swedish Institute of Computer Science. 00009 * All rights reserved. 00010 * 00011 * Redistribution and use in source and binary forms, with or without 00012 * modification, are permitted provided that the following conditions 00013 * are met: 00014 * 1. Redistributions of source code must retain the above copyright 00015 * notice, this list of conditions and the following disclaimer. 00016 * 2. Redistributions in binary form must reproduce the above copyright 00017 * notice, this list of conditions and the following disclaimer in the 00018 * documentation and/or other materials provided with the distribution. 00019 * 3. Neither the name of the Institute nor the names of its contributors 00020 * may be used to endorse or promote products derived from this software 00021 * without specific prior written permission. 00022 * 00023 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00024 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00025 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00026 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00027 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00028 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00029 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00031 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00032 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00033 * SUCH DAMAGE. 00034 * 00035 * This file is part of the Contiki operating system. 00036 * 00037 * \file 00038 * Header file for the simple-udp module. 00039 * \author 00040 * Adam Dunkels <adam@sics.se> 00041 * 00042 */ 00043 00044 #include "contiki-net.h" 00045 #include "net/simple-udp.h" 00046 00047 #include <string.h> 00048 00049 00050 PROCESS(simple_udp_process, "Simple UDP process"); 00051 static uint8_t started = 0; 00052 static uint8_t databuffer[UIP_BUFSIZE]; 00053 00054 #define UIP_IP_BUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN]) 00055 00056 /*---------------------------------------------------------------------------*/ 00057 static void 00058 init_simple_udp(void) 00059 { 00060 if(started == 0) { 00061 process_start(&simple_udp_process, NULL); 00062 started = 1; 00063 } 00064 } 00065 /*---------------------------------------------------------------------------*/ 00066 /** 00067 * \brief Send a UDP packet 00068 * \param c A pointer to a struct simple_udp_connection 00069 * \param data A pointer to the data to be sent 00070 * \param datalen The length of the data 00071 * 00072 * This function sends a UDP packet. The packet will be 00073 * sent to the IP address and with the UDP ports that were 00074 * specified when the connection wa registered with 00075 * simple_udp_register(). 00076 * 00077 * \sa simple_udp_sendto() 00078 */ 00079 int 00080 simple_udp_send(struct simple_udp_connection *c, 00081 const void *data, uint16_t datalen) 00082 { 00083 if(c->udp_conn != NULL) { 00084 uip_udp_packet_sendto(c->udp_conn, data, datalen, 00085 &c->remote_addr, UIP_HTONS(c->remote_port)); 00086 } 00087 return 0; 00088 } 00089 /*---------------------------------------------------------------------------*/ 00090 /** 00091 * \brief Send a UDP packet to a specified IP address 00092 * \param c A pointer to a struct simple_udp_connection 00093 * \param data A pointer to the data to be sent 00094 * \param datalen The length of the data 00095 * \param to The IP address of the receiver 00096 * 00097 * This function sends a UDP packet to a specified IP 00098 * address. The packet will be sent with the UDP ports 00099 * that were specified when the connection wa registered 00100 * with simple_udp_register(). 00101 * 00102 * \sa simple_udp_send() 00103 */ 00104 int 00105 simple_udp_sendto(struct simple_udp_connection *c, 00106 const void *data, uint16_t datalen, 00107 const uip_ipaddr_t *to) 00108 { 00109 if(c->udp_conn != NULL) { 00110 uip_udp_packet_sendto(c->udp_conn, data, datalen, 00111 to, UIP_HTONS(c->remote_port)); 00112 } 00113 return 0; 00114 } 00115 /*---------------------------------------------------------------------------*/ 00116 /** 00117 * \brief Register a UDP connection 00118 * \param c A pointer to a struct simple_udp_connection 00119 * \param local_port The local UDP port in host byte order 00120 * \param remote_addr The remote IP address 00121 * \param remote_port The remote UDP port in host byte order 00122 * \param receive_callback A pointer to a function to be called for incoming packets 00123 * \retval 0 If no UDP connection could be allocated 00124 * \retval 1 If the connection was successfully allocated 00125 * 00126 * This function registers a UDP connection and attaches a 00127 * callback function to it. The callback function will be 00128 * called for incoming packets. The local UDP port can be 00129 * set to 0 to indicate that an ephemeral UDP port should 00130 * be allocated. The remote IP address can be NULL, to 00131 * indicate that packets from any IP address should be 00132 * accepted. 00133 * 00134 */ 00135 int 00136 simple_udp_register(struct simple_udp_connection *c, 00137 uint16_t local_port, 00138 uip_ipaddr_t *remote_addr, 00139 uint16_t remote_port, 00140 simple_udp_callback receive_callback) 00141 { 00142 00143 init_simple_udp(); 00144 00145 c->local_port = local_port; 00146 c->remote_port = remote_port; 00147 if(remote_addr != NULL) { 00148 uip_ipaddr_copy(&c->remote_addr, remote_addr); 00149 } 00150 c->receive_callback = receive_callback; 00151 00152 PROCESS_CONTEXT_BEGIN(&simple_udp_process); 00153 c->udp_conn = udp_new(remote_addr, UIP_HTONS(remote_port), c); 00154 if(c->udp_conn != NULL) { 00155 udp_bind(c->udp_conn, UIP_HTONS(local_port)); 00156 } 00157 PROCESS_CONTEXT_END(); 00158 00159 if(c->udp_conn == NULL) { 00160 return 0; 00161 } 00162 return 1; 00163 } 00164 /*---------------------------------------------------------------------------*/ 00165 PROCESS_THREAD(simple_udp_process, ev, data) 00166 { 00167 struct simple_udp_connection *c; 00168 PROCESS_BEGIN(); 00169 00170 while(1) { 00171 PROCESS_WAIT_EVENT(); 00172 if(ev == tcpip_event) { 00173 00174 /* An appstate pointer is passed to use from the IP stack 00175 through the 'data' pointer. We registered this appstate when 00176 we did the udp_new() call in simple_udp_register() as the 00177 struct simple_udp_connection pointer. So we extract this 00178 pointer and use it when calling the reception callback. */ 00179 c = (struct simple_udp_connection *)data; 00180 00181 /* Defensive coding: although the appstate *should* be non-null 00182 here, we make sure to avoid the program crashing on us. */ 00183 if(c != NULL) { 00184 00185 /* If we were called because of incoming data, we should call 00186 the reception callback. */ 00187 if(uip_newdata()) { 00188 /* Copy the data from the uIP data buffer into our own 00189 buffer to avoid the uIP buffer being messed with by the 00190 callee. */ 00191 memcpy(databuffer, uip_appdata, uip_datalen()); 00192 00193 /* Call the client process. We use the PROCESS_CONTEXT 00194 mechanism to temporarily switch process context to the 00195 client process. */ 00196 if(c->receive_callback != NULL) { 00197 PROCESS_CONTEXT_BEGIN(c->client_process); 00198 c->receive_callback(c, 00199 &(UIP_IP_BUF->srcipaddr), 00200 UIP_HTONS(UIP_IP_BUF->srcport), 00201 &(UIP_IP_BUF->destipaddr), 00202 UIP_HTONS(UIP_IP_BUF->destport), 00203 databuffer, uip_datalen()); 00204 PROCESS_CONTEXT_END(); 00205 } 00206 } 00207 } 00208 } 00209 00210 } 00211 00212 PROCESS_END(); 00213 } 00214 /*---------------------------------------------------------------------------*/ 00215 /** @} */