
This allows us to skip needing to include the non-existent build_string_from_mask() or get_string() counterparts in the documentation index.
250 lines
7.1 KiB
C
250 lines
7.1 KiB
C
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* libmm-glib -- Access modem status & information from glib applications
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library 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
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the
|
|
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301 USA.
|
|
*
|
|
* Copyright (C) 2022 Aleksander Morgado <aleksander@aleksander.es>
|
|
*/
|
|
|
|
#include "mm-cell-info.h"
|
|
#include "mm-cell-info-cdma.h"
|
|
#include "mm-cell-info-gsm.h"
|
|
#include "mm-cell-info-umts.h"
|
|
#include "mm-cell-info-tdscdma.h"
|
|
#include "mm-cell-info-lte.h"
|
|
#include "mm-cell-info-nr5g.h"
|
|
|
|
#include "mm-enums-types.h"
|
|
#include "mm-flags-types.h"
|
|
#include "mm-errors-types.h"
|
|
|
|
/**
|
|
* SECTION: mm-cell-info
|
|
* @title: MMCellInfo
|
|
* @short_description: Helper base object to report cell info
|
|
*
|
|
* The #MMCellInfo is a base object used to report cell information.
|
|
*
|
|
* This object is retrieved from the #MMModem object with
|
|
* mm_modem_get_cell_info() or mm_modem_get_cell_info_sync().
|
|
*/
|
|
|
|
G_DEFINE_TYPE (MMCellInfo, mm_cell_info, G_TYPE_OBJECT)
|
|
|
|
#define PROPERTY_CELL_TYPE "cell-type"
|
|
#define PROPERTY_SERVING "serving"
|
|
|
|
struct _MMCellInfoPrivate {
|
|
MMCellType cell_type;
|
|
gboolean serving;
|
|
};
|
|
|
|
/*****************************************************************************/
|
|
|
|
static void
|
|
ensure_cell_type (MMCellInfo *self)
|
|
{
|
|
if (self->priv->cell_type != MM_CELL_TYPE_UNKNOWN)
|
|
return;
|
|
|
|
if (MM_IS_CELL_INFO_CDMA (self))
|
|
self->priv->cell_type = MM_CELL_TYPE_CDMA;
|
|
else if (MM_IS_CELL_INFO_GSM (self))
|
|
self->priv->cell_type = MM_CELL_TYPE_GSM;
|
|
else if (MM_IS_CELL_INFO_UMTS (self))
|
|
self->priv->cell_type = MM_CELL_TYPE_UMTS;
|
|
else if (MM_IS_CELL_INFO_TDSCDMA (self))
|
|
self->priv->cell_type = MM_CELL_TYPE_TDSCDMA;
|
|
else if (MM_IS_CELL_INFO_LTE (self))
|
|
self->priv->cell_type = MM_CELL_TYPE_LTE;
|
|
else if (MM_IS_CELL_INFO_NR5G (self))
|
|
self->priv->cell_type = MM_CELL_TYPE_5GNR;
|
|
}
|
|
|
|
/**
|
|
* mm_cell_info_get_cell_type:
|
|
* @self: a #MMCellInfo.
|
|
*
|
|
* Get the type of cell.
|
|
*
|
|
* Returns: a #MMCellType.
|
|
*
|
|
* Since: 1.20
|
|
*/
|
|
MMCellType
|
|
mm_cell_info_get_cell_type (MMCellInfo *self)
|
|
{
|
|
g_return_val_if_fail (MM_IS_CELL_INFO (self), MM_CELL_TYPE_UNKNOWN);
|
|
|
|
ensure_cell_type (self);
|
|
|
|
return self->priv->cell_type;
|
|
}
|
|
|
|
/**
|
|
* mm_cell_info_get_serving:
|
|
* @self: a #MMCellInfo.
|
|
*
|
|
* Get whether the cell is a serving cell or a neighboring cell.a
|
|
*
|
|
* Returns: %TRUE if the cell is a serving cell, %FALSE otherwise.
|
|
*
|
|
* Since: 1.20
|
|
*/
|
|
gboolean
|
|
mm_cell_info_get_serving (MMCellInfo *self)
|
|
{
|
|
g_return_val_if_fail (MM_IS_CELL_INFO (self), FALSE);
|
|
|
|
return self->priv->serving;
|
|
}
|
|
|
|
/**
|
|
* mm_cell_info_set_serving: (skip)
|
|
*/
|
|
void
|
|
mm_cell_info_set_serving (MMCellInfo *self,
|
|
gboolean serving)
|
|
{
|
|
g_return_if_fail (MM_IS_CELL_INFO (self));
|
|
|
|
self->priv->serving = serving;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
/**
|
|
* mm_cell_info_get_dictionary: (skip)
|
|
*/
|
|
GVariant *
|
|
mm_cell_info_get_dictionary (MMCellInfo *self)
|
|
{
|
|
g_autoptr(GVariantDict) dict = NULL;
|
|
|
|
dict = MM_CELL_INFO_GET_CLASS (self)->get_dictionary (self);
|
|
g_assert (dict);
|
|
|
|
g_variant_dict_insert_value (dict, PROPERTY_SERVING, g_variant_new_boolean (self->priv->serving));
|
|
g_variant_dict_insert_value (dict, PROPERTY_CELL_TYPE, g_variant_new_uint32 (mm_cell_info_get_cell_type (self)));
|
|
|
|
return g_variant_ref_sink (g_variant_dict_end (dict));
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
/**
|
|
* mm_cell_info_new_from_dictionary: (skip)
|
|
*/
|
|
MMCellInfo *
|
|
mm_cell_info_new_from_dictionary (GVariant *dictionary,
|
|
GError **error)
|
|
{
|
|
g_autoptr(MMCellInfo) self = NULL;
|
|
g_autoptr(GVariantDict) dict = NULL;
|
|
GVariant *aux;
|
|
|
|
dict = g_variant_dict_new (dictionary);
|
|
|
|
aux = g_variant_dict_lookup_value (dict, PROPERTY_CELL_TYPE, G_VARIANT_TYPE_UINT32);
|
|
if (!aux) {
|
|
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS,
|
|
"missing '" PROPERTY_CELL_TYPE "' key in cell info");
|
|
return NULL;
|
|
}
|
|
switch (g_variant_get_uint32 (aux)) {
|
|
case MM_CELL_TYPE_CDMA:
|
|
self = mm_cell_info_cdma_new_from_dictionary (dict);
|
|
break;
|
|
case MM_CELL_TYPE_GSM:
|
|
self = mm_cell_info_gsm_new_from_dictionary (dict);
|
|
break;
|
|
case MM_CELL_TYPE_UMTS:
|
|
self = mm_cell_info_umts_new_from_dictionary (dict);
|
|
break;
|
|
case MM_CELL_TYPE_TDSCDMA:
|
|
self = mm_cell_info_tdscdma_new_from_dictionary (dict);
|
|
break;
|
|
case MM_CELL_TYPE_LTE:
|
|
self = mm_cell_info_lte_new_from_dictionary (dict);
|
|
break;
|
|
case MM_CELL_TYPE_5GNR:
|
|
self = mm_cell_info_nr5g_new_from_dictionary (dict);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
g_variant_unref (aux);
|
|
|
|
if (!self) {
|
|
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS,
|
|
"unknown '" PROPERTY_CELL_TYPE "' key value in cell info");
|
|
return NULL;
|
|
}
|
|
|
|
aux = g_variant_dict_lookup_value (dict, PROPERTY_SERVING, G_VARIANT_TYPE_BOOLEAN);
|
|
if (aux) {
|
|
mm_cell_info_set_serving (self, g_variant_get_boolean (aux));
|
|
g_variant_unref (aux);
|
|
}
|
|
|
|
return g_steal_pointer (&self);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
/**
|
|
* mm_cell_info_build_string: (skip)
|
|
*/
|
|
gchar *
|
|
mm_cell_info_build_string (MMCellInfo *self)
|
|
{
|
|
GString *str;
|
|
GString *substr;
|
|
|
|
substr = MM_CELL_INFO_GET_CLASS (self)->build_string (self);
|
|
g_assert (substr);
|
|
|
|
ensure_cell_type (self);
|
|
|
|
str = g_string_new (NULL);
|
|
g_string_append_printf (str, "cell type: %s, serving: %s",
|
|
mm_cell_type_get_string (self->priv->cell_type),
|
|
self->priv->serving ? "yes" : "no");
|
|
g_string_append_len (str, substr->str, (gssize)substr->len);
|
|
|
|
g_string_free (substr, TRUE);
|
|
|
|
return g_string_free (str, FALSE);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
static void
|
|
mm_cell_info_init (MMCellInfo *self)
|
|
{
|
|
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MM_TYPE_CELL_INFO, MMCellInfoPrivate);
|
|
self->priv->cell_type = MM_CELL_TYPE_UNKNOWN;
|
|
}
|
|
|
|
static void
|
|
mm_cell_info_class_init (MMCellInfoClass *klass)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
g_type_class_add_private (object_class, sizeof (MMCellInfoPrivate));
|
|
}
|