APIs to start and stop multicast traffic. For stopping and staring multicast traffic
it manipulates multicast fd and IP_DROP_MEMBERSHIP.
OCStopMulticastTraffic interface is called from rd_client. It stops the multicast traffic.
OCStartMulticastTraffic is implemented but it is not called as this functionality is
not yet implemented.
Change-Id: If56c7af074cbba097b7b23d1abd787093872418a
Signed-off-by: Habib Virji <habib.virji@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/2387
Reviewed-by: Abhishek Sharma <ce.abhishek@samsung.com>
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Abhishek Pandey <abhi.siso@samsung.com>
Reviewed-by: Patrick Lankswert <patrick.lankswert@intel.com>
CAResult_t CAStartListeningServer();
/**
+ * Stops the server from receiving the multicast traffic. This is used by sleeping
+ * device to not receives the multicast traffic.
+ * @return ::CA_STATUS_OK or ::CA_STATUS_FAILED
+ */
+CAResult_t CAStopListeningServer();
+
+/**
* Starts discovery servers.
* This API is used by resource required clients for listening multicast requests.
* Based on the adapters configurations, different kinds of servers are started.
typedef CAResult_t (*CAAdapterStartListeningServer)();
/**
+ * Stopping listening server to not receive multicast search requests
+ * Transport Specific Behavior:
+ * WIFI/ETH Stops multicast server on all available IPs. This is required for the
+ * thin device that call this function once all local resources are pushed to the
+ * resource directory.
+ * @return ::CA_STATUS_OK or ::CA_STATUS_FAILED
+ * ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+typedef CAResult_t (*CAAdapterStopListeningServer)();
+
+/**
* for starting discovery servers for receiving multicast advertisements
* Transport Specific Behavior:
* WIFI/ETH Starts multicast server on all available IPs and defined port
/** Listening Server function address. */
CAAdapterStartListeningServer startListenServer;
+ /** Stops receiving the multicast traffic. */
+ CAAdapterStopListeningServer stopListenServer;
+
/** Discovery Server function address. **/
CAAdapterStartDiscoveryServer startDiscoveryServer;
CAResult_t CAStartEDRListeningServer();
/**
+ * Stop listening server for receiving multicast search requests.
+ * Stop RFCOMM Server with prefixed UUID as per OIC specification.
+ *
+ * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAStopEDRListeningServer();
+
+/**
* Starting discovery server for receiving multicast advertisements.
* Starts RFCOMM Server with prefixed UUID as per OIC specification.
*
CAResult_t CAStartEDRListeningServer();
/**
+ * @brief Stops listening server for receiving multicast search requests.
+ *
+ * @return #CA_STATUS_OK or Appropriate error code
+ */
+CAResult_t CAStopEDRListeningServer();
+
+/**
* @brief Starts discovery server for receiving multicast advertisements.
* Starts RFCOMM Server with prefixed UUID as per OIC specification.
* @return #CA_STATUS_OK or Appropriate error code
CAResult_t CAStartListeningServerAdapters();
/**
+ * Stop listening servers to receive search requests from clients.
+ * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAStopListeningServerAdapters();
+
+/**
* Start discovery servers to receive advertisements from server.
* @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
*/
CAResult_t CAStartListeningServerAdapters();
/**
+ * @brief Stops listening servers to receive search requests from clients
+ * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CAStopListeningServerAdapters();
+
+/**
* @brief Start discovery servers to receive advertisements from server
* @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
*/
CAResult_t CAStartIPListeningServer();
/**
+ * Stop listening server from receiving multicast search requests.
+ * Transport Specific Behavior:
+ * IP closes open multicast socket for a particular interface.
+ * @return ::CA_STATUS_OK or Appropriate error code.
+ */
+CAResult_t CAStopIPListeningServer();
+
+/**
* Start discovery servers for receiving multicast advertisements.
* Transport Specific Behavior:
* IP Starts multicast server on a particular interface and prefixed port
void CAIPStopServer();
/**
+ * Starts receiving the multicast traffic.
+ *
+ * This will be used in case sleepy device wants to start back receiving the multicast
+ * traffic.
+ */
+CAResult_t CAIPStartListenServer();
+
+/**
+ * Stops the multicast traffic.
+ *
+ * This is to be used by the sleeping device to stop receiving multicast traffic.
+ * Once this is set no multicast traffic will be received. Device can still receive
+ * the unicast traffic.
+ */
+CAResult_t CAIPStopListenServer();
+
+/**
* Set this callback for receiving data packets from peer devices.
*
* @param[in] callback Callback to be notified on reception of unicast/multicast data packets.
CAResult_t CAStartRAListeningServer();
/**
+ * Stops listening server from receiving search requests.
+ * @return ::CA_NOT_SUPPORTED.
+ */
+CAResult_t CAStopRAListeningServer();
+
+/**
* Start discovery servers for receiving advertisements.
* @return ::CA_NOT_SUPPORTED.
*/
CAResult_t CAStartTCPListeningServer();
/**
+ * Stops listening server from receiving connect requests.
+ * Transport Specific Behavior:
+ * TCP Stops Listening Server on a particular interface and prefixed port
+ * number and as per OIC Specification.
+ * @return ::CA_STATUS_OK or Appropriate error code.
+ */
+CAResult_t CAStopTCPListeningServer();
+
+/**
* Start discovery servers for receiving advertisements.
* Transport Specific Behavior:
* TCP Starts Discovery server on a particular interface and prefixed port
CAConnectivityHandler_t handler;
handler.startAdapter = CAStartEDR;
handler.startListenServer = CAStartEDRListeningServer;
+ handler.stopListenServer = CAStopEDRListeningServer;
handler.startDiscoveryServer = CAStartEDRDiscoveryServer;
handler.sendData = CASendEDRUnicastData;
handler.sendDataToAll = CASendEDRMulticastData;
return CAStartServer();
}
+CAResult_t CAStopEDRListeningServer()
+{
+ OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+ return CAEDRServerStop();
+}
+
CAResult_t CAStartEDRDiscoveryServer()
{
OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
CAConnectivityHandler_t handler = {
.startAdapter = CAStartEDR,
.startListenServer = CAStartEDRListeningServer,
+ .stopListenServer = CAStopEDRListeningServer,
.startDiscoveryServer = CAStartEDRDiscoveryServer,
.sendData = CASendEDRUnicastData,
.sendDataToAll = CASendEDRMulticastData,
return CA_STATUS_OK;
}
+CAResult_t CAStopEDRListeningServer()
+{
+ OIC_LOG(DEBUG, TAG, "CAStopEDRListeningServer");
+
+ return CA_STATUS_OK;
+}
+
CAResult_t CAStartEDRDiscoveryServer()
{
OIC_LOG(DEBUG, TAG, "CAStartEDRDiscoveryServer");
static CAResult_t CAStartLEListeningServer();
/**
+ * Stops listening server from receiving multicast search requests.
+ *
+ * Transport Specific Behavior:
+ * LE Starts GATT Server with prefixed UUID and Characteristics
+ * per OIC Specification.
+ * @return ::CA_STATUS_OK or Appropriate error code.
+ */
+static CAResult_t CAStopLEListeningServer();
+
+/**
* Sarting discovery of servers for receiving multicast
* advertisements.
*
.startAdapter = CAStartLE,
.stopAdapter = CAStopLE,
.startListenServer = CAStartLEListeningServer,
+ .stopListenServer = CAStopLEListeningServer,
.startDiscoveryServer = CAStartLEDiscoveryServer,
.sendData = CASendLEUnicastData,
.sendDataToAll = CASendLEMulticastData,
#endif
}
+static CAResult_t CAStopLEListeningServer()
+{
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "Listen server stop not supported.");
+ return CA_NOT_SUPPORTED;
+}
+
static CAResult_t CAStartLEDiscoveryServer()
{
OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
return CAStartListeningServerAdapters();
}
+CAResult_t CAStopListeningServer()
+{
+ OIC_LOG(DEBUG, TAG, "CAStopListeningServer");
+
+ if(!g_isInitialized)
+ {
+ return CA_STATUS_NOT_INITIALIZED;
+ }
+
+ return CAStopListeningServerAdapters();
+}
+
CAResult_t CAStartDiscoveryServer()
{
OIC_LOG(DEBUG, TAG, "CAStartDiscoveryServer");
if(handler.startAdapter == NULL ||
handler.startListenServer == NULL ||
+ handler.stopListenServer == NULL ||
handler.startDiscoveryServer == NULL ||
handler.sendData == NULL ||
handler.sendDataToAll == NULL ||
return CA_STATUS_OK;
}
+CAResult_t CAStopListeningServerAdapters()
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+
+ u_arraylist_t *list = CAGetSelectedNetworkList();
+ if (!list)
+ {
+ OIC_LOG(ERROR, TAG, "No selected network");
+ return CA_STATUS_FAILED;
+ }
+
+ for (uint32_t i = 0; i < u_arraylist_length(list); i++)
+ {
+ void* ptrType = u_arraylist_get(list, i);
+ if(ptrType == NULL)
+ {
+ continue;
+ }
+
+ CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
+
+ int index = CAGetAdapterIndex(connType);
+ if (index == -1)
+ {
+ OIC_LOG(ERROR, TAG, "unknown connectivity type!");
+ continue;
+ }
+
+ if (g_adapterHandler[index].stopListenServer != NULL)
+ {
+ g_adapterHandler[index].stopListenServer();
+ }
+ }
+
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
CAResult_t CAStartDiscoveryServerAdapters()
{
OIC_LOG(DEBUG, TAG, "IN");
// Length of the IP address decimal notation string
#define IPNAMESIZE (16)
+/** Multicast IP address.*/
+#define IPv4_MULTICAST "224.0.1.187"
+
+/** Multicast Port.*/
+#define IPv4_MULTICAST_PORT 5683
+
CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port,
const bool forceStart, int32_t *serverFD);
static CAResult_t CAArduinoRecvData(int32_t sockFd);
OIC_LOG_V(ERROR, TAG, "Start unicast server failed[%d]", ret);
return ret;
}
- ret = CAIPStartMulticastServer("0.0.0.0", "224.0.1.187", 5683);
+ ret = CAIPStartMulticastServer("0.0.0.0", IPv4_MULTICAST, IPv4_MULTICAST_PORT);
if (CA_STATUS_OK != ret)
{
OIC_LOG_V(ERROR, TAG, "Start multicast failed[%d]", ret);
return CA_STATUS_OK;
}
+CAResult_t CAIPStartListenServer()
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ CAResult_t ret = CAIPStartMulticastServer("0.0.0.0", IPv4_MULTICAST, IPv4_MULTICAST_PORT);
+ if (CA_STATUS_OK != ret)
+ {
+ OIC_LOG_V(ERROR, TAG, "Start multicast failed[%d]", ret);
+ }
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAIPStopListenServer()
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ CAResult_t ret = CAIPStopMulticastServer();
+ if (CA_STATUS_OK != ret)
+ {
+ OIC_LOG_V(ERROR, TAG, "Stop multicast failed[%d]", ret);
+ }
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
void CAIPStopServer()
{
OIC_LOG(DEBUG, TAG, "IN");
// Length of the IP address decimal notation string
#define IPNAMESIZE (16)
+/** Multicast IP address.*/
+#define IPv4_MULTICAST "224.0.1.187"
+
+/** Multicast Port.*/
+#define IPv4_MULTICAST_PORT 5683
+
// Start offsets based on end of received data buffer
#define IP_RECBUF_IPADDR_OFFSET (6)
#define IP_RECBUF_PORT_OFFSET (2)
OIC_LOG_V(ERROR, TAG, "Start unicast server failed[%d]", ret);
return ret;
}
- ret = CAIPStartMulticastServer("0.0.0.0", "224.0.1.187", 5683);
+ ret = CAIPStartMulticastServer("0.0.0.0", IPv4_MULTICAST, IPv4_MULTICAST_PORT);
if (CA_STATUS_OK != ret)
{
OIC_LOG_V(ERROR, TAG, "Start multicast failed[%d]", ret);
return CAIPStopUnicastServer();
}
+CAResult_t CAIPStartListenServer()
+{
+ CAResult_t ret = CAIPStartMulticastServer("0.0.0.0", IPv4_MULTICAST, IPv4_MULTICAST_PORT);
+ if (CA_STATUS_OK != ret)
+ {
+ OIC_LOG_V(ERROR, TAG, "Start multicast failed[%d]", ret);
+ }
+ return ret;
+}
+
+CAResult_t CAIPStopListenServer()
+{
+ return CAIPStopMulticastServer();
+}
+
void CAIPStopServer()
{
OIC_LOG(DEBUG, TAG, "IN");
OIC_LOG(DEBUG, TAG, "OUT");
return CA_STATUS_OK;
}
-
CAConnectivityHandler_t ipHandler;
ipHandler.startAdapter = CAStartIP;
ipHandler.startListenServer = CAStartIPListeningServer;
+ ipHandler.stopListenServer = CAStopIPListeningServer;
ipHandler.startDiscoveryServer = CAStartIPDiscoveryServer;
ipHandler.sendData = CASendIPUnicastData;
ipHandler.sendDataToAll = CASendIPMulticastData;
CAResult_t CAStartIPListeningServer()
{
OIC_LOG(DEBUG, TAG, "IN");
+ CAResult_t ret = CAIPStartListenServer();
+ if (CA_STATUS_OK != ret)
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to start listening server![%d]", ret);
+ return ret;
+ }
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return CA_STATUS_OK;
+}
+CAResult_t CAStopIPListeningServer()
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ CAResult_t ret = CAIPStopListenServer();
+ if (CA_STATUS_OK != ret)
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to stop listening server![%d]", ret);
+ return ret;
+ }
OIC_LOG(DEBUG, TAG, "OUT");
return CA_STATUS_OK;
}
static CAIPPacketReceivedCallback g_packetReceivedCallback;
static void CAHandleNetlink();
-static void CAApplyInterfaces();
static void CAFindReadyMessage();
static void CASelectReturned(fd_set *readFds, int ret);
static void CAProcessNewInterface(CAInterface_t *ifchanged);
caglobals.ip.selectTimeout = CAGetPollingInterval(caglobals.ip.selectTimeout);
- CAApplyInterfaces();
+ res = CAIPStartListenServer();
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to start listening server![%d]", res);
+ return res;
+ }
caglobals.ip.terminate = false;
res = ca_thread_pool_add_task(threadPool, CAReceiveHandler, NULL);
//applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressGlb, interface);
}
-static void CAApplyInterfaces()
+CAResult_t CAIPStartListenServer()
{
u_arraylist_t *iflist = CAIPGetInterfaceInformation(0);
if (!iflist)
{
OIC_LOG_V(ERROR, TAG, "get interface info failed: %s", strerror(errno));
- return;
+ return CA_STATUS_FAILED;
}
uint32_t len = u_arraylist_length(iflist);
}
u_arraylist_destroy(iflist);
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAIPStopListenServer()
+{
+ u_arraylist_t *iflist = CAIPGetInterfaceInformation(0);
+ if (!iflist)
+ {
+ OIC_LOG_V(ERROR, TAG, "Get interface info failed: %s", strerror(errno));
+ return CA_STATUS_FAILED;
+ }
+
+ uint32_t len = u_arraylist_length(iflist);
+ OIC_LOG_V(DEBUG, TAG, "IP network interfaces found: %d", len);
+
+ for (uint32_t i = 0; i < len; i++)
+ {
+ CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
+
+ if (!ifitem)
+ {
+ continue;
+ }
+
+ if ((ifitem->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
+ {
+ continue;
+ }
+ if (ifitem->family == AF_INET)
+ {
+ close(caglobals.ip.m4.fd);
+ close(caglobals.ip.m4s.fd);
+ caglobals.ip.m4.fd = -1;
+ caglobals.ip.m4s.fd = -1;
+ OIC_LOG_V(DEBUG, TAG, "IPv4 network interface: %s cloed", ifitem->name);
+ }
+ if (ifitem->family == AF_INET6)
+ {
+ close(caglobals.ip.m6.fd);
+ close(caglobals.ip.m6s.fd);
+ caglobals.ip.m6.fd = -1;
+ caglobals.ip.m6s.fd = -1;
+ OIC_LOG_V(DEBUG, TAG, "IPv6 network interface: %s", ifitem->name);
+ }
+ }
+ u_arraylist_destroy(iflist);
+ return CA_STATUS_OK;
}
static void CAProcessNewInterface(CAInterface_t *ifitem)
OIC_LOG(DEBUG, TAG, "OUT");
return CA_STATUS_OK;
}
-
CAConnectivityHandler_t raHandler = {};
raHandler.startAdapter = CAStartRA;
raHandler.startListenServer = CAStartRAListeningServer;
+ raHandler.stopListenServer = CAStopRAListeningServer;
raHandler.startDiscoveryServer = CAStartRADiscoveryServer;
raHandler.sendData = CASendRAUnicastData;
raHandler.sendDataToAll = CASendRAMulticastData;
return CA_NOT_SUPPORTED;
}
+CAResult_t CAStopRAListeningServer()
+{
+ OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support listening for multicast data");
+ return CA_NOT_SUPPORTED;
+}
+
CAResult_t CAStartRADiscoveryServer()
{
OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support discovery of multicast servers");
CAConnectivityHandler_t TCPHandler = {
.startAdapter = CAStartTCP,
.startListenServer = CAStartTCPListeningServer,
+ .stopListenServer = CAStopTCPListeningServer,
.startDiscoveryServer = CAStartTCPDiscoveryServer,
.sendData = CASendTCPUnicastData,
.sendDataToAll = CASendTCPMulticastData,
return CA_STATUS_OK;
}
+CAResult_t CAStopTCPListeningServer()
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
CAResult_t CAStartTCPDiscoveryServer()
{
OIC_LOG(DEBUG, TAG, "IN");
OCStackResult OCStop();
/**
+ * This function starts receiving the multicast traffic. This can be only called
+ * when stack is in OC_STACK_INITIALIZED state but device is not receiving multicast
+ * traffic.
+ *
+ * @return ::OC_STACK_OK on success, some other value upon failure.
+ */
+OCStackResult OCStartMulticastServer();
+
+/**
+ * This function stops receiving the multicast traffic. The rest of the stack
+ * keeps working and no resource are deleted. Device can still receive the unicast
+ * traffic. Once this is set, no response to multicast /oic/res will be sent by the
+ * device. This is to be used for devices that uses other entity to push resources.
+ *
+ * @return ::OC_STACK_OK on success, some other value upon failure.
+ */
+OCStackResult OCStopMulticastServer();
+
+/**
* This function is Called in main loop of OC client or server.
* Allows low-level processing of stack services.
*
return OC_STACK_OK;
}
+OCStackResult OCStartMulticastServer()
+{
+ if(stackState != OC_STACK_INITIALIZED)
+ {
+ OC_LOG(ERROR, TAG, "OCStack is not initalized. Cannot start multicast server.");
+ return OC_STACK_ERROR;
+ }
+ CAResult_t ret = CAStartListeningServer();
+ if (CA_STATUS_OK != ret)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed starting listening server: %d", ret);
+ return OC_STACK_ERROR;
+ }
+ return OC_STACK_OK;
+}
+
+OCStackResult OCStopMulticastServer()
+{
+ CAResult_t ret = CAStopListeningServer();
+ if (CA_STATUS_OK != ret)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed stopping listening server: %d", ret);
+ return OC_STACK_ERROR;
+ }
+ return OC_STACK_OK;
+}
+
CAMessageType_t qualityOfServiceToMessageType(OCQualityOfService qos)
{
switch (qos)
# Build notification manager project
SConscript('notification-manager/SConscript')
-
+
# Build resource-encapsulation project
if target_os not in ['tizen']:
SConscript('resource-encapsulation/SConscript')
OCStackApplicationResult ret = OC_STACK_DELETE_TRANSACTION;
OC_LOG(DEBUG, TAG, "Successfully published resources.");
- // TOOO: Stop multicast traffic on the client.
+ if (OC_STACK_OK == OCStopMulticastServer())
+ {
+ OC_LOG_V(DEBUG, TAG, "Stopped receiving the multicast traffic.");
+ }
+ else
+ {
+ OC_LOG_V(DEBUG, TAG, "Failed stopping the multicast traffic.");
+ }
return ret;
}