#!/usr/bin/python2.7

'''This script generates the wifi and bluetooth MAC addresses assigned to a
board, given the MAC address of it's primary ethernet interface. It's primary
purpose is to store the MAC addresses in files on the root filesystem after
system first start because we cannot burn these addresses into the peripherals,
other than the ethernet PHY.

This script only works in the case where the MAC addresses have been allocated
in a monotonically adjacent style for all devices, and that wifi/bluetooth
follows the ethernet MAC in series.
'''


import struct
import sys


MAC_VENDOR_PREFIX_STR = '70:20:84'

BD_ADDR_PATH = '/etc/bluetooth/.bt_nv.bin'
WIFI_ADDR_PATH = '/lib/firmware/wlan/wlan_mac.bin'

BD_NVITEM = 0x02
BD_RDWR_PROT = 0x00
BD_NVITEM_SIZE = 0x06
BD_ADDR_HEADER_STRUCT = r'BBB'
BD_ADDR_MAC_STRUCT = r'BBBBBB'

WIFI_CONFIG_TEMPLATE = '''\
Intf0MacAddress={0}
END
'''

ETHERNET_DEVICE = 'eth0'


def GenerateNextMac(mac_address_str):
    '''Given a MAC address string, generate the next MAC address in sequence.

    Note: this strips off the vendor prefix and increments as though the suffix
    was an integer. If the device suffix rolls over, there is no error thrown or
    any other checking done.

    Parameters:
      mac_address_str: string. Colon-separated six-octet hexidecimal MAC address.

    Returns:
      string. The next MAC address in the sequence.
    '''
    device_suffix = GetMacDeviceSuffixString(mac_address_str)
    suffix_number = MacDeviceSuffixToNumber(device_suffix)
    suffix_string = MacDeviceSuffixNumberToString(suffix_number + 1)
    next_mac = MAC_VENDOR_PREFIX_STR + ':' + suffix_string
    return next_mac


def MacDeviceSuffixNumberToString(device_suffix_number):
    '''Given a device suffix number, generate a colon-separated hexidecimal
    representation.

    Parameters:
      device_suffix_number: integer. The number to convert into a MAC suffix.

    Returns:
      string. The colon-separated hexidecimal version of the number passed in.
    '''
    suffix_string = '%06x' % device_suffix_number
    suffix_array = []

    for idx in range(0, len(suffix_string), 2):
        suffix_array.append(suffix_string[idx] + suffix_string[idx + 1])

    return ':'.join(suffix_array)


def MacDeviceSuffixToNumber(mac_suffix):
    '''Converts a given a three-octet colon separated hexidecimal MAC device suffix
    into an integer.'''
    mac_array = mac_suffix.split(':')
    flatmac = ''.join(mac_array)
    return int(flatmac, 16)


def GetMacDeviceSuffixString(mac_address):
    '''Strip the vendor prefix from a given a full six-octet colon separated
    hexidecimal MAC.'''
    mac_array = mac_address.split(':')
    return ':'.join(mac_array[3:])


def FindEthernetMacString(device):
    '''Returns the MAC address string for a given network device from sysfs.

    If an error occurs attempting to read from sysfs, or runs into an EOF
    prematurely, returns None.
    '''
    sysfs_path = '/sys/class/net/%s/address' % (device)

    try:
        with open(sysfs_path, 'r') as fp:
            address = fp.readline()
        if len(address) == 0:
            return None
        address = address[:-1]
        return address.lower()
    except Exception as e:
        print('Error reading %s: %s' % (sysfs_path, e))
        return None


def WriteWifiMacAddress(next_mac):
    '''Writes the given MAC address string to the wifi configuration files.'''
    try:
        with open(WIFI_ADDR_PATH, 'w') as fp:
            fp.write(WIFI_CONFIG_TEMPLATE.format(next_mac.translate(None, ':')))
        return True
    except Exception as e:
        print('Error writing wifi configuration to %s: %s' % (WIFI_ADDR_PATH, e))
        return False


def WriteBluetoothMacAddress(next_mac):
    '''Writes the given MAC address string to a binary file readable by Bluez.'''
    mac_bytes = [int(x, 16) for x in next_mac.split(':')]

    try:
        with open(BD_ADDR_PATH, 'w') as fp:
            fp.write(struct.pack(BD_ADDR_HEADER_STRUCT, BD_NVITEM, BD_RDWR_PROT,
                                 BD_NVITEM_SIZE))
            fp.write(struct.pack(BD_ADDR_MAC_STRUCT, *mac_bytes))
        return True
    except Exception as e:
        print('Error writing bluetooth configuration to %s: %s' % (BD_ADDR_PATH, e))


def IsDVTMacAddress(base_mac_address):
    '''Checks to see if the given MAC address is within the allocated DVT range.'''
    prefix_string = GetMacDevicePrefixString(base_mac_address)

    if prefix_string == 'f4:f5:e8':
        return True

    return False


def Main():
    base_mac_address = FindEthernetMacString(ETHERNET_DEVICE)

    if base_mac_address == None:
        sys.stderr.write('Unable to find MAC address for device %s\n' % (ETHERNET_DEVICE))
        sys.exit(1)

    if IsDVTMacAddress(base_mac_address):
        sys.stderr.write('Detected DVT MAC address for device %s\n' % (ETHERNET_DEVICE))
        sys.stderr.write('Cowardly refusing to set the MAC addresses\n')
        sys.exit(0)

    next_mac = GenerateNextMac(base_mac_address)
    print('Wifi/Bt MAC address will be %s' % next_mac)

    WriteWifiMacAddress(next_mac)
    WriteBluetoothMacAddress(next_mac)


if __name__ == '__main__':
    Main()
