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]]
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]]
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
http://forum.cyanogenmod.org/topic/105128-wifi-bug-cm12/[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]]
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. :)


// vim: set syntax=asciidoc:
