资讯动态

高通平台IA APN问题分析之一

发布时间:2026/10/17 15:42:00 来源:尧图企业网站定制
1、问题描述在android 5G产品开发过程中通过UI设置APN后OTA空口发现APN并未使用UI设置的APN将相关问题分析记录如下。2、qcril-nr中设置 IA APN 流程1、设置IA APN时通过函数getAttachListSyncQMI对应QMI_WDS_GET_LTE_ATTACH_PDN_LIST_REQ_V01获取所有attach apn list。当attach apn list不为空 调用函数compareModemAttachParams比对APN是否和modem attach的参数是否一致。void ProfileHandler::handleInitialAttachRequest(std::shared_ptrMessage msg) { std::shared_ptrSetInitialAttachApnRequestMessage m std::static_pointer_castSetInitialAttachApnRequestMessage(msg); Log::getInstance().d([ProfileHandler]: Handling: msg-dump()); if( m ! NULL ) { requestProfile m-mProfile; if(mPendingMessage ! nullptr) { Log::getInstance().d([ProfileHandler] Received another IA, Stopping retry timer.); sendSetInitialAttachResponse(RIL_E_INTERNAL_ERR); } mPendingMessage msg; if(!wds_endpoint) { Log::getInstance().d([ProfileHandler] wds_endpoint is NULL. Sending error response); sendSetInitialAttachResponse(RIL_E_GENERIC_FAILURE); return; } //1、获取所以attach list apn Message::Callback::Status status wds_endpoint-getAttachListSync(attach_list); { Log::getInstance().d([ProfileHandler] failed to get attach list, result std::to_string((int) status)); sendSetInitialAttachResponse(RIL_E_OEM_ERROR_3); return; } if(attach_list nullptr) { Log::getInstance().d(Modem Attach list is NULL. Returning Failure response); sendSetInitialAttachResponse(RIL_E_GENERIC_FAILURE); return; } { stringstream ss; ss Attach List:; copy(attach_list-begin(), attach_list-end(), ostream_iteratorint(ss, ,)); Log::getInstance().d([ProfileHandler] ss.str()); logBuffer.addLogWithTimestamp(ss.str()); } //Check if first profile in attach list is a null profile //2、当attach apn list不为空 调用函数compareModemAttachParams比对APN是否和modem attach的参数是否一致. if (!attach_list-empty() isNullProfile(attach_list-front())) { compareModemAttachParams(); } else { initialAttachHandler(); } } }2、使用QMI获取QMI_WDS_GET_LTE_ATTACH_PARAMS_REQ_V01 modem attach网络参数 对比modem中APN是否一直如果一致直接返回成功void ProfileHandler::compareModemAttachParams() { wds_get_lte_attach_params_resp_msg_v01 curr_attach_params; memset(curr_attach_params, 0x0, sizeof(curr_attach_params)); if (!wds_endpoint) { sendSetInitialAttachResponse(RIL_E_INTERNAL_ERR); return; } //3、获取modem attch参数可能为空 auto rc wds_endpoint-getLteAttachParams(curr_attach_params); if (rc Message::Callback::Status::SUCCESS) { if (curr_attach_params.resp.result QMI_RESULT_SUCCESS_V01) { if (!matchModemProfileParams(curr_attach_params,requestProfile.apn,requestProfile.protocol)) { Log::getInstance().d([ProfileHandler] : Modem attach params did not match, fallback to inital attach logic); initialAttachHandler(); } else { //4、modem参数和ap设置的参数完全一致直接返回成功 sendSetInitialAttachResponse(RIL_E_SUCCESS); } return; } else if ((curr_attach_params.resp.result QMI_RESULT_FAILURE_V01) (curr_attach_params.resp.error QMI_ERR_OP_IN_PROGRESS_V01)) { if(mIARetry MAX_IA_RETRY_ATTEMPT) { Log::getInstance().d([ProfileHandler] : Reached maximum retries for GET_LTE_ATTACH_PARAMS); sendSetInitialAttachResponse(RIL_E_INTERNAL_ERR); return; } else { Log::getInstance().d([ProfileHandler] : Starting Retry Attach Timer); auto timeoutFn std::bind(ProfileHandler::getAttachParamsTimeoutHander, this, std::placeholders::_1); mIARetryAttachTimer TimeKeeper::getInstance().set_timer(timeoutFn, nullptr, RETRY_ATTACH_TIMEOUT); return; } } } //for any other scenario fallback to the initial attach logic initialAttachHandler(); }3、如果不匹配调用initialAttachHandler进行进一步的处理void ProfileHandler::initialAttachHandler( ) { RIL_Errno result RIL_E_SUCCESS; Log::getInstance().d([ProfileHandler] initialAttachHandler ENTRY); if (!attach_list) { Log::getInstance().d([ProfileHandler] attachlist is NULL); sendSetInitialAttachResponse(RIL_E_INTERNAL_ERR); return; } // Check if requestProfile matches any of the the attached profiles ProfileHandler::AttachResponse resp matchAttachProfile(*attach_list); //5、检查attch apn是否在attach_list中如果modem存在 if ( resp SUCCESS ) { attachProfileKey util.findOrCreateProfileForLteAttach(convertDataProfileInfoToProfileParams(requestProfile)); if (attachProfileKey nullptr) { Log::getInstance().d([ProfileHandler] No matching profile found and failed to create new profile); Log::getInstance().d(EXIT with FAILURE ); result RIL_E_OEM_ERROR_3; sendSetInitialAttachResponse(RIL_E_OEM_ERROR_3); return; } // update attach list if( !(attach_list-empty()) ) { attach_list-pop_front(); } attach_list-push_front(attachProfileKey-getProfileId()); { stringstream ss; ss New Attach List:; copy(attach_list-begin(), attach_list-end(), ostream_iteratorint(ss, ,)); Log::getInstance().d([ProfileHandler] ss.str()); logBuffer.addLogWithTimestamp(ss.str()); } //6、更新modem profile num更新到modem if(requestProfile.preferred ((int)requestProfile.supportedApnTypesBitmap (int)ApnTypes_t::DEFAULT) (int)ApnTypes_t::DEFAULT) { Log::getInstance().d([ProfileHandler] Setting default profile to profileId std::to_string(attachProfileKey-getProfileId())); wds_endpoint-setDefaultProfileNum(attachProfileKey-getTechType(), attachProfileKey-getProfileId()); } /* Three Cases: 1st Case: Non-LTE RAT: If the current RAT is non-LTE, then we update the attach list only. Detach/Attach request is not sent to modem. If the current RAT is LTE PS Service is available, 2nd Case: LTE( PS Service Available) DDS SUB: We send Detach request to modem after detach is complete, we update the attach list on modem. Later Attach request is sent to modem. 3rd Case: LTE( PS Service Available) Non-DDS SUB: We update the attach list first then issue Detach request to modem. After receiving Detach response from modem, we send this as IA response to telephony without waiting for Detach Indication. So IA request ends here. Attach request is NOT sent to modem. */ //7、同步apn list到modem AttachResult res setAttachList(); if ( res AttachResult::DETACH_NEEDED) { Log::getInstance().d([ProfileHandler] :: Legacy method. Obsolete with newer modem versions); result RIL_E_INTERNAL_ERR; } else if ( res AttachResult::GENERIC_FAILURE ) { // in the event that attach list update failed due to a QMI error // we need to notify RIL Log::getInstance().d([ProfileHandler] GENERIC_FAILURE Sending error response); result RIL_E_INTERNAL_ERR; } #ifdef QMI_RIL_UTF releaseQdpAttachProfile(); #endif } else { if (!mApAssistMode dsd_endpoint) { dsd_endpoint-setApnInfoSync(requestProfile.apn, requestProfile.supportedApnTypesBitmap); } else { Log::getInstance().d([ProfileHandler] Did not update apn types.); } Log::getInstance().d([ProfileHandler] Skipping reattach); result RIL_E_SUCCESS; } sendSetInitialAttachResponse(RIL_E_SUCCESS); }4、如果匹配attach_list通过函数setDefaultProfileNum更新modem对应的profile id通过函数setAttachList更新modem apn list。3、对应Log分析1、RILJ Log09-28 11:03:18.325 2765 4074 D RILJ : [0500] SET_INITIAL_ATTACH_APN[DataProfile[ApnSetting] UC_APN_VSIM_1, 3206, 46006, 3gnet, , null, , null, null, 0, supl | hipri | default | ia, IP, IP, true, 0, false, 0, 0, 0, 0, 0, imsi, 460060042315337, false, UNKNOWN, UNKNOWN, 0, -1, -1, false, -1762095381, TrafficDescriptor{mDnn3gnet, null}, preferredfalse] [PHONE0]09-28 11:03:18.338 2765 3425 D RILJ : [0500] SET_INITIAL_ATTACH_APN [PHONE0]2、qcril log 过滤qcril log检索ProfileHandler3、QMI Log 检索关键字WDS_GET_LTE_ATTACH_PDN_LIST|WDS_SET_LTE_ATTACH_PDN_LIST|WDS_GET_LTE_ATTACH_PARAMS|WDS_SET_DEFAULT_PROFILE_NUM4、OTA Log5G OTA可以检索dnn5. 两种场景解释你抓包看到 “请求 DNN 和 Accept 返回 DNN 不一致”场景 A安卓 APN 配置正常映射UE Request 携带 DNN安卓选中的 APNcmnet → RIL 把cmnet作为 DNN 写入 PDU Session Establishment Request。- 网络收到这个 DNN- 如果签约里这个 DNN 不允许运营商策略允许 fallbackSMF 就返回签约的默认 DNN于是 Accept 消息里 DNN 变了。这就是你前面遇到的现象UE 请求 DNN源自安卓 APN网络返回另一个 DNN。场景 BUE 不携带 DNN非常常见安卓在 5G SA 下可以不填 DNN IE 直接发 PDU 会话建立请求URSP 规则驱动、默认数据会话1. 安卓不把 APN 映射上去PDU Session Establishment Request 里 DNN IE 不存在2. SMF 查 UDM 签约在当前 S-NSSAI 切片下取该用户默认 DNN3. 在 PDU Session Establishment Accept 里把这个默认 DNN 带回给 UE4. 抓包看到请求消息没有 DNNAccept 带回 DNN5. 你拿安卓 APN 页面的 APN 名字和 Accept 里 DNN 对比 → 自然对不上。4、对比之前Android 4G产品分析对应之前的4G产品4G产品使用qcrild5G产品使用qcrilNrd4G使用了/vendor/qcom/proprietary/qcril-hal代码5G产品使用了/vendor/qcom/proprietary/qcril-nr代码其中设置IA APN时需要deatch apn重新Attach时更新APN其中qcril log处理逻和5G平台类似

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑