软总线主要包括四大模块:发现,连接,组网,传输。今天我们主要详细介绍一下发现模块。之前我们已经介绍过软总线的PublishService接口和StartDiscovery接口。接下来我们分别详细介绍这些接口的实现细节。
PublishService接口
之前我们介绍软总线的接口的时候,发现PublishService会调用DiscInterfaceByMedium来完成对应的业务处理,DiscInterfaceByMedium的源码如下所示:
static int32_t DiscInterfaceByMedium(const DiscInfo *info, const InterfaceFuncType type)
{
switch (info->medium) {
case BLE:
return DiscInterfaceProcess(&(info->option), g_discBleInterface, info->mode, type);
case COAP:
return DiscInterfaceProcess(&(info->option), g_discCoapInterface, info->mode, type);
case AUTO: {
int32_t ret1 = DiscInterfaceProcess(&(info->option), g_discBleInterface, info->mode, type);
int32_t ret2 = DiscInterfaceProcess(&(info->option), g_discCoapInterface, info->mode, type);
if ((ret1 == SOFTBUS_OK) || (ret2 == SOFTBUS_OK)) {
return SOFTBUS_OK;
}
return SOFTBUS_DISCOVER_MANAGER_INNERFUNCTION_FAIL;
}
default:
return SOFTBUS_DISCOVER_MANAGER_INNERFUNCTION_FAIL;
}
}
即DiscInterfaceByMedium函数根据info的媒介类型,选择不同的接口变量来进行相应的处理。以COAP类型为例,DiscInterfaceProcess的源码如下:
static int32_t DiscInterfaceProcess(const InnerOption *option, const DiscoveryFuncInterface *interface,
const DiscoverMode mode, InterfaceFuncType type)
{
if (interface == NULL) {
return SOFTBUS_DISCOVER_MANAGER_INNERFUNCTION_FAIL;
}
switch (type) {
case PUBLISH_FUNC:
return ((mode == DISCOVER_MODE_ACTIVE) ? (interface->Publish(&(option->publishOption))) :
(interface->StartScan(&(option->publishOption))));
case UNPUBLISH_FUNC:
return ((mode == DISCOVER_MODE_ACTIVE) ? (interface->Unpublish(&(option->publishOption))) :
(interface->StopScan(&(option->publishOption))));
case STARTDISCOVERTY_FUNC:
return ((mode == DISCOVER_MODE_ACTIVE) ? (interface->StartAdvertise(&(option->subscribeOption))) :
(interface->Subscribe(&(option->subscribeOption))));
case STOPDISCOVERY_FUNC:
return ((mode == DISCOVER_MODE_ACTIVE) ? (interface->StopAdvertise(&(option->subscribeOption))) :
(interface->Unsubscribe(&(option->subscribeOption))));
default:
return SOFTBUS_DISCOVER_MANAGER_INNERFUNCTION_FAIL;
}
}
可以看到,当处理类型为PUBLISH_FUNC的时候,如果为主动发现,则调用接口变量的Publish函数处理。如果是被动发现的话,则调用接口变量的StartScan函数处理。
而g_discCoapInterface在DiscMgrInit中初始化,其指向g_discCoapFuncInterface接口,源码如下:
static DiscoveryFuncInterface g_discCoapFuncInterface = {
.Publish = CoapPublish,
.StartScan = CoapStartScan,
.Unpublish = CoapUnPublish,
.StopScan = CoapStoptScan,
.StartAdvertise = CoapStartAdvertise,
.Subscribe = CoapSubscribe,
.StopAdvertise = CoapStopAdvertise,
.Unsubscribe = CoapUnsubscribe
};
因此,在COAP下,如果为主动发现,则相应的处理函数为CoapPublish。如果为被动发现,则相应的处理函数为CoapStartScan,接下来我们介绍这两个对应的处理。
CoapPublish
CoapPublish的源码如下所示:
static int32_t CoapPublish(const PublishOption *option)
{
if (option == NULL || g_publishMgr == NULL) {
return SOFTBUS_INVALID_PARAM;
}
if (pthread_mutex_lock(&(g_publishMgr->lock)) != 0) {
LOG_ERR("pthread mutex lock failed.");
return SOFTBUS_LOCK_ERR;
}
if (RegisterAllCapBitmap(CAPABILITY_NUM, option->capabilityBitmap, g_publishMgr, MAX_CAP_NUM) != SOFTBUS_OK) {
(void)pthread_mutex_unlock(&(g_publishMgr->lock));
LOG_ERR("merge publish capability failed.");
return SOFTBUS_DISCOVER_COAP_MERGE_CAP_FAIL;
}
if (g_publishMgr->isUpdate) {
if (DiscCoapRegisterCapability(CAPABILITY_NUM, g_publishMgr->allCap) != SOFTBUS_OK) {
(void)pthread_mutex_unlock(&(g_publishMgr->lock));
LOG_ERR("register all capability to dfinder failed.");
return SOFTBUS_DISCOVER_COAP_REGISTER_CAP_FAIL;
}
}
if (DiscCoapRegisterServiceData(option->capabilityData, option->dataLen) != SOFTBUS_OK) {
(void)pthread_mutex_unlock(&(g_publishMgr->lock));
LOG_ERR("register service data to dfinder failed.");
return SOFTBUS_ERR;
}
if (DiscCoapStartDiscovery(ACTIVE_PUBLISH) != SOFTBUS_OK) {
(void)pthread_mutex_unlock(&(g_publishMgr->lock));
LOG_ERR("coap start publish failed.");
return SOFTBUS_DISCOVER_COAP_START_DISCOVER_FAIL;
}
(void)pthread_mutex_unlock(&(g_publishMgr->l