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 "caipadapter_singlethread.h"
27 #include "caadapterutils.h"
29 #include "oic_malloc.h"
30 #include "caipinterface_singlethread.h"
34 * @brief Logging tag for module name
40 * @brief Unicast port number (to listen for incoming data on unicast server).
41 * Note :- Actual port number may differ based on result of bind() operation.
47 * @brief Secured (unicast) port number as defined in COAP Specification, RFC-7252.
49 #define CA_SECURE_PORT 5684
53 * @brief Multicast port number as defined in COAP Specification, RFC-7252.
55 #define CA_MCAST_PORT 5683
58 * @def CA_MULTICAST_IP
59 * @brief Multicast IP Address
61 #define CA_MULTICAST_IP "224.0.1.187"
65 * @var g_networkPacketCallback
66 * @brief Network Packet Received Callback to CA
68 static CANetworkPacketReceivedCallback g_networkPacketCallback = NULL;
71 * @var g_networkChangeCallback
72 * @brief Network Changed Callback to CA
75 static CANetworkChangeCallback g_networkChangeCallback = NULL;
78 * @var g_isMulticastServerStarted
79 * @brief Flag to check if multicast server is started
81 static bool g_isMulticastServerStarted = false;
84 * @var g_startUnicastServerRequested
85 * @brief Flag to check if server start requested by CA.
87 static bool g_startUnicastServerRequested = false;
90 * @var g_unicastServerport
91 * @brief port number on which unicast server is running.
93 static uint16_t g_unicastServerport = 0;
96 * @var g_startMulticastServerRequested
97 * @brief Flag to check if server start requested by CA.
99 static bool g_startMulticastServerRequested = false;
102 static void CAIPNotifyNetworkChange(const char *address, uint16_t port,
103 CANetworkStatus_t status);
104 static void CAIPConnectionStateCB(const char *ipAddress,
105 CANetworkStatus_t status);
106 static void CAIPPacketReceivedCB(const char *ipAddress, uint16_t port,
107 const void *data, uint32_t dataLength);
108 static CAResult_t CAIPStopServers();
110 void CAIPNotifyNetworkChange(const char *address, uint16_t port, CANetworkStatus_t status)
112 CALocalConnectivity_t *localEndpoint = CAAdapterCreateLocalEndpoint(CA_IPV4, address);
115 OIC_LOG(ERROR, TAG, "Out of memory!");
118 localEndpoint->addressInfo.IP.port = port;
120 if (NULL != g_networkChangeCallback)
122 g_networkChangeCallback(localEndpoint, status);
125 CAAdapterFreeLocalEndpoint(localEndpoint);
128 void CAIPConnectionStateCB(const char *ipAddr,
129 CANetworkStatus_t status)
131 OIC_LOG(DEBUG, TAG, "IN");
133 CAResult_t ret = CA_STATUS_FAILED;
134 /* If IP is connected, then get the latest IP from the IP Interface
135 * and start unicast and multicast servers if requested earlier */
136 if (CA_INTERFACE_UP == status)
138 uint16_t port = CA_PORT;
139 int32_t serverFd = -1;
140 /* Start Unicast server if requested earlier */
141 if (g_startUnicastServerRequested)
143 ret = CAIPStartUnicastServer("0.0.0.0", &port, false, &serverFd);
144 if (CA_STATUS_OK == ret)
146 OIC_LOG_V(DEBUG, TAG, "unicast started:%d", port);
147 CAIPSetUnicastSocket(serverFd);
148 CAIPSetUnicastPort(port);
149 g_unicastServerport = port;
153 OIC_LOG_V(ERROR, TAG, "FAILED:%d", ret);
157 /* Start Multicast server if requested earlier */
158 if (g_startMulticastServerRequested)
160 uint16_t multicastPort = CA_MCAST_PORT;
161 ret = CAIPStartMulticastServer("0.0.0.0", CA_MULTICAST_IP, multicastPort, &serverFd);
162 if (CA_STATUS_OK == ret)
164 OIC_LOG_V(DEBUG, TAG, "multicast started:%d", multicastPort);
165 g_isMulticastServerStarted = true;
169 OIC_LOG_V(ERROR, TAG, "strt mcast srv fail:%d", ret);
173 char *ipAddress = NULL;
174 char *ifcName = NULL;
175 CAResult_t ret = CAIPGetInterfaceInfo(&ifcName, &ipAddress);
176 if (CA_STATUS_OK != ret)
178 OIC_LOG_V(ERROR, TAG, "get interface info fail:%d", ret);
183 /* Notify network change to CA */
184 CAIPNotifyNetworkChange(ipAddress, port, status);
190 CAIPNotifyNetworkChange("", 0, status);
191 /* Stop both Unicast and Multicast servers */
192 ret = CAIPStopServers();
193 if (CA_STATUS_OK != ret)
195 OIC_LOG_V(ERROR, TAG, "stop srv fail:%d", ret);
200 OIC_LOG(DEBUG, TAG, "OUT");
203 void CAIPPacketReceivedCB(const char *ipAddress, uint16_t port,
204 const void *data, uint32_t dataLength)
206 OIC_LOG(DEBUG, TAG, "IN");
207 OIC_LOG_V(DEBUG, TAG, "sddress:%s", ipAddress);
208 OIC_LOG_V(DEBUG, TAG, "port:%d", port);
209 OIC_LOG_V(DEBUG, TAG, "data:%s", data);
211 /* CA is freeing this memory */
212 CARemoteEndpoint_t *endPoint = CAAdapterCreateRemoteEndpoint(CA_IPV4, ipAddress, NULL);
213 if (NULL == endPoint)
215 OIC_LOG(ERROR, TAG, "Out of memory!");
218 endPoint->addressInfo.IP.port = port;
220 if (g_networkPacketCallback)
222 g_networkPacketCallback(endPoint, data, dataLength);
224 CAAdapterFreeRemoteEndpoint(endPoint);
225 OIC_LOG(DEBUG, TAG, "OUT");
228 CAResult_t CAInitializeIP(CARegisterConnectivityCallback registerCallback,
229 CANetworkPacketReceivedCallback networkPacketCallback,
230 CANetworkChangeCallback netCallback)
232 OIC_LOG(DEBUG, TAG, "IN");
233 VERIFY_NON_NULL(registerCallback, TAG, "registerCallback");
234 VERIFY_NON_NULL(networkPacketCallback, TAG, "networkPacketCallback");
235 VERIFY_NON_NULL(netCallback, TAG, "netCallback");
237 g_networkChangeCallback = netCallback;
238 g_networkPacketCallback = networkPacketCallback;
240 CAResult_t ret = CAIPInitializeNetworkMonitor();
241 if (CA_STATUS_OK != ret)
243 OIC_LOG_V(ERROR, TAG, "init n/w fail:%d", ret);
246 CAIPSetConnectionStateChangeCallback(CAIPConnectionStateCB);
248 ret = CAIPInitializeServer();
249 if (CA_STATUS_OK != ret)
251 OIC_LOG_V(ERROR, TAG, "init fail:%d", ret);
255 CAIPSetPacketReceiveCallback(CAIPPacketReceivedCB);
257 CAConnectivityHandler_t IPHandler;
258 IPHandler.startAdapter = CAStartIP;
259 IPHandler.startListenServer = CAStartIPListeningServer;
260 IPHandler.startDiscoveryServer = CAStartIPDiscoveryServer;
261 IPHandler.sendData = CASendIPUnicastData;
262 IPHandler.sendDataToAll = CASendIPMulticastData;
263 IPHandler.GetnetInfo = CAGetIPInterfaceInformation;
264 IPHandler.readData = CAReadIPData;
265 IPHandler.stopAdapter = CAStopIP;
266 IPHandler.terminate = CATerminateIP;
267 registerCallback(IPHandler, CA_IPV4);
269 OIC_LOG(INFO, TAG, "success");
270 OIC_LOG(DEBUG, TAG, "OUT");
274 CAResult_t CAStartIP()
276 OIC_LOG(DEBUG, TAG, "IN");
278 /* Start monitoring IP network */
279 CAResult_t ret = CAIPStartNetworkMonitor();
280 if (CA_STATUS_OK != ret)
282 OIC_LOG(ERROR, TAG, "strt n/w monitor fail");
285 g_startUnicastServerRequested = true;
286 bool retVal = CAIPIsConnected();
289 OIC_LOG(ERROR, TAG, "not connected");
293 uint16_t unicastPort = CA_PORT;
294 int32_t serverFd = 0;
295 // Address is hardcoded as we are using Single Interface
296 ret = CAIPStartUnicastServer("0.0.0.0", &unicastPort, false, &serverFd);
297 if (CA_STATUS_OK == ret)
299 OIC_LOG_V(DEBUG, TAG, "unicast started:%d", unicastPort);
300 CAIPSetUnicastSocket(serverFd);
301 CAIPSetUnicastPort(unicastPort);
302 g_unicastServerport = unicastPort;
305 OIC_LOG(DEBUG, TAG, "OUT");
309 CAResult_t CAStartIPListeningServer()
311 OIC_LOG(DEBUG, TAG, "IN");
313 CAResult_t ret = CA_STATUS_OK;
314 uint16_t multicastPort = CA_MCAST_PORT;
315 int32_t serverFD = 1;
316 if (g_isMulticastServerStarted == true)
318 OIC_LOG(ERROR, TAG, "Already Started!");
319 return CA_SERVER_STARTED_ALREADY;
322 g_startMulticastServerRequested = true;
323 bool retVal = CAIPIsConnected();
326 OIC_LOG(ERROR, TAG,"Not connected");
327 return CA_ADAPTER_NOT_ENABLED;
330 ret = CAIPStartMulticastServer("0.0.0.0", CA_MULTICAST_IP, multicastPort, &serverFD);
331 if (CA_STATUS_OK == ret)
333 OIC_LOG(INFO, TAG, "multicast success");
334 g_isMulticastServerStarted = true;
337 OIC_LOG(DEBUG, TAG, "OUT");
341 CAResult_t CAStartIPDiscoveryServer()
343 OIC_LOG(DEBUG, TAG, "IN");
344 /* Both listening and discovery server are same */
345 OIC_LOG(DEBUG, TAG, "OUT");
346 return CAStartIPListeningServer();
349 int32_t CASendIPUnicastData(const CARemoteEndpoint_t *remoteEndpoint, const void *data,
352 OIC_LOG(DEBUG, TAG, "IN");
354 VERIFY_NON_NULL_RET(remoteEndpoint, TAG, "remoteEndpoint", -1);
355 VERIFY_NON_NULL_RET(data, TAG, "data", -1);
358 OIC_LOG(ERROR, TAG, "Invalid length");
362 CAIPSendData(remoteEndpoint->addressInfo.IP.ipAddress,
363 remoteEndpoint->addressInfo.IP.port, data, dataLength, false);
364 OIC_LOG(DEBUG, TAG, "OUT");
368 int32_t CASendIPMulticastData(const void *data, uint32_t dataLength)
370 OIC_LOG(DEBUG, TAG, "IN");
372 VERIFY_NON_NULL_RET(data, TAG, "data", -1);
375 OIC_LOG(ERROR, TAG, "Invalid length");
379 CAIPSendData(CA_MULTICAST_IP, CA_MCAST_PORT, data, dataLength, true);
380 OIC_LOG(DEBUG, TAG, "OUT");
384 CAResult_t CAGetIPInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
386 OIC_LOG(DEBUG, TAG, "IN");
387 VERIFY_NON_NULL(info, TAG, "info");
388 VERIFY_NON_NULL(size, TAG, "size");
390 bool retVal = CAIPIsConnected();
393 OIC_LOG(ERROR, TAG, "Not connected");
394 return CA_ADAPTER_NOT_ENABLED;
397 char *ipAddress = NULL;
398 char *ifcName = NULL;
399 CAResult_t ret = CAIPGetInterfaceInfo(&ipAddress, &ifcName);
400 if (CA_STATUS_OK != ret)
402 OIC_LOG_V(ERROR, TAG, "get interface info fail:%d", ret);
408 // Create local endpoint using util function
409 (*info) = CAAdapterCreateLocalEndpoint(CA_IPV4, ipAddress);
412 OIC_LOG(ERROR, TAG, "malloc fail");
415 return CA_MEMORY_ALLOC_FAILED;
418 (*info)->addressInfo.IP.port = g_unicastServerport;
424 OIC_LOG(INFO, TAG, "success");
425 OIC_LOG(DEBUG, TAG, "OUT");
429 CAResult_t CAReadIPData()
435 CAResult_t CAIPStopServers()
437 CAResult_t result = CAIPStopUnicastServer();
438 if (CA_STATUS_OK != result)
440 OIC_LOG_V(ERROR, TAG, "stop ucast srv fail:%d", result);
443 CAIPSetUnicastSocket(-1);
444 CAIPSetUnicastPort(0);
445 g_unicastServerport = 0;
447 result = CAIPStopMulticastServer();
448 if (CA_STATUS_OK != result)
450 OIC_LOG_V(ERROR, TAG, "stop mcast srv fail:%d", result);
453 g_isMulticastServerStarted = false;
458 CAResult_t CAStopIP()
460 OIC_LOG(DEBUG, TAG, "IN");
462 g_startUnicastServerRequested = false;
463 g_startMulticastServerRequested = false;
464 CAIPStopNetworkMonitor();
465 CAResult_t result = CAIPStopServers();
466 if (CA_STATUS_OK != result)
468 OIC_LOG_V(ERROR, TAG, "stop srv fail:%d", result);
471 OIC_LOG(DEBUG, TAG, "OUT");
477 OIC_LOG(DEBUG, TAG, "IN");
479 CAIPSetConnectionStateChangeCallback(NULL);
480 CAIPTerminateNetworkMonitor();
481 CAIPSetPacketReceiveCallback(NULL);
482 OIC_LOG(INFO, TAG, "Terminated Ethernet");
483 OIC_LOG(DEBUG, TAG, "OUT");