BG95-M5 - QMI mode on Debian

Hello,

I have a BG95-M5 with the following information:

ATI

Quectel
BG95-M5
Revision: BG95M5LAR02A03

My goal is to have ModemManager to be able to use it.

ModemManager doesn’t support PPP, so the modem needs to be put in QMI mode.

Looking at the documentation, I have done:

AT+QCFGEXT="usbnet","rmnet"

OK

I have then rebooted the modem, but nothing appears under /dev/cdc-wdm* :

ls /dev/cdc-wdm*
ls: /dev/cdc-wdm*: No such file or directory

I do not understand why nothing appears in /dev/cdc-wdm*, can someone help me out ?

I don’t think QMI is [fully] supported by this modem.
Do you mind sharing the output of AT+QCFGEXT=?
and cat /sys/kernel/debug/usb/devices

Here’s the output of AT+QCFGEXT=?

+QCFGEXT: "addgeo",<geoid>,<mode>,<shape>,<lat1>,<lon1>,<lat2>[,<lon2>[,<lat3>,<lon3>[,<lat4>,<lon4>]]]
+QCFGEXT: "deletegeo",<geoid>
+QCFGEXT: "querygeo",<geoid>
+QCFGEXT: "nipdcfg"[,<type>[,<apn>[,<username>,<password>]]]
+QCFGEXT: "nipd"[,<mode>[,<timeout>]]
+QCFGEXT: "nipds"[,<mode>,<data>[,<data_length>[,<rai_flag>]]
+QCFGEXT: "nipdr"[,<read_length>[,<read_mode>]]
+QCFGEXT: "dump"[,(0,1)]
+QCFGEXT: "quecopen"[,(0,1)]
+QCFGEXT: "disusb",(0,1)
+QCFGEXT: "usb/event"
+QCFGEXT: "fota_apn",<iptype>,<apn>[,<username>,<password>]
+QCFGEXT: "sni"[,(0,1)]
+QCFGEXT: "dnsc_timeout"[,(2-300)]
+QCFGEXT: "pwm",<pin>[,(0,1)[,(1-99),(293-600000)]]
+QCFGEXT: "usbnet"[,"ecm,modem,rmnet"]
+QCFGEXT: "fota_http_header",<header_key>,<header_value>
+QCFGEXT: "fota_wd_gpio",<switch>,<pin_num>,<feed_interval>
+QCFGEXT: "ap_os_version"

And here is the relevant part of the cat /sys/kernel/debug/usb/devices

T:  Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 22 Spd=480  MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=2c7c ProdID=0700 Rev= 0.00
S:  Manufacturer=Quectel, Incorporated
S:  Product=Quectel LPWA Module
S:  SerialNumber=56171261
C:* #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=500mA
I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=60 Driver=option
E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
E:  Ad=83(I) Atr=03(Int.) MxPS=  64 Ivl=2ms
E:  Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
E:  Ad=85(I) Atr=03(Int.) MxPS=  64 Ivl=2ms
E:  Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms

I suggest using ECM. ModemManager is not needed.

This is your QMI interface. My understanding QMI support in this modem is broken or incomplete, that’s why the interface is not taken by the driver.

Alright, thank you.

By any chance, do you know how “port forwarding” works with ECM ?

Using ECM I get assigned a private IP : 192.168.X.X, and the modem itself obviously has a different public IP address.

I assume every packets incoming on the modem to be directly sent over the only “client” which is my device, is it correct ?

What is the Linux kernel version? And what is the ModemManager version?
BG95 ECM do not support IPPT and it cannot obain the public IP address.

Most of the time the modem itself will have a private IP as well, check with at+cgpaddr

No, it will be dropped by default. Only return traffic will pass the NAT.

@Bean.Wang-Q

I do not use modem manager as I put my BG95 in ECM mode.
Linux Kernel is 6.6.22-v8.

@jfrog is there a configuration to be made in order for the incoming traffic not to be dropped ?

What is in at+cgpaddr response?

You need add it in the drivers/net/usb/qmi_wwan.c
{QMI_QUIRK_SET_DTR)(0x2c7c, 0x0700, 3)},

I have my “public” IP (I’ve censored parts of it because it seems it is a fixed ip)

at+cgpaddr
+CGPADDR: 1,198.XX.121.XX 

@Bean.Wang-Q

Will QMI mode allow me to have the public ip address ?

Right, you have a public IP that is not common these days.
Speaking generally, you can pass this IP to the host if the modem operates in MBIM, QMI, PPP modes and in ECM if there is an option to disable NAT or configure passthrough.
So in your case PPP and QMI (questionable) should do the job.

Yes, we do have a very specific use case where we have a partnership with a mobile carrier that allow us to have a private APN.

If I’m understanding correctly, without an option to disable NAT on the BG95-M5 in ECM mode, the device won’t be reachable using its public IP address, rendering the ECM mode useless in our case.

To summarize, for the BG95-M5 this leaves either QMI or PPP, and QMI is supposed to be used alongside with ModemManager, and PPP is supposed to be used “manually”. Am I understanding this correctly ?

Generally yes, but if QMI works you can also use standard Linux qmicli, etc.

Hi,

So after patching my kernel as per @Bean.Wang-Q advice, I now have /dev/cdc-wdm0 appear when plugging my BG-95.

However, when trying to manually enable the connection using qmicli, I encounter errors:

qmicli -d /dev/cdc-wdm0 --wds-start-network="apn=***,auth=CHAP,username=***,password=****=="
error: couldn't start network: QMI protocol error (25): 'DeviceUnsupported'

qmicli -d /dev/cdc-wdm0 --wds-get-current-settings
error: couldn't get current settings: QMI protocol error (94): 'NotSupported'

Some commands do work:

qmicli -d /dev/cdc-wdm0 --dms-get-operating-mode

[/dev/cdc-wdm0] Operating mode retrieved:
        Mode: 'online'
        HW restricted: 'no'
qmicli --device=/dev/cdc-wdm0  --uim-get-card-status

[/dev/cdc-wdm0] Successfully got card status
Provisioning applications:
        Primary GW:   slot '1', application '1'
        Primary 1X:   session doesn't exist
        Secondary GW: session doesn't exist
        Secondary 1X: session doesn't exist
Slot [1]:
        Card state: 'present'
        UPIN state: 'not-initialized'
                UPIN retries: '0'
                UPUK retries: '0'
        Application [1]:
                Application type:  'usim (2)'
                Application state: 'ready'
                Application ID:
                        A0:00:00:00:87:10:02:FF:33:FF:FF:89:06:21:00:FF
                Personalization state: 'ready'
                UPIN replaces PIN1: 'no'
                PIN1 state: 'disabled'
                        PIN1 retries: '3'
                        PUK1 retries: '10'
                PIN2 state: 'enabled-not-verified'
                        PIN2 retries: '1'
                        PUK2 retries: '10'

I am not sure why some qmicli commands work while other commands are not working ?

I tried to warn you earlier:

Right, I was hoping it was only related to the modem detection by Linux.

@Bean.Wang-Q do you know if a firmware update would help ? Maybe the firmware version that I currently have doesn’t support QMI completely ?

Yes. BG95 is based Qualcomm 9x05 and QMI is not fully supported.
I think you can update the firmware and test it again, if it is still not supported, you might cannot use the qmicli and mmcli. But maybe you can try the QConnectManager.

@Bean.Wang-Q I’ve updated the firmware, qmicli and mmcli are still NOT working :frowning:

I’ll try with QConnectManager.

Actually the BG95-M5 is also support the PPP. But I am not sure whether the ModemManager can use the PPP with this modem.

Please try the script

#!/bin/sh

#quectel-pppd devname apn user password
echo "quectel-pppd options in effect:"
QL_DEVNAME=/dev/ttyUSB3
QL_APN=3gnet
QL_USER=user
QL_PASSWORD=passwd
QL_PDP=1
QL_IP=IP #IP, IPV4, IPV6, IPV4V6
if [ $# -ge 1 ]; then
	QL_DEVNAME=$1	
	echo "devname   $QL_DEVNAME    # (from command line)"
else
	echo "devname   $QL_DEVNAME    # (default)"
fi
if [ $# -ge 2 ]; then
	QL_APN=$2	
	echo "apn       $QL_APN    # (from command line)"
else
	echo "apn       $QL_APN    # (default)"
fi
if [ $# -ge 3 ]; then
	QL_USER=$3	
	echo "user      $QL_USER   # (from command line)"
else
	echo "user      $QL_USER   # (default)"
fi
if [ $# -ge 4 ]; then
	QL_PASSWORD=$4	
	echo "password  $QL_PASSWORD   # (from command line)"
else
	echo "password  $QL_PASSWORD   # (default)"
fi

CONNECT="'chat -s -v ABORT BUSY ABORT \"NO CARRIER\" ABORT \"NO DIALTONE\" ABORT ERROR ABORT \"NO ANSWER\" TIMEOUT 30 \
\"\" AT OK ATE0 OK ATI\;+CSUB\;+CSQ\;+CPIN?\;+COPS?\;\&D2 \
OK AT+CGDCONT=$QL_PDP,\\\"$QL_IP\\\",\\\"$QL_APN\\\",,0,0 OK ATD*99***$QL_PDP# CONNECT'"

OPTIONS="noauth debug defaultroute noipdefault novj novjccomp noccp ipcp-accept-local ipcp-accept-remote ipcp-max-configure 30 local modem dump nodetach nocrtscts usepeerdns"

if [ "$QL_IP" == "IPV6" ]; then
OPTIONS="$OPTIONS noip +ipv6"
fi
if [ "$QL_IP" == "IPV4V6" ]; then
OPTIONS="$OPTIONS +ipv6"
fi

pppd $QL_DEVNAME 115200 user "$QL_USER" password "$QL_PASSWORD" \
connect "'$CONNECT'" \
disconnect 'chat -s -v ABORT ERROR ABORT "NO DIALTONE" SAY "\nSending break to the modem\n" "" +++ "" +++ "" +++ SAY "\nGood bay\n"' \
$OPTIONS &