summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRicardo Cerqueira <cyanogenmod@cerqueira.org>2014-05-28 17:12:24 +0100
committerDan Pasanen <dan.pasanen@gmail.com>2018-01-04 15:11:50 -0600
commit3862075500a0fdc411ce8f611f583e41f4c03c74 (patch)
tree025f33e1cb6823122cf72049ef003b303fd235de
parent85020096379028721d925b4c5489d3652f950a22 (diff)
downloadandroid_hardware_qcom_wlan-3862075500a0fdc411ce8f611f583e41f4c03c74.tar.gz
android_hardware_qcom_wlan-3862075500a0fdc411ce8f611f583e41f4c03c74.tar.bz2
android_hardware_qcom_wlan-3862075500a0fdc411ce8f611f583e41f4c03c74.zip
wcnss_qmi: Generate a fixed random mac address if the NV doesn't provide one
If the NV is corrupted or blanked out, QMI won't return a MAC address and prima will fallback to a fixed one. If the board defines a TARGET_WCNSS_MAC_PREFIX value (2 to 4 hex values), use that prefix to generate a random (and persistent) hwaddr instead. For "TARGET_WCNSS_MAC_PREFIX := 0a0b0c0d", the last 2 bytes will be pseudo-randomized, and the final address will be in the "0a:0b:0c:0d:XX:YY" format. Change-Id: Ie38cb5d3724223b2ec1ae45e6a9a4f2285229731
-rw-r--r--wcnss-service/Android.mk5
-rw-r--r--wcnss-service/wcnss_qmi_client.c57
2 files changed, 62 insertions, 0 deletions
diff --git a/wcnss-service/Android.mk b/wcnss-service/Android.mk
index a0561e3..c78c5cd 100644
--- a/wcnss-service/Android.mk
+++ b/wcnss-service/Android.mk
@@ -55,6 +55,11 @@ LOCAL_SHARED_LIBRARIES := libc libcutils libutils liblog
LOCAL_SHARED_LIBRARIES += libqmiservices libqmi_cci
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/libmdmdetect/inc
LOCAL_SHARED_LIBRARIES += libmdmdetect
+
+ifneq ($(TARGET_WCNSS_MAC_PREFIX),)
+ LOCAL_CFLAGS += -DWCNSS_INVALID_MAC_PREFIX=\"$(TARGET_WCNSS_MAC_PREFIX)\"
+endif
+
LOCAL_CFLAGS += -DWCNSS_QMI
LOCAL_SRC_FILES += wcnss_qmi_client.c
diff --git a/wcnss-service/wcnss_qmi_client.c b/wcnss-service/wcnss_qmi_client.c
index 3e1fb0e..5a9e0db 100644
--- a/wcnss-service/wcnss_qmi_client.c
+++ b/wcnss-service/wcnss_qmi_client.c
@@ -29,6 +29,8 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifdef WCNSS_QMI
#define LOG_TAG "wcnss_qmi"
#include <cutils/log.h>
+#include <stdlib.h>
+#include <sys/stat.h>
#include "wcnss_qmi_client.h"
#include "qmi_client.h"
#include "device_management_service_v01.h"
@@ -107,8 +109,63 @@ int wcnss_qmi_get_wlan_address(unsigned char *pBdAddr)
ALOGE("%s: Succesfully Read WLAN MAC Address", __func__);
return SUCCESS;
} else {
+#ifdef WCNSS_INVALID_MAC_PREFIX
+#ifndef WCNSS_GENMAC_FILE
+#define WCNSS_GENMAC_FILE "/persist/.genmac"
+#endif
+ int i = 0;
+ struct stat statbuf;
+ FILE *genmac;
+ int macbytes[6] = { 0, };
+ // Limit the prefix to 4 bytes, we want at least 2 to be random
+ int prefixlen = strnlen(WCNSS_INVALID_MAC_PREFIX,8)/2;
+
+ // Misconfigured device source...?
+ if (prefixlen < 2) {
+ return FAILED;
+ }
+
+ // Use a previously stored value if it exists
+ if (!stat(WCNSS_GENMAC_FILE, &statbuf)) {
+ genmac = fopen(WCNSS_GENMAC_FILE,"r");
+ if (fscanf(genmac, "%c%c%c%c%c%c", &pBdAddr[0],
+ &pBdAddr[1], &pBdAddr[2], &pBdAddr[3],
+ &pBdAddr[4], &pBdAddr[5]) == 6) {
+ fclose(genmac);
+ ALOGE("%s: Succesfully Read local WLAN MAC Address", __func__);
+ return SUCCESS;
+ }
+ fclose(genmac);
+ }
+
+ sscanf(WCNSS_INVALID_MAC_PREFIX, "%2x%2x%2x%2x",
+ &macbytes[0], &macbytes[1],
+ &macbytes[2], &macbytes[3]);
+
+ // We don't need strong randomness, and if the NV is corrupted
+ // any hardware values are suspect, so just seed it with the
+ // current time
+ srand(time(NULL));
+
+ for (i = prefixlen; i<6; i++) {
+ macbytes[i] = rand() % 255;
+ }
+ // Invert them
+ for (i = 0; i < 6; i++) {
+ pBdAddr[i] = macbytes[5-i];
+ }
+
+ // Store for reuse
+ genmac = fopen(WCNSS_GENMAC_FILE,"w");
+ fwrite(pBdAddr, 1, 6, genmac);
+ fclose(genmac);
+
+ ALOGE("%s: Failed to Read WLAN MAC Address, successfully randomized one", __func__);
+ return SUCCESS;
+#else
ALOGE("%s: Failed to Read WLAN MAC Address", __func__);
return FAILED;
+#endif
}
}