Fixing Android MAC Address Conflicts

If you already know this is the fix for your issue, you can skip this section. Otherwise, I’ll get on to describing the problem.

I have been frustrated for the last few days with my phone. I have run CyanogenMod for a while now on my LG G3 (since the early alpha builds), while my wife ran a variant of the stock carrier rom. However, due to poor battery life issues, she wanted to have CyanogenMod since my phone gets about twice as much battery life than hers does. Obligingly, I flashed CyanogenMod on her phone. That night I noticed a problem was occuring with both of our phones, which I unfortunately didn’t realize the source of until today.

Symptoms

The symptoms of the issue were wifi was repeatedly dropping. Rebooting wifi and/or toggling airplane mode would fix the issue for a few minutes, but it got progressively worse. A few hours before writing this post, it was so bad I could only maintain a wifi connection for about 10 seconds before it would fail and not even try to reconnect for about five minutes.

The Problem

After puzzling through the issue, it occured to me what it must have been: conflicting mac addresses.

I checked my wife’s and my phones and sure enough, their mac addresses were identical, specifically 00:90:4c:c5:12:38. I did some Googling and found many other people to have the same issue in varying versions and roms of Android. After some hunting, I found a temporary fix, but the fix was for a different phone, which stored its config files in a different location (oddly). I did a bit of digging through the filesystem (find /system -type f -exec grep -H macaddr "\{}" \;) and finally found the file that needed to be modified for my phone/version of Android. For reusability purposes, I also turned this into a fairly friendly script so other folks can do it too.

Note though that this issue is very obscure and the likelyhood of seeing is it slim. Only people running at least two phones with this bug at the same time and on the same wifi network will experience this issue. This is why my phone operated fine for months until I put CyanogenMod on my wife’s phone and she connected to our wifi. Further (to the credit of the CM and the various other Android devs out there), this problem would be tremendously difficult for a dev to track down because it is only problematic with two or more phones, something I doubt most devs are testing at the same time with.

The Fix Script

This script needs to be run as root to work correctly (if you don’t run it as root, it’ll complain at you and exit). Once you’ve run this script as root, simply reboot your phone and your new mac address will take effect.

#!/system/xbin/bash

# Ensure we are running as root, because this won't work otherwise.
uid=$(id | sed -n 's/uid=\([0-9]\+\).*/\1/p')
if [[ ${uid} != 0 ]]; then
  echo "Not running as root. Cannot proceed. Exiting..."
  exit 1
fi

echo "Remounting /system with write access so we can make the modification."
mount -o remount,rw /system

# The path to the wlan cal file
cal_path=/system/etc/wifi/bcmdhd.cal

# Don't need this, but might be handy to have documented
#old_mac=00:90:4c:c5:12:38

# Generate the new mac address
new_mac=$(printf '00:90:4c:%02x:%02x:%02x\n' $[RANDOM%256] $[RANDOM%256] $[RANDOM%256])

# Sed expression to replace the mac address with something less problematic
sed -i "s/macaddr=.*/macaddr=${new_mac}/" ${cal_path}

echo "Your new mac address is ${new_mac}."

I personally placed this on my internal storage at /storage/sdcard0/mac_fix.sh. To execute it, as root just run…​

bash /storage/sdcard0/mac_fix.sh

Note the preceeding call to the bash command. Ordinarily you would be able to set the execute bit on the script and directly call it. However, Android defaults to setting the noexec mount option for the sdcard filesystems (both sdcard0 and sdcard1), thus chmod +x doesn’t work. This could be worked around in the script, but it would make it longer and I don’t see the need for it. :)