专栏首页程序猿的那点事从wlan_mac.bin文件中读取MAC地址

从wlan_mac.bin文件中读取MAC地址

/vendor/qcom/opensource/wlan/qcacld-3.0/Android.mk

ifeq ($(PRODUCT_VENDOR_MOVE_ENABLED),true)
$(shell ln -sf /mnt/vendor/persist/wlan_mac.bin $(TARGET_OUT_VENDOR)/firmware/wlan/qca_cld/wlan_mac.bin)else
$(shell ln -sf /mnt/vendor/persist/wlan_mac.bin $(TARGET_OUT_ETC)/firmware/wlan/qca_cld/wlan_mac.bin)endif

/vendor/qcom/opensource/wlan/qcacld-3.0/core/hdd/inc/wlan_hdd_misc.h

#define WLAN_MAC_FILE              "wlan/qca_cld/" PREFIX "wlan_mac.bin"

/vendor/qcom/opensource/wlan/qcacld-3.0/core/hdd/src/wlan_hdd_main.c

/**
 * hdd_initialize_mac_address() - API to get wlan mac addresses
 * @hdd_ctx: HDD Context
 *
 * Get MAC addresses from platform driver or wlan_mac.bin. If platform driver
 * is provisioned with mac addresses, driver uses it, else it will use
 * wlan_mac.bin to update HW MAC addresses.
 *
 * Return: None
 */static int hdd_initialize_mac_address(hdd_context_t *hdd_ctx){
	QDF_STATUS status;
	int ret;
	bool update_mac_addr_to_fw = true;

	ret = hdd_platform_wlan_mac(hdd_ctx);
	if (hdd_ctx->config->mac_provision || !ret) {
		hdd_info("using MAC address from platform driver");
		return ret;
	}

	hdd_info("MAC is not programmed in platform driver ret: %d, use wlan_mac.bin",
		 ret);

	status = hdd_update_mac_config(hdd_ctx);

	if (QDF_IS_STATUS_SUCCESS(status)) {
		hdd_info("using MAC address from wlan_mac.bin");
		return 0;
	}

	hdd_info("using default MAC address");

	/* Use fw provided MAC */
	if (!qdf_is_macaddr_zero(&hdd_ctx->hw_macaddr)) {
		hdd_update_macaddr(hdd_ctx, hdd_ctx->hw_macaddr, false);
		update_mac_addr_to_fw = false;
	} else if (hdd_generate_macaddr_auto(hdd_ctx) != 0) {
		struct qdf_mac_addr mac_addr;

		hdd_err("MAC failure from device serial no.");
		cds_rand_get_bytes(0, (uint8_t *)(&mac_addr), sizeof(mac_addr));
		/*
		 * Reset multicast bit (bit-0) and set
		 * locally-administered bit
		 */
		mac_addr.bytes[0] = 0x2;
		hdd_update_macaddr(hdd_ctx, mac_addr, true);
	}

	if (update_mac_addr_to_fw) {
		ret = hdd_update_mac_addr_to_fw(hdd_ctx);
		if (ret)
			hdd_err("MAC address out-of-sync, ret:%d", ret);
	}
	return 0;
}

/vendor/qcom/opensource/wlan/qcacld-3.0/core/hdd/src/wlan_hdd_cfg.c

/**
 * hdd_update_mac_config() - update MAC address from cfg file
 * @pHddCtx: the pointer to hdd context
 *
 * It overwrites the MAC address if config file exist.
 *
 * Return: QDF_STATUS_SUCCESS if the MAC address is found from cfg file
 *      and overwritten, otherwise QDF_STATUS_E_INVAL
 */QDF_STATUS hdd_update_mac_config(hdd_context_t *pHddCtx){
	int status, i = 0;
	const struct firmware *fw = NULL;
	char *line, *buffer = NULL;
	char *temp = NULL;
	char *name, *value;
	int max_mac_addr = QDF_MAX_CONCURRENCY_PERSONA;
	tCfgIniEntry macTable[QDF_MAX_CONCURRENCY_PERSONA];
	tSirMacAddr customMacAddr;
	
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;

	memset(macT("request_firmware failed; status:%d", status);
		qdf_status = QDF_STATUS_E_FAILURE;
		return qdf_status;
	}

	if (!fw || !fw->data || !fw->size) {
		hdd_alert("invalid firmware");
		qdf_status = QDF_STATUS_E_INVAL;
		goto config_exit;
	}

	hdd_debug("wlan_mac.bin size %zu", fw->size);

	temp = qdf_mem_malloc(fw->size + 1);

	if (temp == NULL) {
		hdd_err("fail to alloc memory");
		qdf_status = QDF_STATUS_E_NOMEM;
		goto config_exit;
	}
	buffer = temp;
	qdf_mem_copy(buffer, fw->data, fw->size);
	buffer[fw->size] = 0x0;

	/* data format:
	 * Intf0MacAddress=00AA00BB00CC
	 * Intf1MacAddress=00AA00BB00CD
	 * END
	 */
	while (buffer != NULL) {
		line = get_next_line(buffer);
		buffer = i_trim(buffer);

		if (strlen((char *)buffer) == 0 || *buffer == '#') {
			buffer = line;
			continue;
		}
		if (strncmp(buffer, "END", 3) == 0)
			break;

		name = buffer;
		buffer = strnchr(buffer, strlen(buffer), '=');
		if (buffer) {
			*buffer++ = '\0';
			i_trim(name);
			if (strlen(name) != 0) {
				buffer = i_trim(buffer);
				if (strlen(buffer) == 12) {
					value = buffer;
					macTable[i].name = name;
					macTable[i++].value = value;
					if (i >= QDF_MAX_CONCURRENCY_PERSONA)
						break;
				}
			}
		}
		buffer = line;
	}

	if (i != 0 && i <= QDF_MAX_CONCURRENCY_PERSONA) {
		hdd_debug("%d Mac addresses provided", i);
	} else {
		hdd_err("invalid number of Mac address provided, nMac = %d", i);
		qdf_status = QDF_STATUS_E_INVAL;
		goto config_exit;
	}

	qdf_status = update_mac_from_string(pHddCtx, &macTable[0], i);
	if (QDF_IS_STATUS_ERROR(qdf_status)) {
		hdd_err("Invalid MAC addresses provided");
		goto config_exit;
	}
	pHddCtx->num_provisioned_addr = i;
	hdd_debug("Populating remaining %d Mac addreses",
		   max_mac_addr - i);
	hdd_populate_random_mac_addr(pHddCtx, max_mac_addr - i);

	if (pHddCtx->num_provisioned_addr)
		qdf_mem_copy(&customMacAddr,
			     &pHddCtx->provisioned_mac_addr[0].bytes[0],
			     sizeof(tSirMacAddr));
	else
		qdf_mem_copy(&customMacAddr,
			     &pHddCtx->derived_mac_addr[0].bytes[0],
			     sizeof(tSirMacAddr));

	sme_set_custom_mac_addr(customMacAddr);
config_exit:
	qdf_mem_free(temp);
	release_firmware(fw);
	return qdf_status;
}

/vendor/qcom/opensource/wlan/qcacld-3.0/core/hdd/src/wlan_hdd_cfg.c

/**
 * update_mac_from_string() - convert string to 6 bytes mac address
 * @pHddCtx: the pointer to hdd context
 * @macTable: the macTable to carry the conversion
 * @num: number of the interface
 *
 * 00AA00BB00CC -> 0x00 0xAA 0x00 0xBB 0x00 0xCC
 *
 * Return: None
 */static QDF_STATUS update_mac_from_string(hdd_context_t *pHddCtx,					 tCfgIniEntry *macTable, int num)
{
	int i = 0, j = 0, res = 0;
	char *candidate = NULL;
	struct qdf_mac_addr macaddr[QDF_MAX_CONCURRENCY_PERSONA];
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	memset(macaddr, 0, sizeof(macaddr));

	for (i = 0; i < num; i++) {
		candidate = macTable[i].value;
		for (j = 0; j < QDF_MAC_ADDR_SIZE; j++) {
			res =
				hex2bin(&macaddr[i].bytes[j], &candidate[(j << 1)],
					1);
			if (res < 0)
				break;
		}
		if (res == 0 && !qdf_is_macaddr_zero(&macaddr[i])) {
			qdf_mem_copy((uint8_t *)&pHddCtx->
				     provisioned_mac_addr[i].bytes[0],
				     (uint8_t *) &macaddr[i].bytes[0],
				     QDF_MAC_ADDR_SIZE);
		} else {
			status = QDF_STATUS_E_FAILURE;
			break;
		}
	}
	return status;
}

/vendor/qcom/opensource/wlan/qca-wifi-host-cmn/qdf/inc/qdf_util.h

*
 * This function returns a bool that tells if a MacAddress is made up of
 * all zeros.
 *
 * Return: true if the MacAddress is all Zeros
 * false if the MacAddress is not all Zeros.
 */static inline bool qdf_is_macaddr_zero(struct qdf_mac_addr *mac_addr){
	struct qdf_mac_addr zero_mac_addr = QDF_MAC_ADDR_ZERO_INITIALIZER;

	return qdf_is_macaddr_equal(mac_addr, &zero_mac_addr);
   }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Wi-Fi PNO扫描流程(Android P)

    简介:当手机灭屏情况下,有保存网络时,若已连接,不扫描,否则,PNO扫描,即只扫描已保存的网络。最小间隔min=20s,最大间隔max=20s*3=60s

    用户7557625
  • wpa_supplicant 框架

    Android WiFi系统引入了wpa_supplicant,它的整个WiFi系统以wpa_supplicant为核心来定义上层用户接口和下层驱动接口。整个W...

    用户7557625
  • WCNSS_qcom_cfg.ini WIFI配置文件解析

    用户7557625
  • python 读写压缩文件

    import gzip with gzip.open('somefile.gz', 'rt') as f: text = f.read()

    用户5760343
  • LeetCode 107. Binary Tree Level Order Traversal II

    Given a binary tree, return the bottom-up level order traversal of its nodes' va...

    ShenduCC
  • H3CNE实验系列 | V** (GRE)

    路由器 R1 和路由器 R3 间通过其他网络相连,运行 IP 协议的似有玩了过的两个子

    网络技术联盟站
  • 马云:WTO模式将会被颠覆,20年后不用讨论隐私...

    大数据文摘
  • 2018-3-8 11周3次课 php

    make install会把redis.so放在 /usr/local/php7/lib/php/extensions/no-debug-zts-2016030...

    py3study
  • Android | Tangram动态页面之路(六)数据分离

    经过前五篇系列文章,对Tangram和vlayout也有了初步认识,这篇文章开始将结合业务场景使用,探索框架能力能对业务带来的支持,因为调研本身是一个需要不断踩...

    Holiday
  • 032.核心组件-kube-proxy

    Kubernetes为了支持集群的水平扩展、高可用性,抽象出了Service的概念。Service是对一组Pod的抽象,它会根据访问策略(如负载均衡策略)来访问...

    木二

扫码关注云+社区

领取腾讯云代金券