mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-09-21 11:53:01 +00:00
lib: qmi: Add api to verify maximum length of a QMI message
The new API is added to verify the maximum length of a QMI message embedded inside the message descriptor matches the expected maximum length of the concerned QMI message. The expected maximum length of the QMI message is calculated using the message descriptor which describes all the elements in the structure. Change-Id: I09602df410d9891d60f1502245ad055653f8f0f7 Signed-off-by: Karthikeyan Ramasubramanian <kramasub@codeaurora.org>
This commit is contained in:
parent
99f5e80f1e
commit
5554a12b7b
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -150,6 +150,15 @@ int qmi_kernel_encode(struct msg_desc *desc,
|
|||
int qmi_kernel_decode(struct msg_desc *desc, void *out_c_struct,
|
||||
void *in_buf, uint32_t in_buf_len);
|
||||
|
||||
/**
|
||||
* qmi_verify_max_msg_len() - Verify the maximum length of a QMI message
|
||||
* @desc: Pointer to structure descriptor.
|
||||
*
|
||||
* @return: true if the maximum message length embedded in structure
|
||||
* descriptor matches the calculated value, else false.
|
||||
*/
|
||||
bool qmi_verify_max_msg_len(struct msg_desc *desc);
|
||||
|
||||
#else
|
||||
static inline int qmi_kernel_encode(struct msg_desc *desc,
|
||||
void *out_buf, uint32_t out_buf_len,
|
||||
|
@ -164,6 +173,11 @@ static inline int qmi_kernel_decode(struct msg_desc *desc,
|
|||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline bool qmi_verify_max_msg_len(struct msg_desc *desc)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -89,6 +89,71 @@ static int _qmi_kernel_decode(struct elem_info *ei_array,
|
|||
void *in_buf, uint32_t in_buf_len,
|
||||
int dec_level);
|
||||
|
||||
/**
|
||||
* qmi_calc_max_msg_len() - Calculate the maximum length of a QMI message
|
||||
* @ei_array: Struct info array describing the structure.
|
||||
* @level: Level to identify the depth of the nested structures.
|
||||
*
|
||||
* @return: expected maximum length of the QMI message or 0 on failure.
|
||||
*/
|
||||
static int qmi_calc_max_msg_len(struct elem_info *ei_array,
|
||||
int level)
|
||||
{
|
||||
int max_msg_len = 0;
|
||||
struct elem_info *temp_ei;
|
||||
|
||||
if (!ei_array)
|
||||
return max_msg_len;
|
||||
|
||||
for (temp_ei = ei_array; temp_ei->data_type != QMI_EOTI; temp_ei++) {
|
||||
/* Flag to identify the optional element is not encoded */
|
||||
if (temp_ei->data_type == QMI_OPT_FLAG)
|
||||
continue;
|
||||
|
||||
if (temp_ei->data_type == QMI_DATA_LEN) {
|
||||
max_msg_len += (temp_ei->elem_size == sizeof(uint8_t) ?
|
||||
sizeof(uint8_t) : sizeof(uint16_t));
|
||||
continue;
|
||||
} else if (temp_ei->data_type == QMI_STRUCT) {
|
||||
max_msg_len += qmi_calc_max_msg_len(temp_ei->ei_array,
|
||||
(level + 1));
|
||||
} else {
|
||||
max_msg_len += (temp_ei->elem_len * temp_ei->elem_size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Type & Length info. not prepended for elements in the
|
||||
* nested structure.
|
||||
*/
|
||||
if (level == 1)
|
||||
max_msg_len += (TLV_TYPE_SIZE + TLV_LEN_SIZE);
|
||||
}
|
||||
return max_msg_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* qmi_verify_max_msg_len() - Verify the maximum length of a QMI message
|
||||
* @desc: Pointer to structure descriptor.
|
||||
*
|
||||
* @return: true if the maximum message length embedded in structure
|
||||
* descriptor matches the calculated value, else false.
|
||||
*/
|
||||
bool qmi_verify_max_msg_len(struct msg_desc *desc)
|
||||
{
|
||||
int calc_max_msg_len;
|
||||
|
||||
if (!desc)
|
||||
return false;
|
||||
|
||||
calc_max_msg_len = qmi_calc_max_msg_len(desc->ei_array, 1);
|
||||
if (calc_max_msg_len != desc->max_msg_len) {
|
||||
pr_err("%s: Calc. len %d != Passed len %d\n",
|
||||
__func__, calc_max_msg_len, desc->max_msg_len);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* qmi_kernel_encode() - Encode to QMI message wire format
|
||||
* @desc: Pointer to structure descriptor.
|
||||
|
@ -103,6 +168,7 @@ int qmi_kernel_encode(struct msg_desc *desc,
|
|||
void *in_c_struct)
|
||||
{
|
||||
int enc_level = 1;
|
||||
int ret, calc_max_msg_len;
|
||||
|
||||
if (!desc || !desc->ei_array)
|
||||
return -EINVAL;
|
||||
|
@ -113,8 +179,14 @@ int qmi_kernel_encode(struct msg_desc *desc,
|
|||
if (desc->max_msg_len < out_buf_len)
|
||||
return -ETOOSMALL;
|
||||
|
||||
return _qmi_kernel_encode(desc->ei_array, out_buf,
|
||||
in_c_struct, out_buf_len, enc_level);
|
||||
ret = _qmi_kernel_encode(desc->ei_array, out_buf,
|
||||
in_c_struct, out_buf_len, enc_level);
|
||||
if (ret == -ETOOSMALL) {
|
||||
calc_max_msg_len = qmi_calc_max_msg_len(desc->ei_array, 1);
|
||||
pr_err("%s: Calc. len %d != Out buf len %d\n",
|
||||
__func__, calc_max_msg_len, out_buf_len);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(qmi_kernel_encode);
|
||||
|
||||
|
|
Loading…
Reference in a new issue