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 CAEndpoint_t *localEndpoint = CAAdapterCreateLocalEndpoint(CA_IPV4, address);
115 OIC_LOG(ERROR, TAG, "Out of memory!");
118 localEndpoint->port = port;
120 if (NULL != g_networkChangeCallback)
122 g_networkChangeCallback(localEndpoint, status);
125 CAAdapterFreeEndpoint(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 CAEndpoint_t *endPoint = CAAdapterCreateEndpoint(CA_DEFAULT_FLAGS, CA_IPV4, ipAddress, port);
213 if (NULL == endPoint)
215 OIC_LOG(ERROR, TAG, "Out of memory!");
219 if (g_networkPacketCallback)
221 g_networkPacketCallback(endPoint, data, dataLength);
223 CAAdapterFreeEndpoint(endPoint);
224 OIC_LOG(DEBUG, TAG, "OUT");
227 CAResult_t CAInitializeIP(CARegisterConnectivityCallback registerCallback,
228 CANetworkPacketReceivedCallback networkPacketCallback,
229 CANetworkChangeCallback netCallback)
231 OIC_LOG(DEBUG, TAG, "IN");
232 VERIFY_NON_NULL(registerCallback, TAG, "registerCallback");
233 VERIFY_NON_NULL(networkPacketCallback, TAG, "networkPacketCallback");
234 VERIFY_NON_NULL(netCallback, TAG, "netCallback");
236 g_networkChangeCallback = netCallback;
237 g_networkPacketCallback = networkPacketCallback;
239 CAResult_t ret = CAIPInitializeNetworkMonitor();
240 if (CA_STATUS_OK != ret)
242 OIC_LOG_V(ERROR, TAG, "init n/w fail:%d", ret);
245 CAIPSetConnectionStateChangeCallback(CAIPConnectionStateCB);
247 ret = CAIPInitializeServer();
248 if (CA_STATUS_OK != ret)
250 OIC_LOG_V(ERROR, TAG, "init fail:%d", ret);
254 CAIPSetPacketReceiveCallback(CAIPPacketReceivedCB);
256 CAConnectivityHandler_t IPHandler;
257 IPHandler.startAdapter = CAStartIP;
258 IPHandler.startListenServer = CAStartIPListeningServer;
259 IPHandler.startDiscoveryServer = CAStartIPDiscoveryServer;
260 IPHandler.sendData = CASendIPUnicastData;
261 IPHandler.sendDataToAll = CASendIPMulticastData;
262 IPHandler.GetnetInfo = CAGetIPInterfaceInformation;
263 IPHandler.readData = CAReadIPData;
264 IPHandler.stopAdapter = CAStopIP;
265 IPHandler.terminate = CATerminateIP;
266 registerCallback(IPHandler, CA_IPV4);
268 OIC_LOG(INFO, TAG, "success");
269 OIC_LOG(DEBUG, TAG, "OUT");
273 CAResult_t CAStartIP()
275 OIC_LOG(DEBUG, TAG, "IN");
277 /* Start monitoring IP network */
278 CAResult_t ret = CAIPStartNetworkMonitor();
279 if (CA_STATUS_OK != ret)
281 OIC_LOG(ERROR, TAG, "strt n/w monitor fail");
284 g_startUnicastServerRequested = true;
285 bool retVal = CAIPIsConnected();
288 OIC_LOG(ERROR, TAG, "not connected");
292 uint16_t unicastPort = CA_PORT;
293 int32_t serverFd = 0;
294 // Address is hardcoded as we are using Single Interface
295 ret = CAIPStartUnicastServer("0.0.0.0", &unicastPort, false, &serverFd);
296 if (CA_STATUS_OK == ret)
298 OIC_LOG_V(DEBUG, TAG, "unicast started:%d", unicastPort);
299 CAIPSetUnicastSocket(serverFd);
300 CAIPSetUnicastPort(unicastPort);
301 g_unicastServerport = unicastPort;
304 OIC_LOG(DEBUG, TAG, "OUT");
308 CAResult_t CAStartIPListeningServer()
310 OIC_LOG(DEBUG, TAG, "IN");
312 CAResult_t ret = CA_STATUS_OK;
313 uint16_t multicastPort = CA_MCAST_PORT;
314 int32_t serverFD = 1;
315 if (g_isMulticastServerStarted == true)
317 OIC_LOG(ERROR, TAG, "Already Started!");
318 return CA_SERVER_STARTED_ALREADY;
321 g_startMulticastServerRequested = true;
322 bool retVal = CAIPIsConnected();
325 OIC_LOG(ERROR, TAG,"Not connected");
326 return CA_ADAPTER_NOT_ENABLED;
329 ret = CAIPStartMulticastServer("0.0.0.0", CA_MULTICAST_IP, multicastPort, &serverFD);
330 if (CA_STATUS_OK == ret)
332 OIC_LOG(INFO, TAG, "multicast success");
333 g_isMulticastServerStarted = true;
336 OIC_LOG(DEBUG, TAG, "OUT");
340 CAResult_t CAStartIPDiscoveryServer()
342 OIC_LOG(DEBUG, TAG, "IN");
343 /* Both listening and discovery server are same */
344 OIC_LOG(DEBUG, TAG, "OUT");
345 return CAStartIPListeningServer();
348 int32_t CASendIPUnicastData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLength)
350 OIC_LOG(DEBUG, TAG, "IN");
352 VERIFY_NON_NULL_RET(endpoint, TAG, "remoteEndpoint", -1);
353 VERIFY_NON_NULL_RET(data, TAG, "data", -1);
356 OIC_LOG(ERROR, TAG, "Invalid length");
360 CAIPSendData(endpoint->addr, endpoint->port, data, dataLength, false);
361 OIC_LOG(DEBUG, TAG, "OUT");
365 int32_t CASendIPMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLength)
367 OIC_LOG(DEBUG, TAG, "IN");
369 VERIFY_NON_NULL_RET(data, TAG, "data", -1);
372 OIC_LOG(ERROR, TAG, "Invalid length");
376 CAIPSendData(CA_MULTICAST_IP, CA_MCAST_PORT, data, dataLength, true);
377 OIC_LOG(DEBUG, TAG, "OUT");
381 CAResult_t CAGetIPInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
383 OIC_LOG(DEBUG, TAG, "IN");
384 VERIFY_NON_NULL(info, TAG, "info");
385 VERIFY_NON_NULL(size, TAG, "size");
387 bool retVal = CAIPIsConnected();
390 OIC_LOG(ERROR, TAG, "Not connected");
391 return CA_ADAPTER_NOT_ENABLED;
394 char *ipAddress = NULL;
395 char *ifcName = NULL;
396 CAResult_t ret = CAIPGetInterfaceInfo(&ipAddress, &ifcName);
397 if (CA_STATUS_OK != ret)
399 OIC_LOG_V(ERROR, TAG, "get interface info fail:%d", ret);
405 // Create local endpoint using util function
406 (*info) = CAAdapterCreateLocalEndpoint(CA_IPV4, ipAddress);
409 OIC_LOG(ERROR, TAG, "malloc fail");
412 return CA_MEMORY_ALLOC_FAILED;
415 (*info)->port = g_unicastServerport;
421 OIC_LOG(INFO, TAG, "success");
422 OIC_LOG(DEBUG, TAG, "OUT");
426 CAResult_t CAReadIPData()
432 CAResult_t CAIPStopServers()
434 CAResult_t result = CAIPStopUnicastServer();
435 if (CA_STATUS_OK != result)
437 OIC_LOG_V(ERROR, TAG, "stop ucast srv fail:%d", result);
440 CAIPSetUnicastSocket(-1);
441 CAIPSetUnicastPort(0);
442 g_unicastServerport = 0;
444 result = CAIPStopMulticastServer();
445 if (CA_STATUS_OK != result)
447 OIC_LOG_V(ERROR, TAG, "stop mcast srv fail:%d", result);
450 g_isMulticastServerStarted = false;
455 CAResult_t CAStopIP()
457 OIC_LOG(DEBUG, TAG, "IN");
459 g_startUnicastServerRequested = false;
460 g_startMulticastServerRequested = false;
461 CAIPStopNetworkMonitor();
462 CAResult_t result = CAIPStopServers();
463 if (CA_STATUS_OK != result)
465 OIC_LOG_V(ERROR, TAG, "stop srv fail:%d", result);
468 OIC_LOG(DEBUG, TAG, "OUT");
474 OIC_LOG(DEBUG, TAG, "IN");
476 CAIPSetConnectionStateChangeCallback(NULL);
477 CAIPTerminateNetworkMonitor();
478 CAIPSetPacketReceiveCallback(NULL);
479 OIC_LOG(INFO, TAG, "Terminated Ethernet");
480 OIC_LOG(DEBUG, TAG, "OUT");