aboutsummaryrefslogtreecommitdiff
path: root/libqcdm
diff options
context:
space:
mode:
Diffstat (limited to 'libqcdm')
-rw-r--r--libqcdm/src/Makefile.am2
-rw-r--r--libqcdm/src/log-items.h34
-rw-r--r--libqcdm/src/logs.c184
-rw-r--r--libqcdm/src/logs.h50
4 files changed, 253 insertions, 17 deletions
diff --git a/libqcdm/src/Makefile.am b/libqcdm/src/Makefile.am
index 2caaf008..f13098f3 100644
--- a/libqcdm/src/Makefile.am
+++ b/libqcdm/src/Makefile.am
@@ -16,6 +16,8 @@ libqcdm_la_SOURCES = \
commands.h \
errors.c \
errors.h \
+ logs.c \
+ logs.h \
result.c \
result.h \
result-private.h \
diff --git a/libqcdm/src/log-items.h b/libqcdm/src/log-items.h
index 71f0f1e0..8802dfdb 100644
--- a/libqcdm/src/log-items.h
+++ b/libqcdm/src/log-items.h
@@ -37,7 +37,7 @@ enum {
DM_LOG_ITEM_EVDO_REV_POWER_CONTROL = 0x1063,
DM_LOG_ITEM_EVDO_ARQ_EFFECTIVE_RECEIVE_RATE = 0x1066,
DM_LOG_ITEM_EVDO_AIR_LINK_SUMMARY = 0x1068,
- DM_LOG_ITEM_EVDO_POWER = 0x1069
+ DM_LOG_ITEM_EVDO_POWER = 0x1069,
DM_LOG_ITEM_EVDO_FWD_LINK_PACKET_SNAPSHOT = 0x106A,
DM_LOG_ITEM_EVDO_ACCESS_ATTEMPT = 0x106C,
DM_LOG_ITEM_EVDO_REV_ACTIVITY_BITS_BUFFER = 0x106D,
@@ -91,14 +91,14 @@ struct DMLogItemCdmaReversePowerControl {
typedef struct DMLogItemCdmaReversePowerControl DMLogItemCdmaReversePowerControl;
/* DM_LOG_ITEM_EVDO_PILOT_SETS_V2 */
-struct EvdoPilotSetsV2PilotRecord {
+struct DMLogItemEvdoPilotSetsV2Pilot {
u_int16_t pilot_pn;
/* HDR pilot energy doesn't appear to be in the same units as 1x pilot
- * energy (eg, -0.5 dBm increments). Instead, you can approximate EC/IO
- * by using this formula empirically derived from simultaneous AT!ECIO
- * and HDR Pilot Sets V2 results from a Sierra modem:
+ * energy (eg, -0.5 dBm increments). Instead it appears roughly correlated
+ * to RSSI dBm by using this formula empirically derived from simultaneous
+ * AT!RSSI and HDR Pilot Sets V2 results from a Sierra modem:
*
- * EC/IO = (pilot_energy / -50) + 1
+ * RSSI dBm = -110 + (MAX(pilot_energy - 50, 0) / 14)
*/
u_int16_t pilot_energy;
union {
@@ -122,22 +122,22 @@ struct EvdoPilotSetsV2PilotRecord {
} Remaining;
};
} __attribute__ ((packed));
-typedef struct EvdoPilotSetsV2PilotRecord EvdoPilotSetsV2PilotRecord;
+typedef struct DMLogItemEvdoPilotSetsV2Pilot DMLogItemEvdoPilotSetsV2Pilot;
/* DM_LOG_ITEM_EVDO_PILOT_SETS_V2 */
struct DMLogItemEvdoPilotSetsV2 {
u_int8_t pn_offset;
- u_int8_t active_set_count;
- u_int8_t active_set_window;
- u_int16_t active_set_channel;
+ u_int8_t active_count;
+ u_int8_t active_window;
+ u_int16_t active_channel;
u_int8_t unknown1;
- u_int8_t candidate_set_count;
- u_int8_t candidate_set_window;
- u_int8_t remaining_set_count;
- u_int8_t remaining_set_window;
+ u_int8_t candidate_count;
+ u_int8_t candidate_window;
+ u_int8_t remaining_count;
+ u_int8_t remaining_window;
u_int8_t unknown2;
- EvdoPilotSetsV2PilotRecord records[];
+ DMLogItemEvdoPilotSetsV2Pilot sets[];
} __attribute__ ((packed));
typedef struct DMLogItemEvdoPilotSetsV2 DMLogItemEvdoPilotSetsV2;
@@ -148,7 +148,7 @@ struct DMLogItemWcdmaTaFingerInfo {
u_int8_t non_coherent_interval_len;
u_int8_t num_paths;
u_int32_t path_enr;
- int32_t pn_pos_path
+ int32_t pn_pos_path;
int16_t pri_cpich_psc;
u_int8_t unknown1;
u_int8_t sec_cpich_ssc;
@@ -214,7 +214,7 @@ typedef struct DMLogItemGsmBurstMetric DMLogItemGsmBurstMetric;
struct DMLogItemGsmBurstMetrics {
u_int8_t channel;
- DMLogItemBurstMetric metrics[4];
+ DMLogItemGsmBurstMetric metrics[4];
} __attribute__ ((packed));
typedef struct DMLogItemGsmBurstMetrics DMLogItemGsmBurstMetrics;
diff --git a/libqcdm/src/logs.c b/libqcdm/src/logs.c
new file mode 100644
index 00000000..ef604f6e
--- /dev/null
+++ b/libqcdm/src/logs.c
@@ -0,0 +1,184 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <endian.h>
+
+#include "log-items.h"
+#include "logs.h"
+#include "errors.h"
+#include "dm-commands.h"
+#include "result-private.h"
+#include "utils.h"
+
+
+/**********************************************************************/
+
+static qcdmbool
+check_log_item (const char *buf, size_t len, u_int16_t log_code, size_t min_len, int *out_error)
+{
+ DMCmdLog *log_cmd = (DMCmdLog *) buf;
+
+ if (len < sizeof (DMCmdLog)) {
+ qcdm_err (0, "DM log item malformed (must be at least %zu bytes in length)", sizeof (DMCmdLog));
+ if (out_error)
+ *out_error = -QCDM_ERROR_RESPONSE_MALFORMED;
+ return FALSE;
+ }
+
+ if (buf[0] != DIAG_CMD_LOG) {
+ if (out_error)
+ *out_error = -QCDM_ERROR_RESPONSE_UNEXPECTED;
+ return FALSE;
+ }
+
+ if (le16toh (log_cmd->log_code) != log_code) {
+ if (out_error)
+ *out_error = -QCDM_ERROR_RESPONSE_UNEXPECTED;
+ return FALSE;
+ }
+
+ if (len < sizeof (DMCmdLog) + min_len) {
+ qcdm_err (0, "DM log item response not long enough (got %zu, expected "
+ "at least %zu).", len, sizeof (DMCmdLog) + min_len);
+ if (out_error)
+ *out_error = -QCDM_ERROR_RESPONSE_BAD_LENGTH;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**********************************************************************/
+
+#define PILOT_SETS_LOG_ACTIVE_SET "active-set"
+#define PILOT_SETS_LOG_CANDIDATE_SET "candidate-set"
+#define PILOT_SETS_LOG_REMAINING_SET "remaining-set"
+
+static const char *
+set_num_to_str (u_int32_t num)
+{
+ if (num == QCDM_LOG_ITEM_EVDO_PILOT_SETS_V2_TYPE_ACTIVE)
+ return PILOT_SETS_LOG_ACTIVE_SET;
+ if (num == QCDM_LOG_ITEM_EVDO_PILOT_SETS_V2_TYPE_CANDIDATE)
+ return PILOT_SETS_LOG_CANDIDATE_SET;
+ if (num == QCDM_LOG_ITEM_EVDO_PILOT_SETS_V2_TYPE_REMAINING)
+ return PILOT_SETS_LOG_REMAINING_SET;
+ return NULL;
+}
+
+QcdmResult *
+qcdm_log_item_evdo_pilot_sets_v2_new (const char *buf, size_t len, int *out_error)
+{
+ QcdmResult *result = NULL;
+ DMLogItemEvdoPilotSetsV2 *pilot_sets;
+ DMCmdLog *log_cmd = (DMCmdLog *) buf;
+ size_t sets_len;
+
+ qcdm_return_val_if_fail (buf != NULL, NULL);
+
+ if (!check_log_item (buf, len, DM_LOG_ITEM_EVDO_PILOT_SETS_V2, sizeof (DMLogItemEvdoPilotSetsV2), out_error))
+ return NULL;
+
+ pilot_sets = (DMLogItemEvdoPilotSetsV2 *) log_cmd->data;
+
+ result = qcdm_result_new ();
+
+ sets_len = pilot_sets->active_count * sizeof (DMLogItemEvdoPilotSetsV2Pilot);
+ if (sets_len > 0) {
+ qcdm_result_add_u8_array (result,
+ PILOT_SETS_LOG_ACTIVE_SET,
+ (const u_int8_t *) &pilot_sets->sets[0],
+ sets_len);
+ }
+
+ sets_len = pilot_sets->candidate_count * sizeof (DMLogItemEvdoPilotSetsV2Pilot);
+ if (sets_len > 0) {
+ qcdm_result_add_u8_array (result,
+ PILOT_SETS_LOG_CANDIDATE_SET,
+ (const u_int8_t *) &pilot_sets->sets[pilot_sets->active_count],
+ sets_len);
+ }
+
+ sets_len = pilot_sets->remaining_count * sizeof (DMLogItemEvdoPilotSetsV2Pilot);
+ if (sets_len > 0) {
+ qcdm_result_add_u8_array (result,
+ PILOT_SETS_LOG_REMAINING_SET,
+ (const u_int8_t *) &pilot_sets->sets[pilot_sets->active_count + pilot_sets->candidate_count],
+ sets_len);
+ }
+
+ return result;
+
+}
+
+qcdmbool
+qcdm_log_item_evdo_pilot_sets_v2_get_num (QcdmResult *result,
+ u_int32_t set_type,
+ u_int32_t *out_num)
+{
+ const char *set_name;
+ const u_int8_t *array = NULL;
+ size_t array_len = 0;
+
+ qcdm_return_val_if_fail (result != NULL, FALSE);
+
+ set_name = set_num_to_str (set_type);
+ qcdm_return_val_if_fail (set_name != NULL, FALSE);
+
+ if (qcdm_result_get_u8_array (result, set_name, &array, &array_len))
+ return FALSE;
+
+ *out_num = array_len / sizeof (DMLogItemEvdoPilotSetsV2Pilot);
+ return TRUE;
+}
+
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+
+qcdmbool
+qcdm_log_item_evdo_pilot_sets_v2_get_pilot (QcdmResult *result,
+ u_int32_t set_type,
+ u_int32_t num,
+ u_int32_t *out_pilot_pn,
+ u_int32_t *out_pilot_energy,
+ int32_t *out_rssi_dbm)
+{
+ const char *set_name;
+ DMLogItemEvdoPilotSetsV2Pilot *pilot;
+ const u_int8_t *array = NULL;
+ size_t array_len = 0;
+
+ qcdm_return_val_if_fail (result != NULL, FALSE);
+
+ set_name = set_num_to_str (set_type);
+ qcdm_return_val_if_fail (set_name != NULL, FALSE);
+
+ if (qcdm_result_get_u8_array (result, set_name, &array, &array_len))
+ return FALSE;
+
+ qcdm_return_val_if_fail (num < array_len / sizeof (DMLogItemEvdoPilotSetsV2Pilot), FALSE);
+
+ pilot = (DMLogItemEvdoPilotSetsV2Pilot *) &array[num * sizeof (DMLogItemEvdoPilotSetsV2Pilot)];
+ *out_pilot_pn = le16toh (pilot->pilot_pn);
+ *out_pilot_energy = le16toh (pilot->pilot_energy);
+ *out_rssi_dbm = (int32_t) (-110.0 + ((float) MAX (le16toh (pilot->pilot_energy) - 50, 0) / 14.0));
+ return TRUE;
+}
+
+/**********************************************************************/
+
diff --git a/libqcdm/src/logs.h b/libqcdm/src/logs.h
new file mode 100644
index 00000000..bb17d1f8
--- /dev/null
+++ b/libqcdm/src/logs.h
@@ -0,0 +1,50 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LIBQCDM_LOGS_H
+#define LIBQCDM_LOGS_H
+
+#include "utils.h"
+#include "result.h"
+
+/**********************************************************************/
+
+enum {
+ QCDM_LOG_ITEM_EVDO_PILOT_SETS_V2_TYPE_UNKNOWN = 0,
+ QCDM_LOG_ITEM_EVDO_PILOT_SETS_V2_TYPE_ACTIVE = 1,
+ QCDM_LOG_ITEM_EVDO_PILOT_SETS_V2_TYPE_CANDIDATE = 2,
+ QCDM_LOG_ITEM_EVDO_PILOT_SETS_V2_TYPE_REMAINING = 3,
+};
+
+QcdmResult *qcdm_log_item_evdo_pilot_sets_v2_new (const char *buf,
+ size_t len,
+ int *out_error);
+
+qcdmbool qcdm_log_item_evdo_pilot_sets_v2_get_num (QcdmResult *result,
+ u_int32_t set_type,
+ u_int32_t *out_num);
+
+qcdmbool qcdm_log_item_evdo_pilot_sets_v2_get_pilot (QcdmResult *result,
+ u_int32_t set_type,
+ u_int32_t num,
+ u_int32_t *out_pilot_pn,
+ u_int32_t *out_pilot_energy,
+ int32_t *out_rssi_dbm);
+
+/**********************************************************************/
+
+#endif /* LIBQCDM_LOGS_H */