OpenHarmony 电话子系统源码解析之Cellular_Data 原创 精华

深开鸿
发布于 2022-5-7 15:10
浏览
1收藏

作者:樊超

1. 电话子系统概述

电话服务子系统各个模块主要作用如下:

核心服务模块:主要功能是初始化RIL管理、SIM卡和搜网模块。

数据服务模块:主要功能是实现数据上网和路由管理相关的业务。

通话管理模块:主要功能是管理CS(Circuit Switch,电路交换)、IMS(IP Multimedia Subsystem,IP多媒体子系统)和OTT(over the top,OTT解决方案)三种类型的通话,申请通话所需要的音视频资源,处理多路通话时产生的各种冲突。

蜂窝通话模块:主要功能是实现基于运营商网络的基础通话。

短彩信模块:主要功能是短信收发和彩信编解码。

状态注册模块:主要功能是提供电话服务子系统各种消息事件的订阅以及取消订阅的API。

1.1 电话子系统框架图

OpenHarmony 电话子系统源码解析之Cellular_Data-鸿蒙开发者社区

2. Cellular_Data(数据服务模块)

2.1 代码目录

\base\telephony\ cellular_data

├─ frameworks # napi接口存放目录

├─ interfaces # 对外部暴露的接口

├─ services # 服务内部代码

│ ├─ apn_manager # apn管理

│ ├─ state_machine # data 状态机

│ ├─ utils # 通用逻辑

│ └─ 外部files

├─ sa_profile # sa文件

├─ ohos.build # 编译build

└─ test # 测试相关

2.2 流程图

APP调用数据业务的流程会依次经过Data Service,Core Service,RIL Adapter/RILD,再经过AT命令的处理到达CP处理器。

CP处理器处理完数据命令后,会依次将结果再返回,到达Data Service,最终将获得的上网相关数据,如ip,interface,gateway,dns等设置到netmanager/netd,最终配置到kernel中。

流程图如下:

OpenHarmony 电话子系统源码解析之Cellular_Data-鸿蒙开发者社区

2.3 data service初始化流程

Data service的初始化流程如下图所示:

OpenHarmony 电话子系统源码解析之Cellular_Data-鸿蒙开发者社区

具体的代码调用流程如下:

\telephony\cellular_data\services\src\cellular_data_service.cpp

在OnStart函数中先等待CoreService启动成功WaitCoreServiceToInit,然后进行data service的init初始化流程。

1.	void CellularDataService::OnStart()  
2.	{  
3.	    if (state_ == ServiceRunningState::STATE_RUNNING) {  
4.	        TELEPHONY_LOGE("CellularDataService has already started.");  
5.	        return;  
6.	    }  
7.	    WaitCoreServiceToInit();  
8.	    if (!Init()) {  
9.	        TELEPHONY_LOGE("failed to init CellularDataService");  
10.	        return;  
11.	    }  
12.	    state_ = ServiceRunningState::STATE_RUNNING;  
13.	    TELEPHONY_LOGD("CellularDataService::OnStart start service success.");  
14.	}  

在初始化init流程中,会依次进行InitModule的初始化,主要是生成CellularDataController和netd相关的对象的初始化.

1.	void CellularDataService::InitModule()  
2.	{  
3.	    simSwitcher_ = std::make_unique<SIMSwitcher>();  
4.	    if (simSwitcher_ == nullptr) {  
5.	        TELEPHONY_LOGE("CellularDataService init module failed simSwitcher_ is null");  
6.	        return;  
7.	    }  
8.	    auto &netAgent = CellularDataNetAgent::GetInstance();  
9.	    netAgent.ClearNetProvider();  
10.	    cellularDataControllers_.clear();  
11.	    uint32_t netCapabilities = NetCapabilities::NET_CAPABILITIES_INTERNET | NetCapabilities::NET_CAPABILITIES_MMS;  
12.	    int32_t simNum = SimUtils::GetSimNum();  
13.	    for (int32_t i = 0; i < simNum; ++i) {  
14.	        auto cellularDataController = std::make_shared<CellularDataController>(eventLoop_, i);  
15.	        if (cellularDataController == nullptr) {  
16.	            TELEPHONY_LOGE("CellularDataService init module failed cellularDataController is null");  
17.	            continue;  
18.	        }  
19.	        cellularDataControllers_.push_back(std::move(cellularDataController));  
20.	        NetProvider netProvider = { 0 };  
21.	        netProvider.providerId = NET_CONN_ERR_INVALID_PROVIDER_ID;  
22.	        netProvider.slotId = i;  
23.	        netProvider.netType = NetworkType::NET_TYPE_CELLULAR;  
24.	        netProvider.capabilities = netCapabilities;  
25.	        netAgent.AddNetProvider(netProvider);  
26.	    }  
27.	}  

\telephony\cellular_data\services\src\cellular_data_controller.cpp

在AsynchronousRegister函数中,会依次进行CellularDataController的初始化、注册监听事件、注册database监听。还有要进行CellularDataHandler的初始化。

1.	void CellularDataController::AsynchronousRegister()  
2.	{  
3.	    auto core = CoreManager::GetInstance().getCore(slotId_);  
4.	    if (core != nullptr && core->IsInitCore()) {  
5.	        TELEPHONY_LOGD("core inited %{public}d", slotId_);  
6.	        Init();  
7.	        RegisterEvents();  
8.	        return;  
9.	    }  
10.	}  
11.	  
12.	void CellularDataController::Init()  
13.	{  
14.	    cellularDataHandler_ = std::make_shared<CellularDataHandler>(GetEventRunner(), slotId_);  
15.	    settingObserver_ = std::make_shared<CellularDataSettingObserver>(cellularDataHandler_);  
16.	    cellularDataRdbObserver_ = std::make_unique<CellularDataRdbObserver>(cellularDataHandler_).release();  
17.	    if (cellularDataHandler_ == nullptr || settingObserver_ == nullptr || cellularDataRdbObserver_ == nullptr) {  
18.	        TELEPHONY_LOGE("CellularDataController init failed, "  
19.	            "cellularDataHandler_ or settingObserver_ or cellularDataRdbObserver_ is null");  
20.	        return;  
21.	    }  
22.	    cellularDataHandler_->Init();  
23.	    RegisterDatabaseObserver();  
24.	}

注册的监听事件包括了网络状态的监听、radio状态的监听和电话状态的监听等,这些都会对数据的状态产生影响。

1.	void CellularDataController::RegisterEvents()  
2.	{  
3.	    if (cellularDataHandler_ == nullptr) {  
4.	        TELEPHONY_LOGE("core is null or cellularDataHandler is null");  
5.	        return;  
6.	    }  
7.	    TELEPHONY_LOGD("NetworkSearchUtils register start");  
8.	    SimUtils::RegisterIccFileLoadedNotify(  
9.	        slotId_, cellularDataHandler_, ObserverHandler::RADIO_SIM_RECORDS_LOADED, nullptr);  
10.	    NetworkSearchUtils::RegisterForPSNotify(  
11.	        slotId_, cellularDataHandler_, ObserverHandler::RADIO_PS_CONNECTION_ATTACHED, nullptr);  
12.	    NetworkSearchUtils::RegisterForPSNotify(  
13.	        slotId_, cellularDataHandler_, ObserverHandler::RADIO_PS_CONNECTION_DETACHED, nullptr);  
14.	    NetworkSearchUtils::RegisterForPSNotify(  
15.	        slotId_, cellularDataHandler_, ObserverHandler::RADIO_PS_ROAMING_OPEN, nullptr);  
16.	    NetworkSearchUtils::RegisterForPSNotify(  
17.	        slotId_, cellularDataHandler_, ObserverHandler::RADIO_PS_ROAMING_CLOSE, nullptr);  
18.	    NetworkSearchUtils::RegisterForRadioStateChanged(  
19.	        slotId_, cellularDataHandler_, ObserverHandler::RADIO_STATE_CHANGED, nullptr);  
20.	    NetworkSearchUtils::RegisterPsRatChanged(  
21.	        slotId_, cellularDataHandler_, ObserverHandler::RADIO_PS_RAT_CHANGED, nullptr);  
22.	    CellularCallUtils::RegisterCallStateUpdateChanged(  
23.	        slotId_, cellularDataHandler_, ObserverHandler::RADIO_CALL_STATUS_INFO, nullptr);  
24.	    TELEPHONY_LOGD("NetworkSearchUtils register end"); 

\telephony\cellular_data\services\src\cellular_data_handler.cpp

CellularDataHandler的Init函数中,主要是对apn管理相关的模块进行初始化,包含ApnManager和ApnHolder等。

1.	void CellularDataHandler::Init()  
2.	{  
3.	    sequence_ = 0;  
4.	    apnManager_ = std::make_unique<ApnManager>().release();  
5.	    dataSwitchSettings_ = std::make_unique<DataSwitchSettings>();  
6.	    connectionManager_ = std::make_unique<DataConnectionManager>(GetEventRunner(), slotId_).release();  
7.	    if ((apnManager_ == nullptr) || (dataSwitchSettings_ == nullptr) || (connectionManager_ == nullptr)) {  
8.	        TELEPHONY_LOGE("apnManager_ or dataSwitchSettings_ or connectionManager_ is null");  
9.	        return;  
10.	    }  
11.	    apnManager_->InitApnHolders();  
12.	    apnManager_->CreateAllApnItem();  
13.	    dataSwitchSettings_->LoadSwitchValue(slotId_);  
14.	}  

\telephony\cellular_data\services\src\apn_manager\ apn_manager.cpp

\telephony\cellular_data\services\src\apn_manager\ apn_holder.cpp.cpp

\telephony\cellular_data\services\src\apn_manager\ apn_item.cpp

apn_manager负责对所有apn进行管理,包括创建、查找和删除等操作。

apn_holder就是一个apn profile。

2.4 data service建立流程

Data service的建立流程如下图所示:

OpenHarmony 电话子系统源码解析之Cellular_Data-鸿蒙开发者社区

具体的代码调用流程如下:

\telephony\core_service\interfaces\innerkits\cellular_data\ cellular_data_manager.cpp

\telephony\core_service\interfaces\innerkits\cellular_data\ cellular_data_service.cpp

\telephony\core_service\interfaces\innerkits\cellular_data\ cellular_data_controller.cpp

\telephony\core_service\interfaces\innerkits\cellular_data\ cellular_data_handler.cpp

按照上面的时序图可以看出,从cellular_data_manager->cellular_data_service-> cellular_data_controller->cellular_data_handler,是直接调用Enable CellularData。主要的流程在cellular_data_handler中,具体说明EstablishDataConnection过程中比较重要的流程,其中包含了data状态机的创建EstablishDataConnection和connect event的发送:

1.	bool CellularDataHandler::EstablishDataConnection(sptr<ApnHolder> &apnHolder, int32_t radioTech)  
2.	{  
3.	    auto cellularDataStateMachine = FindIdleCellularDataConnection();  
4.	    if (cellularDataStateMachine == nullptr) {  
5.	        cellularDataStateMachine = CreateCellularDataConnect();  
6.	        if (cellularDataStateMachine == nullptr) {  
7.	            TELEPHONY_LOGE("cellularDataStateMachine is null");  
8.	            return false;  
9.	        }  
10.	        cellularDataStateMachine->Init();  
11.	    }  
12.	    TELEPHONY_LOGD("MSG_SM_CONNECT profileId:%{public}d networkType:%{public}d", profileId, radioTech);  
13.	    auto event = InnerEvent::Get(CellularDataEventCode::MSG_SM_CONNECT, object);  
14.	    cellularDataStateMachine->SendEvent(event);  
15.	    return true;  
16.	}  

\telephony\cellular_data\services\src\state_machine\ cellular_data_state_machine.cpp:

创建default data所需要的状态机,类似的,任何类型的数据,应该都会创建其所对应的状态机:

std::shared_ptr<CellularDataStateMachine> CellularDataHandler::CreateCellularDataConnect()  
{  
    auto cellularDataStateMachine =  
        std::make_shared<CellularDataStateMachine>(connectionManager_, shared_from_this(), GetEventRunner());  
    if (cellularDataStateMachine == nullptr) {  
        TELEPHONY_LOGE("cellularDataStateMachine is null");  
        return nullptr;  
    }  
    sequence_++;  
    intStateMachineMap_[sequence_] = cellularDataStateMachine;  
    return cellularDataStateMachine;  
}

接下来会进行data状态机的init初始化操作,会依次创建Active、Inactive等状态到状态机中,并设置初始状态为Active,为后续的data connect做好准备:

void CellularDataStateMachine::Init()  
{  
    activeState_ = std::make_unique<Active>(  
        std::weak_ptr<CellularDataStateMachine>(shared_from_this()), "Active").release();  
    inActiveState_ = std::make_unique<Inactive>(  
        std::weak_ptr<CellularDataStateMachine>(shared_from_this()), "Inactive").release();  
    activatingState_ = std::make_unique<Activating>(  
        std::weak_ptr<CellularDataStateMachine>(shared_from_this()), "Activating").release();  
    disconnectingState_ = std::make_unique<Disconnecting>(  
        std::weak_ptr<CellularDataStateMachine>(shared_from_this()), "Disconnecting").release();  
    defaultState_ = std::make_unique<Default>(  
        std::weak_ptr<CellularDataStateMachine>(shared_from_this()), "Default").release();  
    netProviderInfo_ = std::make_unique<NetProviderInfo>().release();  
    netLinkInfo_ = std::make_unique<NetLinkInfo>().release();  
    if (activeState_ == nullptr || inActiveState_ == nullptr || activatingState_ == nullptr ||  
        disconnectingState_ == nullptr || defaultState_ == nullptr || netProviderInfo_ == nullptr ||  
        netLinkInfo_ == nullptr) {  
        TELEPHONY_LOGE("memory allocation failed");  
        return;  
    }  
    activeState_->SetParentState(defaultState_);  
    inActiveState_->SetParentState(defaultState_);  
    activatingState_->SetParentState(defaultState_);  
    disconnectingState_->SetParentState(defaultState_);  
    StateMachine::SetOriginalState(inActiveState_);  
    StateMachine::Start();  
}

在上面状态机创建的过程中,最后会建立数据请求:

1.	auto event = InnerEvent::Get(CellularDataEventCode::MSG_SM_CONNECT, object);
2.	cellularDataStateMachine->SendEvent(event);  

这个流程会按照状态机当前的状态来执行,会先走到inactive状态中,执行真正的DoConnect,并转换状态到Activating。

1.	bool Inactive::StateProcess(const AppExecFwk::InnerEvent::Pointer &event)  
2.	{  
3.	    auto eventCode = event->GetInnerEventId();  
4.	    switch (eventCode) {  
5.	        case CellularDataEventCode::MSG_SM_CONNECT: {  
6.	            TELEPHONY_LOGD("Inactive::MSG_SM_CONNECT");  
7.	            shareStateMachine->DoConnect(*(event->GetUniqueObject<DataConnectionParams>()));  
8.	            shareStateMachine->TransitionTo(shareStateMachine->activatingState_);  
9.	            retVal = PROCESSED;  
10.	            break;  
11.	        }  
12.	        default:  
13.	            TELEPHONY_LOGE("StateProcess handle nothing!");  
14.	            break;  
15.	    }  
16.	    return retVal;  
17.	}

最终是通过状态机的DoConnect来建立数据的:

\telephony\cellular_data\services\src\state_machine\ cellular_data_state_machine.cpp:

1.	void CellularDataStateMachine::DoConnect(const DataConnectionParams &connectionParams)  
2.	{  
3.	    if (connectionParams.GetApnHolder() == nullptr) {  
4.	        TELEPHONY_LOGE("apnHolder is null");  
5.	        return;  
6.	    }  
7.	    RilAdapterUtils::ActivatePdpContext(slotId, radioTech, dataProfile, false, true, event);  
8.	}

接下来就会将建立数据的请求发送给core,最终发送给ril_adapter,完成数据建立的流程。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
2
收藏 1
回复
举报
回复
    相关推荐