0b7caa60a9ed8e1874e4e8d8ace42ca4594c3efd
[platform/upstream/iotivity.git] / csdk / libcoap-4.1.1 / address.h
1 /* address.h -- representation of network addresses
2  *
3  * Copyright (C) 2010,2011 Olaf Bergmann <bergmann@tzi.org>
4  *
5  * This file is part of the CoAP library libcoap. Please see
6  * README for terms of use. 
7  */
8
9 /** 
10  * @file address.h
11  * @brief representation of network addresses
12  */
13
14 #ifndef _COAP_ADDRESS_H_
15 #define _COAP_ADDRESS_H_
16
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20
21 #include "config.h"
22
23 #ifdef HAVE_ASSERT_H
24 #include <assert.h>
25 #else
26 #ifndef assert
27 #warning "assertions are disabled"
28 #  define assert(x)
29 #endif
30 #endif
31
32 #include <string.h>
33 #include <stdint.h>
34 #include "ocsocket.h"
35
36 #ifdef HAVE_NETINET_IN_H
37 #include <netinet/in.h>
38 #endif
39 #ifdef HAVE_NETINET_IN_H
40 #include <sys/socket.h>
41 #endif
42
43 #ifdef WITH_LWIP
44 #include <lwip/ip_addr.h>
45
46 typedef struct coap_address_t {
47         uint16_t port;
48         ip_addr_t addr;
49 } coap_address_t;
50
51 /* FIXME oversimplification: just assuming it's an ipv4 address instead of
52  * looking up the appropraite lwip function */
53
54 #define _coap_address_equals_impl(A, B) ((A)->addr.addr == (B)->addr.addr && A->port == B->port)
55
56 /* FIXME sure there is something in lwip */
57
58 #define _coap_is_mcast_impl(Address) 0
59
60 #endif /* WITH_LWIP */
61 #ifdef WITH_CONTIKI
62 #include "uip.h"
63
64 typedef struct coap_address_t {
65   unsigned char size;
66   uip_ipaddr_t addr;
67   unsigned short port;
68 } coap_address_t;
69
70 #define _coap_address_equals_impl(A,B)                          \
71   ((A)->size == (B)->size                                       \
72    && (A)->port == (B)->port                                    \
73    && uip_ipaddr_cmp(&((A)->addr),&((B)->addr)))
74
75 #define _coap_is_mcast_impl(Address) uip_is_addr_mcast(&((Address)->addr))
76 #endif /* WITH_CONTIKI */
77
78 #ifdef WITH_POSIX
79
80 #pragma pack(push, 1)
81 /** multi-purpose address abstraction */
82 typedef struct coap_address_t {
83   socklen_t size;               /**< size of addr */
84   union {
85     struct sockaddr     sa;
86     struct sockaddr_storage st;
87     struct sockaddr_in  sin;
88     struct sockaddr_in6 sin6;
89   } addr;
90 } coap_address_t;
91 #pragma pack(pop)
92
93 static inline int 
94 _coap_address_equals_impl(const coap_address_t *a,
95                           const coap_address_t *b) {
96   if (a->size != b->size || a->addr.sa.sa_family != b->addr.sa.sa_family)
97     return 0;
98   
99   /* need to compare only relevant parts of sockaddr_in6 */
100  switch (a->addr.sa.sa_family) {
101  case AF_INET:
102    return 
103      a->addr.sin.sin_port == b->addr.sin.sin_port && 
104      memcmp(&a->addr.sin.sin_addr, &b->addr.sin.sin_addr, 
105             sizeof(struct in_addr)) == 0;
106  case AF_INET6:
107    return a->addr.sin6.sin6_port == b->addr.sin6.sin6_port && 
108      memcmp(&a->addr.sin6.sin6_addr, &b->addr.sin6.sin6_addr, 
109             sizeof(struct in6_addr)) == 0;
110  default: /* fall through and signal error */
111    ;
112  }
113  return 0;
114 }
115
116 static inline int
117 _coap_is_mcast_impl(const coap_address_t *a) {
118   if (!a)
119     return 0;
120
121  switch (a->addr.sa.sa_family) {
122  case AF_INET:
123    return IN_MULTICAST(a->addr.sin.sin_addr.s_addr);
124 case  AF_INET6:
125   return IN6_IS_ADDR_MULTICAST(&a->addr.sin6.sin6_addr);
126  default:                       /* fall through and signal error */
127    ;
128   }
129  return 0;
130 }
131
132 #endif /* WITH_POSIX */
133
134 #ifdef WITH_ARDUINO
135 typedef OCDevAddr coap_address_t;
136
137 static inline int 
138 _coap_address_equals_impl(const coap_address_t *a,
139         const coap_address_t *b) {
140     uint32_t i;
141
142     if ((a == NULL) || (b == NULL))
143         return 0;
144
145     if (a->size != b->size)
146         return 0;
147
148     for (i = 0; i < a->size; i++)
149     {
150         if (a->addr[i] != b->addr[i])
151             return 0;
152     }
153     return 1;
154 }
155
156 static inline int
157 _coap_is_mcast_impl(const coap_address_t *a) {
158     if (!a)
159         return 0;
160
161     /* TODO */
162     return 1;
163 }
164
165 #endif /* WITH_ARDUINO */
166
167 /** 
168  * Resets the given coap_address_t object @p addr to its default
169  * values.  In particular, the member size must be initialized to the
170  * available size for storing addresses.
171  * 
172  * @param addr The coap_address_t object to initialize.
173  */
174 static inline void
175 coap_address_init(coap_address_t *addr) {
176   assert(addr);
177   memset(addr, 0, sizeof(coap_address_t));
178 #ifndef WITH_LWIP
179   /* lwip has constandt address sizes and doesn't need the .size part */
180   addr->size = sizeof(addr->addr);
181 #endif
182 }
183
184 /**
185  * Compares given address objects @p a and @p b. This function returns
186  * @c 1 if addresses are equal, @c 0 otherwise. The parameters @p a
187  * and @p b must not be @c NULL;
188  */
189 static inline int
190 coap_address_equals(const coap_address_t *a, const coap_address_t *b) {
191   assert(a); assert(b);
192   return _coap_address_equals_impl(a, b);
193 }
194
195 /**
196  * Checks if given address @p a denotes a multicast address.  This
197  * function returns @c 1 if @p a is multicast, @c 0 otherwise.
198  */
199 static inline int 
200 coap_is_mcast(const coap_address_t *a) {
201   return a && _coap_is_mcast_impl(a);
202 }
203  
204 #ifdef __cplusplus
205 }
206 #endif
207
208 #endif /* _COAP_ADDRESS_H_ */