broadband-modem-mbim: implement extended signal support with ATDS
This commit is contained in:

committed by
Dan Williams

parent
7a941466c2
commit
ab9130682c
@@ -82,6 +82,7 @@ struct _MMBroadbandModemMbimPrivate {
|
|||||||
gboolean is_pco_supported;
|
gboolean is_pco_supported;
|
||||||
gboolean is_ussd_supported;
|
gboolean is_ussd_supported;
|
||||||
gboolean is_atds_location_supported;
|
gboolean is_atds_location_supported;
|
||||||
|
gboolean is_atds_signal_supported;
|
||||||
|
|
||||||
/* Process unsolicited notifications */
|
/* Process unsolicited notifications */
|
||||||
guint notification_id;
|
guint notification_id;
|
||||||
@@ -1797,7 +1798,9 @@ query_device_services_ready (MbimDevice *device,
|
|||||||
if (device_services[i]->cids[j] == MBIM_CID_ATDS_LOCATION) {
|
if (device_services[i]->cids[j] == MBIM_CID_ATDS_LOCATION) {
|
||||||
mm_dbg ("ATDS location is supported");
|
mm_dbg ("ATDS location is supported");
|
||||||
self->priv->is_atds_location_supported = TRUE;
|
self->priv->is_atds_location_supported = TRUE;
|
||||||
break;
|
} else if (device_services[i]->cids[j] == MBIM_CID_ATDS_SIGNAL) {
|
||||||
|
mm_dbg ("ATDS signal is supported");
|
||||||
|
self->priv->is_atds_signal_supported = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -3333,6 +3336,195 @@ modem_3gpp_scan_networks (MMIfaceModem3gpp *self,
|
|||||||
mbim_message_unref (message);
|
mbim_message_unref (message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Check support (Signal interface) */
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
modem_signal_check_support_finish (MMIfaceModemSignal *self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
return g_task_propagate_boolean (G_TASK (res), error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
modem_signal_check_support (MMIfaceModemSignal *self,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GTask *task;
|
||||||
|
|
||||||
|
task = g_task_new (self, NULL, callback, user_data);
|
||||||
|
g_task_return_boolean (task, MM_BROADBAND_MODEM_MBIM (self)->priv->is_atds_signal_supported);
|
||||||
|
g_object_unref (task);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Load extended signal information (Signal interface) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
MMSignal *gsm;
|
||||||
|
MMSignal *umts;
|
||||||
|
MMSignal *lte;
|
||||||
|
} SignalLoadValuesResult;
|
||||||
|
|
||||||
|
static void
|
||||||
|
signal_load_values_result_free (SignalLoadValuesResult *result)
|
||||||
|
{
|
||||||
|
g_clear_object (&result->gsm);
|
||||||
|
g_clear_object (&result->umts);
|
||||||
|
g_clear_object (&result->lte);
|
||||||
|
g_slice_free (SignalLoadValuesResult, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
modem_signal_load_values_finish (MMIfaceModemSignal *self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
MMSignal **cdma,
|
||||||
|
MMSignal **evdo,
|
||||||
|
MMSignal **gsm,
|
||||||
|
MMSignal **umts,
|
||||||
|
MMSignal **lte,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
SignalLoadValuesResult *result;
|
||||||
|
|
||||||
|
result = g_task_propagate_pointer (G_TASK (res), error);
|
||||||
|
if (!result)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (gsm && result->gsm) {
|
||||||
|
*gsm = result->gsm;
|
||||||
|
result->gsm = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (umts && result->umts) {
|
||||||
|
*umts = result->umts;
|
||||||
|
result->umts = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lte && result->lte) {
|
||||||
|
*lte = result->lte;
|
||||||
|
result->lte = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
signal_load_values_result_free (result);
|
||||||
|
|
||||||
|
/* No 3GPP2 support */
|
||||||
|
if (cdma)
|
||||||
|
*cdma = NULL;
|
||||||
|
if (evdo)
|
||||||
|
*evdo = NULL;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
atds_signal_query_ready (MbimDevice *device,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GTask *task)
|
||||||
|
{
|
||||||
|
MbimMessage *response;
|
||||||
|
SignalLoadValuesResult *result;
|
||||||
|
GError *error = NULL;
|
||||||
|
guint32 rssi;
|
||||||
|
guint32 error_rate;
|
||||||
|
guint32 rscp;
|
||||||
|
guint32 ecno;
|
||||||
|
guint32 rsrq;
|
||||||
|
guint32 rsrp;
|
||||||
|
guint32 snr;
|
||||||
|
|
||||||
|
response = mbim_device_command_finish (device, res, &error);
|
||||||
|
if (!response ||
|
||||||
|
!mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error) ||
|
||||||
|
!mbim_message_atds_signal_response_parse (response, &rssi, &error_rate, &rscp, &ecno, &rsrq, &rsrp, &snr, &error)) {
|
||||||
|
g_task_return_error (task, error);
|
||||||
|
g_object_unref (task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = g_slice_new0 (SignalLoadValuesResult);
|
||||||
|
|
||||||
|
if (rscp <= 96) {
|
||||||
|
result->umts = mm_signal_new ();
|
||||||
|
mm_signal_set_rscp (result->umts, -120.0 + rscp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ecno <= 49) {
|
||||||
|
if (!result->umts)
|
||||||
|
result->umts = mm_signal_new ();
|
||||||
|
mm_signal_set_ecio (result->umts, -24.0 + ((float) ecno / 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rsrq <= 34) {
|
||||||
|
result->lte = mm_signal_new ();
|
||||||
|
mm_signal_set_rsrq (result->lte, -19.5 + ((float) rsrq / 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rsrp <= 97) {
|
||||||
|
if (!result->lte)
|
||||||
|
result->lte = mm_signal_new ();
|
||||||
|
mm_signal_set_rsrp (result->lte, -140.0 + rsrp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (snr <= 35) {
|
||||||
|
if (!result->lte)
|
||||||
|
result->lte = mm_signal_new ();
|
||||||
|
mm_signal_set_snr (result->lte, -5.0 + snr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RSSI may be given for all 2G, 3G or 4G so we detect to which one applies */
|
||||||
|
if (rssi <= 31) {
|
||||||
|
gdouble value;
|
||||||
|
|
||||||
|
value = -113.0 + (2 * rssi);
|
||||||
|
if (result->lte)
|
||||||
|
mm_signal_set_rssi (result->lte, value);
|
||||||
|
else if (result->umts)
|
||||||
|
mm_signal_set_rssi (result->umts, value);
|
||||||
|
else {
|
||||||
|
result->gsm = mm_signal_new ();
|
||||||
|
mm_signal_set_rssi (result->gsm, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result->gsm && !result->umts && !result->lte) {
|
||||||
|
g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
|
||||||
|
"No signal details given");
|
||||||
|
g_object_unref (task);
|
||||||
|
signal_load_values_result_free (result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_task_return_pointer (task, result, (GDestroyNotify) signal_load_values_result_free);
|
||||||
|
g_object_unref (task);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
modem_signal_load_values (MMIfaceModemSignal *self,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MbimDevice *device;
|
||||||
|
MbimMessage *message;
|
||||||
|
GTask *task;
|
||||||
|
|
||||||
|
if (!peek_device (self, &device, callback, user_data))
|
||||||
|
return;
|
||||||
|
|
||||||
|
task = g_task_new (self, NULL, callback, user_data);
|
||||||
|
|
||||||
|
message = mbim_message_atds_signal_query_new (NULL);
|
||||||
|
mbim_device_command (device,
|
||||||
|
message,
|
||||||
|
5,
|
||||||
|
NULL,
|
||||||
|
(GAsyncReadyCallback)atds_signal_query_ready,
|
||||||
|
task);
|
||||||
|
mbim_message_unref (message);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Check support (Messaging interface) */
|
/* Check support (Messaging interface) */
|
||||||
|
|
||||||
@@ -3774,10 +3966,10 @@ iface_modem_messaging_init (MMIfaceModemMessaging *iface)
|
|||||||
static void
|
static void
|
||||||
iface_modem_signal_init (MMIfaceModemSignal *iface)
|
iface_modem_signal_init (MMIfaceModemSignal *iface)
|
||||||
{
|
{
|
||||||
iface->check_support = NULL;
|
iface->check_support = modem_signal_check_support;
|
||||||
iface->check_support_finish = NULL;
|
iface->check_support_finish = modem_signal_check_support_finish;
|
||||||
iface->load_values = NULL;
|
iface->load_values = modem_signal_load_values;
|
||||||
iface->load_values_finish = NULL;
|
iface->load_values_finish = modem_signal_load_values_finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Reference in New Issue
Block a user