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 ******************************************************************/
20 #include "cawifiinterface.h"
22 #include <sys/types.h>
23 #include <sys/socket.h>
26 #include <sys/select.h>
27 #include <arpa/inet.h>
28 #include <netinet/in.h>
32 #include "caadapterutils.h"
34 #include "caadapternetdtls.h"
37 #include "oic_malloc.h"
38 #include "oic_string.h"
41 * @def WIFI_SERVER_TAG
42 * @brief Logging tag for module name
44 #define WIFI_SERVER_TAG "WIFI_SERVER"
47 * @def CA_UDP_BIND_RETRY_COUNT
48 * @brief Retry count in case of socket bind failure.
50 #define CA_UDP_BIND_RETRY_COUNT 10
54 * @brief max length for ip
59 * @var g_unicastServerSocketFD
60 * @brief Unicast server socket descriptor
62 static int32_t g_unicastServerSocketFD = -1;
65 * @var g_mutexUnicastServer
66 * @brief Mutex to synchronize unicast server
68 static u_mutex g_mutexUnicastServer = NULL;
72 * @brief Flag to control the Receive Unicast Data Thread
74 static bool g_stopUnicast = false;
77 * @var g_multicastServerSocketFD
78 * @brief socket descriptor for multicast server
80 static int32_t g_multicastServerSocketFD = -1;
83 * @var g_mutexMulticastServer
84 * @brief Mutex to synchronize secure multicast server
86 static u_mutex g_mutexMulticastServer = NULL;
89 * @var g_stopMulticast
90 * @brief Flag to control the Receive Multicast Data Thread
92 static bool g_stopMulticast = false;
96 * @var g_secureUnicastServerSocketFD
97 * @brief Secure unicast server socket descriptor
99 static int32_t g_secureUnicastServerSocketFD = -1;
102 * @var g_mutexSecureUnicastServer
103 * @brief Mutex to synchronize secure unicast server
105 static u_mutex g_mutexSecureUnicastServer = NULL;
108 * @var g_stopSecureUnicast
109 * @brief Flag to control the unicast secure data receive thread
111 static bool g_stopSecureUnicast = false;
116 * @brief ThreadPool for storing u_thread_pool_t handle passed from adapter
118 static u_thread_pool_t g_threadPool = NULL;
121 * @var g_multicastServerInterface
122 * @brief Local interface on which multicast server is running
124 static char g_multicastServerInterface[IPNAMESIZE];
127 * @var g_multicastMemberReq
128 * @brief ip_mreq structure passed to join a multicast group
130 static struct ip_mreq g_multicastMemberReq;
133 * @var g_packetReceivedCallback
134 * @brief Callback for notifying the upper layer on receival data from remote OIC device
136 static CAWiFiPacketReceivedCallback g_packetReceivedCallback = NULL;
139 * @var g_exceptionCallback
140 * @brief Callback for notifying the upper layer when unicast/multicast server encounters exception
142 static CAWiFiExceptionCallback g_exceptionCallback = NULL;
145 @brief Thread context information for unicast, multicast and secured unicast server
151 CAAdapterServerType_t type;
152 } CAAdapterReceiveThreadContext_t;
154 static void CAReceiveHandler(void *data)
156 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
158 VERIFY_NON_NULL_VOID(data, WIFI_SERVER_TAG, "Invalid thread context");
160 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)data;
161 while (true != *(ctx->stopFlag))
164 struct timeval timeout;
170 FD_SET(ctx->socket_fd, &reads);
172 int ret = select(ctx->socket_fd + 1, &reads, NULL, NULL, &timeout);
173 if (*(ctx->stopFlag) == true)
175 OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Stop request received for [%d] server", ctx->type);
180 OIC_LOG_V(FATAL, WIFI_SERVER_TAG, "select returned error %s", strerror(errno));
183 if (!FD_ISSET(ctx->socket_fd, &reads))
188 // Read data from socket
189 struct sockaddr_in srcSockAddress;
191 socklen_t srcAddressLen = sizeof(srcSockAddress);
192 char recvBuffer[COAP_MAX_PDU_SIZE] = {};
194 if (-1 == (recvLen = recvfrom(ctx->socket_fd, recvBuffer,
195 sizeof(recvBuffer), 0, (struct sockaddr *) &srcSockAddress,
198 OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "%s", strerror(errno));
201 else if (0 == recvLen)
203 OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Server socket shutdown [%d]!", ctx->type);
205 // Notify upper layer this exception
206 if (g_exceptionCallback)
208 g_exceptionCallback(ctx->type);
214 const char *ipAddress = inet_ntoa(srcSockAddress.sin_addr);
215 uint16_t srcPort = ntohs(srcSockAddress.sin_port);
217 char *srcIPAddress = OICStrdup(ipAddress);
218 if(NULL == srcIPAddress)
221 OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Error in OICStrdup, exit CAReceiveHandler");
225 OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Received packet from %s:%d\n",
226 srcIPAddress, srcPort);
227 OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
228 recvBuffer, recvLen);
230 char *netMask = NULL;
231 if (CA_STATUS_OK != CAWiFiGetInterfaceSubnetMask(&netMask))
233 OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to get ethernet subnet");
234 OICFree(srcIPAddress);
238 if (!CAAdapterIsSameSubnet(g_multicastServerInterface, srcIPAddress, netMask))
240 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Packet received from different subnet, Ignore!");
241 OICFree(srcIPAddress);
249 case CA_UNICAST_SERVER:
250 case CA_MULTICAST_SERVER:
251 // Notify data to upper layer
252 if (g_packetReceivedCallback)
254 g_packetReceivedCallback(srcIPAddress, srcPort, recvBuffer, recvLen, false);
258 case CA_SECURED_UNICAST_SERVER:
260 CAResult_t ret = CAAdapterNetDtlsDecrypt(srcIPAddress,
262 (uint8_t *)recvBuffer,
264 OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "CAAdapterNetDtlsDecrypt returns [%d]", ret);
267 #endif //__WITH_DTLS__
269 // Should never occur
270 OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Invalid server type");
271 OICFree(srcIPAddress);
276 OICFree(srcIPAddress);
282 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
285 static CAResult_t CAWiFiCreateSocket(int *socketFD, const char *localIp, uint16_t *port,
289 // Create a UDP socket
290 if (-1 == (sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)))
292 OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to create Socket, Error code: %s",
294 return CA_STATUS_FAILED;
297 // Make the socket non-blocking
298 if (-1 == fcntl(sock, F_SETFL, O_NONBLOCK))
300 OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
304 return CA_STATUS_FAILED;
307 if (true == forceStart)
309 int32_t setOptionOn = 1;
310 if (-1 == setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
311 (char *) &setOptionOn,
312 sizeof(setOptionOn)))
314 OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to set SO_REUSEADDR! Error code: %s",
318 return CA_STATUS_FAILED;
322 struct sockaddr_in sockAddr;
323 bool isBound = false;
324 uint16_t serverPort = *port;
326 sockAddr.sin_family = AF_INET;
327 sockAddr.sin_port = htons(serverPort);
330 sockAddr.sin_addr.s_addr = inet_addr(localIp);
334 sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
338 for (i = 0; i < CA_UDP_BIND_RETRY_COUNT; i++)
340 if (-1 == bind(sock, (struct sockaddr *) &sockAddr,
343 if (false == forceStart)
345 OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to bind socket[%s]. Trying again..",
348 //Set the port to next one
350 sockAddr.sin_port = htons(serverPort);
355 OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to bind socket[%s]!",
365 if (false == isBound)
368 return CA_STATUS_FAILED;
376 static CAResult_t CAWiFiCloseSocket(int *socketFD)
380 OIC_LOG(INFO, WIFI_SERVER_TAG, "Server not running");
381 return CA_SERVER_NOT_STARTED;
385 if (-1 == close(*socketFD))
387 OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to close the socket, Error code: %s\n",
389 return CA_STATUS_FAILED;
396 static CAResult_t CAStartUnicastServer(const char *localAddress, uint16_t *port,
397 bool forceStart, bool isSecured, int *serverFD)
399 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
401 CAResult_t ret = CAWiFiCreateSocket(serverFD, localAddress, port, forceStart);
402 if (CA_STATUS_OK != ret)
404 OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to create unicast socket");
409 * The task to listen for data from unicast socket is added to the thread pool.
410 * This is a blocking call is made where we try to receive some data..
411 * We will keep waiting until some data is received.
412 * This task will be terminated when thread pool is freed on stopping the adapters.
413 * Thread context will be freed by thread on exit.
415 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)
416 OICMalloc(sizeof(CAAdapterReceiveThreadContext_t));
419 OIC_LOG(ERROR, WIFI_SERVER_TAG, "Out of memory!");
421 return CA_MEMORY_ALLOC_FAILED;
424 ctx->stopFlag = &g_stopUnicast;
425 ctx->socket_fd = *serverFD;
426 ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
427 if (CA_STATUS_OK != u_thread_pool_add_task(g_threadPool, CAReceiveHandler, (void *)ctx))
429 OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to create read thread!");
432 return CA_STATUS_FAILED;
435 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
439 static void CAWiFiServerDestroyMutex(void)
441 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
443 if (g_mutexUnicastServer)
445 u_mutex_free(g_mutexUnicastServer);
446 g_mutexUnicastServer = NULL;
450 if (g_mutexSecureUnicastServer)
452 u_mutex_free(g_mutexSecureUnicastServer);
453 g_mutexSecureUnicastServer = NULL;
457 if (g_mutexMulticastServer)
459 u_mutex_free(g_mutexMulticastServer);
460 g_mutexMulticastServer = NULL;
463 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
466 static CAResult_t CAWiFiServerCreateMutex(void)
468 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
470 g_mutexUnicastServer = u_mutex_new();
471 if (!g_mutexUnicastServer)
473 OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
474 return CA_STATUS_FAILED;
478 g_mutexSecureUnicastServer = u_mutex_new();
479 if (!g_mutexSecureUnicastServer)
481 OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
483 CAWiFiServerDestroyMutex();
484 return CA_STATUS_FAILED;
488 g_mutexMulticastServer = u_mutex_new();
489 if (!g_mutexMulticastServer)
491 OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
493 CAWiFiServerDestroyMutex();
494 return CA_STATUS_FAILED;
497 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
501 CAResult_t CAWiFiInitializeServer(const u_thread_pool_t threadPool)
503 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
506 VERIFY_NON_NULL(threadPool, WIFI_SERVER_TAG, "Thread pool handle is NULL");
509 if (CA_STATUS_OK != CAWiFiServerCreateMutex())
511 OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to create mutex!");
512 return CA_STATUS_FAILED;
515 g_threadPool = threadPool;
517 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
521 void CAWiFiTerminateServer(void)
523 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
528 CAWiFiServerDestroyMutex();
530 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
533 CAResult_t CAWiFiStartUnicastServer(const char *localAddress, uint16_t *port,
534 const bool forceStart, const bool isSecured,
537 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
540 VERIFY_NON_NULL(localAddress, WIFI_SERVER_TAG, "localAddress");
541 VERIFY_NON_NULL(port, WIFI_SERVER_TAG, "port");
542 VERIFY_NON_NULL(serverFD, WIFI_SERVER_TAG, "server socket FD");
546 OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Invalid input: port is invalid!");
547 return CA_STATUS_INVALID_PARAM;
551 if (false == isSecured)
553 u_mutex_lock(g_mutexUnicastServer);
554 if (-1 != g_unicastServerSocketFD)
556 OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Unicast Server is Started Already!",
557 CA_SERVER_STARTED_ALREADY);
559 *serverFD = g_unicastServerSocketFD;
560 u_mutex_unlock(g_mutexUnicastServer);
561 return CA_SERVER_STARTED_ALREADY;
564 g_stopUnicast = false;
565 if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, forceStart, isSecured,
566 &g_unicastServerSocketFD))
568 OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to start unicast server!");
569 close(g_unicastServerSocketFD);
570 g_unicastServerSocketFD = -1;
571 u_mutex_unlock(g_mutexUnicastServer);
572 return CA_STATUS_FAILED;
575 *serverFD = g_unicastServerSocketFD;
576 u_mutex_unlock(g_mutexUnicastServer);
579 else // Start unicast server for secured communication
581 u_mutex_lock(g_mutexSecureUnicastServer);
582 if (-1 != g_secureUnicastServerSocketFD)
584 OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Unicast Server is Started Already!",
585 CA_SERVER_STARTED_ALREADY);
587 *serverFD = g_secureUnicastServerSocketFD;
588 u_mutex_unlock(g_mutexSecureUnicastServer);
589 return CA_SERVER_STARTED_ALREADY;
592 g_stopSecureUnicast = false;
593 if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, forceStart, isSecured,
594 &g_secureUnicastServerSocketFD))
596 OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to start unicast server!");
597 g_secureUnicastServerSocketFD = -1;
598 u_mutex_unlock(g_mutexSecureUnicastServer);
599 return CA_STATUS_FAILED;
602 *serverFD = g_secureUnicastServerSocketFD;
603 u_mutex_unlock(g_mutexSecureUnicastServer);
606 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
610 CAResult_t CAWiFiStartMulticastServer(const char *localAddress, const char *multicastAddress,
611 const uint16_t multicastPort, int32_t *serverFD)
613 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
616 VERIFY_NON_NULL(localAddress, WIFI_SERVER_TAG, "Local address is NULL");
617 VERIFY_NON_NULL(multicastAddress, WIFI_SERVER_TAG, "Multicast address is NULL");
618 VERIFY_NON_NULL(serverFD, WIFI_SERVER_TAG, "serverFD address is NULL");
620 uint16_t port = multicastPort;
623 OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Invalid input: Multicast port is invalid!");
624 return CA_STATUS_INVALID_PARAM;
627 u_mutex_lock(g_mutexMulticastServer);
629 if (g_multicastServerSocketFD != -1)
631 OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast Server is already running!");
632 u_mutex_unlock(g_mutexMulticastServer);
633 return CA_SERVER_STARTED_ALREADY;
636 CAResult_t ret = CAWiFiCreateSocket(&g_multicastServerSocketFD, multicastAddress, &port, true);
637 if (ret != CA_STATUS_OK)
639 OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to create multicast socket");
640 u_mutex_unlock(g_mutexMulticastServer);
644 // Add membership to receiving socket (join group)
645 memset(&g_multicastMemberReq, 0, sizeof(struct ip_mreq));
646 g_multicastMemberReq.imr_interface.s_addr = inet_addr(localAddress);
647 inet_aton(multicastAddress, &g_multicastMemberReq.imr_multiaddr);
649 if (-1 == setsockopt(g_multicastServerSocketFD, IPPROTO_IP, IP_ADD_MEMBERSHIP,
650 (char *) &g_multicastMemberReq,
651 sizeof(struct ip_mreq)))
653 OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to add to multicast group, Error code: %s\n",
655 close(g_multicastServerSocketFD);
656 g_multicastServerSocketFD = -1;
657 u_mutex_unlock(g_mutexMulticastServer);
658 return CA_STATUS_FAILED;
662 * The task to listen to data from multicastcast socket is added to the thread pool.
663 * This is a blocking call is made where we try to receive some data.
664 * We will keep waiting until some data is received.
665 * This task will be terminated when thread pool is freed on stopping the adapters.
666 * Thread context will be freed by thread on exit.
668 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)
669 OICMalloc(sizeof(CAAdapterReceiveThreadContext_t));
672 OIC_LOG(ERROR, WIFI_SERVER_TAG, "Out of memory!");
673 close(g_multicastServerSocketFD);
674 g_multicastServerSocketFD = -1;
675 return CA_MEMORY_ALLOC_FAILED;
678 ctx->stopFlag = &g_stopMulticast;
679 ctx->socket_fd = g_multicastServerSocketFD;
680 ctx->type = CA_MULTICAST_SERVER;
682 g_stopMulticast = false;
683 if (CA_STATUS_OK != u_thread_pool_add_task(g_threadPool, CAReceiveHandler, (void *)ctx))
685 OIC_LOG(ERROR, WIFI_SERVER_TAG, "thread_pool_add_task failed!");
687 close(g_multicastServerSocketFD);
688 g_multicastServerSocketFD = -1;
689 g_stopMulticast = true;
690 u_mutex_unlock(g_mutexMulticastServer);
691 return CA_STATUS_FAILED;
694 *serverFD = g_multicastServerSocketFD;
695 strncpy(g_multicastServerInterface, localAddress, IPNAMESIZE);
696 u_mutex_unlock(g_mutexMulticastServer);
698 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
702 CAResult_t CAWiFiStopUnicastServer()
704 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
706 u_mutex_lock(g_mutexUnicastServer);
707 g_stopUnicast = true;
708 CAResult_t ret = CAWiFiCloseSocket(&g_unicastServerSocketFD);
709 u_mutex_unlock(g_mutexUnicastServer);
711 OIC_LOG_V(INFO, WIFI_SERVER_TAG, "Unicast server stopped [%d]", ret);
716 CAResult_t CAWiFiStopSecureUnicastServer()
718 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
720 u_mutex_lock(g_mutexSecureUnicastServer);
721 g_stopSecureUnicast = true;
722 CAResult_t ret = CAWiFiCloseSocket(&g_secureUnicastServerSocketFD);
723 u_mutex_unlock(g_mutexSecureUnicastServer);
725 OIC_LOG_V(INFO, WIFI_SERVER_TAG, "Secured unicast server stopped [%d]", ret);
730 CAResult_t CAWiFiStopMulticastServer(void)
732 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
734 u_mutex_lock(g_mutexMulticastServer);
736 if (g_multicastServerSocketFD == -1)
738 OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast server is not yet started");
739 u_mutex_unlock(g_mutexMulticastServer);
740 return CA_SERVER_NOT_STARTED;
743 g_stopMulticast = true;
745 // leave the group after you are done
746 if (-1 == setsockopt(g_multicastServerSocketFD, IPPROTO_IP, IP_DROP_MEMBERSHIP,
747 (char *)&g_multicastMemberReq,
748 sizeof(struct ip_mreq)))
750 OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to leave multicast group, Error code: %s\n",
754 CAResult_t ret = CAWiFiCloseSocket(&g_multicastServerSocketFD);
755 u_mutex_unlock(g_mutexMulticastServer);
757 OIC_LOG_V(INFO, WIFI_SERVER_TAG, "Multicast server stopped [%d]", ret);
761 CAResult_t CAWiFiGetUnicastServerInfo(const bool isSecured, char **ipAddress,
762 uint16_t *port, int32_t *serverFD)
764 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
767 VERIFY_NON_NULL(ipAddress, WIFI_SERVER_TAG, "IP address");
768 VERIFY_NON_NULL(port, WIFI_SERVER_TAG, "Port");
769 VERIFY_NON_NULL(serverFD, WIFI_SERVER_TAG, "Server ID");
771 struct sockaddr_in sockAddr;
772 socklen_t len = sizeof(struct sockaddr_in);
773 if (-1 == getsockname(g_unicastServerSocketFD, (struct sockaddr *)&sockAddr, &len))
775 OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed in getsockname [%s]!", strerror(errno));
776 return CA_STATUS_FAILED;
780 const char *serverAddress = inet_ntoa(sockAddr.sin_addr);
781 *ipAddress = (serverAddress) ? strndup(serverAddress, strlen(serverAddress)) : NULL;
782 *port = ntohs(sockAddr.sin_port);
784 *serverFD = (true == isSecured) ? g_secureUnicastServerSocketFD : g_unicastServerSocketFD;
786 *serverFD = g_unicastServerSocketFD;
788 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
792 void CAWiFiSetPacketReceiveCallback(CAWiFiPacketReceivedCallback callback)
794 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
796 g_packetReceivedCallback = callback;
799 void CAWiFiSetExceptionCallback(CAWiFiExceptionCallback callback)
801 OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
803 g_exceptionCallback = callback;