qcdm: add Pilot Set retrieval for signal strength calculations
Determined from various sources including RTManager and "Technical Introduction to CDMA" (Course RF100 Chapter 7).
This commit is contained in:
@@ -365,6 +365,128 @@ qcdm_cmd_sw_version_result (const char *buf, gsize len, GError **error)
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
gsize
|
||||
qcdm_cmd_pilot_sets_new (char *buf, gsize len, GError **error)
|
||||
{
|
||||
char cmdbuf[3];
|
||||
DMCmdHeader *cmd = (DMCmdHeader *) &cmdbuf[0];
|
||||
|
||||
g_return_val_if_fail (buf != NULL, 0);
|
||||
g_return_val_if_fail (len >= sizeof (*cmd) + DIAG_TRAILER_LEN, 0);
|
||||
|
||||
memset (cmd, 0, sizeof (*cmd));
|
||||
cmd->code = DIAG_CMD_PILOT_SETS;
|
||||
|
||||
return dm_encapsulate_buffer (cmdbuf, sizeof (*cmd), sizeof (cmdbuf), buf, len);
|
||||
}
|
||||
|
||||
#define PILOT_SETS_CMD_ACTIVE_SET "active-set"
|
||||
#define PILOT_SETS_CMD_CANDIDATE_SET "candidate-set"
|
||||
#define PILOT_SETS_CMD_NEIGHBOR_SET "neighbor-set"
|
||||
|
||||
static const char *
|
||||
set_num_to_str (guint32 num)
|
||||
{
|
||||
if (num == QCDM_CMD_PILOT_SETS_TYPE_ACTIVE)
|
||||
return PILOT_SETS_CMD_ACTIVE_SET;
|
||||
if (num == QCDM_CMD_PILOT_SETS_TYPE_CANDIDATE)
|
||||
return PILOT_SETS_CMD_CANDIDATE_SET;
|
||||
if (num == QCDM_CMD_PILOT_SETS_TYPE_NEIGHBOR)
|
||||
return PILOT_SETS_CMD_NEIGHBOR_SET;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
QCDMResult *
|
||||
qcdm_cmd_pilot_sets_result (const char *buf, gsize len, GError **error)
|
||||
{
|
||||
QCDMResult *result = NULL;
|
||||
DMCmdPilotSetsRsp *rsp = (DMCmdPilotSetsRsp *) buf;
|
||||
GByteArray *array;
|
||||
gsize sets_len;
|
||||
|
||||
g_return_val_if_fail (buf != NULL, NULL);
|
||||
|
||||
if (!check_command (buf, len, DIAG_CMD_PILOT_SETS, sizeof (DMCmdPilotSetsRsp), error))
|
||||
return NULL;
|
||||
|
||||
result = qcdm_result_new ();
|
||||
|
||||
sets_len = rsp->active_count * sizeof (DMCmdPilotSetsSet);
|
||||
if (sets_len > 0) {
|
||||
array = g_byte_array_sized_new (sets_len);
|
||||
g_byte_array_append (array, (const guint8 *) &rsp->sets[0], sets_len);
|
||||
qcdm_result_add_boxed (result, PILOT_SETS_CMD_ACTIVE_SET, G_TYPE_BYTE_ARRAY, array);
|
||||
}
|
||||
|
||||
sets_len = rsp->candidate_count * sizeof (DMCmdPilotSetsSet);
|
||||
if (sets_len > 0) {
|
||||
array = g_byte_array_sized_new (sets_len);
|
||||
g_byte_array_append (array, (const guint8 *) &rsp->sets[rsp->active_count], sets_len);
|
||||
qcdm_result_add_boxed (result, PILOT_SETS_CMD_CANDIDATE_SET, G_TYPE_BYTE_ARRAY, array);
|
||||
}
|
||||
|
||||
sets_len = rsp->neighbor_count * sizeof (DMCmdPilotSetsSet);
|
||||
if (sets_len > 0) {
|
||||
array = g_byte_array_sized_new (sets_len);
|
||||
g_byte_array_append (array, (const guint8 *) &rsp->sets[rsp->active_count + rsp->candidate_count], sets_len);
|
||||
qcdm_result_add_boxed (result, PILOT_SETS_CMD_NEIGHBOR_SET, G_TYPE_BYTE_ARRAY, array);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
gboolean
|
||||
qcdm_cmd_pilot_sets_result_get_num (QCDMResult *result,
|
||||
guint32 set_type,
|
||||
guint32 *out_num)
|
||||
{
|
||||
const char *set_name;
|
||||
GByteArray *array = NULL;
|
||||
|
||||
g_return_val_if_fail (result != NULL, FALSE);
|
||||
|
||||
set_name = set_num_to_str (set_type);
|
||||
g_return_val_if_fail (set_name != NULL, FALSE);
|
||||
|
||||
if (!qcdm_result_get_boxed (result, set_name, (gpointer) &array))
|
||||
return FALSE;
|
||||
|
||||
*out_num = array->len / sizeof (DMCmdPilotSetsSet);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
qcdm_cmd_pilot_sets_result_get_pilot (QCDMResult *result,
|
||||
guint32 set_type,
|
||||
guint32 num,
|
||||
guint32 *out_pn_offset,
|
||||
guint32 *out_ecio,
|
||||
float *out_db)
|
||||
{
|
||||
const char *set_name;
|
||||
GByteArray *array = NULL;
|
||||
DMCmdPilotSetsSet *set;
|
||||
|
||||
g_return_val_if_fail (result != NULL, FALSE);
|
||||
|
||||
set_name = set_num_to_str (set_type);
|
||||
g_return_val_if_fail (set_name != NULL, FALSE);
|
||||
|
||||
if (!qcdm_result_get_boxed (result, set_name, (gpointer) &array))
|
||||
return FALSE;
|
||||
|
||||
g_return_val_if_fail (num < array->len / sizeof (DMCmdPilotSetsSet), FALSE);
|
||||
|
||||
set = (DMCmdPilotSetsSet *) &array->data[num * sizeof (DMCmdPilotSetsSet)];
|
||||
*out_pn_offset = set->pn_offset;
|
||||
*out_ecio = set->ecio;
|
||||
/* EC/IO is in units of -0.5 dB per the specs */
|
||||
*out_db = (float) set->ecio * -0.5;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
gsize
|
||||
qcdm_cmd_nv_get_mdn_new (char *buf, gsize len, guint8 profile, GError **error)
|
||||
{
|
||||
|
@@ -110,6 +110,34 @@ QCDMResult *qcdm_cmd_sw_version_result (const char *buf,
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
enum {
|
||||
QCDM_CMD_PILOT_SETS_TYPE_UNKNOWN = 0,
|
||||
QCDM_CMD_PILOT_SETS_TYPE_ACTIVE = 1,
|
||||
QCDM_CMD_PILOT_SETS_TYPE_CANDIDATE = 2,
|
||||
QCDM_CMD_PILOT_SETS_TYPE_NEIGHBOR = 3,
|
||||
};
|
||||
|
||||
gsize qcdm_cmd_pilot_sets_new (char *buf,
|
||||
gsize len,
|
||||
GError **error);
|
||||
|
||||
QCDMResult *qcdm_cmd_pilot_sets_result (const char *buf,
|
||||
gsize len,
|
||||
GError **error);
|
||||
|
||||
gboolean qcdm_cmd_pilot_sets_result_get_num (QCDMResult *result,
|
||||
guint32 set_type,
|
||||
guint32 *out_num);
|
||||
|
||||
gboolean qcdm_cmd_pilot_sets_result_get_pilot (QCDMResult *result,
|
||||
guint32 set_type,
|
||||
guint32 num,
|
||||
guint32 *out_pn_offset,
|
||||
guint32 *out_ecio,
|
||||
float *out_db);
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
#define QCDM_CMD_NV_GET_MDN_ITEM_PROFILE "profile"
|
||||
#define QCDM_CMD_NV_GET_MDN_ITEM_MDN "mdn"
|
||||
|
||||
|
@@ -279,5 +279,21 @@ struct DMCmdSubsysZteStatusRsp {
|
||||
} __attribute__ ((packed));
|
||||
typedef struct DMCmdSubsysZteStatusRsp DMCmdSubsysZteStatusRsp;
|
||||
|
||||
struct DMCmdPilotSetsSet {
|
||||
guint16 pn_offset;
|
||||
guint16 ecio;
|
||||
} __attribute__ ((packed));
|
||||
typedef struct DMCmdPilotSetsSet DMCmdPilotSetsSet;
|
||||
|
||||
struct DMCmdPilotSetsRsp {
|
||||
guint8 code;
|
||||
guint16 pilot_inc;
|
||||
guint8 active_count;
|
||||
guint8 candidate_count;
|
||||
guint8 neighbor_count;
|
||||
DMCmdPilotSetsSet sets[52];
|
||||
} __attribute__ ((packed));
|
||||
typedef struct DMCmdPilotSetsRsp DMCmdPilotSetsRsp;
|
||||
|
||||
#endif /* LIBQCDM_DM_COMMANDS_H */
|
||||
|
||||
|
@@ -598,6 +598,60 @@ test_com_sw_version (void *f, void *data)
|
||||
*/
|
||||
}
|
||||
|
||||
void
|
||||
test_com_pilot_sets (void *f, void *data)
|
||||
{
|
||||
TestComData *d = data;
|
||||
gboolean success;
|
||||
GError *error = NULL;
|
||||
char buf[256];
|
||||
gint len;
|
||||
QCDMResult *result;
|
||||
gsize reply_len;
|
||||
guint32 num, i;
|
||||
|
||||
len = qcdm_cmd_pilot_sets_new (buf, sizeof (buf), NULL);
|
||||
g_assert (len == 4);
|
||||
|
||||
/* Send the command */
|
||||
success = send_command (d, buf, len);
|
||||
g_assert (success);
|
||||
|
||||
/* Get a response */
|
||||
reply_len = wait_reply (d, buf, sizeof (buf));
|
||||
|
||||
/* Parse the response into a result structure */
|
||||
result = qcdm_cmd_pilot_sets_result (buf, reply_len, &error);
|
||||
g_assert (result);
|
||||
|
||||
num = 0;
|
||||
qcdm_cmd_pilot_sets_result_get_num (result, QCDM_CMD_PILOT_SETS_TYPE_ACTIVE, &num);
|
||||
g_message ("%s: Active Pilots: %d", __func__, num);
|
||||
for (i = 0; i < num; i++) {
|
||||
guint32 pn_offset = 0, ecio = 0;
|
||||
float db = 0;
|
||||
|
||||
qcdm_cmd_pilot_sets_result_get_pilot (result,
|
||||
QCDM_CMD_PILOT_SETS_TYPE_ACTIVE,
|
||||
i,
|
||||
&pn_offset,
|
||||
&ecio,
|
||||
&db);
|
||||
g_message (" %d: PN offset %d", i, pn_offset);
|
||||
g_message (" EC/IO %d (%.1f dB)", ecio, db);
|
||||
}
|
||||
|
||||
num = 0;
|
||||
qcdm_cmd_pilot_sets_result_get_num (result, QCDM_CMD_PILOT_SETS_TYPE_CANDIDATE, &num);
|
||||
g_message ("%s: Candidate Pilots: %d", __func__, num);
|
||||
|
||||
num = 0;
|
||||
qcdm_cmd_pilot_sets_result_get_num (result, QCDM_CMD_PILOT_SETS_TYPE_NEIGHBOR, &num);
|
||||
g_message ("%s: Neighbor Pilots: %d", __func__, num);
|
||||
|
||||
qcdm_result_unref (result);
|
||||
}
|
||||
|
||||
void
|
||||
test_com_cm_subsys_state_info (void *f, void *data)
|
||||
{
|
||||
|
@@ -37,6 +37,8 @@ void test_com_status (void *f, void *data);
|
||||
|
||||
void test_com_sw_version (void *f, void *data);
|
||||
|
||||
void test_com_pilot_sets (void *f, void *data);
|
||||
|
||||
void test_com_cm_subsys_state_info (void *f, void *data);
|
||||
|
||||
void test_com_hdr_subsys_state_info (void *f, void *data);
|
||||
|
@@ -98,6 +98,7 @@ int main (int argc, char **argv)
|
||||
g_test_suite_add (suite, TESTCASE (test_com_read_mode_pref, data->com_data));
|
||||
g_test_suite_add (suite, TESTCASE (test_com_status, data->com_data));
|
||||
g_test_suite_add (suite, TESTCASE (test_com_sw_version, data->com_data));
|
||||
g_test_suite_add (suite, TESTCASE (test_com_pilot_sets, data->com_data));
|
||||
g_test_suite_add (suite, TESTCASE (test_com_cm_subsys_state_info, data->com_data));
|
||||
g_test_suite_add (suite, TESTCASE (test_com_hdr_subsys_state_info, data->com_data));
|
||||
g_test_suite_add (suite, TESTCASE (test_com_zte_subsys_status, data->com_data));
|
||||
|
Reference in New Issue
Block a user