ZTE MF831 for use with OpenWRT: serial modem instead of cdc_ether

How to turn a ZTE MF831 into a dumb serial modem

Update and warning:

This article was written for the austrian version of the ZTE MF 831 back in October 2015. It is probably outdated by now. Most of the information contained herein and in the comments stems from my own and other user’s findings, 4pda.ru, draisberghof.info, archlinux and various other sources. I still own two ZTE MF831, which I regularly use. I used to have them in modem mode and are now using both in CDC mode. I can affirm, that switching modes -back and forth- works for these two models (Sw. WEB_HOFAUTMF831V1.0.0B02, Fw. BD_HOFATMF831V1.0.0B02, Hw. MF831-1.0.0).

Nevertheless, if you are not experienced in Android ADB, Linux, networking principles, terminal commands (AT/Hayes), you better restrain from reading on. You should really should be an expert in all that, if you decide to continue at your own risk.

Why that warning?

In the recent years I received some comments from people, some posts contained constructive feedback and experiences for which I am grateful. Comments of all that kind correspond to the way, a community works and are highly appreciated in order to improve a ‘howto’ like this.

Today (June, 9th 2019) I received quite the opposite: A posting, that contained mere hate speech, and menace against my family and me, blaming me for advising to send back a device, that up to my experience, was a defective in the first place.

I’d therefore like to repeat, that the mode switching commands are implemented by the manufacturer, ZTE himself. (The device’s OS is Android; mode switching by sending a HTTP request, simply invokes an AT command server and disables networking capabilities on USB; likewise, corresponding AT commands revert that). These command lists can be found at several places on the net, and they even work on various other ZTE models, but with variations, that you need to do research on. The commands used here partially even had been previously published by ZTE Australia and were republished in 2012 and relinked e.g. at http://www.3g-modem-wiki.com/page/ZTE+AT-commands, but after several website redesigns at ZTE, the manual is no longer available at the referenced link. Check they wayback archive at your convenience: https://web.archive.org/web/20091006172214/http://www.zte.com.au/downloads/USB_Modem_Config_Procedure.pdf. At no point in the main article did I describe any alteration of the firmware, unless for naming the possibility of firmware recovery, which relies on firmware, that the manufacturer published  officially through it’s distributor back in the year 2014.

Until today, I received one report of one completely unresponsive MF831, which is most probably caused by a defective flash chip – and another similar experience, where a modeswitch never even has been tried:

A brand new MF831 my employer had used at home, got defective after two weeks in service in combination with an original TP-Link MR3240. The replacement LTE stick -also a MF831- is in service until today.

I also had two other defective MF831, but the problem I encountered with both, was a mere mechanical defect: A ‘triple sim card’ (nano, micro, mini) got loose somehow and it’s adapting frame and got entangled with pin 5 when I tried to exchange the sim card. That resulted -and that’s at no surprise either- in an ‘unavailabe network’ message.

What I have published then, back in 2014, was to the best of my  knowledge and belief and represents the steps I did, that worked for me  repeatedly.

I, personally, think the modeswitch, that is undocumented in the users manual, but well known among router programmers, is safe to use on the devices I’ve tested. A risk still remains – you have been warned.

Your alternatives are:

a. OpenWRT nowadays works like a charm with USB cdc devices. So, if you don’t have a contract with a public IP and you don’t need port forwarding – simply use the stick in it’s  default mode and stop reading.

b. Get a professional LTE routing equipment, that costs far more than the MF831’s lousy 25 Euros , if it’s still in stock. It’s successor, the MF833V will be sold for as low as 29,99 Euros starting next week…

c. Get another device, that is configured/flashed to use serial mode by default.

So, dear readers – you, once more, have been warned not to read on.

If you decided otherwise, here is the original article:

Background story:
Recently the austrian discounter Hofer started to sell equipment capable of LTE and bundled it with SIM cards of it’s MNVO HoT (Hofer Telekom).

Among those items is a relatively cheap LTE class 4 modem – the ZTE MF831.
Optically it is unbranded, but it seems to contain a firmware optimized for HoT.

If you put in the SIM card, wait until it’s activated and charge the account with a minimum of 10 Euros, you can book the option “HoT data LTE”, which will allow you to use up to 3GB of data within a period of 30 days at speeds up to 50 Mbit/s (download) and 10 Mbit/s (upload).

First tests show, that these maximum values are close to reality. My meassurements showed values from around 34/5 Mbit/s up to 50/9 Mbit/s (indoor ) in Vienna using ‘RTR Netztest’. That’s good enough to prepare some tests with OpenWRT, OpenVPN and the ZTE MF831, but there’s a caveat:

About USB-Ethernet, NAT, NAT trunks, colliding address space, …
When you use the MF 831 on a laptop, it makes sense to use the USB-Ethernet mode. The stick presents itself to it as a dhcp+nat router, that is listening on it’s IPv4 RFC1918 address

Unfortunately that Ethernet NAT mode has some drawbacks:
You cannot reconfigure the network address or netmask, nor the DHCP range.
You already have a NAT trunk setup with most mobile internet providers in Austria (this contradicts principles of network neutrality).
As far as I know, you can apply for a non RFC1918 IPv4 address only when using VOLmobil (an MNVO@TMA; costs: +8 Euros/month) or within the network of Hutchison Drei with product except the ‘Initiative 100%’. There it’s called ‘Open Internet’ and can be configured without additional costs from within the ‘Kundenzone’.
Furthermore, since most gateways from austrian mobile network providers are unpingable, there is some risk, that IPv6 tunnels and other tunnels may fail due to problems with PMTU discovery. It seems, that the MF831 NAT router mode does not respect this issue. It’s LAN MTU is 1500, but pings over 1456 bytes payload will fail on their way.
There are probably even more issues.
But there is light at the horizon:

Solution: Dumb serial modem (emulation) mode

If you could convince the MF831 to behave like a simple modem, your OpenWRT router or linux computer can then take care of dialing in. This way you eliminate one NAT layer and use your public ip address, if available, port forwards and such things, that were previously unusable.

I found this ArchLinux Howto for the MF831’s predecessor, the MF823:

This howto describes how to use the MF823 as a serial modem device, how to switch modes and more.
If you keep some things in mind, it will work for the MF831, too:

Please understand, that switching the modem mode will render the webinterface unusable until you revert the changes. Unplugging and replugging will NOT undo the changes made, so be careful.
I’ll describe this reversal procedure later.

I assume, that you are running Linux.
Connect the modem to one of your computers’ USB  port.
The modem is preconfigured to automatically connect to the network. In serial mode this causes the access to it to be blocked. So

  1. First step (important!): deactive auto connect:
    1. Go to
    2. click on ‘Home’
    3. click ‘Disconnect’ or ‘Trennen’
    4. click ‘Settings’ or ‘Einstellungen’
    5. click ‘Network settings’ or ‘Netzwerkeinstellungen’
    6. click ‘Dial-up settings’ or ‘Einwahleinstellungen’
    7. click the radio button labeled ‘Manual’ or ‘Manuell’
    8. leave all other settings as they are.
  2.  Put the MF831 into download mode:
    Caution: You will NOT be able to access the modem through it’s web interface after that!!!

    1. Call from your web browser.
      The modems led will turn red and go back to green or blue after approximately 20 seconds.
    2. Check, if the modem was detected –
      1. if everything worked as expected
        1. dmesg will say something like
          [15337.497593] usb 1-1.2: new high-speed USB device number 21 using ehci-pci
          [15337.628188] usb 1-1.2: New USB device found, idVendor=19d2, idProduct=0016
          [15337.628196] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
          [15337.628200] usb 1-1.2: Product: ZTE Wireless Ethernet Adapter
          [15337.628203] usb 1-1.2: Manufacturer: ZTE,Incorporated
          [15337.640979] option 1-1.2:1.0: GSM modem (1-port) converter detected
          [15337.641170] usb 1-1.2: GSM modem (1-port) converter now attached to ttyUSB0
          [15337.641400] option 1-1.2:1.1: GSM modem (1-port) converter detected
          [15337.641543] usb 1-1.2: GSM modem (1-port) converter now attached to ttyUSB1
          [15337.641831] option 1-1.2:1.2: GSM modem (1-port) converter detected
          [15337.642222] usb 1-1.2: GSM modem (1-port) converter now attached to ttyUSB2
        2. ls -la /dev/ttyUSB* will list those three devices.
        3. lsusb will list ID 19d2:0016 ZTE WCDMA Technologies MSM
        4. NetworkManager will mislead you by listing the device as ‘ZTE Wireless Ethernet Adapter’, but you can configure it with profiles like any other serial modem.
      2. if it did not work:
        1. It may be still in Ethernet mode:
          1. lsusb’s output is something else than 19d2:0016, e.g. 19d2:1405 or 19d2:1403.
          2. the modem is then still pingable at
          3. dmesg will list cdc-ether in some way.
            In these cases: try again from step 2 above.
        2.  The drivers are not detected:
          1. lsusb shows 19d2:0016
          2. There are no devices: /dev/ttyUSB0, /dev/ttyUSB1, /dev/ttyUSB2
          3. Solution: su – / sudo su and
            echo “19d2 0016” > /sys/bus/usb-serial/drivers/option1/new_id
            (Remark: Make sure, those ‘”‘ are straight double quotes on your linux console)

            1. dmesg should now output something like in 2.1.1 – everthing is alright.
            2. you may want to consider to put that echo line in /etc/rc.local (just before the line “exit 0”) or to upgrade your kernel.
    3.  Reverting back to Ethernet mode
      If you do not need the serial mode any longer or in the case something went wrong (e.g. you are getting ‘ressource unavailable’ messages on connecting to the serial modem – reason: you forgot step 1.6.) you can revert the above:

      1. Disconnect any session that’s accessing /dev/ttyUSB1 or /dev/ttyUSB2
        1. Open gtkserial or another serial terminal (or simply echo the following AT commands to /dev/ttyUSB2)
          emark 1: on debian you with gtkserial you need to be in group ‘dialout’,
          Remark 2: Make sure Modem Manager does not block /dev/ttyUSB2: service ModemManager stop

          Remark 3: If you don’t see your input within the terminal, turn on local echo.


        2. Disconnect the modem from usb, wait, reconnect it
        3. lsusb will then first show the 19d2:1225 (mass storage device) and will later modeswitch to device 19d2:1405.

The device is now back in ethernet mode.

I’ll continue this blog entry as soon as I have a spare USB-capable wifi router running OpenWRT. I guess I can replace my TP-Link MA260 1:1 with the new LTE stick. We’ll see…

On OpenWRT Chaos Calmer 15.05 (TL-WR1043NDv2) I needed to modify /etc/rc.local like mentioned above. Otherwise the “generic” driver would have been used, which only provides the diagnostic interface /dev/ttyUSB0. It won’t work that way – you need the driver named “option1”. After modifying and rebooting it works out of the box with /dev/ttyUSB2, service type any.

Update 2: I just had the case, where an MF831 entered the “real” download mode after a number of resets (that a script initiated). USBIDs are 19d2:0076 (vendor:device). I’ll report on this.

Have fun!

Disclaimer: Any of the trademarks, service marks, collective marks, design rights or similar rights that are mentioned, used or cited within this post are the property of their respective owners.


netcup dot de

Netcup.de: Vouchers each -30% auf Webhosting 2000/Coupons: Webhosting 2000 – 30% off .

Update (Drivers): If you are encountering problems with your MF831 on Windows 10 after mode switching, you probably need the correct drivers. Since the the device is using RNDIS, serial drivers are not included. It turns out, that drivers for the MF192 will do fine.  I found some Windows 8 modem drivers on the ZTE Australia Pty Ltd’s website: http://www.ztemobiles.com.au/downloads/software/Win8_Modem_Drivers.zip
You need to unzip them and run the setup routine. If it still does not work, you may need to call windows’ device manager, go into the “ZTE Ethernet …” properties. Click “update drivers”, and let Windows look for the drivers automatically. Do these steps for each of the three devices. Afterwards you can speak to your modem through Putty on either COM4, COM5 or similar.

[A little update on available modes and how to switch:]

The following URLs can be called, when the modem is pingable at it’s default IP address If the switched mode doesn’t leave the modem in a pingable state, the method to revert to CDC mode is described below.

Again, the russian forum 4pda (спасибо, друзья!) has some more information on available modes for the similar MF823 and MF830 modems. See here: https://4pda.ru/forum/index.php?showtopic=555876&st=1400

Let me repeat that translated and corrected info for your convenience:

Base URL is

N can be one of the following values:

0 – PID = 0016: ZTE download mode. Corresponds to AT+ZCDRUN=E.
1 – PID = 1225: Mass Storage Device (MSD), corresponds to AT+ZCDRUN=9 in combination with AT+ZCDRUN=F.
2 – PID = 2004: Unclear: similar to MSD like mode 1225 without card reader function. Probably for compatibility with other operating systems.
N=3 – PID = 1403: RNDIS + MSD. Corresponds to AT+ZCDRUN=8 in combination with AT+ZCDRUN=F.
N=4 – PID = 1403: just the same as N=3 ->19d2:1403
N=5 – PID = 1405: CDC/ECM mode instead of RNDIS.
N=6 – PID = 1404: RNDIS + diagnostic port + two COM ports + MSD + ADB interface (MF8230ZTED010000).
N=7 – PID = 1244: CDC + diagnostic port + two COM ports + MSD + ADB (MF8230ZTED010000).
N=8 – PID = 1402: diagnostic port + two COM ports + WWAN adapter + MSD + ADB (1234567890ABCDEF).
N=9 – PID = 9994: MBIM + diagnostic port + two COM ports + ADB (1234567890ABCDEF).



154 thoughts on “ZTE MF831 for use with OpenWRT: serial modem instead of cdc_ether

  1. Hi Erich,

    thank you for your reply and your patience with my issue.

    I added the static ARP entry as you suggested but the device is still not pingable…Also when flooding the interface with broadcasts the modem doesn’t respond in any way (0.0B received). It’s really strange…

    The Update Software is not working for me either because on all three PCs I tested the modem, the Software does not recognise the modem and stays idle…it also doesn’t appear anywhere in device manager…

    Thanks in advance,


    1. OK, I’m running out of ideas… let’s get back to what happened in the first place.
      When did the stick cease to operate normally? In what setup did you use it, when it was still working?

      For the ARP method: it does not always work – the device has to work normally and mustn’t filter for spoofed addresses. Some ancient alcatel dsl modems had a method called “ping-to-life”, that would trigger a reset, when special mac address was associatied with a certain ip and that ip got pinged on boot. But that was very specific procedure of those devices.

      That the Update SW does not work is strange under the aspect, that linux would correctly discover the device for what it is. Perhaps we need an additional driver on Windows? Usually, if you follow the updater’s instructions from the manual and on screen step by step, it should always work.

      Another idea would be to get the device into adb mode somehow – but in order to trigger that mode switch, we’d need IP connectivity in the first place, what makes it a cat hunting it’s own tail…

      Any ideas, community?


      1. Hi Erich,

        thanks again for your answer.

        When i bought the stick it was working in Ethernet Mode of course, but I switched to Serial Mode according to this tutorial some months ago. It was working just as expected until i switched it back to Ethernet Mode last week (also according to this tutorial). Since then, it’s not working any more…

        Ok, sorry, but the ARP method didn’t work…

        I will try again with the Update SW on Windows. Do you know if there’s an Update SW for Linux available?

        Thanks in advance,


      2. Ok. Was there any black box device involved, that would send AT-commands or modeswitching commands?
        As reported, I had one case, where a MF831 with a TP-Link router with OEM firmware had unrecoverable problems with the GUI. That was before the FWUpdate was released to the public and Hofer exchanged the defective device. Afair the TP-Link executed a modeswitch by itself.
        The modeswitch must have completed – otherwise the device id wouldn’t be 1405. I know of no way to turn dhcp off or changing IPs through AT commands.

        If you are sure, you didn’t mangle anything else than just switching the mode, and flashing still won’t work, it’s likely a hardware defect (bad flash cells or something like that) you should return the device. That case should still be covered by the warranty. If they refuse write back.

        It could also be, that you plugged out the stick a second too soon after the modeswitch. But then again recovery flashing should work.

        No, there is no Linux FW loader I’d know of. Still it’s android you are uploading. If you are more into experiments, then please turn to XDA developers forum https://www.xda-developers.com/. They may have the answers you are looking for.


  2. Hi Erich,

    thanks for your answer.

    No additional device was used, just the Raspberry Pi, the modem stick and a Software called sakis3g, which sent the AT-commands to establish the connection to the Internet. When I switched the modem back to Ethernet mode, I just “echoed” the four commands above to “/dev/ttyUSB2″…

    Anyway, I will try to give it back…



  3. Hi Erich,

    I used sagis3g in combination with “umtskeeper”, which is responsible for keeping the Internet Connection with sakis3g alive (the name may be a bit confusing, it also works with 4g). The only thing I had to do was installing the package “ppp”, downloading umtskeeper and sakis3g and start umtskeeper with the following command on startup:

    sudo /opt/umtskeeper –sakisoperators “USBINTERFACE=’2′ OTHER=’USBMODEM’ USBMODEM=’19d2:0016′ APN=’****’ SIM_PIN=’****'” –sakisswitches “–sudo –console” –devicename ‘ZTE’ –log –silent –monthstart 8 –nat ‘no’ &

    This created a Network Interface called “ppp0” which had the WAN IP-Address and connected my device to the Internet.



    1. in modem mode, pppd uses chat to control the modem via AT commands. chat usually initializes a modem with at&f ate1 and at&v1 or similar. In rare cases even registers are set. On the stick the AT command set, as far as I’ve noticed, is provided by a daemon on top of android. It’s not completely unlikely, that an AT command could switch profiles that way. It’s strange nevertheless. It shouldn’t happen anyway.

      What are you going to do now? Will you return the stick or will you keep experimenting? Let me know, please.


    2. Yet another idea…
      Look for similar devices (mf823?) and try to switch modes from usb_modeswitch using the switch messages.
      Perhaps we can get back to serial mode, read out current settings and reset to factory defaults that way, then switch back as described in the article. Another idea could be to get into android debugging mode, but that could eventually be dangerous from a perspective of warranties.


      1. Hi Erich,

        thanks for your reply.

        I already tried to get back to serial mode with usb_modeswitch but I wasn’t able to find the correct “MessageContent” which is necessary to switch the modem…all the messages I tried so far (also the one for the mf823) wouldn’t work for me, because it seems that the MessageContent also has something to do with the mode you want to achieve (to be honest, I’m not concern with what it does anyway), but the error message says that the modem is already in the mode I want to have it to. Of course I tried to switch it from 1405 to 0016, but usb_modeswitch would always say that it’s already in the mode that I want…I will try again and post the output as soon as possible.

        Thanks in advance,


  4. Hi Erich,

    now I’ve tried to switch the modem with usb_modeswitch. What I tried so far:

    1. Edit /etc/usb_modeswitch.conf and add the following lines:




    2. Plug the modem in and wait until it comes into mode 1225 (you need to be fast before it switches to 1405 automatically)
    3. Run “usb_modeswitch -c /etc/usb_modeswitch.conf”
    4. “lsusb” now shows mode 1403, but I don’t notice any difference, device still doesn’t give me an ip or works when assigning a static ip.

    This was the only other configuration that was “working”. Of course I also tried to switch to mode 0016, but if I write 0x0016 as TargetProduct, it switches to 1403 anyway…that’s why I think that the MessageContent has something to do with the mode you want to achieve…

    I’ve also tried multiple MessageContents, but the only one that made a difference (1405 to 1403) was the one that I found on http://www.draisberghof.de/usb_modeswitch/bb/viewtopic.php?f=3&t=2124 used for the MF190. Any other MessageContents found didn’t make a difference at all or threw an error message that the code isn’t working like so (device already connected and in 1405 mode):

    cmd: sudo usb_modeswitch -v 19d2 -p 1405 -V 19d2 -P 0016 -W -M “55534243123456780000000080000c85010101180101010101000000000000” -m 0x01 -r 0x81

    Output (last lines): Error: can’t use storage command in MessageContent with interface 0;
    interface class is 2, expected 8. Abort

    The MessageContent used here is the same as above, but the error message was the same with others used.

    I know it’s getting more and more complicated but I hope you understand the lines above.

    Thanks in advance,


    1. Thanks for your reply and all the infos.
      1. Please keep in mind, that usb-modeswitch may in some cases already provide a different configuration and get’s triggered automatically by udev, hotplug and alike. If so, your command line and scripts will interfere.
      2. AFAIR/AFAIK you can always send two switching commands at once. see -2 from the command’s built-in help.
      3. Switching should alway happen from 19d2:1225 to any of the other modes e.g. 0016,1404,1405, … I don’t think that it makes sense to switch from 1405 to any of the others directly – why it would the command would throw an error in this state.
      4. see https://wiki.archlinux.org/index.php/ZTE_MF_823_(Megafon_M100-3)_4G_Modem on mode 1403.
      5. Will the stick stay in mode 1403 after a replugging procedure, or will it fall back to 1405?
      If it does not keep a mode setting state, this could indicate a faulty flash chip – usually the device ‘remembers’ modem mode and cdc mode. I don’t know if that applies to RDNIS+MSD, as well. If the flash chip really was faulty, you should return your MF831. Switching alone won’t harm the device, usually. At least the flash recovery should work.

      I’ll be offline for a few days from now. Good luck in the meanwhile.


  5. Hello Erich,

    Thanks for the howto, it was very useful.

    I would just like to give some feedback which may be useful for others. I’m using a RouterStation Pro with OpenWRT 15.05.1, more precisely:

    root@voyager:~# cat /etc/openwrt_release
    DISTRIB_DESCRIPTION=’OpenWrt Chaos Calmer 15.05.1′

    After switching the MF831 to modem mode it was detected automatically, so this version of OpenWRT definitely has a suitable usb-modeswitch JSON file. I had to modify the device to /dev/ttyUSB1 though, but that was the only manual change.

    For the record: I’m a customer of Drei and using one of their Hui Flat packages. You can indeed tick a checkmark on their web portal which gives the router a publicly visible IPv4 address.




    1. Hi I am using ASUS MERLIN on AC68. I managed to do a factory reset and serial mode works, but the speed has dropped significantly (15mbs vs 70mbs). I would like to revert back to original mode. Any instructions on how to do this on a MAC computer?


      1. Hello Daniel!
        I am no Mac user, so I can only guess, that “Serial” from Mac App Store will be the tool of your choice.

        Also ArchLinux website describes the mode switch on OS X for the similar MF823: https://wiki.archlinux.org/index.php/ZTE_MF_823_(Megafon_M100-3)_4G_Modem

        You need to determine what your serial port of the modem is. Then connect to it and follow the steps to revert through AT-Commands as described above. It’s all the same for any system – a) Make sure modem is detected, b) Connect to it with a terminal program, c) use the AT-Commands.

        If you have a terminal program on Merlin, you can use that, too. Sometimes bash redirection of an echo command to the serial line may also work, but this cannot be advised.
        Socat will always do, if available – but it is not included in most WRTs.

        What’s present on all Router-Firmwares and generally on linux is pppd and chat. Chat’s only purpose is to communicate with a modem – so we can make use of that.

        Create a chat script in /etc/chatscripts. e.g. ‘mf831-revert.chat’ with the following content:

        ABORT 'BUSY'
        TIMEOUT 30
        ECHO ON
        '' AT&F
        OK ATE1
        OK AT+ZSNT=0,0,0
        OK AT+ZBANDI=0
        OK AT+ZCDRUN=9
        OK AT+ZCDRUN=F

        Remark: ZSNT and ZBANDI aren’t necessary, they just reset to automatic band and operation mode selection, just in case you changed these values, while ZCDRUN is already well known to my readers.

        You should then make sure, that chat and ppp are not already running (of course you won´t do that in a remote session…):

        pgrep chat >/dev/null && killall -9 chat
        pgrep pppd >/dev/null && killall -9 pppd

        Now invoke pppd on the modem’s serial interface. That will call chat with the given chatscript, where $modemdevice should be set to your modem’s serial terminal port e.g. /dev/ttyUSB2 – either set the variable modemdevice=/dev/ttyUSB2 or replace ${modemdevice} with /dev/ttyUSB2:

        /usr/sbin/pppd debug ${modemdevice} 115200 modem crtscts asyncmap 0 lock noauth connect "/usr/sbin/chat -v -t 30 -f /etc/scripts/mf831-revert.chat"

        I am using a similar script on one of my routers to automatically change modes as needed. But there can be issues with the appropriate timing. Sometimes the modem will switch to real download mode 0016. You’d have to plug it off and replug then.


      2. I’m using an AC68 too with the same ZTE. Can you explain the step you’ve done, because i can’t configure the router.


  6. Actually my modem works better now, it used to hang on some webpages. My only issue now is that the speed is slow, the LED is green so it should be on 4G.

    I have connected the modem to my Mac but it does not show up under ttyUSB*. Any suggestions?


    1. Red light = not registered in provider network or rebooting
      Green light = EDGE, GPRS, UMTS, WCDMA…
      Blue light = LTE

      Do you need to switch the radio protocols? – Here we go:

      Serial mode – AT Commands – from http://www.3g-modem-wiki.com/page/ZTE+AT-commands:
      AT+ZSNT=0,0,0 (Auto) - Default
      AT+ZSNT=1,0,0 GPRS Only
      AT+ZSNT=2,0,0 3G Only
      AT+ZSNT=0,0,1 GPRS Preferred
      AT+ZSNT=0,0,2 3G Preferred

      While disconnected, you can set the preference from the menu to 4G only.

      Console in CDC-Mode – via curl:
      /usr/bin/curl -s -m 3 -e "" -d "goformId=SET_BEARER_PREFERENCE" -d "BearerPreference=Only_LTE"

      If anyone needs a shell script do that on the router, here it is an example – errors possible:


      case ${DEBUG} in
      logger "${0##*/}: $1"
      return 0
      determineMode() {
      mode=$(lsusb -d 19d2: | sed -r "s/(.*)(19d2\:){1}([[:digit:]]{4})(.*)/\3/g")
      echo $mode | egrep -q '^[0-9]+$'
      if [ $? -eq 1 ] ; then
      let mode=0
      echo $mode
      return 0
      REFERRER="http://$(echo $1)/index.html"
      SCRIPT="http://$(echo $1)/goform/goform_set_cmd_process"
      case $2 in
      wLog "set autoconnect"
      ${CURL} -s -m 3 -e ${REFERRER} -d "goformId=SET_CONNECTION_MODE" -d "ConnectionMode=auto_dial" ${SCRIPT}
      wLog "reboot MF831"
      ${CURL} -s -m 3 -e ${REFERRER} -d "goformId=REBOOT_DEVICE" ${SCRIPT}
      until [ $(determineMode) -eq 1225 ]; do
      sleep 2
      wLog "Initiate Internet connection"
      ${CURL} -s -m 3 -e ${REFERRER} -d "goformId=CONNECT_NETWORK" ${SCRIPT}
      wLog "Disconnecting from Internet"
      ${CURL} -s -m 3 -e ${REFERRER} -d "goformId=DISCONNECT_NETWORK" ${SCRIPT}
      wLog "setting bearer to auto"
      ${CURL} -s -m 3 -e ${REFERRER} -d "goformId=SET_BEARER_PREFERENCE" -d "BearerPreference=NETWORK_auto" ${SCRIPT}
      ${CURL} -s -m 3 -e ${REFERRER} -d "goformId=SET_BEARER_PREFERENCE" -d "BearerPreference=Only_GSM" ${SCRIPT}
      wLog "setting bearer to auto"
      ${CURL} -s -m 3 -e ${REFERRER} -d "goformId=SET_BEARER_PREFERENCE" -d "BearerPreference=Only_WCDMA" ${SCRIPT}
      wLog "setting bearer to auto"
      ${CURL} -s -m 3 -e ${REFERRER} -d "goformId=SET_BEARER_PREFERENCE" -d "BearerPreference=Only_LTE" ${SCRIPT}
      return 0

      # THE MF831's CDC IPv4 ADDRESS:
      # DEBUG: LOG OUTPUT: 0=enabled
      if [ $# -gt 0 ]; then
      case $1 in
      curlAction ${MODEMIP} reboot
      curlAction ${MODEMIP} connect
      curlAction ${MODEMIP} disconnect
      curlAction ${MODEMIP} bearer
      curlAction ${MODEMIP} bearer2g
      curlAction ${MODEMIP} bearer3g
      curlAction ${MODEMIP} bearer4g
      echo $(determineMode)
      echo "Command syntax: $0 --[reboot|connect|disconnect|bearer|bearer2g|bearer3g|bearer4g]
      exit 0

      Does that help?


  7. I double checked my manual, green light means 4G network, blue light 2G/3G,

    I want to mode switch back. How do I do that from the router? AC68


    1. In the quick start manual of mf831, there is no hint regarding this…
      My own mf831 behaves the way I described. Double check in CDC mode on it’s panel.


  8. I don’t want double NAT, I just need this 4 dongle to work with maxima speed with my router. Does it help to change to openwrt, ROOTer?


    1. All the same codebase. But I’d give LEDE 17.01.2 a try – now, that LEDE and OpenWRT rejoined forces, it’s the newest available codebase of OpenWRT.

      The speed issues could have different reasons:
      First, the MF831 is an android device that is actually doing tethering on the CDC Ethernet. Let’s call that its native mode of operation.
      If we are using the android device in serial mode, it seems, that mode is an emulated one, providing the three interfaces described. At this point performance issues are already likely to happen.
      Second, since mobile networks are radio networks, external distortion, reflection etc may always appear.
      You can measure only the incoming signal levels, but you will never know, if the sent (outgoing) signals of your modem arrive just the same way at the base station. In AT/serial mode the commands for querying the signal strength is AT+ZRSSI and for determining the mode of operation (as also indicated by the led’s colour) with AT+ZPAS?.
      Third, regarding NAT: You cannot really escape carrier grade NAT, unless your tariff allows you to pay for an optional external IP. So in CDC mode you will have at least a three level NAT (CGN,Android,Router), in serial mode at least a two level NAT (CGN, Router), where CGN could itself hold some more layers in theory.

      Your speed tradeoff will consist of various problems:
      1. ftp://ftp.wayne.edu/ldp/en/Tuning-Linux/networkdialup.html Serial speed itself.
      2. MTU sizes (Lowered in mobile Network to at least 1492 (because of PPP).
      3. Masquerading on Linux, MSS Clamping, …

      ad 1: I just tested a few things on my laptop, with the MF831 directly connected to it. I am using Yesss (A1 Telekom Austria in this setup).
      +ZRSSI: -108,-13,-74,2.4
      +ZPAS: “LTE”,”CS_PS”

      As you can see, I don’t have optimal radio conditions. An RSSI of -108 dB isn’t amazingly good, so I cannot expect high data rates anyhow.

      Speedtest.net and speedof.me vary. The peak was about 30Mbit/s DL, 12 Mbit/s UL. The median was around 15 DL 10 UL. When setting the serial speed to 38400 manually, throughputs attain a non representative peak of 20 DL, 9 UL and a median of 17 DL 9 UL. Did you notice, that UL values are rather steady?

      ad 2) a lowered MTU will always mean, that the same amount of data is more likely to get split up in smaller packets, of which we need more… In case of VPNs this is a relevant factor, if fragments should be 1500, while the layer below only transmits packet sizes of 1492. The payload of 1460 in case of IPv4 would decrease to 1452 likewise. Instead of one packet, you suddenly transmit 2. Factor 50%.

      ad 3) You could lower the MTU of the devices behind your NAT gateway or optimize the MTU (see 2). Clamping will help, but affects only TCP, not UDP or ICMP. I’dont know, if mobile network operators support baby jumbo frames already, if so, that could be a solution to the problem. Please report back on that, if you find out more.
      NAT – Connection tracking is useful, but on elderly pieces of hardware, if may have impacts on performance – especially when using zram as a swap on low memory devices.

      For the moment, I don’t see problems caused by the emulator on android, but that’s just a single opinion.


      1. Ok I have reverted back now by issuing the AT commands. The speedtest is faster but it hangs on some pages very annoying. Should I change the MTU, right now it’s set to 1500?


      2. I just tried some thing on my TL-WR1043NDv1 running lede 17.01.2:

        I modified /etc/chatscript/3g.chat:
        ABORT BUSY
        TIMEOUT 10
        “” “AT&F”
        OK “ATE1”
        OK “AT+ZSNT=6,0,0”
        OK “AT+CREG?”
        OK “AT+ZRSSI?”
        OK ‘AT+CGDCONT=1,”IP”,”$USE_APN”‘
        SAY “Calling UMTS/GPRS”
        TIMEOUT 30
        CONNECT ‘ ‘

        AT+ZSNT=6,0,0 should lock the stick to the LTE bearer.
        AT+ZSNT=0,0,6 should prefer the LTE bearer.
        We’ll log signal strength on connection, too (ZRSSI)


        Could you test, if that helps with the speed issues?


      3. Well after switching back to Ethernet mode, I noticed that my old configuration was untouched, even my port forward. So modeswitching does not do a factory reset. The led light was green so I was already on 4G network when using serial mode. I was already locked on the 2600MHz band.

        That’s why I believe your suggestion will not work. I am pretty confident this is an MTU issue.


      4. Did you configure the port forward on the MF831, like the russian forum suggests? Then you would have modified the CDC profile on the modem? That change is stored to the modem’s flash and would remain persistent – as it happend with the modifications regarding the menu. What you call factory settings simply means to switch these profiles in normal operation. In order to restore really everything, use the manufacturer’s flashing tool.

        As mentioned before, on my own specimen the green light represents the bearer WCDMA/UMTS. Blue indicates LTE access in my case. I’ve double checked this. So I am wondering, if you use a different model or revision.

        My suggestion was for serial mode, not CDC mode – and of course the MTU is lowered eight Bytes in a PPP session running on the router, unless this is handled somehow… you can always try to find out by pinging your next neighbour in the routing table with bigger packets. If I am right, ping -M do -c1 -s 1452 nexthop would work, while ping -M do -c1 -s 1453 nexthop would fail: ping: local error: Message too long, mtu=1492
        Remember, that the ping command of OpenWRT/LEDE does not understand the switch “-M” which set Fragment/Don’t fragment bits – so do that from your linux pc.


    1. issues: usbmode seems to auto-reset the stick to CDC mode on each reboot in 17.01.2. I didn’t recognize other major issues in that test setup.
      You can disable usbmode: /etc/init.d/usbmode stop; /etc/init.d/usbmode disable.
      I wonder, if the modeswitch from 1225 to 0016 would be affected that way. If so, we ‘d have to replace the file /etc/usbmode.json with an appropriate one.
      Sometimes only one port is detected instead of three ports. Bind driver option to 19d2:0016 by setting this in /etc/rc.local before “exit 0“:

      grep -i "19d2\ 0016" /sys/bus/usb-serial/drivers/option1/new_id >/dev/null || echo "19d2 0016 ff" | tee /sys/bus/usb-serial/drivers/option1/new_id

      I have to admit, that rarely use serial mode any longer in my own setups now, since my tunnel server and various scripts can overcome most of the problems. CDC is now also some kind of advantage for me: I can exchange the stick including the prepaid SIM and don’t have to care about setups. I even save a little RAM on the LEDE box this way. Since I don’t have a public IP with cheap prepaid SIM I’d have to deal with CGN issues anyways. The only drawbacks are, that miredo is missing for LEDE and 6to4 and tunnel brokers don’t work that way… but I can tunnel IPv6 through the encrypted main tunnel, too. (Here in Austria there is still no widely used IPv6 mobile setup). Nevertheless miredo came in handy as a second tunnel for maintenance. The other thing is a deadlock of the mf831 sometimes. It switches to real download mode (0076), and I can only stop that by unplugging/replugging
      – but I guess, that’s a programming bug in one of my older reconnect scripts.

      Pragmatism has won.


  9. Hej!
    I read this post and its’ comments with great interest, not because I need to change the mode of my modem, but because I’d like to try a factory reset. I have two similar MF831 modems. They both have the same settings as far as I can see from the web interface. They both work nicely with my Mac, but one of them has suddenly stopped working on my Raspberry Pi 3 (Raspian Stretch).
    The green light blinks, it shows up as 19d2:1408, and if I do ifconfig it shows up as usb0 just as the health one does. But the inet address is different: The healthy one sows 192.168.0.XXX and the bad one 169.254.113.XXX.
    And the bad one is “all but” unusable: I cannot, for example, ping outside adresses, neither by name (i.e. google.com) nor by adress (i.e.

    What does work is outbound udp: I run Ardupilot on the pi which outputs its’ data to a fixed outside ip on port 14550.

    I tried, among other things, to do: Call
    – which did its’ thing, and then I reverted via AT commands which also worked well, in the hope that this would reset something back to factory settings, but no luck there.

    Any Ideas of what might be going on?


    1. Hello Fredrik!
      On the model I have, a steadily lit green LED would indicate a 2G or 3G connection, while blue means LTE. The LED would only blink in red on a reboot, blink in green or blue for a short time, while the connection attemps -i.e. registration with the network- are in progress.
      Mode 19d2:1408 is currently unknown to me – you may find an answer to that question at http://www.draisberghof.de/usb_modeswitch/bb/viewtopic.php?f=3&t=1645. It could also be, that you have another hardware revision of the modem. Another idea would be the usb_modeswitch package – it sends an initialization/modeswitch command,to the modem, shortly after it has been plugged in. The base mode would be 1225. W/o usb-modeswitch it would automatically turn itself to 1405 after a while, afaik. Check if usb-modeswitch is present on your device. If so try to deactivate the modeswitch by uncommenting/removing the section for 19d2:1225 or it’s decimal equivalent (make a backup of that configuration files before altering these).

      169.254.113.XXX is an APIPA address. That is an autoconfiguration or „Zero config“ mechanism that will choose a quasi-random address out of in the abscence of a dhcp server. That address does not stem from the MF831! It’s your PC’s self-assigned address. You may try to give your PC a static IP for usb0 – such as The modem is listening at per defaults and will provide a DHCP server (unless altered as described by the russian forum posts mentioned earlier). If all works well, you can ping the modem at Routing outside still wouldn’t work unless you define as the default router and dns server statically. But you would rather prefer to reset to factory defaults. The „goform“-link you reposted, does not do that. It’s a modeswitch command only. I wonder how that link could work, when you can’t reach the modem on it’s IP address in the first place?! You didn’t try that on the faulty modem, did you?!

      The mf831 is a native android device. Look into lsusb when plugging the faulty modem in again. It won’t start as 19d2:1408, but 19d2:1225 rather.

      If you manage to get it into android mode without CDC or modem emulation, you can connect through adb and try to debug from there, but I would not recommend that. Better try a full factory reset:

      A full factory reset would require to reflash the original zte modem firmware for your specific device. Go ask ZTE or your distributor for that file (only works on the Windows platform). Real download mode has the usb id 19d2:0076, afair.

      I hope, that info helps you to recover. Since this is not the first reply regarding a faulty modem, please share any information on how it may have happened to become faulty. Perhaps the commentors here will find a common solution alltogether.


  10. when i connect my zte mf831 modem to my windows 10 pc, it makes a sound of detection, but apart from that nothing, no UI.. pls help


    1. ?

      Since I don’t know anything from you, besides, that your mf831 makes a sound of detection on windows 10 … and my mentalist app for android does not work either, could you please try to be a little more precise on what lead to that situation?


  11. Hi Erich,
    your link to the win8 driver isn’t working anymore. Do you know an other location where to download maybe a win10 version, if there’s one? Thanks!


    1. It turns out, that archive.org – the wayback machine – is quite a treasure chest:

      Here is the archived firmware file containing the ZTE MF831 HoT Firmware:

      But, it is also available here:

      The original driver file is still available from http://www.ztemobiles.com.au/downloads/software/Win8_Modem_Drivers.zip


      1. Hi Erich
        I know the topic is quite old but I need your help. First of all many thanks for your original article that I successfully used for setting a MF831 working with OpenWrt in ether mode (2017). Thanks, good job.
        Then i wrote the appropriate script to manage connection, profiles and sms Tx/Rx using the goform instruction set (using tcpdump to get the appropriate command/status sequences).

        But recently while making some minor changes (add some more status request) my USB stick suddenly disconnect from the router and I was unable to recover.

        Then I did some test on both OpenWrt and a Debian machine: lsusb is OK (19d2:1405), Dmseg is still OK (driver installed), but pinging doesn’t work => the stick is unreachable.
        I thought it was broken (HW failure) and bought a new one (not that much expensive).
        Unfortunately after some hours working well the second stick failed the same.

        Looking into more details on both sticks:
        No ether connection on linux (OpenWrt or Debian) while lsusb/Dmesg are OK
        Unstable connection on Windows (XP or 7) can go up to open web interface but fail to go up to connection (when fail the device is sometime still pingable!)

        I decided to test the modem mode (0016). From a Windows station I was able to switch the units.
        On both OpenWrt and Debian the device is well detected and installed (two ports on OpenWrt, three ports on Debian). Unfortunately not possible to communicate with the device. In fact it is not possible to setup a connection using AT commands (no response / no execution) however it is possible to revert the device to ether mode (partially listening but not talking??)

        At the end I decided to test flashing one of the unit with a new software using the DL_MF831_HOF_AT_EUV1.00.00.zip package. Flashing was successful.
        Unfortunately the device behavior is still the same.

        Have you any suggestion regarding something wrong in what I did/set??


      2. I have no idea, why the stick wouldn’t respond to a ping while it is in mode 1405. Since there haven’t been recent software updates for the stick, I suppose the behaviour in OpenWRT and/or Debian may have changed. Another possibility could be the existence of a network or device within the same IP/Broadcast range or a firewall rule.

        Regarding the problem with the modem serial ports: see point in the article. The kernel wrongfully detects another type of modem: You need to manually override this at runtime, before the module is loaded.-> echo “19d2 0016” > /sys/bus/usb-serial/drivers/option1/new_id – you can do this with hotplug.d or rc.local on OpenWRT. For Debian/Ubuntu see /etc/modprobe.d


      3. Hi Erik
        THKs for the comments anyway.
        Regarding the modem mode I already did it as you said with no results.
        Regarding the ether mode, as it was partially working on windows I had the idea to set the PC network interface in static IP mode using the usual stick IP as gateway/DNS. Frankly I don’t know why, but it worked on the both sticks.
        I reproduced the config on both the a Debian machine and an OpenWrt router and it worked as well.
        I have no technical undertsanding of such a behaviour. But it works. I’m OK now
        Season’s Greetings!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s