MSM8916 debian restart modem

0. 停止 ModemManager,避免它在基带重启期间不断访问设备

systemctl stop ModemManager

1. 停止modem

echo stop > /sys/class/remoteproc/remoteproc0/state
cat /sys/class/remoteproc/remoteproc0/state

命令应该返回 offline 的状态
2. 启动modem

echo start > /sys/class/remoteproc/remoteproc0/state
cat /sys/class/remoteproc/remoteproc0/state

状态应该恢复为 running
3. 启动ModemManager

systemctl start ModemManager

4. 等待10秒左右, 查看modem是否可用

mmcli -L

UZ801

FY_UZ801_V3.0
/priv-app/MifiService.apk
配置文件在 /data/mificonfig.json

AT+WRIMEI? 查询IMEI
AT+USB=1,268968726 设置调试模式
AT+WRIMEI= 写IMEI
AT+SLOT? 查询卡槽
AT^OTPPROGRAM?
AT^SYSCONFIG=
AT+SLOT= 设置卡槽
1 外置卡槽
2 嵌入式贴片卡

JZ02

[persist.sys.iccid]: [89860123851000342641]
[persist.sys.juzhen.customer]: [XU]
[persist.sys.juzhen.sn]: [1]
[persist.sys.juzhen.ssid.prefix]: [4G-UFI-]
[persist.sys.juzhen.type]: [ufi]

/system/framework/services.jar
com.android.server.LightsService
private static final String LED_SIM1_EN_FILE = “/sys/class/leds/sim1_switch_gpio/brightness”;
private static final String LED_SIM2_EN_FILE = “/sys/class/leds/sim2_switch_gpio/brightness”;
private static final String LED_SIM3_EN_FILE = “/sys/class/leds/sim3_switch_gpio/brightness”;
private static final String LED_SIM_DET_FILE = “/sys/class/leds/sim_hotdet_gpio/brightness”

sim_hot_detect.write(LightsService.outH); // 写1
Thread.sleep(2000L); // 等待2秒

pin_sim111.write(LightsService.outL);
pin_sim222.write(LightsService.outL);
pin_sim333.write(LightsService.outL);
pin_sim111.write(LightsService.outH); // 将 SIM1 写高

Thread.sleep(500L); // 等待0.5秒

sim_hot_detect.write(LightsService.outL);

跟别的版本有点不一样。

sim1 是 贴片卡
sim3 是 外置卡槽

debian中

		sim_sel {
			label = "sim:sel";
			gpios = <0x49 0x01 0x00>;
			default-state = "on";
		};

		sim_en {
			label = "sim:en";
			gpios = <0x49 0x14 0x00>;
			default-state = "off";
		};

		sim_sel2 {
			label = "sim:sel2";
			gpios = <0x49 0x16 0x00>;
			default-state = "off";
		};

		sim_en2 {
			label = "sim:en2";
			gpios = <0x49 0x17 0x00>;
			default-state = "off";
		};

sim_sel2 对应于 原 sim1
sim_en2  对应于 原 sim2
sim_sel  对应于 原 sim3 (也就外置卡槽)
sim_en   对应于 原 hotdet

android中

			sim1_switch_gpio {
				gpios = <0x4f 0x16 0x00>;
				label = "sim1_switch_gpio";
				linux,default-trigger = "none";
				default-state = "on";
				retain-state-suspended;
			};

			sim2_switch_gpio {
				gpios = <0x4f 0x17 0x00>;
				label = "sim2_switch_gpio";
				linux,default-trigger = "none";
				default-state = "off";
				retain-state-suspended;
			};

			sim3_switch_gpio {
				gpios = <0x4f 0x01 0x00>;
				label = "sim3_switch_gpio";
				linux,default-trigger = "none";
				default-state = "off";
				retain-state-suspended;
			};

			sim_hotdet_gpio {
				gpios = <0x4f 0x14 0x00>;
				label = "sim_hotdet_gpio";
				linux,default-trigger = "none";
				default-state = "off";
				retain-state-suspended;
			};

echo 1 > /sys/class/leds/sim_hotdet_gpio/brightness
sleep 1
echo 0 > /sys/class/leds/sim1_switch_gpio/brightness
echo 0 > /sys/class/leds/sim2_switch_gpio/brightness
echo 0 > /sys/class/leds/sim3_switch_gpio/brightness
echo 1 > /sys/class/leds/sim3_switch_gpio/brightness
sleep 0.5
echo 0 > /sys/class/leds/sim_hotdet_gpio/brightness

要改成

echo 1 > /sys/class/leds/sim:en/brightness
sleep 1
echo 0 > /sys/class/leds/sim:sel2/brightness
echo 0 > /sys/class/leds/sim:en2/brightness
echo 0 > /sys/class/leds/sim:sel/brightness
echo 1 > /sys/class/leds/sim:sel/brightness
sleep 0.5
echo 0 > /sys/class/leds/sim:en/brightness

UFI003

切换卡
卡0
TelephonyManager.write_int(“/sys/class/leds/SIM_EN/brightness”, 1);
TelephonyManager.write_int(“/sys/class/leds/SIM_SEL/brightness”, 0);
TelephonyManager.write_int(“/sys/class/leds/ESIM_SEL/brightness”, 0);
TelephonyManager.write_int(“/sys/class/leds/ESIM2_SEL/brightness”, 0);
SimDetector.this.SimWait(500);
TelephonyManager.write_int(“/sys/class/leds/SIM_SEL/brightness”, 1); 拉高外置卡
SimDetector.this.SimWait(300);
TelephonyManager.write_int(“/sys/class/leds/SIM_EN/brightness”, 0);

卡1
TelephonyManager.write_int(“/sys/class/leds/SIM_EN/brightness”, 1);
TelephonyManager.write_int(“/sys/class/leds/SIM_SEL/brightness”, 0);
TelephonyManager.write_int(“/sys/class/leds/ESIM_SEL/brightness”, 0);
TelephonyManager.write_int(“/sys/class/leds/ESIM2_SEL/brightness”, 0);
SimDetector.this.SimWait(500);
TelephonyManager.write_int(“/sys/class/leds/ESIM_SEL/brightness”, 1);
SimDetector.this.SimWait(300);
TelephonyManager.write_int(“/sys/class/leds/SIM_EN/brightness”, 0);

卡2
TelephonyManager.write_int(“/sys/class/leds/SIM_EN/brightness”, 1);
TelephonyManager.write_int(“/sys/class/leds/SIM_SEL/brightness”, 0);
TelephonyManager.write_int(“/sys/class/leds/ESIM_SEL/brightness”, 0);
TelephonyManager.write_int(“/sys/class/leds/ESIM2_SEL/brightness”, 0);
SimDetector.this.SimWait(500);
TelephonyManager.write_int(“/sys/class/leds/ESIM2_SEL/brightness”, 1); 拉高 ESIM2
SimDetector.this.SimWait(300);
TelephonyManager.write_int(“/sys/class/leds/SIM_EN/brightness”, 0);

系统属性

[persist.ufi.card.plug]: [yes]
[persist.ufi.ft.haveeth]: [0]
[persist.ufi.ft.mqtt_th]: [0]
[persist.ufi.ft.only_sn]: [1]
[persist.ufi.ft.simsw]: [1]
[persist.ufi.ft.simsw_pw]: [0]
[persist.ufi.ft.simswitchpword]: [zx]
[persist.ufi.ft.weblogo]: [NORMAL]
[persist.ufi.ft.withmtp]: [0]
[persist.ufi.ft.write_imei]: [1]
[persist.ufi.imei.ssid]: []
[persist.ufi.nosignal.reboot]: [no]
[persist.ufi.ping.router]: []
[persist.ufi.qhyl.light]: []
[persist.ufi.qhyl.switchsim]: []
[persist.ufi.signal.check]: [yes]
[persist.ufi.sim.pooling]: [no]
[persist.ufi.sim.prior]: [DE]
[persist.ufi.sn.auth.service]: [1]
[persist.ufi.wifi.light]: [yes]

GPIO定义

		gpio-leds {
			compatible = "gpio-leds";
			pinctrl-names = "default";
			pinctrl-0 = <0xec>;


			SIM_SEL {
				gpios = <0x4f 0x02 0x00>;
				label = "SIM_SEL";
				linux,default-trigger = "none";
				default-state = "off";
				retain-state-suspended;
			};

			sim_en {
				gpios = <0x4f 0x01 0x00>;
				label = "SIM_EN";
				linux,default-trigger = "none";
				default-state = "off";
				retain-state-suspended;
			};

			ESIM_SEL {
				gpios = <0x4f 0x00 0x00>;
				label = "ESIM_SEL";
				linux,default-trigger = "none";
				default-state = "on";
				retain-state-suspended;
			};

			ESIM2_SEL {
				gpios = <0x4f 0x03 0x00>;
				label = "ESIM2_SEL";
				linux,default-trigger = "none";
				default-state = "off";
				retain-state-suspended;
			};

xposed

public class Workaround implements IXposedHookLoadPackage {
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) {
        if(!lpparam.packageName.equals("com.android.systemui")) {
            return;
        }

        try {
            XposedHelpers.findAndHookMethod("com.android.systemui.ElinkAutoTestService$SnImeiCheckThread", lpparam.classLoader, "enter_SnImeiCheckFailed", new Object[]{XC_MethodReplacement.DO_NOTHING});
        }
        catch(Exception e) {
            XposedBridge.log(e);
        }
    }
}

GPIO控制着 SIM卡 GND脚的 通断

新讯WF2充电宝410MiFi

[persist.ufi.card.plug]: [yes]
[persist.ufi.sim.prior]: [DE]

[persist.ufi.sn.auth.service]: [1]
[persist.ufi.ft.only_sn]: [0] 修改IMEI后,不会自动变成飞行模式
[persist.ufi.nosignal.reboot]: [no] 无信号,不重启
[persist.ufi.qhyl.switchsim]
[persist.ufi.ft.server]: [NONE]
[persist.ufi.ft.simsw_pw]: [1] 切换sim卡需要密码
[persist.ufi.ft.simswitchpword]: [qhyl_2] 切换sim卡的密码
———————-
[persist.radio.airplane_mode_on]: [0]
———————-
app/PhoneFeatures.apk
priv-app/SystemUI.apk
priv-app/cpeweb.apk

————
双卡版本
切换到 卡槽0
TelephonyManager.write_int(“/sys/class/leds/SIM_EN/brightness”, 1);
TelephonyManager.write_int(“/sys/class/leds/SIM_SEL/brightness”, 0); 关闭外置SIM
SimDetector.this.SimWait(500);
TelephonyManager.write_int(“/sys/class/leds/SIM_EN/brightness”, 0);
卡槽1
TelephonyManager.write_int(“/sys/class/leds/SIM_EN/brightness”, 1);
TelephonyManager.write_int(“/sys/class/leds/SIM_SEL/brightness”, 1); 开启外置SIM
SimDetector.this.SimWait(500);
TelephonyManager.write_int(“/sys/class/leds/SIM_EN/brightness”, 0);

三卡版:
卡0:
TelephonyManager.write_int(“/sys/class/leds/SIM_EN/brightness”, 1);
TelephonyManager.write_int(“/sys/class/leds/SIM_SEL/brightness”, 0);
TelephonyManager.write_int(“/sys/class/leds/ESIM_SEL/brightness”, 0);
TelephonyManager.write_int(“/sys/class/leds/ESIM2_SEL/brightness”, 0);
SimDetector.this.SimWait(500);
TelephonyManager.write_int(“/sys/class/leds/SIM_SEL/brightness”, 1); 选择外置SIM
SimDetector.this.SimWait(300);
TelephonyManager.write_int(“/sys/class/leds/SIM_EN/brightness”, 0);
卡1:
TelephonyManager.write_int(“/sys/class/leds/SIM_EN/brightness”, 1);
TelephonyManager.write_int(“/sys/class/leds/SIM_SEL/brightness”, 0);
TelephonyManager.write_int(“/sys/class/leds/ESIM_SEL/brightness”, 0);
TelephonyManager.write_int(“/sys/class/leds/ESIM2_SEL/brightness”, 0);
SimDetector.this.SimWait(500);
TelephonyManager.write_int(“/sys/class/leds/ESIM_SEL/brightness”, 1); 选择第1个ESIM
SimDetector.this.SimWait(300);
TelephonyManager.write_int(“/sys/class/leds/SIM_EN/brightness”, 0);
卡2:
TelephonyManager.write_int(“/sys/class/leds/SIM_EN/brightness”, 1);
TelephonyManager.write_int(“/sys/class/leds/SIM_SEL/brightness”, 0);
TelephonyManager.write_int(“/sys/class/leds/ESIM_SEL/brightness”, 0);
TelephonyManager.write_int(“/sys/class/leds/ESIM2_SEL/brightness”, 0);
SimDetector.this.SimWait(500);
TelephonyManager.write_int(“/sys/class/leds/ESIM2_SEL/brightness”, 1); 选择第2个ESIM
SimDetector.this.SimWait(300);
TelephonyManager.write_int(“/sys/class/leds/SIM_EN/brightness”, 0);

———-
IMEI写
Diag_LSM_Init
diag_register_callback
———
String sn_check = SystemProperties.get(“persist.ufi.ft.only_sn”, “1”);
Log.e(“ElinkAutoTestService”, “enable_sn_check: ” + sn_check);
this.enable_sn_check = Integer.parseInt(s);

高通410WiFi棒子修改显示分辨率

准备工具
1. unpackbootimg

git clone https://github.com/anestisb/android-unpackbootimg
cd android-unpackbootimg
make

2. dtimgextract

git clone https://github.com/s0be/dtimgextract
cd dtimgextrace
gcc dtimgextract.c -o dtimgextract 或者 make

或者
https://github.com/wuxianlin/dtimg2dtb-python

3.device-tree-compiler Debian系统自带,用apt安装

apt install device-tree-compiler

4. dtbtool

wget https://github.com/CyanogenMod/android_device_qcom_common/blob/cm-14.1/dtbtool/dtbtool.c
gcc dtbtool.c -o dtbtool

5. edl

安装方法参考 https://softs.im/msm8916-wifi-dongle/

步骤:
1. 9008模式 读出 boot.img

edl r boot boot.img

2. 解包 boot.img

mkdir boot
./unpackbootimg -i boot.img -o boot

可以看到在boot目录创建了很多文件,其中 boot.img-dtb 就是我们所需要的。
3. 解包 dt.img
将 boot.img-dtb复制到 合适的位置

mkdir unpack
cd unpack
../dtimgextract ../boot/boot.img-dtb 

4. 反编译 dtb
在上一步的目录执行以下命令

mkdir output
for i in $(ls *.dtb);do dtc -I dtb -O dts -o ../output/$i.dts $i;done

反编译会出来大量警告

5. 查找设备使用的设备树

cd output
grep -rn "MSM 8916 512MB MTP" .

可以看见本次查找出了四个文件,经过对比发现四个文件内容完全一致,修改其中一个 然后覆盖另外三个即可。

6. 修改屏幕分辨率
打开ce_8_100_0.dtb.dts文件找到qcom,mdss_spi_st7735s_128128_cmd这一项
其中 qcom,mdss-spi-panel-with 和 qcom,mdss-spi-panel-height 就是

qcom,mdss_dsi_st7796s_320p_video {
				qcom,mdss-dsi-panel-name = "st7796s 320p video mode dsi panel";
				qcom,mdss-dsi-panel-controller = <0x42>;
				qcom,mdss-dsi-panel-type = "dsi_video_mode";
				qcom,mdss-dsi-panel-framerate = <0x3c>;
				qcom,mdss-dsi-virtual-channel-id = <0x00>;
				qcom,mdss-dsi-stream = <0x00>;
				qcom,mdss-dsi-panel-width = <0x140>;
				qcom,mdss-dsi-panel-height = <0x1e0>;

或者

			qcom,mdss_spi_st7735s_128128_cmd {
				qcom,mdss-spi-panel-name = "st7735s 128128 command mode spi panel";
				qcom,mdss-spi-panel-destination = "display_1";
				qcom,mdss-spi-panel-controller = <0x45>;
				qcom,mdss-spi-panel-framerate = <0x1b>;
				qcom,mdss-spi-panel-width = <0x84>;
				qcom,mdss-spi-panel-height = <0x84>;

Simulator video 比较正常 640×480 (0x280, 0x1e0)

			qcom,mdss_dsi_sim_video {
				qcom,mdss-dsi-panel-name = "Simulator video mode dsi panel";
				qcom,mdss-dsi-panel-controller = <0x44>;
				qcom,mdss-dsi-panel-type = "dsi_video_mode";
				qcom,mdss-dsi-panel-destination = "display_1";
				qcom,mdss-dsi-panel-framerate = <0x3c>;
				qcom,mdss-dsi-virtual-channel-id = <0x00>;
				qcom,mdss-dsi-stream = <0x00>;
				qcom,mdss-dsi-panel-width = <0x280>;
				qcom,mdss-dsi-panel-height = <0x1e0>;

可以改成 0x356,0x1e0 也就是

实际改成

			qcom,mdss_spi_st7735s_128128_cmd {
				qcom,mdss-spi-panel-name = "st7735s 128128 command mode spi panel";
				qcom,mdss-spi-panel-destination = "display_1";
				qcom,mdss-spi-panel-controller = <0x45>;
				qcom,mdss-spi-panel-framerate = <0x1b>;
				qcom,mdss-spi-panel-width = <0x140>;
				qcom,mdss-spi-panel-height = <0x1e0>;

320×480
7. 编译dtb
修改完后对已修改的文件进行编译,使用以下命令,其中为ce_8_100_0.dtb.dts修改过的设备树源码,ce_8_100_0.dtb为编译后生成的设备树。

dtc -I dts -O dtb -o ce_8_100_0.dtb ce_8_100_0.dtb.dts

8.打包dt.img
把新生成的dtb文件替换掉第2步解包出来的unpack文件夹中对应的dtb文件,
将替换后的unpack文件夹复制到dtbtool文件夹中,
其中的output文件夹删掉,
执行以下命令进行打包。

./dtbtool -o boot.img-dtb unpack/

9.打包boot.img
把新生成的boot.img-dtb替换掉第1步解包出来的boot文件夹中的boot.img-dtb,
执行以下命令进行打包。

./mkbootimg \
--kernel boot/boot.img-zImage \
--ramdisk boot/boot.img-ramdisk.gz \
--cmdline "$(cat boot/boot.img-cmdline)" \
--board "$(cat boot/boot.img-board)" \
--base "$(cat boot/boot.img-base)" \
--pagesize "$(cat boot/boot.img-pagesize)" \
--dt boot/boot.img-dtb \
--kernel_offset "$(cat boot/boot.img-kerneloff)" \
--ramdisk_offset "$(cat boot/boot.img-ramdiskoff)" \
--second_offset "$(cat boot/boot.img-secondoff)" \
--tags_offset "$(cat boot/boot.img-tagsoff)" \
--os_version "4.4.4" \
--os_patch_level "2023-05-08" \
--hash "$(cat boot/boot.img-hash)" \
--output newboot.img

常用vowifi ims服务器IP地址

马来西亚

115.164.160.40 CelcomDigi 502 16 epdg.epc.mnc016.mcc502.pub.3gppnetwork.org
115.164.160.40 CelcomDigi 502 19 epdg.epc.mnc019.mcc502.pub.3gppnetwork.org
115.164.32.40 CelcomDigi 502 16 epdg.epc.mnc016.mcc502.pub.3gppnetwork.org
115.164.32.40 CelcomDigi 502 19 epdg.epc.mnc019.mcc502.pub.3gppnetwork.org
42.153.28.64 Telekom Malaysia 502 11 epdg.epc.mnc011.mcc502.pub.3gppnetwork.org
42.153.24.64 Telekom Malaysia 502 11 epdg.epc.mnc011.mcc502.pub.3gppnetwork.org
202.75.146.43 502 12 epdg.epc.mnc012.mcc502.pub.3gppnetwork.org
202.75.146.42 502 12 epdg.epc.mnc012.mcc502.pub.3gppnetwork.org
202.75.146.41 502 12 epdg.epc.mnc012.mcc502.pub.3gppnetwork.org

123.136.110.180 U-Mobile 502 18 epdg.epc.mnc018.mcc502.pub.3gppnetwork.org
123.136.100.132 U-Mobile 502 18 epdg.epc.mnc018.mcc502.pub.3gppnetwork.org

英国VOXI (Vodafone 子公司)
epdg.epc.mnc015.mcc234.pub.3gppnetwork.org
88.82.11.221
88.82.11.208
148.252.188.96

泰国
119.31.123.26 AIS 520 03 epdg.epc.mnc003.mcc520.pub.3gppnetwork.org
119.31.121.14 AIS 520 03 epdg.epc.mnc003.mcc520.pub.3gppnetwork.org
61.91.170.166 True 520 04 epdg.epc.mnc004.mcc520.pub.3gppnetwork.org
61.91.170.102 True 520 04 epdg.epc.mnc004.mcc520.pub.3gppnetwork.org
111.84.240.252 520 05 epdg.epc.mnc005.mcc520.pub.3gppnetwork.org
111.84.112.252 520 05 epdg.epc.mnc005.mcc520.pub.3gppnetwork.org
1.20.66.24 520 17 epdg.epc.mnc017.mcc520.pub.3gppnetwork.org
1.20.65.24 520 17 epdg.epc.mnc017.mcc520.pub.3gppnetwork.org

德国O2 (西班牙 Telefonica 的子公司)
epdg.epc.mnc003.mcc262.pub.3gppnetwork.org
213.20.151.16
213.20.175.56
213.20.31.8
62.52.52.30

新西兰
118.149.14.20 2degrees 530 24 epdg.ims.2degrees.net.nz
203.96.213.193 One NZ 530 01 epdg.epc.mnc001.mcc530.pub.3gppnetwork.org
203.96.213.192 One NZ 530 01 epdg.epc.mnc001.mcc530.pub.3gppnetwork.org
122.63.255.115 Spark 530 05 epdg.epc.mnc005.mcc530.pub.3gppnetwork.org
122.63.255.112 Spark 530 05 epdg.epc.mnc005.mcc530.pub.3gppnetwork.org
122.63.255.109 Spark 530 05 epdg.epc.mnc005.mcc530.pub.3gppnetwork.org

ejabberd安装配置

1. 安装
apt install ejabberd

2. 配置

修改 ejabberd.xml
1) 域名
hosts:
# – localhost
– softs.im
2) 证书
certfiles:
# – “/etc/ejabberd/ejabberd.pem”
– /etc/ejabberd/softs.im/fullchain.pem
– /etc/ejabberd/softs.im/privkey.pem

3) 并确保 access_rules 下的 configure 权限允许该管理员:

access_rules:
configure:
allow: admin

4) 添加管理员

acl:
admin:
user:
– “cmcc@softs.im”

5) 如果需要让 Gajim支持文件传输,需要打开mod_http_upload
第一处,将 /upload: mod_http_upload 这一行的 #号 注释去掉
port: 5443
ip: “::”
module: ejabberd_http
tls: true
protocol_options: ‘TLS_OPTIONS’
request_handlers:
/api: mod_http_api
/bosh: mod_bosh
## /captcha: ejabberd_captcha
/upload: mod_http_upload
/ws: ejabberd_http_ws
在 modules: 下面开启 mod_http_upload, 也是将相关的 #号 注释去掉

mod_http_upload:
put_url: https://@HOST@:5443/upload
docroot: “/var/upload”
注意,我添加了一个 docroot, 服务器会将接收到的文件存在这个目录

3.
重启 ejabberd
ejabberdctl restart

4.
注册管理员
ejabberdctl register admin localhost password
(将 admin、localhost 和 password 替换为您的自定义用户名、域名和密码)

5.
访问 https://softsim:5280/admin/ 来管理

特别强调:
XMPP 的 文件传输体验 不只是客户端问题,最好是服务器上也给予支持。

P2P直传(老方式),在 conversation和dino上支持,但NAT环境容易失败,并且传输慢
HTTP Upload(推荐) 文件先上传服务器

rust中的引用为什么可以直接比较大小

Rust 中两个引用(如 &T)可以直接比较大小,是因为 Rust 的标准库为实现了 Ord 或 PartialOrd trait 的类型 T 的引用类型 &T 自动实现了这些 trait。具体来说,当比较 &a 和 &b 时,实际上是在比较它们所指向的底层数据 a 和 b 的值

原因有以下两点:
1. 智能隐式解引用(Dereferencing): Rust 的比较运算符(<, >, <=, >=)会处理引用。编译器在比较时,会自动深入引用层级,比较指向的实际数值,而非引用本身的内存地址。

2. Trait 自动实现: Rust 标准库中存在类似 impl Ord for &T 的定义。即如果类型 T 本身是可以比较顺序的(实现了 Ord),那么 &T 也自动拥有比较顺序的能力。

或者这么来理解: 在 Rust 中,比较运算符(如 >, <, ==)实际上是对标准库中 Trait(特征)的语法糖。比如 > 对应的是 PartialOrd 这个特征(Trait), 如果一个类型 T 可以比较大小,那么它的引用 &T 也可以比较大小;并且,比较两个引用时,Rust 会自动去比较它们所指向的底层数据。

所以,只要引用指向的类型实现了 PartialOrd(如整数、浮点数、字符串等),引用之间就能直接比较。

fn main() {
    let number_list = vec![34, 50, 25, 100, 65];

    let mut largest = &number_list[0];

    for number in &number_list {
        if number > largest {
            largest = number;
        }
    }

    println!("The largest number is {largest}");
}

中 if number > largest 改成 *number > *largest 也是可以的。 这就是手动解引用。

如果我真的想比较引用的“内存地址”怎么办?
因为 Rust 默认比较引用是指向的值,如果你在某些极少数的底层场景下,真的想要比较两个变量是不是存放在内存的同一个位置(比较地址大小),你需要把它们转换成裸指针(Raw Pointers):

if (number as *const i32) > (largest as *const i32)

5G NSA的几种形式

NSA就是LTE与NR的双连接,具体有:
EN-DC (4G核心网,4G基站为主站,5G基站为辅) E_UTRAN New Radio-Dual Connectivity
NE-DC (5G核心网, 5G为主,4G为辅助)
NGEN-DC (5G核心网,4G为主, 5G为辅)