Nexus 5 – CyanogenMod CDMA Fix

Looking for the download? It’s at the bottom of the page!


CDMA support in CyanogenMod can be pretty hit or miss for a lot of people.

Lots of “fixes” have been floating around for a while. Usually they have some modified list of APNs and modified system files. I think I’ve even seen one “fix” that included binaries from an older build of CM!

When looking at these “fixes”, I couldn’t find anything in them that was actually a fix. I’d duplicate some of their changes (without flashing the zip), and it wouldn’t help at all. Many of the fixes didn’t even look like they would do anything. My rate of success and failure remain unchanged.

The CyanogenMod dev(s) partially fixed some of the issues around mid-2016.
Many of the programs used for CDMA connections were in the wrong directory. They were placed in /system/app/ instead of /system/priv-app/.

This commit from March shows some path confusion: http://review.cyanogenmod.org/#/c/135501/

I made a flashable zip that would move the applications to the correct /system/priv-app/ location, but it isn’t needed any more with the current builds of CyanogenMod.

With stock/Google Android, my Nexus 5 would immediately connect to Sprint, without any issue.
With CyanogenMod 12.0 or 13.0, my Nexus 5 would suddenly have issues. Sometimes it would connect, sometimes it would easily lose the LTE connection. Forcing the device to 1xRTT CDMA was the only way I could get a consistent, reliable connection. How fast is 1xRTT CDMA? Oh, I’d get about 0.1 Mbps down, 0.06 Mbps up, and around 600 ms latency.

I know my phone was capable of a decent, usable LTE connection. But changing random settings and flashing random zips wasn’t helping, and I couldn’t really tell what any of those changes were doing, or if they were actually changing anything at all!

Luckily, there are some tools available to help.

The first are accessed via dialing codes. Just open the phone app, and dial one of the following numbers.

You can view your list of APNs, as well as your 1xRTT/EvDo/eHRPD/LTE connection information with this code:

*#*#33284#*#*

You can watch the stats and info as your device connects to different towers, see the MNC/MCC information of the connected tower, and more.

This code will also show you connection information, as well as allow you to force the device into various connection modes and then test if you have a working data connection:

*#*#4636#*#*

It’s useful if you want to make sure that 1xRTT, eHRPD, and LTE are all working correctly.

For this last code, it performs a telephony reset, and will reboot your device and try to trigger another activation. Do not dial this one until you are ready to reboot and want to reset your connection.

*#*#72786#*#*

It is useful for when you make a telephony system change and want the system to activate using the new configuration.

The next set of tools are from the command line. You can run them via local terminal, an SSH connection to the device (if running an SSH server), or via an adb shell.

This command lets you view system settings:

getprop

This command lets you set system settings:

setprop

Using the *#*#4636#*#* code, I noticed that “CellInfo” kept showing 000 for MCC and MNC, despite it being set by the SIM card.

There are several MCC/MNC sets that Sprint uses, with two being the most common in my area. MCC of 310 & MNC of 120, and MCC of 311 & MNC of 870.

Something to note: The “311870” pair is in the CyanogenMod apns-conf.xml file once, and in the Stock apns-conf.xml file 11 times. Why would the CM team have removed carrier information?

The value seen on the “CellInfo” page is from gsm.operator.numeric.

Since I know it isn’t supposed to be 000000, I ran the command “setprop gsm.operator.numeric 310120” to change its value. When I did that, it seemed to actually get a connection to a tower. However, when I changed connection technology (LTE to 1xRTT, for example), gsm.operator.numeric reset back to 000000.

Even when I added it to /system/build.prop, it still changed back to 000000. This is because that variable is set by the system. If you see any “fix” where they tell you to change that in build.prop, it won’t work. It doesn’t do anything. It will be immediately changed by the system.

So how do you get the value to stick?

You set ro.cdma.home.operator.numeric.

I added this to my build.prop:

ro.cdma.home.operator.numeric=310120

I rebooted, and made note of gsm.operator.numeric. It would change to 000000 when changing connection methods (such as forcing LTE down to eHRPD or 1xRTT), but then change right back to 310120 and make a connection.

There was one issue: while the newer technologies connected, I could no longer force a 1xRTT/CDMA connection. I don’t like any “fix” that breaks something else, so I kept looking into it.

I found that if I also set the value of ro.cdma.default_numeric, 1xRTT/CDMA would be able to connect. So, I added this to my build.prop:

ro.cdma.default_numeric=310120

With the two values set, I could go back and forth between LTE, eHRPD, and 1xRTT without issue. I rebooted several times to make sure it worked. I even dialed *#*#72786#*#* to reset telephony and re-activate. It still worked.

I wanted to make sure that this could work from a fresh install, so I went ahead and did a full system wipe, and did a clean install of CyanogenMod.

I made the two changes again to my build.prop and rebooted. And then… Nothing. It wasn’t working now. I tried to think why it wouldn’t be working now – what was different from before?

Then I remembered. I was using the apns-conf.xml file from the Stock Nexus 5 image before. I had copied it over the CM on when trying some other so-called “fixes” for CDMA / Sprint. Doing a new flash of CM put its apns-conf.xml file right back, which would have removed a lot of the Sprint entries. Again, I have no idea why the CM devs though it would be a good idea to remove carrier information in the first place.

So I copied the Stock Nexus 5 apns-conf.xml file back over the CM version, then dialed *#*#72786#*#* again to re-initialize telephony.

After a reboot, I got the “Activating…” screen, and then an LTE connection was established! I’ve since rebooted, re-flashed, and tested my Nexus 5 in multiple locations. The connection has been working fine, just like it does with the Stock Nexus 5 image that Google provides.

So, there you go. Those three changes (ro.cdma.home.operator.numeric, ro.cdma.default_numeric, and stock apns-conf.xml) on CyanogenMod 13.0 got CDMA and Sprint working for me.

I then put together a flashable zip file to automate the process for anyone that wants to try it.

There are no binaries in it, just a script to update build.prop, and a copy of the Stock apns-conf.xml file (pulled from the “6.0.1 (MOB30D)” Nexus 5 image provided by Google). It’s all plain-text, so you can easily view what it does.

You can grab it here: N5_Sprint_Fix.zip (~52KB)

The installation script has been updated to take advantage of addon.d to persist after an upgrade.

Installation Instructions:

1) Copy the “N5_Sprint_Fix” zip file to your device.
2) Boot into Recovery / TWRP.
3) Flash the “N5_Sprint_Fix” zip file.
4) Reboot your device.
5) Dial *#*#72786#*#* to re-trigger cellular activation.