天天看點

OpenHarmony 電話子系統源碼解析之Cellular_Data

作者:樊超

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,完成資料建立的流程。

繼續閱讀