切换数据失败0x1671分析

1、问题背景

        切换双卡数据开关,无法切换成功,且单机必现该问题

2、问题分析

    搜索Log发现相关拨号无法建立成功,返回0x1671,无法建立PDN连接。

 

相关拨号上层未下发相关AT命令,属于上层报错,并非网络问题,相关具体在代码RtcDataController.cpp的函数enqueueForPreferredDataMode中上报。

其中RFX_STATUS_KEY_SLOT_ALLOW表示当前RILD当前DDS,如果是当前DDS,这个SETUP_DATA_CALL下发到RILD的下一层,否者直接返回错误。那说明当前DDS没有更新,导致了问题。

对比正常切换和异常切换的Log分析。

正常Log

异常Log

异常Log在切换DDS时实际是没有切换的

从Log可以看到虽然上层都下发了> SET_PREFERRED_DATA_MODEM

并且RILD都回复了< SET_PREFERRED_DATA_MODEM 但是实际DDS确没有切换。相关切换流程总结如下。

红色框为问题出现的地方。查看相关代码

红色框为问题出现的地方。查看相关代码

说明mOnDemandQueue请求中还有相关请求在处理,导致无法下发切换DDS。最终在框架层发现如下异常请求,包名为“com.tencent.android.qqdownloader”,但是请求的能力没有Internet能力,只有BANDWITH和PRIORITIZE_LATENCY能力。卸载相关APP后问题恢复。

3、对比测试

        发现5G手机发现无此问题,原因在于5G modem支持有区别

相关代码区别在于EDataSimSupported是支持的,在5G平台

相关AT命令如下

4、解决方案

针对无APN相关的请求不要放入相关队列。

        由于 PRIORITIZE_LATENCY  PRIORITIZE_BANDWIDTH 与5G切片强相关,建议修改是加上5G能力判断。

5、延展验证

     抓取MTK 副卡发彩信流程

        0x1671实际为MTK设计的流程,当SETUP_DATA_CALL请求存在时,不允许相关DDS下发切换。如果只是临时的报错,可以忽略,如果一直上报错误,需要check相关拨号逻辑。

以下是使用Go语言编写的测试程序: ```go package main import ( "fmt" "math/rand" "net" "time" ) const ( deviceNum = 10 // 设备数量 modbusTcp = "localhost" // modbus tcp 地址 modbusPort = "502" // modbus tcp 端口 startState = 1 // 设备起始状态 stateNum = 3 // 状态数量 switchInterval = 5 // 状态切换间隔时间(秒) state1Duration = 10 // 状态1持续时间(秒) state2Duration = 20 // 状态2持续时间(秒) state3Duration = 30 // 状态3持续时间(秒) ) func main() { // 初始化设备状态 states := make([]int, deviceNum) for i := 0; i < deviceNum; i++ { states[i] = startState } // 连接 modbus tcp conn, err := net.Dial("tcp", modbusTcp + ":" + modbusPort) if err != nil { fmt.Println("连接 modbus tcp 失败:", err) return } defer conn.Close() // 模拟设备状态切换 for { for i := 0; i < deviceNum; i++ { // 计算下一状态 nextState := states[i] % stateNum + 1 // 发送当前状态 err := sendModbus(conn, i + 1, states[i]) if err != nil { fmt.Println("发送 modbus tcp 数据失败:", err) return } // 更新状态 states[i] = nextState // 等待切换时间 switchTime := rand.Intn(switchInterval) + 1 time.Sleep(time.Duration(switchTime) * time.Second) // 等待当前状态持续时间 switch states[i] { case 1: time.Sleep(time.Duration(state1Duration) * time.Second) case 2: time.Sleep(time.Duration(state2Duration) * time.Second) case 3: time.Sleep(time.Duration(state3Duration) * time.Second) } } } } // 发送 modbus tcp 数据 func sendModbus(conn net.Conn, deviceID int, state int) error { data := []byte{0x00, 0x01, 0x00, 0x00, 0x00, 0x06, byte(deviceID), 0x06, 0x00, 0x00, 0x00, byte(state)} _, err := conn.Write(data) return err } ``` 这个程序模拟了10台设备,每个设备都有3种状态,起始状态为1,之后依次切换到2、3、1状态,每切换一次状态都会通过Modbus TCP发送当前状态,发送的数据格式为`00 01 00 00 00 06 [设备ID] 06 00 00 00 [状态]`。程序中的参数可以根据实际情况进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值