规范12388举报网站建设管理ueditor编辑wordpress
规范12388举报网站建设管理,ueditor编辑wordpress,wordpress li分页,crm软件下载前言
在工业平板和车载终端的开发中#xff0c;为了保证网络的可靠性#xff0c;通常会设计双 SIM 卡槽。基于 Rockchip RK3568 平台和 Android 14 系统#xff0c;本文将详细记录如何集成移远#xff08;Quectel#xff09;EM06K LTE-A 模块#xff0c;并实现 “双卡单待…前言在工业平板和车载终端的开发中为了保证网络的可靠性通常会设计双 SIM 卡槽。基于 Rockchip RK3568 平台和 Android 14 系统本文将详细记录如何集成移远QuectelEM06K LTE-A 模块并实现 “双卡单待” 功能。所谓的“双卡单待”指硬件上连接了两张 SIM 卡但同一时间只有一张卡与 4G 模块通信通过串口指令来切换。一、 硬件原理与准备1.1 硬件拓扑SoC:RK3568OS:Android14Kernel:Linux6.14G 模块:Quectel EM060K (M.2 接口走 USB 3.0/2.0 协议)双卡方案:SIM1 连接到模拟开关通道 ASIM2 连接到模拟开关通道 B模拟开关输出连接到 EM06K 的 SIM 接口1.2 准备工作RK3568 Android 14 源码环境移远官方提供的驱动包Quectel_Linux_USB_Serial_Option_DriverQuectel_Android_RIL_Driver (注意获取适配 Android 14 的版本)二、内核驱动移植 (Kernel)在 Android 14 (Kernel 6.1) 中首先要确保 EM06K 被识别。2.1 添加 USB VID/PID修改 drivers/usb/serial/option.c在 usb_device_id 列表中添加 EM06K 的 ID通常移远模块 VID 为 0x030b/* Quectel EM06K */#defineQUECTEL_PRODUCT_EM060K0x030b{USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID,QUECTEL_PRODUCT_EM060K,0xff,0x00,0x40)},{USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID,QUECTEL_PRODUCT_EM060K,0xff,0xff,0x30)},{USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID,QUECTEL_PRODUCT_EM060K,0xff,0xff,0x40)},2.2 驱动移植参考移远文档推荐使用qmi_wwan_q.c将文件放到放到kernel-6.1/drivers/net/usb。文档说可以和内核自带的qmi_wwan.c可以共存但编译起来还是有点差异我就把qmi_wwan.c注释掉了不影响正常使用kernel-6.1/drivers/net/usb/Makefile配置如下#obj-$(CONFIG_USB_NET_QMI_WWAN)qmi_wwan.oobj-$(CONFIG_USB_NET_QMI_WWAN)qmi_wwan_q.o和配置rockchip_deconfigCONFIG_USB_NET_QMI_WWANy移植完成后查看日志[568.184715][T86]usb1-1:Product:EM060K-GL[568.184755][T86]usb1-1:Manufacturer:Quectel[568.184792][T86]usb1-1:SerialNumber:5b050a26[568.338560][T86]option1-1:1.0:GSMmodem(1-port)converter detected[568.341022][T86]usb1-1:GSMmodem(1-port)converter now attached to ttyUSB0[568.343017][T86]option1-1:1.1:GSMmodem(1-port)converter detected[568.345266][T86]usb1-1:GSMmodem(1-port)converter now attached to ttyUSB1[568.347646][T86]option1-1:1.2:GSMmodem(1-port)converter detected[568.350496][T86]usb1-1:GSMmodem(1-port)converter now attached to ttyUSB2[568.356266][T86]option1-1:1.3:GSMmodem(1-port)converter detected[568.359250][T86]usb1-1:GSMmodem(1-port)converter now attached to ttyUSB3[568.389126][T86]qmi_wwan_q1-1:1.4:cdc-wdm0:USB WDM device[568.389605][T86]qmi_wwan_q1-1:1.4:Quectel EM060K-GL work on RawIP mode[568.390788][T86]qmi_wwan_q1-1:1.4:rx_urb_size16384[568.401388][T86]qmi_wwan_q1-1:1.4wwan0:registerqmi_wwan_qat usb-xhci-hcd.0.auto-1,WWAN/QMI Raw IP device,c2:c4:70:07:63:ac通过上面的日志可以看到已经识别到EM060K-GL并且qmi_wwan_q驱动已将wwan0网卡注册但/dev/cdc-wdm0节点还没有注册需要修改system/core/init/devices.cpp文件。diff--git a/system/core/init/devices.cpp b/system/core/init/devices.cpp index d29ffd6..9bc5199100644---a/system/core/init/devices.cppb/system/core/init/devices.cpp -563,6563,10voidDeviceHandler::HandleUevent(constUeventuevent){intdevice_iduevent.minor%1281;devpathStringPrintf(/dev/bus/usb/%03d/%03d,bus_id,device_id);}}elseif(StartsWith(uevent.subsystem,usbmisc)!uevent.device_name.empty()){//add by zfx for pppdevpath/dev/uevent.device_name;}elseif(StartsWith(uevent.subsystem,usb)){// ignore other USB eventsreturn;再执行ifconfig查看网卡已经可以看到wwan0获取到ip。rk3568_t:/$ ifconfig wwan0 Link encap:UNSPEC Driver qmi_wwan_q inet addr:10.6.113.140Mask:255.255.255.248inet6 addr:240e:47c:3880:f6:cda6:5cfb:40f1:8b7e/64Scope:Global inet6 addr:240e:47c:3880:f6:f450:37ff:fec3:ec30/64Scope:Global inet6 addr:fe80::f450:37ff:fec3:ec30/64Scope:Link UP RUNNING NOARP MTU:1500Metric:1RX packets:25errors:0dropped:0overruns:0frame:0TX packets:37errors:0dropped:0overruns:0carrier:0collisions:0txqueuelen:1000RX bytes:6231TX bytes:3480三、 Android RIL 集成 (Android 14)Android 14 对权限管理更为严格集成 RIL 时需注意 SELinux 和 init 配置。另外Android14 SDKRIL Driver版本需要大于V4.0.0。3.1 移植 RIL 库在 Android 的 RIL (Radio Interface Layer) 架构中libril.so 和 libreference-ril.so 是两个处于不同层级、承担不同职责的关键动态链接库。libril.so 对接上层它负责与 rild (RIL Daemon 守护进程) 配合接收来自 Android Framework (电话服务进程) 的请求在 Android 8.0 以后通过 HIDL/AIDL 接口早期通过 Socket而 libreference-ril.so 是模组厂商参考 Google 标准写的“硬件操作员”负责对接 4G/5G 模块比如将标准请求翻译成该模组能听懂的 AT 指令如 ATD10086;并通过串口/dev/ttyUSB2 等发送给 4G 模块。这是移远提供的ril库但短信功能不能使用我会将ril相关库放到附件。然后将ril相关文件到系统源码将libril.so以及libreference-ril.so 放到vendor/rockchip/common/phone/lib下将chat、ip-down、ip-up 放到vendor/rockchip/common/phone/bin下将ql-ril.conf放到vendor/rockchip/common/phone/codec下3.2 修改系统配置修改device/rockchip/rk356x/BoardConfig.mkdiff--git a/device/rockchip/rk356x/BoardConfig.mk b/device/rockchip/rk356x/BoardConfig.mk index dd95ac2..042e0f7100755---a/device/rockchip/rk356x/BoardConfig.mkb/device/rockchip/rk356x/BoardConfig.mk -131,3131,12 BOARD_ROCKCHIP_TRUST_MERGE_TO_UBOOT:true BOARD_BASEPARAMETER_SUPPORT:true TARGET_SUPPORTS_OMX_SERVICE:false# 避免libril.so与系统自带lbril.so编译报错BUILD_BROKEN_DUP_RULES:true# 避免phone.mk将PRODUCT_PROPERTY_OVERRIDESro.boot.norilfalseBOARD_HAVE_DONGLE?true# 避免ppp拨号相关elf文件编译安装报错BUILD_BROKEN_ELF_PREBUILT_PRODUCT_COPY_FILES:trueBOARD_SELINUX_ENFORCING?true修改device/rockchip/common/device.mkdiff--git a/device/rockchip/common/device.mk b/device/rockchip/common/device.mk index efe9267..718954d100644---a/device/rockchip/common/device.mkb/device/rockchip/common/device.mk -886,3886,16 endififeq($(strip $(BOARD_BIOMETRICS_FACE)),true)$(call inherit-product,device/rockchip/common/modules/biometrics.mk)endifPRODUCT_MODEM?QUECTEL# 宏控如果没有指定Modem将使用QUECTELPRODUCT_PROPERTY_OVERRIDES\persist.radio.multisim.configdsdsPRODUCT_PACKAGES\android.hardware.secure_element \android.hardware.secure_element1.0\android.hardware.secure_element1.1\android.hardware.secure_element1.2\android.hardware.secure_element-service.example \VtsHalSecureElementTargetTest \android.hardware.radio-library.compat \VtsHalRadioTargetTest修改 device/rockchip/rk356x/device.mkdiff--git a/device/rockchip/rk356x/device.mk b/device/rockchip/rk356x/device.mk index2d427d5..0b7064c100644---a/device/rockchip/rk356x/device.mkb/device/rockchip/rk356x/device.mk -87,387,6 PRODUCT_PROPERTY_OVERRIDES\ ro.build.shutdown_timeout6\ persist.enable_task_snapshotsfalse \ ro.vendor.frameratelocktrue# 指明使用QUECTEL Modemphone.mk将会安装移远相关文件PRODUCT_MODEM:QUECTEL修改vendor/rockchip/common/phone/phone.mkdiff--git a/vendor/rockchip/common/phone/phone.mk b/vendor/rockchip/common/phone/phone.mk index61881e4..5ec116c100755---a/vendor/rockchip/common/phone/phone.mkb/vendor/rockchip/common/phone/phone.mk -4,64,25 CUR_PATH:vendor/rockchip/common ######################################################### #3G Dongle SUPPORT #########################################################PRODUCT_PACKAGES\android.hardware.radio1.0-radio-service \android.hardware.radio1.5-radio-service \android.hardware.radio1.6-radio-service \android.hardware.radio.config1.2-servicePRODUCT_PACKAGES\android.hardware.radio.config-V1-ndk.vendor \android.hardware.radio.data-V1-ndk.vendor \android.hardware.radio.messaging-V1-ndk.vendor \android.hardware.radio.modem-V1-ndk.vendor \android.hardware.radio.network-V1-ndk.vendor \android.hardware.radio.sim-V1-ndk.vendor \android.hardware.radio.voice-V1-ndk.vendor \libbase.vendor \libbinder_ndk.vendorPRODUCT_COPY_FILES\ $(CUR_PATH)/phone/etc/ppp/ip-down:system/etc/ppp/ip-down \ $(CUR_PATH)/phone/etc/ppp/ip-up:system/etc/ppp/ip-up \ -17,636,16 PRODUCT_COPY_FILES\ $(CUR_PATH)/phone/lib/libril-dts4108c.so:system/lib/libril.so endififeq($(strip $(PRODUCT_MODEM)),QUECTEL)PRODUCT_COPY_FILES\$(CUR_PATH)/phone/lib/libreference-ril.so:vendor/lib64/libquectel-ril.so \$(CUR_PATH)/phone/lib/libril.so:vendor/lib64/libril.so \$(CUR_PATH)/phone/codec/ql-ril.conf:/system/etc/ql-ril.conf \$(CUR_PATH)/phone/bin/chat:system/bin/chat \$(CUR_PATH)/phone/bin/ip-up:system/bin/ip-up \$(CUR_PATH)/phone/bin/ip-down:system/bin/ip-downendififeq($(strip $(BOARD_HAVE_DONGLE)),true)PRODUCT_PACKAGES\ rild \ -34,463,7 endif PRODUCT_PROPERTY_OVERRIDES\ keyguard.no_require_simtrue \ ro.com.android.dataroamingtrue \-ril.function.dataonly1ril.function.dataonly1\ro.telephony.default_network26\rild.libpath/vendor/lib64/libquectel-ril.so \rild.libargs-d/dev/ttyUSB23.3 RIL配置修改ril-daemon启动信息指定ril库和串口。iff--git a/hardware/ril/rild/rild.rc b/hardware/ril/rild/rild.rc index f6beb54..1470e61100644---a/hardware/ril/rild/rild.rcb/hardware/ril/rild/rild.rc -1,51,5-service vendor.ril-daemon/vendor/bin/hw/rildservice ril-daemon/vendor/bin/hw/rild-l/vendor/lib64/libquectel-ril.so---d/dev/ttyUSB2 class main user radio-group radio cache inet misc audio log readproc wakelockgroup radio cache inet misc audio sdcard_rw log capabilities BLOCK_SUSPEND NET_ADMIN NET_RAWRIL的AIDL接口配置修改/device/rockchip/common/manifests/manifest_level_34.xmldiff--git a/device/rockchip/common/manifests/manifest_level_34.xml b/device/rockchip/common/manifests/manifest_level_34.xml index db306c1..7b111d6100644---a/device/rockchip/common/manifests/manifest_level_34.xmlb/device/rockchip/common/manifests/manifest_level_34.xml -26,526,76instancedefault/instance/interface/halhal formataidloptionaltruenameandroid.hardware.broadcastradio/nameinterfacenameIBroadcastRadio/nameregex-instance.*/regex-instance/interface/halhal formataidloptionaltruenameandroid.hardware.radio.config/nameversion2/versioninterfacenameIRadioConfig/nameinstancedefault/instance/interface/halhal formataidloptionaltruenameandroid.hardware.radio.data/nameversion2/versioninterfacenameIRadioData/nameinstanceslot1/instance/interface/halhal formataidloptionaltruenameandroid.hardware.radio.messaging/nameversion2/versioninterfacenameIRadioMessaging/nameinstanceslot1/instance/interface/halhal formataidloptionaltruenameandroid.hardware.radio.modem/nameversion2/versioninterfacenameIRadioModem/nameinstanceslot1/instance/interface/halhal formataidloptionaltruenameandroid.hardware.radio.network/nameversion2/versioninterfacenameIRadioNetwork/nameinstanceslot1/instance/interface/halhal formataidloptionaltruenameandroid.hardware.radio.sim/nameversion2/versioninterfacenameIRadioSim/nameinstanceslot1/instance/interface/halhal formataidloptionaltruenameandroid.hardware.radio.sap/nameversion1/versioninterfacenameISap/nameinstanceslot1/instance/interface/halhal formataidloptionaltruenameandroid.hardware.radio.voice/nameversion2/versioninterfacenameIRadioVoice/nameinstanceslot1/instance/interface/hal/manifest修改device/rockchip/common/manifests/compatibility_matrix_level_34.xmldiff--git a/device/rockchip/common/manifests/compatibility_matrix_level_34.xml b/device/rockchip/common/manifests/compatibility_matrix_level_34.xml index930cab5..4b49ba0100644---a/device/rockchip/common/manifests/compatibility_matrix_level_34.xmlb/device/rockchip/common/manifests/compatibility_matrix_level_34.xml -71,671,117instancedefault/instance/interface/halhal formathidloptionaltruenameandroid.hardware.radio.config/name!--See compatibility_matrix.4.xml on versioning of radio config HAL.--version1.0/versionversion1.1/versioninterfacenameIRadioConfig/nameinstancedefault/instance/interface/halhal formathidloptionaltruenameandroid.hardware.radio.config/nameversion1.3/versioninterfacenameIRadioConfig/nameinstancedefault/instance/interface/halhal formataidloptionaltruenameandroid.hardware.radio.data/nameversion1/versioninterfacenameIRadioData/nameinstanceslot1/instanceinstanceslot2/instanceinstanceslot3/instance/interface/halhal formataidloptionaltruenameandroid.hardware.radio.messaging/nameversion1/versioninterfacenameIRadioMessaging/nameinstanceslot1/instanceinstanceslot2/instanceinstanceslot3/instance/interface/halhal formataidloptionaltruenameandroid.hardware.radio.modem/nameversion1/versioninterfacenameIRadioModem/nameinstanceslot1/instanceinstanceslot2/instanceinstanceslot3/instance/interface/halhal formataidloptionaltruenameandroid.hardware.radio.network/nameversion1/versioninterfacenameIRadioNetwork/nameinstanceslot1/instanceinstanceslot2/instanceinstanceslot3/instance/interface/halhal formataidloptionaltruenameandroid.hardware.radio.sim/nameversion1/versioninterfacenameIRadioSim/nameinstanceslot1/instanceinstanceslot2/instanceinstanceslot3/instance/interface/halhal formataidloptionaltruenameandroid.hardware.radio.voice/nameversion1/versioninterfacenameIRadioVoice/nameinstanceslot1/instanceinstanceslot2/instanceinstanceslot3/instance/interface/halhal formathidloptionaltruenameandroid.hardware.radio/nameversion1.1/versionversion1.2/versionversion1.3/versionversion1.4/versionversion1.5/versionversion1.6/versioninterfacenameIRadio/nameinstanceslot1/instanceinstanceslot2/instanceinstanceslot3/instance/interface/halhal formathidloptionaltruenameandroid.hardware.radio/nameversion1.2/versioninterfacenameISap/nameinstanceslot1/instance/interface/halhal formathidloptionaltruenameandroid.hardware.radio.deprecated/nameversion1.0/versioninterfacenameIOemHook/nameinstanceslot1/instance/interface/halvndkversion0.0.0/version/vndk配置4G相关功能开启和配置Phone Featurediff--git a/device/rockchip/common/overlay/frameworks/base/core/res/res/values/config.xml b/device/rockchip/common/overlay/frameworks/base/core/res/res/values/config.xml index32d04ce..49036f1100644---a/device/rockchip/common/overlay/frameworks/base/core/res/res/values/config.xmlb/device/rockchip/common/overlay/frameworks/base/core/res/res/values/config.xml -20,1620,16resources!--This device is notvoice capable;its data-only.---bool nameconfig_voice_capablefalse/boolbool nameconfig_voice_capabletrue/bool!--This device does not allow sms service.---bool nameconfig_sms_capablefalse/boolbool nameconfig_sms_capabletrue/bool!--Flag indicating whether the current device allows data.If true,this means that the device supports data connectivity through the telephony network.This can be overridden to falsefordevices that support voice and/or sms.---bool nameconfig_mobile_data_capablefalse/boolbool nameconfig_mobile_data_capabletrue/bool!--If this is true,the screen will come on when you unplug usb/power/whatever.--bool nameconfig_unplugTurnsOnScreentrue/bool-52,752,7!--Setting this true forces the headset jack switches to use the/dev/input/event subsystem rather than the uevent framework.---bool nameconfig_useDevInputEventForAudioJackfalse/boolbool nameconfig_useDevInputEventForAudioJacktrue/bool!--Enable device idle mode--bool nameconfig_enableAutoPowerModestrue/booldiff--git a/device/rockchip/rk356x/overlay/frameworks/base/core/res/res/values/config.xml b/device/rockchip/rk356x/overlay/frameworks/base/core/res/res/values/config.xml index58a7e08..682611b100755---a/device/rockchip/rk356x/overlay/frameworks/base/core/res/res/values/config.xmlb/device/rockchip/rk356x/overlay/frameworks/base/core/res/res/values/config.xml -31,631,14!--the6th element indicates boot-time dependency-met value.--string-array translatablefalsenamenetworkAttributesitemwifi,1,1,2,-1,true/itemitemmobile,0,0,0,-1,true/itemitemmobile_mms,2,0,2,60000,true/itemitemmobile_supl,3,0,2,60000,true/itemitemmobile_dun,4,0,2,60000,true/itemitemmobile_hipri,5,0,3,60000,true/itemitemmobile_fota,10,0,2,60000,true/itemitemmobile_ims,11,0,2,60000,true/itemitemmobile_cbs,12,0,2,60000,true/itemitembluetooth,7,7,0,-1,true/itemitemethernet,9,9,9,-1,true/item/string-array3.4 Selinux权限配置Android 14 必须处理 AVC 拒绝在/system/sepolicy/vendor/rild.te中添加权限。diff--git a/system/sepolicy/vendor/rild.te b/system/sepolicy/vendor/rild.te index fc84ef7..27e3156100644---a/system/sepolicy/vendor/rild.teb/system/sepolicy/vendor/rild.te -7,37,4net_domain(rild)#public,but conceptually should go with thistype rild_exec,exec_type,vendor_file_type,file_type;init_daemon_domain(rild)allow rild self:packet_socket{create bind write read};给ttyUSB和cdc-wdm节点权限修改device/rockchip/common/sepolicy/private/file_contextsdiff--git a/device/rockchip/common/sepolicy/private/file_contexts b/device/rockchip/common/sepolicy/private/file_contexts index4df1488..480eabe100644---a/device/rockchip/common/sepolicy/private/file_contextsb/device/rockchip/common/sepolicy/private/file_contexts -3,33,18#All Rockchip configs/data/misc/cfg_rockchip(/.*)?u:object_r:rockchip_config_data_file:s0# quectel port/dev/ttyUSB[0-9]u:object_r:radio_device:s0/dev/ttyUSB3 u:object_r:serial_device:s0/dev/ttyACM[0-9]u:object_r:radio_device:s0/dev/cdc-wdm[0-9]u:object_r:radio_device:s0/dev/qcqmi[0-9]u:object_r:radio_device:s0/vendor/bin/hw/rild u:object_r:rild_exec:s0/dev/socket/rildOemHook u:object_r:rild_socket:s0#PCIe/dev/mhi_DUN u:object_r:radio_device:s0/dev/mhi_DIAG u:object_r:radio_device:s0/dev/mhi_BHI u:object_r:radio_device:s0/dev/mhi_LOOPBACK u:object_r:radio_device:s0/dev/mhi_QMI0 u:object_r:radio_device:s0修改device/rockchip/common/rootdir/ueventd.rockchip.rc这里有个/dev/ttyUSB3也是读写AT指令的设置成system用户组留给settings APP使用用来做切卡动作切卡详细在后面。diff--git a/device/rockchip/common/rootdir/ueventd.rockchip.rc b/device/rockchip/common/rootdir/ueventd.rockchip.rc index20d3765..9f8d59b100644---a/device/rockchip/common/rootdir/ueventd.rockchip.rcb/device/rockchip/common/rootdir/ueventd.rockchip.rc -69,769,7 import/vendor/etc/ueventd.car.rc/dev/ttyUSB00660radio radio/dev/ttyUSB10660radio radio/dev/ttyUSB20660radio radio-/dev/ttyUSB30660radio radio/dev/ttyUSB30660system system/dev/ttyUSB40660radio radio/dev/ttyUSB50660radio radio/dev/ttyUSB60660radio radio -77,677,18 import/vendor/etc/ueventd.car.rc/dev/ttyUSB80660radio radio/dev/ttyUSB90660radio radio#quectel port/dev/ttyACM*0660radio radio/dev/cdc-wdm*0660radio radio/dev/qcqmi*0660radio radio/dev/cdc-acm*0660radio radio#PCIe/dev/mhi_DUN0660radio radio/dev/mhi_DIAG0660radio radio/dev/mhi_BHI0660radio radio/dev/mhi_LOOPBACK0660radio radio/dev/mhi_QMI00660radio radio#formali-t764/dev/mali00666system system修改device/rockchip/common/sepolicy/vendor/system_app.te 让系统应用可以操作串口。diff--git a/device/rockchip/common/sepolicy/vendor/system_app.te b/device/rockchip/common/sepolicy/vendor/system_app.te index b220aae..fdfd589100644---a/device/rockchip/common/sepolicy/vendor/system_app.teb/device/rockchip/common/sepolicy/vendor/system_app.te -69,369,4 allow system_app sysfs_rpmsg_device:file r_file_perms;allow system_app sysfs_rpmsg_device:dir{search read open getattr};allow system_app sysfs_rpmsg_device:lnk_file r_file_perms;allow system_app device:dir{search read open getattr};allow system_app serial_device:chr_file rw_file_perms;四、 编译和调试至此移远em060k模组就算是配置完成了在编译前还有一个警告需要去除。diff--git a/external/usb_modeswitch/usb_dongle/Android.mk b/external/usb_modeswitch/usb_dongle/Android.mk index1ee43ff..afc59ff100755---a/external/usb_modeswitch/usb_dongle/Android.mkb/external/usb_modeswitch/usb_dongle/Android.mk -19,719,7 common_shared_libraries:\ common_cflags:-Werror-Wall-Wno-missing-field-initializers-Wno-unused-variable-Wno-unused-parameter-common_local_tidy_flags:-warnings-as-errorsclang-analyzer-security*,cert-*# common_local_tidy_flags:-warnings-as-errorsclang-analyzer-security*,cert-*common_local_tidy_checks:-*,clang-analyzer-security*,cert-*,-cert-err34-c,-cert-err58-cpp common_local_tidy_checks,-cert-env33-c编译好固件烧写到板卡检查ril库版本是否正确。console:/$ getprop gsm.version.ril-impl Quectel_Android_RIL_Driver_V4.1.0获取ril信息130|console:/$ getprop|grep-i ril[gsm.version.ril-impl]:[Quectel_Android_RIL_Driver_V4.1.0][init.svc.ril-daemon]:[running][ril.function.dataonly]:[1][ro.boot.noril]:[false]通过logcat -b radio -v time查看日志若无异常则em060k模块集成就完毕了。如果不需要短信收发和双卡单待的话到这里4G模组就调试完成了。五、 收发短信em060k模组定位为工业平板之类的设备不支持语音拨号但短信功能是支持的直接集成短信即可使用。diff--git a/device/rockchip/common/modules/rockchip_apps.mk b/device/rockchip/common/modules/rockchip_apps.mk index7b3a9ba..1885bf9100644---a/device/rockchip/common/modules/rockchip_apps.mkb/device/rockchip/common/modules/rockchip_apps.mk -20,420,6 PRODUCT_PACKAGES\ RkVideoPlayer \ RkExplorer \ StressTest \-RKUpdateServiceRKUpdateService \messaging# Dialer注意有些ril库不支持短信功能为了减少调试工作量可直接使用我上传的ril库。六、 双卡单待由于 Android RIL 默认不知道你有两张物理卡我们需要通过给em060k模块发指令来“欺骗”模块让它重新读卡。6.1 切换流程查询卡槽防止不知切哪个卡槽指令ATQUIMSLOT?切卡指令QUIMSLOT: 1。重置模块通过 CFUN0/1 或者复位引脚让 EM06K 重新初始化并读取新的 SIM 卡信息。这一步移远自动处理系统点击重启即可6.2 应用层Settings切卡新增布局修改packages/apps/Settings/res下的文件。diff--git a/packages/apps/Settings/res/xml/network_provider_sims_list.xml b/packages/apps/Settings/res/xml/network_provider_sims_list.xml index b21341e..4f61054100644---a/packages/apps/Settings/res/xml/network_provider_sims_list.xmlb/packages/apps/Settings/res/xml/network_provider_sims_list.xml -40,440,12 android:valuetrue//intent/com.android.settingslib.RestrictedPreferenceListPreferenceandroid:dialogTitlestring/select_default_slotandroid:entriesarray/sim_slot_switchandroid:entryValuesarray/sim_slot_switch_valuesandroid:keysim_slot_list_keyandroid:summarystring/sim_slot1android:titlestring/select_default_slot//PreferenceScreendiff--git a/packages/apps/Settings/res/values/arrays.xml b/packages/apps/Settings/res/values/arrays.xml index afb48d5..26a0575100644---a/packages/apps/Settings/res/values/arrays.xmlb/packages/apps/Settings/res/values/arrays.xml -1555,51555,13itemstring/battery_app_item_hint_in_fg/itemitemstring/battery_app_item_hint_in_fg/item/string-array-string-array namesim_slot_switchitemstring/sim_slot1/itemitemstring/sim_slot2/item/string-arraystring-array namesim_slot_switch_valuestranslatablefalseitem1/itemitem2/item/string-array/resourcesdiff--git a/packages/apps/Settings/res/values/strings.xml b/packages/apps/Settings/res/values/strings.xml index f5399d0..19f1cba100644---a/packages/apps/Settings/res/values/strings.xmlb/packages/apps/Settings/res/values/strings.xml -12409,412409,8string namesr_onOn/stringstring namesr_offOff/string!----string nameselect_default_slotSelectdefaultSIM slot/stringstring namesim_slot1SIM Slot1/stringstring namesim_slot2SIM Slot2/string/resourcesdiff--git a/packages/apps/Settings/res/values-zh-rCN/strings.xml b/packages/apps/Settings/res/values-zh-rCN/strings.xml index21fbb7b..c966e04100644---a/packages/apps/Settings/res/values-zh-rCN/strings.xmlb/packages/apps/Settings/res/values-zh-rCN/strings.xml -4846,44846,8string namesr_on已开启/stringstring namesr_off已关闭/string!----string nameselect_default_slot选择默认SIM卡槽/stringstring namesim_slot1SIM卡槽1/stringstring namesim_slot2SIM卡槽2/string/resources新增一个工具类SerialATManager.java用来读写串口。package com.android.settings.network;import android.util.Log;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;public class SerialATManager{privatestaticfinal String TAGSerialATManager;privatestaticfinal String DEVICE_PATH/dev/ttyUSB3;// 目标设备节点privatestaticfinalintBAUD_RATE115200;// 波特率需与 Modem 匹配privatestaticfinalintDATA_BITS8;// 数据位privatestaticfinalintSTOP_BITS1;// 停止位privatestaticfinalintPARITY0;// 校验位0无校验private File mDeviceFile;private OutputStream mOutputStream;// 写 AT 指令private InputStream mInputStream;// 读 AT 响应private boolean mIsOpenfalse;private OnATResponseListener mResponseListener;// 响应回调// AT 指令响应回调接口public interface OnATResponseListener{voidonResponse(String atCommand,String response);// 成功响应voidonError(String atCommand,String errorMsg);// 错误超时、设备异常}// 初始化并打开串口public booleanopenSerialPort(OnATResponseListener listener){if(mIsOpen){Log.w(TAG,Serial port already open);returntrue;}mResponseListenerlistener;mDeviceFilenewFile(DEVICE_PATH);try{// 1. 打开设备节点Android 中需通过系统 API 配置串口参数此处需依赖串口库// 注意原生 Android 无直接配置串口参数的 API需集成 android-serialport-api 或系统层串口工具// 以下为简化示例实际需调用串口配置接口如通过 JNI 或系统服务mOutputStreamnewFileOutputStream(mDeviceFile);mInputStreamnewFileInputStream(mDeviceFile);// 2. 配置串口参数波特率、数据位等需底层支持configureSerialPort(BAUD_RATE,DATA_BITS,STOP_BITS,PARITY);mIsOpentrue;Log.i(TAG,Serial port DEVICE_PATH opened successfully);returntrue;}catch(Exception e){Log.e(TAG,Open serial port failed: e.getMessage());if(mResponseListener!null){mResponseListener.onError(OPEN_PORT,e.getMessage());}closeSerialPort();returnfalse;}}// 配置串口参数需底层支持此处为接口定义privatevoidconfigureSerialPort(intbaudRate,intdataBits,intstopBits,intparity)throws IOException{// 实际实现通过系统 API 或 JNI 调用底层串口配置函数// 示例若集成 android-serialport-api// SerialPort serialPort new SerialPort(mDeviceFile, baudRate, 0);// mInputStream serialPort.getInputStream();// mOutputStream serialPort.getOutputStream();}// 发送 AT 指令带超时等待响应publicvoidsendATCommand(String atCommand,longtimeoutMs){if(!mIsOpen||mOutputStreamnull){Log.e(TAG,Serial port not open, cannot send AT command);if(mResponseListener!null){mResponseListener.onError(atCommand,Serial port not open);}return;}// 1. 发送 AT 指令末尾需加回车换行AT 指令标准格式try{String commandatCommand\r\n;mOutputStream.write(command.getBytes());mOutputStream.flush();Log.i(TAG,Sent AT command: command.trim());}catch(IOException e){Log.e(TAG,Send AT command failed: e.getMessage());if(mResponseListener!null){mResponseListener.onError(atCommand,e.getMessage());}return;}// 2. 读取响应开启子线程避免阻塞主线程newThread(()-{StringBuilder responsenewStringBuilder();longstartTimeSystem.currentTimeMillis();byte[]buffernew byte[1024];intreadLen;try{// 超时等待响应AT 指令响应通常较快超时设 3-5 秒while(System.currentTimeMillis()-startTimetimeoutMs){if(mInputStream.available()0){readLenmInputStream.read(buffer);if(readLen0){response.append(newString(buffer,0,readLen));// 若读到 AT 指令结束标记如 OK、ERROR提前退出if(response.toString().contains(OK)||response.toString().contains(ERROR)){break;}}}Thread.sleep(100);// 避免频繁读取减少 CPU 占用}// 3. 回调响应结果String responseStrresponse.toString().trim();Log.i(TAG,AT response: responseStr);if(mResponseListener!null){if(responseStr.contains(OK)){mResponseListener.onResponse(atCommand,responseStr);}else{mResponseListener.onError(atCommand,Response: responseStr);}}}catch(Exception e){Log.e(TAG,Read AT response failed: e.getMessage());if(mResponseListener!null){mResponseListener.onError(atCommand,e.getMessage());}}}).start();}// 关闭串口publicvoidcloseSerialPort(){try{if(mInputStream!null)mInputStream.close();if(mOutputStream!null)mOutputStream.close();mIsOpenfalse;Log.i(TAG,Serial port closed);}catch(IOException e){Log.e(TAG,Close serial port failed: e.getMessage());}}// 判断串口是否已打开public booleanisSerialPortOpen(){returnmIsOpen;}}修改切卡逻辑index d7d241a..2c318e8100644---a/packages/apps/Settings/src/com/android/settings/network/MobileNetworkListFragment.javab/packages/apps/Settings/src/com/android/settings/network/MobileNetworkListFragment.java -34,1334,28 import com.android.settingslib.search.SearchIndexable;import java.util.ArrayList;import java.util.List;import androidx.preference.Preference;import androidx.preference.ListPreference;import android.util.Log;import com.android.internal.telephony.Phone;import com.android.internal.telephony.PhoneFactory;import android.os.AsyncResult;import android.os.Handler;import android.os.Message;import android.telephony.TelephonyManager;SearchIndexable(forTargetSearchIndexable.ALL~SearchIndexable.ARC)-public class MobileNetworkListFragment extends DashboardFragment{public class MobileNetworkListFragment extends DashboardFragment implements SerialATManager.OnATResponseListener{privatestaticfinal String LOG_TAGNetworkListFragment;staticfinal String KEY_PREFERENCE_CATEGORY_SIMprovider_model_sim_category;privatestaticfinal String KEY_ADD_SIMadd_sim;private ListPreference mListPreference;private final String SIM_LIST_KEYsim_slot_list_key;private SerialATManager mSerialATManager;Override publicvoidonResume(){super.onResume();-49,864,16 public class MobileNetworkListFragment extends DashboardFragment{if(prefListView!null){prefListView.setItemAnimator(null);}// 初始化串口管理器mSerialATManagernewSerialATManager();// 打开串口进入页面时自动打开mSerialATManager.openSerialPort(this);// 发送AT指令查询当前SIM卡槽状态mSerialATManager.sendATCommand(ATQUIMSLOT?,3000);findPreference(KEY_ADD_SIM).setVisible(MobileNetworkUtils.showEuiccSettings(getContext()));mListPreference(ListPreference)findPreference(SIM_LIST_KEY);mListPreference.setOnPreferenceChangeListener(mSimSelectionListener);}Override -103,4126,86 public class MobileNetworkListFragment extends DashboardFragment{context.getSystemService(UserManager.class).isAdminUser();}};// AT 指令成功响应回调OverridepublicvoidonResponse(String atCommand,String response){Log.e(LOG_TAG,指令atCommand\n响应response);if(atCommand.equals(ATQUIMSLOT?)){getActivity().runOnUiThread(newRunnable(){Overridepublicvoidrun(){// 解析响应更新UIif(response.contains(QUIMSLOT: 1)){mListPreference.setValue(1);}elseif(response.contains(QUIMSLOT: 2)){mListPreference.setValue(2);}updateSimSummary();}});}}// AT 指令错误回调OverridepublicvoidonError(String atCommand,String errorMsg){Log.e(LOG_TAG,指令atCommand\n错误errorMsg);}/** * SIM卡选择监听器处理选中变化 */private final Preference.OnPreferenceChangeListener mSimSelectionListenernew Preference.OnPreferenceChangeListener(){Overridepublic booleanonPreferenceChange(Preference preference,Object newValue){if(newValuenull)returnfalse;String selectedSubId(String)newValue;Log.d(LOG_TAG,Selected SIM subId: selectedSubId);if(selectedSubId.isEmpty()){Log.w(LOG_TAG,Invalid SIM selection);returnfalse;}mListPreference.setValue(selectedSubId);updateSimSummary();if(selectedSubId.equals(1)){mSerialATManager.sendATCommand(ATQUIMSLOT1,3000);}else{mSerialATManager.sendATCommand(ATQUIMSLOT2,3000);}returntrue;}};/** * 更新摘要显示当前选中的SIM卡名称 */privatevoidupdateSimSummary(){String selectedValuemListPreference.getValue();CharSequence[]entriesmListPreference.getEntries();CharSequence[]valuesmListPreference.getEntryValues();for(inti0;ivalues.length;i){if(values[i].equals(selectedValue)){mListPreference.setSummary(entries[i]);break;}}}OverridepublicvoidonDestroy(){super.onDestroy();// 关闭串口释放资源if(mSerialATManager!nullmSerialATManager.isSerialPortOpen()){mSerialATManager.closeSerialPort();}}}