qcacld-3.0: Pass correct data length in oem data response msg

Add data length information in oem data response messages. Currently
maximum response size is passed to upper layers.

Change-Id: Id74d44e03755af9a5402e5409ee5f6b5e7abbb7c
CRs-Fixed: 942260
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index 9911133..c44d049 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -916,7 +916,8 @@
 	uint16_t messageType;
 	uint16_t length;
 	bool target_rsp;
-	uint8_t oemDataRsp[OEM_DATA_RSP_SIZE];
+	uint32_t rsp_len;
+	uint8_t *oem_data_rsp;
 } tSirOemDataRsp, *tpSirOemDataRsp;
 
 #endif /* FEATURE_OEM_DATA_SUPPORT */
diff --git a/core/mac/src/pe/include/lim_global.h b/core/mac/src/pe/include/lim_global.h
index b61b4d8..4a98ad3 100644
--- a/core/mac/src/pe/include/lim_global.h
+++ b/core/mac/src/pe/include/lim_global.h
@@ -305,7 +305,8 @@
 
 typedef struct sLimMlmOemDataRsp {
 	bool target_rsp;
-	uint8_t oemDataRsp[OEM_DATA_RSP_SIZE];
+	uint32_t rsp_len;
+	uint8_t *oem_data_rsp;
 } tLimMlmOemDataRsp, *tpLimMlmOemDataRsp;
 #endif
 
diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
index 580d40b..dd1e592 100644
--- a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
+++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
@@ -809,16 +809,30 @@
 	/* get the pointer to the mlm message */
 	pMlmOemDataRsp = (tLimMlmOemDataRsp *) (pMsgBuf);
 
-	msgLength = sizeof(tSirOemDataRsp);
-
+	msgLength = sizeof(*pSirSmeOemDataRsp);
 	/* now allocate memory for the char buffer */
-	pSirSmeOemDataRsp = qdf_mem_malloc(msgLength);
+	pSirSmeOemDataRsp = qdf_mem_malloc(sizeof(*pSirSmeOemDataRsp));
 	if (NULL == pSirSmeOemDataRsp) {
 		lim_log(pMac, LOGP,
-			FL
-				("call to AllocateMemory failed for pSirSmeOemDataRsp"));
+			FL("malloc failed for pSirSmeOemDataRsp"));
+		qdf_mem_free(pMlmOemDataRsp->oem_data_rsp);
+		qdf_mem_free(pMlmOemDataRsp);
 		return;
 	}
+
+	if (pMlmOemDataRsp->rsp_len) {
+		pSirSmeOemDataRsp->oem_data_rsp =
+			qdf_mem_malloc(pMlmOemDataRsp->rsp_len);
+		if (!pSirSmeOemDataRsp->oem_data_rsp) {
+			lim_log(pMac, LOGE,
+				FL("malloc failed for oem_data_rsp"));
+			qdf_mem_free(pSirSmeOemDataRsp);
+			qdf_mem_free(pMlmOemDataRsp->oem_data_rsp);
+			qdf_mem_free(pMlmOemDataRsp);
+			return;
+		}
+	}
+
 #if defined (ANI_LITTLE_BYTE_ENDIAN)
 	sir_store_u16_n((uint8_t *) &pSirSmeOemDataRsp->length, msgLength);
 	sir_store_u16_n((uint8_t *) &pSirSmeOemDataRsp->messageType,
@@ -828,10 +842,14 @@
 	pSirSmeOemDataRsp->messageType = eWNI_SME_OEM_DATA_RSP;
 #endif
 	pSirSmeOemDataRsp->target_rsp = pMlmOemDataRsp->target_rsp;
-	qdf_mem_copy(pSirSmeOemDataRsp->oemDataRsp, pMlmOemDataRsp->oemDataRsp,
-		     OEM_DATA_RSP_SIZE);
+	pSirSmeOemDataRsp->rsp_len = pMlmOemDataRsp->rsp_len;
+	if (pSirSmeOemDataRsp->rsp_len)
+		qdf_mem_copy(pSirSmeOemDataRsp->oem_data_rsp,
+			     pMlmOemDataRsp->oem_data_rsp,
+			     pSirSmeOemDataRsp->rsp_len);
 
 	/* Now free the memory from MLM Rsp Message */
+	qdf_mem_free(pMlmOemDataRsp->oem_data_rsp);
 	qdf_mem_free(pMlmOemDataRsp);
 
 	mmhMsg.type = eWNI_SME_OEM_DATA_RSP;
diff --git a/core/sme/inc/oem_data_api.h b/core/sme/inc/oem_data_api.h
index 110f017..fa1d1f3 100644
--- a/core/sme/inc/oem_data_api.h
+++ b/core/sme/inc/oem_data_api.h
@@ -49,6 +49,7 @@
 
 /* message subtype for internal purpose */
 #define OEM_MESSAGE_SUBTYPE_INTERNAL   0xdeadbeef
+#define OEM_MESSAGE_SUBTYPE_LEN 4
 
 /* Structure for defining req sent to the PE */
 typedef struct tagOemDataReq {
@@ -58,7 +59,8 @@
 } tOemDataReq, tOemDataReqConfig;
 
 typedef struct tagOemDataRsp {
-	uint8_t oemDataRsp[OEM_DATA_RSP_SIZE];
+	uint8_t rsp_len;
+	uint8_t *oem_data_rsp;
 } tOemDataRsp;
 
 typedef enum {
diff --git a/core/sme/src/oem_data/oem_data_api.c b/core/sme/src/oem_data/oem_data_api.c
index 6478e19..a607caa 100644
--- a/core/sme/src/oem_data/oem_data_api.c
+++ b/core/sme/src/oem_data/oem_data_api.c
@@ -351,12 +351,13 @@
 				FL("received target oem data resp"));
 			if (pMac->oemData.oem_data_rsp_callback != NULL)
 				 pMac->oemData.oem_data_rsp_callback(
-					sizeof(tOemDataRsp),
-					&pOemDataRsp->oemDataRsp[0]);
+					pOemDataRsp->rsp_len,
+					pOemDataRsp->oem_data_rsp);
 		} else {
 			sms_log(pMac, LOG1,
 				FL("received internal oem data resp"));
 		}
+		qdf_mem_free(pOemDataRsp->oem_data_rsp);
 	} while (0);
 
 	return status;
diff --git a/core/wma/inc/wma_if.h b/core/wma/inc/wma_if.h
index 9748d67..8b01d00 100644
--- a/core/wma/inc/wma_if.h
+++ b/core/wma/inc/wma_if.h
@@ -680,11 +680,14 @@
 
 /**
  * struct tStartOemDataRsp - start OEM Data response
- * @oemDataRsp: OEM Data response
+ * @target_rsp: Indicates if the rsp is from Target or WMA generated.
+ * @rsp_len: oem data response length
+ * @oem_data_rsp: pointer to OEM Data response
  */
 typedef struct {
 	bool target_rsp;
-	uint8_t oemDataRsp[OEM_DATA_RSP_SIZE];
+	uint32_t rsp_len;
+	uint8_t *oem_data_rsp;
 } tStartOemDataRsp, *tpStartOemDataRsp;
 #endif /* FEATURE_OEM_DATA_SUPPORT */
 
diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c
index 07c8545..53f06fe 100644
--- a/core/wma/src/wma_features.c
+++ b/core/wma/src/wma_features.c
@@ -1253,11 +1253,12 @@
 		return -EINVAL;
 	}
 
-	/* wma puts 4 bytes prefix for msg subtype, so length
+	/*
+	 *  wma puts 4 bytes prefix for msg subtype, so length
 	 * of data received from target should be 4 bytes less
 	 * then max allowed
 	 */
-	if (datalen > (OEM_DATA_RSP_SIZE - 4)) {
+	if (datalen > (OEM_DATA_RSP_SIZE - OEM_MESSAGE_SUBTYPE_LEN)) {
 		WMA_LOGE("%s: Received data len (%d) exceeds max value (%d)",
 			 __func__, datalen, (OEM_DATA_RSP_SIZE - 4));
 		return -EINVAL;
@@ -1268,15 +1269,23 @@
 		WMA_LOGE("%s: Failed to alloc pStartOemDataRsp", __func__);
 		return -ENOMEM;
 	}
+	pStartOemDataRsp->rsp_len = datalen + OEM_MESSAGE_SUBTYPE_LEN;
+	pStartOemDataRsp->oem_data_rsp = qdf_mem_malloc(datalen);
+	if (!pStartOemDataRsp->oem_data_rsp) {
+		WMA_LOGE(FL("malloc failed for oem_data_rsp"));
+		qdf_mem_free(pStartOemDataRsp);
+		return -ENOMEM;
+	}
 
-	qdf_mem_zero(pStartOemDataRsp, sizeof(tStartOemDataRsp));
 	pStartOemDataRsp->target_rsp = true;
-	msg_subtype = (uint32_t *) (&pStartOemDataRsp->oemDataRsp[0]);
+	msg_subtype = (uint32_t *) pStartOemDataRsp->oem_data_rsp;
 	*msg_subtype = WMI_OEM_CAPABILITY_RSP;
-	qdf_mem_copy(&pStartOemDataRsp->oemDataRsp[4], data, datalen);
+	/* copy data after msg sub type */
+	qdf_mem_copy(pStartOemDataRsp->oem_data_rsp + OEM_MESSAGE_SUBTYPE_LEN,
+		     data, datalen);
 
 	WMA_LOGI("%s: Sending WMA_START_OEM_DATA_RSP, data len (%d)",
-		 __func__, datalen);
+		 __func__, pStartOemDataRsp->rsp_len);
 
 	wma_send_msg(wma, WMA_START_OEM_DATA_RSP, (void *)pStartOemDataRsp, 0);
 	return 0;
@@ -1315,11 +1324,12 @@
 		return -EINVAL;
 	}
 
-	/* wma puts 4 bytes prefix for msg subtype, so length
+	/*
+	 * wma puts 4 bytes prefix for msg subtype, so length
 	 * of data received from target should be 4 bytes less
 	 * then max allowed
 	 */
-	if (datalen > (OEM_DATA_RSP_SIZE - 4)) {
+	if (datalen > (OEM_DATA_RSP_SIZE - OEM_MESSAGE_SUBTYPE_LEN)) {
 		WMA_LOGE("%s: Received data len (%d) exceeds max value (%d)",
 			 __func__, datalen, (OEM_DATA_RSP_SIZE - 4));
 		return -EINVAL;
@@ -1330,12 +1340,20 @@
 		WMA_LOGE("%s: Failed to alloc pStartOemDataRsp", __func__);
 		return -ENOMEM;
 	}
+	pStartOemDataRsp->rsp_len = datalen + OEM_MESSAGE_SUBTYPE_LEN;
+	pStartOemDataRsp->oem_data_rsp = qdf_mem_malloc(datalen);
+	if (!pStartOemDataRsp->oem_data_rsp) {
+		WMA_LOGE(FL("malloc failed for oem_data_rsp"));
+		qdf_mem_free(pStartOemDataRsp);
+		return -ENOMEM;
+	}
 
-	qdf_mem_zero(pStartOemDataRsp, sizeof(tStartOemDataRsp));
 	pStartOemDataRsp->target_rsp = true;
-	msg_subtype = (uint32_t *) (&pStartOemDataRsp->oemDataRsp[0]);
+	msg_subtype = (uint32_t *) pStartOemDataRsp->oem_data_rsp;
 	*msg_subtype = WMI_OEM_MEASUREMENT_RSP;
-	qdf_mem_copy(&pStartOemDataRsp->oemDataRsp[4], data, datalen);
+	/* copy data after msg sub type */
+	qdf_mem_copy(pStartOemDataRsp->oem_data_rsp + OEM_MESSAGE_SUBTYPE_LEN,
+		     data, pStartOemDataRsp->rsp_len);
 
 	WMA_LOGI("%s: Sending WMA_START_OEM_DATA_RSP, data len (%d)",
 		 __func__, datalen);
@@ -1376,11 +1394,12 @@
 		return -EINVAL;
 	}
 
-	/* wma puts 4 bytes prefix for msg subtype, so length
+	/*
+	 * wma puts 4 bytes prefix for msg subtype, so length
 	 * of data received from target should be 4 bytes less
 	 * then max allowed
 	 */
-	if (datalen > (OEM_DATA_RSP_SIZE - 4)) {
+	if (datalen > (OEM_DATA_RSP_SIZE - OEM_MESSAGE_SUBTYPE_LEN)) {
 		WMA_LOGE("%s: Received data len (%d) exceeds max value (%d)",
 			 __func__, datalen, (OEM_DATA_RSP_SIZE - 4));
 		return -EINVAL;
@@ -1391,12 +1410,20 @@
 		WMA_LOGE("%s: Failed to alloc pStartOemDataRsp", __func__);
 		return -ENOMEM;
 	}
+	pStartOemDataRsp->rsp_len = datalen + OEM_MESSAGE_SUBTYPE_LEN;
+	pStartOemDataRsp->oem_data_rsp = qdf_mem_malloc(datalen);
+	if (!pStartOemDataRsp->oem_data_rsp) {
+		WMA_LOGE(FL("malloc failed for oem_data_rsp"));
+		qdf_mem_free(pStartOemDataRsp);
+		return -ENOMEM;
+	}
 
-	qdf_mem_zero(pStartOemDataRsp, sizeof(tStartOemDataRsp));
 	pStartOemDataRsp->target_rsp = true;
-	msg_subtype = (uint32_t *) (&pStartOemDataRsp->oemDataRsp[0]);
+	msg_subtype = (uint32_t *) pStartOemDataRsp->oem_data_rsp;
 	*msg_subtype = WMI_OEM_ERROR_REPORT_RSP;
-	qdf_mem_copy(&pStartOemDataRsp->oemDataRsp[4], data, datalen);
+	/* copy data after msg sub type */
+	qdf_mem_copy(pStartOemDataRsp->oem_data_rsp + OEM_MESSAGE_SUBTYPE_LEN,
+		     data, pStartOemDataRsp->rsp_len);
 
 	WMA_LOGI("%s: Sending WMA_START_OEM_DATA_RSP, data len (%d)",
 		 __func__, datalen);
@@ -1420,7 +1447,7 @@
 	WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf;
 	uint8_t *data;
 	uint32_t datalen;
-	tStartOemDataRsp *oem_data_rsp;
+	tStartOemDataRsp *oem_rsp;
 
 	param_buf = (WMI_OEM_RESPONSE_EVENTID_param_tlvs *) datap;
 	if (!param_buf) {
@@ -1442,19 +1469,25 @@
 		return -EINVAL;
 	}
 
-	oem_data_rsp = qdf_mem_malloc(sizeof(*oem_data_rsp));
-	if (!oem_data_rsp) {
+	oem_rsp = qdf_mem_malloc(sizeof(*oem_rsp));
+	if (!oem_rsp) {
 		WMA_LOGE(FL("Failed to alloc oem_data_rsp"));
 		return -ENOMEM;
 	}
+	oem_rsp->rsp_len = datalen;
+	oem_rsp->oem_data_rsp = qdf_mem_malloc(datalen);
+	if (!oem_rsp->rsp_len) {
+		WMA_LOGE(FL("malloc failed for oem_data_rsp"));
+		qdf_mem_free(oem_rsp);
+		return -ENOMEM;
+	}
 
-	qdf_mem_zero(oem_data_rsp, sizeof(tStartOemDataRsp));
-	oem_data_rsp->target_rsp = true;
-	qdf_mem_copy(&oem_data_rsp->oemDataRsp[0], data, datalen);
+	oem_rsp->target_rsp = true;
+	qdf_mem_copy(oem_rsp->oem_data_rsp, data, datalen);
 
 	WMA_LOGI(FL("Sending WMA_START_OEM_DATA_RSP, data len %d"), datalen);
 
-	wma_send_msg(wma, WMA_START_OEM_DATA_RSP, (void *)oem_data_rsp, 0);
+	wma_send_msg(wma, WMA_START_OEM_DATA_RSP, (void *)oem_rsp, 0);
 	return 0;
 }