【笔记】APN 配置参数 bitmask 数据转换(Android KaiOS)

2024-02-20 19:28

本文主要是介绍【笔记】APN 配置参数 bitmask 数据转换(Android KaiOS),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、参数说明

(一)APN配置结构对比

平台AndroidKaiOS
文件类型xmljson
结构每个<apn>标签是一条APN,包含完成的信息层级数组结构,使用JSON格式的数据。最外层是mcc,其次mnc,最后APN用数组形式配置(每个APN都是一个对象,不含mccmnc属性)。
Android: apns-conf.xml
<!-- Android: apns-conf.xml -->
<?xml version="1.0" encoding="utf-8"?>
<apns version="8"><apn carrier="T-Mobile US" mcc="001" mnc="01" apn="fast.t-mobile.com" user="" password="" server="" proxy="" port="" mmsc="http://mms.msg.eng.t-mobile.com/mms/wapenc" mmsproxy="" mmsport="" type="default,mms,supl,hipri,xcap,rcs" protocol="IPV6" roaming_protocol="IP" bearer_bitmask="" mvno_type="ecid" mvno_match_data="[4]4310260" class="" user_visible="true" user_editable="true" authtype="0"/>
</apns>
KaiOS: apns.json

特别需要注意格式(很容易出错),数组最后不用加逗号,注意大/中括号的首位一致性。

{
"202": {"10": [{"carrier":"Wind Internet","apn":"gint.b-online.gr","type":["default","supl"]},{"voicemail":"122","type":["operatorvariant"]},{"carrier":"Wind MMS","apn":"mnet.b-online.gr","mmsc":"http://192.168.200.95/servlets/mms","mmsproxy":"192.168.200.11","mmsport":"9401","type":["mms"]}],"01": [{"carrier":"Cosmote Wireless Internet","apn":"","type":["ia"]},{"voicemail":"123","type":["operatorvariant"]},{"carrier":"Cosmote Wireless Internet","apn":"internet","type":["default","supl"]},{"carrier":"Cosmote Mms","apn":"mms","mmsc":"http://mmsc.cosmote.gr:8002","mmsproxy":"10.10.10.20","mmsport":"8080","type":["mms"]}],"09": [{"carrier":"Q Internet","apn":"myq","type":["default","supl"]},{"voicemail":"122","type":["operatorvariant"]},{"carrier":"Q-Telecom MMS GPRS","apn":"q-mms.myq.gr","mmsc":"http://mms.myq.gr","mmsproxy":"192.168.80.134","mmsport":"8080","type":["mms"]}]
},
"001": {"01": [{"carrier":"Testing SIM default","apn":"test","type":["default"],"protocol":"IPV4V6","roaming_protocol":"IPV4V6","user_visible":"true"},{"carrier":"IMS","apn":"ims","type":["ims"],"protocol":"IPV4V6","roaming_protocol":"IPV4V6","user_visible":"true"},{"carrier":"XCAP","apn":"xcap","type":["xcap"],"protocol":"IPV4V6","roaming_protocol":"IPV4V6","user_visible":"true","authtype":"0"}]
}
}

(二)bearer配置值对比

  • 1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20 (The original bearer value in Android,位运算)
  • 1048575(The original bearer value in KaiOS using decimalism)

二、代码解析

(一)Android

待完善

(二)KaiOS(DataCallManager.jsm)

1、bitmask的进制转换

可以参考PDN建立逻辑,gecko/dom/system/gonk/radio/DataCallManager.jsm

//DataCallManager.jsm//检查对应的rat是否包含在此APN bearer 配置中
// Check rat value include in the bit map or not.
function bitmaskHasTech(aBearerBitmask, aRadioTech) {if (aBearerBitmask == 0) {return true;} else if (aRadioTech > 0) {return (aBearerBitmask & (1 << (aRadioTech - 1))) != 0;}return false;
}//bearer十进制转成二进制
// Show the detail rat type.
function bitmaskToString(aBearerBitmask) {if (aBearerBitmask == 0 || aBearerBitmask === undefined) {return 0;}let val = "";for (let i = 1; i < RIL.GECKO_RADIO_TECH.length; i++) {if ((aBearerBitmask & (1 << (i - 1))) != 0) {val = val.concat(i + "|");}}return val;
}function bearerBitmapHasCdma(aBearerBitmask) {return (RIL_RADIO_CDMA_TECHNOLOGY_BITMASK & aBearerBitmask) != 0;
}

bitmaskToString接口中,将bitmask转化成String时,循环RIL.GECKO_RADIO_TECH的长度次,经过位运算转换成与Android原始配置的bearer_bitmask相同格式的bearer位符,用“|”间隔rat类型位。

是如何通过RIL调用ril_consts.js内的GECKO_RADIO_TECH?

DataCallManager.jsm 中定义RIL对象,并使用XPCOMUtils.defineLazyGetter()方法来实现懒加载,即在要使用时才加载和初始化对象(只有在第一次访问该对象时才会进行初始化和加载),避免不必要的性能开销和资源浪费。
RIL对象是通过ChromeUtils.import 方法从ril_consts.js文件中导入的,该对象由ril_consts.js文件中的代码创建和初始化的。

//DataCallManaer.jsm"use strict";//XPCOM 是一个用于 实现跨语言组件的技术框架。
//导入XPCOMUtils对象(工具库),简化和封装XPCOM组件的开发和使用。
//使用常量const来定义 XPCOMUtils 对象,以确保在运行时不会发生对象被重新赋值的情况。
const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"
);//定义RIL对象,后续调用 RIL.GECKO_RADIO_TECH
XPCOMUtils.defineLazyGetter(this, "RIL", function() {return ChromeUtils.import("resource://gre/modules/ril_consts.js");
});//ref RIL.GECKO_RADIO_TECH
const TCP_BUFFER_SIZES = [null,"4092,8760,48000,4096,8760,48000", // gprs"4093,26280,70800,4096,16384,70800", // edge"58254,349525,1048576,58254,349525,1048576", // umts"16384,32768,131072,4096,16384,102400", // is95a = 1xrtt"16384,32768,131072,4096,16384,102400", // is95b = 1xrtt"16384,32768,131072,4096,16384,102400", // 1xrtt"4094,87380,262144,4096,16384,262144", // evdo0"4094,87380,262144,4096,16384,262144", // evdoa"61167,367002,1101005,8738,52429,262114", // hsdpa"40778,244668,734003,16777,100663,301990", // hsupa = hspa"40778,244668,734003,16777,100663,301990", // hspa"4094,87380,262144,4096,16384,262144", // evdob"131072,262144,1048576,4096,16384,524288", // ehrpd"524288,1048576,2097152,262144,524288,1048576", // lte"122334,734003,2202010,32040,192239,576717", // hspa+"4096,87380,110208,4096,16384,110208", // gsm (using default value)"4096,87380,110208,4096,16384,110208", // tdscdma (using default value)"122334,734003,2202010,32040,192239,576717", // iwlan"122334,734003,2202010,32040,192239,576717", // ca
];//定义了一个常量RIL_RADIO_CDMA_TECHNOLOGY_BITMASK,用于表示CDMA射频技术类型的掩码值。
//RIL.GECKO_RADIO_TECH.indexOf 查找各个CDMA技术类型在GECKO_RADIO_TECH数组中的下标值,
//-1 的目的是得到对应的掩码位数,并将此转换成掩码值,
//使用按位左移(<<)运算符得到掩码值,
//各个掩码值按位或(|)操作得到最终的掩码值。
const RIL_RADIO_CDMA_TECHNOLOGY_BITMASK =(1 << (RIL.GECKO_RADIO_TECH.indexOf("is95a") - 1)) |(1 << (RIL.GECKO_RADIO_TECH.indexOf("is95b") - 1)) |(1 << (RIL.GECKO_RADIO_TECH.indexOf("1xrtt") - 1)) |(1 << (RIL.GECKO_RADIO_TECH.indexOf("evdo0") - 1)) |(1 << (RIL.GECKO_RADIO_TECH.indexOf("evdoa") - 1)) |(1 << (RIL.GECKO_RADIO_TECH.indexOf("evdob") - 1)) |(1 << (RIL.GECKO_RADIO_TECH.indexOf("ehrpd") - 1));// set to true in ril_consts.js to see debug messages
var DEBUG = RIL_DEBUG.DEBUG_RIL;   //调试用的log打印标识符

如上代码,CDMA技术类型对应的掩码值RIL_RADIO_CDMA_TECHNO如下:

is95a: 1 << (5-1) = 0x10
is95b: 1 << (6-1) = 0x20
1xrtt: 1 << (7-1) = 0x40
evdo0: 1 << (8-1) = 0x80
evdoa: 1 << (9-1) = 0x100
evdob: 1 << (14-1) = 0x2000
ehrpd: 1 << (15-1) = 0x4000

2、GECKO_RADIO_TECH 定义网络制式 (ril_consts.js)

在KaiOS中,RIL.GECKO_RADIO_TECH数组是在Gecko内核的代码中定义的,其实现位于Gecko代码库的"gecko/dom/system/gonk/radio/ril_consts.js"文件中。该文件定义了一系列RIL层的常量,包括射频技术类型、消息ID等。在该文件中,可以找到以下代码片段,其中定义了RIL.GECKO_RADIO_TECH数组的元素和顺序:

//GECKO_RADIO_TECH 数组定义射频技术(网络连接)
this.GECKO_RADIO_TECH = [null,"gprs",     //1 GPRS"edge",     //2 EDGE"umts",     //3 UMTS"is95a",    //4 IS-95A"is95b",    //5 IS-95B"1xrtt",    //6 cdma1x?一种CDMA2000射频技术,是CDMAOne技术的升级版(1x Radio Transmission Technology)"evdo0",    //7 EVDO-0"evdoa",    //8 EVDO-A"hsdpa",    //9"hsupa",    //10"hspa",     //11"evdob",    //12 EVDO-B"ehrpd",    //13 EVDO-D"lte",      //14 LTE"hspa+",    //15 HSPA+"gsm",      //16 GSM"tdscdma",  //17 TD-SCDMA"iwlan",    //18 iWLAN(wifi)"lte_ca",   //19 LTE_CA
];//定义遵循的协议类型
this.GECKO_PROFILE_INFO_TYPE_COMMON = 0;
this.GECKO_PROFILE_INFO_TYPE_3GPP = 1;
this.GECKO_PROFILE_INFO_TYPE_3GPP2 = 2;
3、DataCall 对 rat 的使用案例
  dataRegistrationChanged(aRadioTech) {let targetBearer;if (this.apnSetting.bearer === undefined) {targetBearer = 0;} else {targetBearer = this.apnSetting.bearer;}if (DEBUG) {this.debug("dataRegistrationChanged: targetBearer: " +bitmaskToString(targetBearer));}if (bitmaskHasTech(targetBearer, aRadioTech)) {// Ignore same rat type. Let handler process the retry.} else {if (DEBUG) {this.debug("dataRegistrationChanged: current APN do not support this rat reset DC. APN:" +JSON.stringify(this.apnSetting));// Clean the requestedNetworkInterfaces due to current DC can not support this rat under DC retrying state.// Let handler process the retry.let targetRequestedNetworkInterfaces = this.requestedNetworkInterfaces.slice();for (let networkInterface of targetRequestedNetworkInterfaces) {this.disconnect(networkInterface);}}},

gecko/koost/telephony/TelephonyBinderService.h

// Cover the GECKO_RADIO_TECH to NETWORK_TYPE_*
int32_t convertRadioTech(const nsAString& rat);

三、日志分析

追溯在PDN建立过程中,读取apn配置的bearer参数到DataCall使用的radio类型的bearer值变化情况。

四、方案开发

相关介绍:KaiOS 新增APN信息字段的代码实现-CSDN博客

在 APN Editor中实现bearer显示

代码模块:gaia/apps/settings/js/panels/apn_editor/apn_editor.js

/*** The apn editor module*/
'use strict';
define(function(require) { //eslint-disable-lineconst ApnEditorConst = require('panels/apn_editor_tct/apn_editor_const');const ApnEditorSession = require('panels/apn_editor_tct/apn_editor_session');const ApnUtils = require('modules/apn_tct/apn_utils');//以下三个常量都是从ApnEditorConst模块中导入的const { APN_PROPERTIES } = ApnEditorConst;const { APN_PROPERTY_DEFAULTS } = ApnEditorConst;const { VALUE_CONVERTERS } = ApnEditorConst;return function apnEditor(rootElement) {return new ApnEditor(rootElement);};
});
将kaios中十进制的bearer转换同Android原始配置的bitmask

测试代码

// 功能:将十进制bearer转换成1-20字符串(同Android)
function bitmaskToString(aBearerBitmask) {if (aBearerBitmask == 0 || aBearerBitmask === undefined) {return 0;}let val = "";for (let i = 1; i < 20; i++) {if ((aBearerBitmask & (1 << (i - 1))) != 0) {val = val.concat(i + "|");}}return val;
}//常量数组,定义rat
const GECKO_RADIO_TECH = [null,"gprs","edge","umts","is95a","is95b","1xrtt","evdo0","evdoa","hsdpa","hsupa","hspa","evdob","ehrpd","lte","hspa+","gsm","tdscdma","iwlan","lte_ca",
];//将1-20的bitmask转换成对应的网络制式
function bitmaskToRatString(aBitmask) {if (aBitmask == 0 || aBitmask === undefined) {return "unspecified";}let rat = "";let splitResult = aBitmask.split("|");console.log('splitResult = '+ splitResult);rat = splitResult.map(x => GECKO_RADIO_TECH[x]).join(",").slice(0,-1);//slice(startIndex,endIndex) 用于去掉最后一个逗号return rat;
}// 测试代码
let apnBearer = '312312';  //apn.json原始配置值
let targetBearer;  //1-20转换目标值
let bearerString = '';if (apnBearer === undefined) {targetBearer = 0;
} else {targetBearer = apnBearer;
}bearerString = bitmaskToString(targetBearer);// 输出结果
console.log('targetBearer = ' + targetBearer);
console.log('bearerString = '+ bearerString);

这篇关于【笔记】APN 配置参数 bitmask 数据转换(Android KaiOS)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/729291

相关文章

VScode连接远程Linux服务器环境配置图文教程

《VScode连接远程Linux服务器环境配置图文教程》:本文主要介绍如何安装和配置VSCode,包括安装步骤、环境配置(如汉化包、远程SSH连接)、语言包安装(如C/C++插件)等,文中给出了详... 目录一、安装vscode二、环境配置1.中文汉化包2.安装remote-ssh,用于远程连接2.1安装2

Java中注解与元数据示例详解

《Java中注解与元数据示例详解》Java注解和元数据是编程中重要的概念,用于描述程序元素的属性和用途,:本文主要介绍Java中注解与元数据的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参... 目录一、引言二、元数据的概念2.1 定义2.2 作用三、Java 注解的基础3.1 注解的定义3.2 内

将sqlserver数据迁移到mysql的详细步骤记录

《将sqlserver数据迁移到mysql的详细步骤记录》:本文主要介绍将SQLServer数据迁移到MySQL的步骤,包括导出数据、转换数据格式和导入数据,通过示例和工具说明,帮助大家顺利完成... 目录前言一、导出SQL Server 数据二、转换数据格式为mysql兼容格式三、导入数据到MySQL数据

C++中使用vector存储并遍历数据的基本步骤

《C++中使用vector存储并遍历数据的基本步骤》C++标准模板库(STL)提供了多种容器类型,包括顺序容器、关联容器、无序关联容器和容器适配器,每种容器都有其特定的用途和特性,:本文主要介绍C... 目录(1)容器及简要描述‌php顺序容器‌‌关联容器‌‌无序关联容器‌(基于哈希表):‌容器适配器‌:(

C#提取PDF表单数据的实现流程

《C#提取PDF表单数据的实现流程》PDF表单是一种常见的数据收集工具,广泛应用于调查问卷、业务合同等场景,凭借出色的跨平台兼容性和标准化特点,PDF表单在各行各业中得到了广泛应用,本文将探讨如何使用... 目录引言使用工具C# 提取多个PDF表单域的数据C# 提取特定PDF表单域的数据引言PDF表单是一

一文详解Python中数据清洗与处理的常用方法

《一文详解Python中数据清洗与处理的常用方法》在数据处理与分析过程中,缺失值、重复值、异常值等问题是常见的挑战,本文总结了多种数据清洗与处理方法,文中的示例代码简洁易懂,有需要的小伙伴可以参考下... 目录缺失值处理重复值处理异常值处理数据类型转换文本清洗数据分组统计数据分箱数据标准化在数据处理与分析过

大数据小内存排序问题如何巧妙解决

《大数据小内存排序问题如何巧妙解决》文章介绍了大数据小内存排序的三种方法:数据库排序、分治法和位图法,数据库排序简单但速度慢,对设备要求高;分治法高效但实现复杂;位图法可读性差,但存储空间受限... 目录三种方法:方法概要数据库排序(http://www.chinasem.cn对数据库设备要求较高)分治法(常

Redis多种内存淘汰策略及配置技巧分享

《Redis多种内存淘汰策略及配置技巧分享》本文介绍了Redis内存满时的淘汰机制,包括内存淘汰机制的概念,Redis提供的8种淘汰策略(如noeviction、volatile-lru等)及其适用场... 目录前言一、什么是 Redis 的内存淘汰机制?二、Redis 内存淘汰策略1. pythonnoe

Python调用另一个py文件并传递参数常见的方法及其应用场景

《Python调用另一个py文件并传递参数常见的方法及其应用场景》:本文主要介绍在Python中调用另一个py文件并传递参数的几种常见方法,包括使用import语句、exec函数、subproce... 目录前言1. 使用import语句1.1 基本用法1.2 导入特定函数1.3 处理文件路径2. 使用ex

Python将大量遥感数据的值缩放指定倍数的方法(推荐)

《Python将大量遥感数据的值缩放指定倍数的方法(推荐)》本文介绍基于Python中的gdal模块,批量读取大量多波段遥感影像文件,分别对各波段数据加以数值处理,并将所得处理后数据保存为新的遥感影像... 本文介绍基于python中的gdal模块,批量读取大量多波段遥感影像文件,分别对各波段数据加以数值处