流程
AP(串口/Socket/Hidl) → L4A/L4C(AT cmd解析) → MIPC模块(消息装箱) → Modem各层(协议栈/管理/执行)

- 上层AT命令用atSendCommand下发,
- Modem内AT解析器收到后自动转换为对应MIPC消息下发协议栈层处理,完成驱动网络附着/配置,
- 响应再变成AT串回给上层,
- AT、MIPC两层协议各司其职,中间有清晰的“字符串到结构体信令”转换过程。
代码逻辑
- RFX_MSG_REQUEST_SET_DATA_PROFILE
- handleSyncApnTableRequest / handleSetInitialAttachApnRequest
- requestSyncApnTable
vendor/mediatek/proprietary/hardware/ril/fusion/mtk-ril/mdcomm/data/RmcDcReqHandler.cpp
void RmcDcReqHandler::onHandleRequest(const sp<RfxMclMessage>& msg) {
switch (msg->getId()) {
case RFX_MSG_REQUEST_SET_DATA_PROFILE:
handleSyncApnTableRequest(msg);
break;
case RFX_MSG_REQUEST_SET_INITIAL_ATTACH_APN:
handleSetInitialAttachApnRequest(msg);
break;
}
}
如果检查APN没有更新,是不会调用MIPC 更新 Modem APN 的,即便上层下发了 Dataprofile 同步。

vendor/mediatek/proprietary/hardware/ril/fusion/mtk-ril/mdcomm_mipc/data/RmmDcEventHandler.cpp
iaMode分支与平台兼容性
- 代码中支持了多个“iaMode”(兼容MTK不同代基带平台UI/协议实现)。
- Mode 0 和 3 发的是
AT+EIAAPN="apn",id
(常见在老平台)。 - Mode 1、2 发的是全参数
AT+EIAAPN="apn",id,"proto",...
(新平台、功能更丰富,才能带下username/pwd等全参)。 - 提供非法APN会触发
AT+EIAMDPREFER=1
,可能不会生成 MIPC_APN_SET_IA_REQ。
void RmmDcEventHandler::requestSyncApnTable(const sp<RfxMclMessage>& msg) {
int cmdIndex = 1;
sp<RfxMclMessage> resp;
RIL_MtkDataProfileInfo **dataProfilePtrs =
(RIL_MtkDataProfileInfo **)msg->getData()->getData();
int nReqNum = msg->getData()->getDataLength() / sizeof(RIL_MtkDataProfileInfo*);
if (nReqNum <= 0) {
resp = RfxMclMessage::obtainResponse(msg->getId(), RIL_E_GENERIC_FAILURE,
RfxVoidData(), msg, false);
responseToTelCore(resp);
return;
}
adjustBearerBitmask(dataProfilePtrs, nReqNum);
RFX_LOG_D(RFX_LOG_TAG, "[%d][%s] num of pararmeters = %d", m_slot_id, __FUNCTION__, nReqNum);
// avoid syncing the same apn table, e.g. sub id ready then record loaded event
if (s_LastApnTable[m_slot_id] != NULL) {
bool bSameApnTable = true;
if (s_nLastReqNum[m_slot_id] == nReqNum) {
for (int i = 0; i < s_nLastReqNum[m_slot_id]; i++) {
RIL_MtkDataProfileInfo *preProfile = &s_LastApnTable[m_slot_id][i];
RIL_MtkDataProfileInfo *curProfile = dataProfilePtrs[i];
if (preProfile->profileId != curProfile->profileId
|| 0 != strcmp(preProfile->apn, curProfile->apn)
|| 0 != strcmp(preProfile->protocol, curProfile->protocol)
|| 0 != strcmp(preProfile->roamingProtocol, curProfile->roamingProtocol)
|| preProfile->authType != curProfile->authType
|| 0 != strcmp(preProfile->user, curPr