1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
21 #include "caipinterface.h"
27 #include <utility/server_drv.h>
28 #include <utility/wifi_drv.h>
29 #include <IPAddress.h>
33 #include "cainterface.h"
34 #include "caadapterinterface.h"
35 #include "caipadapter.h"
36 #include "caadapterutils.h"
37 #include "oic_malloc.h"
38 #include "oic_string.h"
42 // Length of the IP address decimal notation string
43 #define IPNAMESIZE (16)
45 /** Multicast IP address.*/
46 #define IPv4_MULTICAST "224.0.1.187"
49 #define IPv4_MULTICAST_PORT 5683
51 // Start offsets based on end of received data buffer
52 #define IP_RECBUF_IPADDR_OFFSET (6)
53 #define IP_RECBUF_PORT_OFFSET (2)
55 #define IP_RECBUF_IPADDR_SIZE (IP_RECBUF_IPADDR_OFFSET - IP_RECBUF_PORT_OFFSET)
56 #define IP_RECBUF_PORT_SIZE (IP_RECBUF_PORT_OFFSET - 0)
57 #define IP_RECBUF_FOOTER_SIZE (IP_RECBUF_IPADDR_SIZE + IP_RECBUF_PORT_SIZE)
59 static void CAArduinoCheckData();
60 static void CAPacketReceivedCallback(const char *ipAddress, const uint16_t port,
61 const void *data, const uint32_t dataLength);
63 static CAIPPacketReceivedCallback gPacketReceivedCallback = NULL;
64 static int32_t gUnicastSocket = 0;
65 static bool gServerRunning = false;
71 static uint16_t g_unicastPort = 0;
73 CAResult_t CAIPInitializeServer(const ca_thread_pool_t threadPool)
76 * This API is to keep design in sync with other platforms.
77 * The required implementation is done in Start() api's.
82 void CAIPTerminateServer(void)
85 * This API is to keep design in sync with other platforms.
86 * The required implementation is done in Stop() api's.
90 uint16_t CAGetServerPortNum(const char *ipAddress, bool isSecured)
95 CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port,
98 OIC_LOG(DEBUG, TAG, "IN");
99 VERIFY_NON_NULL(port, TAG, "port");
104 OIC_LOG(DEBUG, TAG, "Error");
105 return CA_STATUS_FAILED;
108 if (WiFi.status() != WL_CONNECTED)
110 OIC_LOG(ERROR, TAG, "ERROR:No WIFI");
111 return CA_STATUS_FAILED;
114 OIC_LOG_V(DEBUG, TAG, "port: %u", *port);
116 Udp.begin((uint16_t ) *port);
117 gServerRunning = true;
118 g_unicastPort = *port;
119 caglobals.ip.u4.port = *port;
120 OIC_LOG(DEBUG, TAG, "OUT");
124 CAResult_t CAIPStartMulticastServer(const char *localAddress, const char *multicastAddress,
125 uint16_t multicastPort)
127 // wifi shield does not support multicast
128 OIC_LOG(DEBUG, TAG, "IN");
129 OIC_LOG(DEBUG, TAG, "OUT");
130 //Arduino wifi shiled does not support multicast.
131 //OCInit() is failing if an error code is returned here,
132 //hence blocking even uni-cast operations.
133 //So default return value is changed to CA_STATUS_OK.
137 CAResult_t CAIPStartServer()
139 uint16_t unicastPort = 55555;
141 CAResult_t ret = CAIPStartUnicastServer("0.0.0.0", &unicastPort, false);
142 if (CA_STATUS_OK != ret)
144 OIC_LOG_V(ERROR, TAG, "Start unicast server failed[%d]", ret);
147 ret = CAIPStartMulticastServer("0.0.0.0", IPv4_MULTICAST, IPv4_MULTICAST_PORT);
148 if (CA_STATUS_OK != ret)
150 OIC_LOG_V(ERROR, TAG, "Start multicast failed[%d]", ret);
155 CAResult_t CAIPStopUnicastServer()
157 OIC_LOG(DEBUG, TAG, "IN");
160 gServerRunning = false;
161 caglobals.ip.u4.port = 0;
162 OIC_LOG(DEBUG, TAG, "OUT");
166 CAResult_t CAIPStopMulticastServer()
168 return CAIPStopUnicastServer();
171 CAResult_t CAIPStartListenServer()
173 CAResult_t ret = CAIPStartMulticastServer("0.0.0.0", IPv4_MULTICAST, IPv4_MULTICAST_PORT);
174 if (CA_STATUS_OK != ret)
176 OIC_LOG_V(ERROR, TAG, "Start multicast failed[%d]", ret);
181 CAResult_t CAIPStopListenServer()
183 return CAIPStopMulticastServer();
186 void CAIPStopServer()
188 OIC_LOG(DEBUG, TAG, "IN");
189 CAResult_t result = CAIPStopUnicastServer();
190 if (CA_STATUS_OK != result)
192 OIC_LOG_V(ERROR, TAG, "stop ucast srv fail:%d", result);
195 CAIPSetUnicastSocket(-1);
196 CAIPSetUnicastPort(0);
198 result = CAIPStopMulticastServer();
199 if (CA_STATUS_OK != result)
201 OIC_LOG_V(ERROR, TAG, "stop mcast srv fail:%d", result);
203 OIC_LOG(DEBUG, TAG, "OUT");
206 void CAPacketReceivedCallback(const char *ipAddress, const uint16_t port,
207 const void *data, const uint32_t dataLength)
209 OIC_LOG(DEBUG, TAG, "IN");
210 if (gPacketReceivedCallback)
212 CASecureEndpoint_t sep =
213 {.endpoint = {.adapter = CA_ADAPTER_IP, .flags = CA_IPV4, .port = port}};
215 OICStrcpy(sep.endpoint.addr, sizeof(sep.endpoint.addr), ipAddress);
216 gPacketReceivedCallback(&sep, data, dataLength);
217 OIC_LOG(DEBUG, TAG, "Notified network packet");
219 OIC_LOG(DEBUG, TAG, "OUT");
222 void CAArduinoCheckData()
224 OIC_LOG(DEBUG, TAG, "IN");
225 char addr[IPNAMESIZE] = {0};
226 uint16_t senderPort = 0;
227 int16_t packetSize = Udp.parsePacket();
228 OIC_LOG_V(DEBUG, TAG, "Rcv packet of size:%d ", packetSize);
231 packetSize = packetSize > COAP_MAX_PDU_SIZE ? COAP_MAX_PDU_SIZE:packetSize;
232 char *data = (char *)OICMalloc(packetSize + 1);
237 IPAddress remoteIp = Udp.remoteIP();
238 senderPort = Udp.remotePort();
239 sprintf(addr, "%d.%d.%d.%d", remoteIp[0], remoteIp[1], remoteIp[2], remoteIp[3]);
240 OIC_LOG_V(DEBUG, TAG, "remoteip: %s, port: %d", addr, senderPort);
241 // read the packet into packetBufffer
242 int32_t dataLen = Udp.read(data, COAP_MAX_PDU_SIZE);
247 CAPacketReceivedCallback(addr, senderPort, data, dataLen);
250 OIC_LOG(DEBUG, TAG, "OUT");
253 void CAIPSetPacketReceiveCallback(CAIPPacketReceivedCallback callback)
255 OIC_LOG(DEBUG, TAG, "IN");
256 gPacketReceivedCallback = callback;
257 OIC_LOG(DEBUG, TAG, "OUT");
260 void CAIPSetExceptionCallback(CAIPExceptionCallback callback)
265 void CAIPSetErrorHandleCallback(CAIPErrorHandleCallback ipErrorCallback)
267 OIC_LOG(DEBUG, TAG, "IN");
268 OIC_LOG(DEBUG, TAG, "OUT");
273 CAArduinoCheckData();
276 CAResult_t CAGetIPInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
278 OIC_LOG(DEBUG, TAG, "IN");
280 VERIFY_NON_NULL(info, TAG, "info is NULL");
281 VERIFY_NON_NULL(size, TAG, "size is NULL");
283 u_arraylist_t *iflist = CAIPGetInterfaceInformation(0);
286 OIC_LOG(ERROR, TAG, "get interface info failed");
287 return CA_STATUS_FAILED;
290 uint32_t len = u_arraylist_length(iflist);
292 CAEndpoint_t *eps = (CAEndpoint_t *)OICCalloc(len, sizeof (CAEndpoint_t));
295 OIC_LOG(ERROR, TAG, "Malloc Failed");
296 u_arraylist_destroy(iflist);
297 return CA_MEMORY_ALLOC_FAILED;
300 for (uint32_t i = 0, j = 0; i < len; i++)
302 CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
307 unsigned char *addr= (unsigned char *) &(ifitem->ipv4addr);
308 snprintf(eps[j].addr, MAX_ADDR_STR_SIZE_CA, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
310 eps[j].flags = CA_IPV4;
311 eps[j].adapter = CA_ADAPTER_IP;
312 eps[j].interface = 0;
313 eps[j].port = caglobals.ip.u4.port;
320 u_arraylist_destroy(iflist);
322 OIC_LOG(DEBUG, TAG, "OUT");