Robot Agent  1.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
udp.c
Go to the documentation of this file.
1 
11  /* -- Includes -- */
12 /* system libraries */
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <arpa/inet.h>
17 #include <netinet/in.h>
18 #include <sys/types.h>
19 #include <sys/socket.h>
20 #include <unistd.h>
21 /* project libraries */
22 #include "udp.h"
23 #include "config.h"
24 #include "def.h"
25 
26  /* -- Defines -- */
27 
28 /* -- Functions -- */
29 
30 
37 {
38  // Local variables
39  int broadcastEnable = 1;
40 
41  // Open socket
42  if((udp->sd_send = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == s_ERROR) {
43  printf("udp_init_broadcast: could not open a send socket.\n");
44  return s_ERROR;
45  }
46 
47  // Enable broadcast
48  if(setsockopt(udp->sd_send, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable)) == s_ERROR) {
49  printf("udp_init_broadcast: could not enable broadcast.\n");
50  return s_ERROR;
51  }
52 
53  // Configure IP and port
54  memset((char *) &udp->sock_send, 0, sizeof(udp->sock_send));
55  udp->sock_send.sin_family = AF_INET;
56  udp->sock_send.sin_port = htons(udp->port);
57 
58  if(inet_pton(AF_INET, udp->broadcast_ip, &udp->sock_send.sin_addr) == s_ERROR) {
59  printf("udp_init_broadcast: inet_pton failed.\n");
60  return s_ERROR;
61  }
62 
63 
64  return s_OK;
65 }
66 
73 {
74  // Open socket
75  if((udp->sd_recv = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == s_ERROR) {
76  printf("udp_init_receive: could not open a receive socket.\n");
77  return s_ERROR;
78  }
79 
80  // Configure IP and port
81  memset((char *) &udp->sock_recv, 0, sizeof(udp->sock_recv));
82  udp->sock_recv.sin_family = AF_INET;
83  udp->sock_recv.sin_port = htons(udp->port);
84  udp->sock_recv.sin_addr.s_addr = htonl(INADDR_ANY);
85 
86  // Bind socket
87  if(bind(udp->sd_recv, (struct sockaddr *)&udp->sock_recv, sizeof(udp->sock_recv)) == s_ERROR) {
88  printf("udp_init_receive: could not bind a socket.\n");
89  return s_ERROR;
90  }
91 
92  // Sender socket len
93  udp->sock_conn_len = sizeof(udp->sock_conn);
94 
95  return s_OK;
96 }
97 
105 udp_t *udp_open(char *broadcast_ip, int port, int packet_size)
106 {
107  // Allocate memory for UDP structure
108  udp_t *udp = (udp_t *)malloc(sizeof(udp_t));
109 
110  strcpy(udp->broadcast_ip, broadcast_ip);
111  udp->port = port;
112  udp->packet_size = packet_size;
113 
114  // Initialize broadcasting
115  if(udp_init_broadcast(udp) == s_ERROR)
116  return NULL;
117 
118  // Initialize reception
119  if(udp_init_receive(udp) == s_ERROR)
120  return NULL;
121 
122  return udp;
123 }
124 
130 int udp_close(udp_t *udp)
131 {
132  int res;
133 
134  // Close sockets
135  res = close(udp->sd_send);
136  res += close(udp->sd_recv);
137 
138  // Free memory
139  free(udp);
140 
141  if(res < 0)
142  {
143  printf("udp_close: could not close UDP sockets.\n");
144  return s_ERROR;
145  }
146  else
147  {
148  return s_OK;
149  }
150 }
151 
159 int udp_broadcast(udp_t *udp, char *packet, int len)
160 {
161 
162  // Broadcast UDP packet/datagram
163  if(sendto(udp->sd_send, packet, len, 0, (struct sockaddr *)&udp->sock_send, sizeof(udp->sock_send)) == s_ERROR) {
164  printf("udp_broadcast: could not send UDP packet.\n");
165  return s_ERROR;
166  }
167 
168  return s_OK;
169 }
170 
178 int udp_receive(udp_t *udp, char *packet, int *len)
179 {
180  // Local variables
181  int n;
182  struct timeval tv;
183 
184  // Configure timer for select()
185  tv.tv_sec = 0;
186  tv.tv_usec = 1000;
187  fd_set infds;
188  FD_ZERO(&infds);
189  FD_SET(udp->sd_recv, &infds);
190 
191  // Receive
192  // while
193  if((n = select(udp->sd_recv + 1, &infds, NULL, NULL, &tv)))
194  {
195  // Receive packet/datagram
196  if((*len = recvfrom( udp->sd_recv,
197  packet,
198  udp->packet_size,
199  0,
200  (struct sockaddr *)&udp->sock_conn,
201  &udp->sock_conn_len)) == s_ERROR)
202  {
203  printf("udp_receive: could not receive UDP packet.\n");
204  return s_ERROR;
205  }
206 
207  // End string
208  packet[*len] = '\0';
209 
210  // Print received packet content and information
211  /*printf("recv from %s:%d - data: %s\n",
212  inet_ntoa(udp->sock_conn.sin_addr),
213  ntohs(udp->sock_conn.sin_port),
214  packet);*/
215 
216  return s_OK;
217  }
218 
219  return s_ERROR;
220 }
char broadcast_ip[16]
Definition: udp.h:43
int udp_receive(udp_t *udp, char *packet, int *len)
Definition: udp.c:178
int udp_close(udp_t *udp)
Definition: udp.c:130
struct sockaddr_in sock_recv
Definition: udp.h:32
int sd_recv
Definition: udp.h:40
int port
Definition: udp.h:44
int sd_send
Definition: udp.h:39
struct sockaddr_in sock_send
Definition: udp.h:31
socklen_t sock_conn_len
Definition: udp.h:36
UDP structure.
Definition: udp.h:28
#define s_OK
Definition: def.h:64
int udp_init_broadcast(udp_t *udp)
Definition: udp.c:36
struct sockaddr_in sock_conn
Definition: udp.h:33
#define s_ERROR
Definition: def.h:65
int packet_size
Definition: udp.h:45
int udp_broadcast(udp_t *udp, char *packet, int len)
Definition: udp.c:159
udp_t * udp_open(char *broadcast_ip, int port, int packet_size)
Definition: udp.c:105
int udp_init_receive(udp_t *udp)
Definition: udp.c:72