Example on how to establish a data connection with Telit FN980 series in Linux using QMI Rmnet and USB interface
Question
Example on how to establish a data connection with Telit FN980 series in Linux using QMI Rmnet and USB interface.
Solution
Example on how to establish a data connection with Telit FN980 series in Linux using QMI Rmnet and USB interface
5G technology introduces new requirements on the interface links between the host systems and cellular modules.
The Linux community continuously commit necessary changes to the kernel drivers and interface management tools to improve the compatibility and performance.
Because of this, it is important that you base your Linux system builds on up-to-date kernel versions, avoiding many problems already solved.
Ensure that you have up-to-date firmware version in the cellular module. Check the dedicated product page here at Techship and the firmware downloads tab.
Early devices and engineering samples came with a older Qualcomm baseline firmware versions and need to be update in Windows systems using the Telit TFI updater tool and cannot be updated with Telit XFP firmware update procedure.
This guide specifically only describes how to establish the QMUX data connection part of the QMI Rmnet USB interface for the Telit FN980 module.
The qmi_wwan kernel driver module and libqmi library is used.
Ensure that you have the module in QMI Rmnet usb mode and qmi_wwan network kernel driver and option usb-serial driver properly loaded to the module interfaces.
Can be checked e.g. through dmesg, usb-devices or lsusb -t commands.
usb-devices
T: Bus=02 Lev=01 Prnt=01 Port=03 Cnt=01 Dev#= 4 Spd=5000 MxCh= 0
D: Ver= 3.20 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 9 #Cfgs= 1
P: Vendor=1bc7 ProdID=1050 Rev=04.14
S: Manufacturer=Telit Wireless Solutions
S: Product=FN980m
S: SerialNumber=
C: #Ifs= 7 Cfg#= 1 Atr=80 MxPwr=896mA
I: If#=0x0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=techship_serial
I: If#=0x1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=usbfs
I: If#=0x2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan
I: If#=0x3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=techship_serial
I: If#=0x4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=techship_serial
I: If#=0x5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=techship_serial
I: If#=0x6 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=techship_serial
If the qmi_wwan and option drivers do not get correctly loaded in your current system build and kernel version, please refer to the manufacturer Linux integration guide.
Alternatively you can try compile our modified out-of-kernel driver module variants: techship_qmi_wwan and techship_serial and load them in your system.
See the git readme files for details on pre-requirements, how to clone, compile and use the make file options to install the drivers.
They are available in the following git repository: https://bitbucket.org/storjor/techship_linux_drivers/src/master/
Once you have drivers correctly loaded, start by disabling the related qmi_wwan network interface name:
ip link set dev wwan0 down
Ensure RAW IP configuration is enabled:
sh -c "echo 'Y' > /sys/class/net/wwan0/qmi/raw_ip"
(observe the path name including the network interface name, update to match the interface name used in your system)
Create a virtual mux interface for the qmi network interface:
sh -c "echo '1' > /sys/class/net/wwan0/qmi/add_mux"
(observe the path name including the network interface name, update to match the interface name used in your system)
Configure the data format on module side:
qmicli -p -d /dev/cdc-wdm0 --device-open-qmi --wda-set-data-format=link-layer-protocol=raw-ip,ul-protocol=qmap,dl-protocol=qmap,dl-max-datagrams=32,dl-datagram-max-size=31744,ep-type=hsusb,ep-iface-number=2
Here in-between you should perform necessary operations to the module prior to having the cellular network data connection established.
Things like SIM state and PIN code entry, module device registration in the cellular network, APN profile management etc.
Once module is ready and registered in cellular network we can proceed to configure and set up the data connection.
Bind the virtual mux network interface to the CID that gets opened, the CID id is given back in the reply:
qmicli -p -d /dev/cdc-wdm0 --device-open-qmi --wds-bind-mux-data-port=mux-id=1,ep-iface-number=2 --client-no-release-cid
It is important to use the --client-no-release-cid attribute here to keep the tunnel open all the time while data connection is established.
If the CID is closed, the data connection on the qmux virtual network interface will close also.
Start the cellular network data connection in the normal way, include the --client-no-release-cid attribute and use the already open CID ID you got back from previous command reply. E.g. like this:
qmicli -p -d /dev/cdc-wdm0 --device-open-qmi --wds-start-network=apn=data.tre.se,ip-type=4 --client-no-release-cid --client-cid=##
Store the packet data handle id from the command reply, to use when stopping network.
Request the cellular connections IP details from the module:
qmicli -p -d /dev/cdc-wdm0 --device-open-qmi --wds-get-current-settings --client-no-release-cid --client-cid=##
Bring up the main QMI RMNET network interface:
ip link set dev wwan0 up
Apply the IP address to the qmux interface that you acquired through qmicli --wds-get-current-settings above, e.g.:
ip addr add 2.64.116.145 dev qmimux0
Apply the given MTU size to the qmux interface that you acquired through qmicli --wds-get-current-settings above, e.g.:
ip link set mtu 1500 dev qmimux0
Bring up the QMUX virtual network interface:
ip link set dev qmimux0 up
You should now have a working cellular network data connection.
Test it e.g. by sending a ping over the qmux interface:
ping -I qmimux0 8.8.8.8 -c 4
PING 8.8.8.8 (8.8.8.8) from 2.68.152.91 qmimux0: 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=57 time=31.5 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=57 time=29.8 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=57 time=36.7 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=57 time=36.0 ms
--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 8ms
rtt min/avg/max/mdev = 29.821/33.494/36.690/2.911 ms
Apply appropriate network interface routing suitable for your use-case, e.g:
ip route add default dev qmimux0
the qmicli --wds-get-current-settings give back DNS server addresses also if they are defined by the cellular network.
Depending on how your Linux distribution handle DNS servers you can add them or instead use a public DNS server.
To stop the cellular data network connection:
Bring down the virtual mux interface:
ip link set qmimux0 down
Flush the ip addresses:
ip -4 -6 address flush dev qmimux0
Use the --wds-stop-network attribute to stop the data connection in module, include the packet data handle and the client ID from when establishing the connection.
qmicli -p -d /dev/cdc-wdm0 --device-open-qmi --wds-stop-network=########## --client-cid=##
Note: by not adding the --client-no-release-cid attribute this client ID will be closed after command execution.
It is up to the host application to manage and poll the connection state of the cellular module.
E.g. it the connection is lost temporarily due to no network coverage in the current location, the host application should tear down and re-establish the data connection when cellular module is registered in network again.
If the data connection fails for some reason several times, ensure that the connect retry attempts do not take place continuously without some extended delays in-between. Depending on the cellular network operator, they can enforce lock-out on your subscription/device for certain time periods in order to protect the network.