diff options
author | Dan Williams <dcbw@redhat.com> | 2010-03-30 00:32:05 -0700 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2010-03-30 00:32:27 -0700 |
commit | 0ae176c63c8686cd3a86b7933be5ae3546782475 (patch) | |
tree | 33486efe86bf3469fbff80283621423c0b37dd6e | |
parent | cff40ac4724780e73f47af4f17cba952ab1ed680 (diff) |
qcdm: add Pilot Set retrieval for signal strength calculations
Determined from various sources including RTManager and
"Technical Introduction to CDMA" (Course RF100 Chapter 7).
-rw-r--r-- | libqcdm/src/commands.c | 122 | ||||
-rw-r--r-- | libqcdm/src/commands.h | 28 | ||||
-rw-r--r-- | libqcdm/src/dm-commands.h | 16 | ||||
-rw-r--r-- | libqcdm/tests/test-qcdm-com.c | 54 | ||||
-rw-r--r-- | libqcdm/tests/test-qcdm-com.h | 2 | ||||
-rw-r--r-- | libqcdm/tests/test-qcdm.c | 1 |
6 files changed, 223 insertions, 0 deletions
diff --git a/libqcdm/src/commands.c b/libqcdm/src/commands.c index 156cf14c..6bdaff06 100644 --- a/libqcdm/src/commands.c +++ b/libqcdm/src/commands.c @@ -366,6 +366,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) { char cmdbuf[sizeof (DMCmdNVReadWrite) + 2]; diff --git a/libqcdm/src/commands.h b/libqcdm/src/commands.h index 0878fe33..38aec359 100644 --- a/libqcdm/src/commands.h +++ b/libqcdm/src/commands.h @@ -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" diff --git a/libqcdm/src/dm-commands.h b/libqcdm/src/dm-commands.h index 35245281..0777104c 100644 --- a/libqcdm/src/dm-commands.h +++ b/libqcdm/src/dm-commands.h @@ -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 */ diff --git a/libqcdm/tests/test-qcdm-com.c b/libqcdm/tests/test-qcdm-com.c index c9fe7296..1327f33e 100644 --- a/libqcdm/tests/test-qcdm-com.c +++ b/libqcdm/tests/test-qcdm-com.c @@ -599,6 +599,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) { TestComData *d = data; diff --git a/libqcdm/tests/test-qcdm-com.h b/libqcdm/tests/test-qcdm-com.h index d9f4ee75..8ea8e605 100644 --- a/libqcdm/tests/test-qcdm-com.h +++ b/libqcdm/tests/test-qcdm-com.h @@ -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); diff --git a/libqcdm/tests/test-qcdm.c b/libqcdm/tests/test-qcdm.c index d87a2e31..0a6801fb 100644 --- a/libqcdm/tests/test-qcdm.c +++ b/libqcdm/tests/test-qcdm.c @@ -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)); |