/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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: * * Copyright (C) 2012-2018 Google, Inc. * Copyright (C) 2018 Aleksander Morgado */ #include #include #include #include "mm-modem-helpers-qmi.h" #include "mm-enums-types.h" #include "mm-log.h" /*****************************************************************************/ MMModemCapability mm_modem_capability_from_qmi_radio_interface (QmiDmsRadioInterface network) { switch (network) { case QMI_DMS_RADIO_INTERFACE_CDMA20001X: return MM_MODEM_CAPABILITY_CDMA_EVDO; case QMI_DMS_RADIO_INTERFACE_EVDO: return MM_MODEM_CAPABILITY_CDMA_EVDO; case QMI_DMS_RADIO_INTERFACE_GSM: return MM_MODEM_CAPABILITY_GSM_UMTS; case QMI_DMS_RADIO_INTERFACE_UMTS: return MM_MODEM_CAPABILITY_GSM_UMTS; case QMI_DMS_RADIO_INTERFACE_LTE: return MM_MODEM_CAPABILITY_LTE; default: mm_warn ("Unhandled QMI radio interface (%u)", (guint)network); return MM_MODEM_CAPABILITY_NONE; } } /*****************************************************************************/ MMModemMode mm_modem_mode_from_qmi_radio_interface (QmiDmsRadioInterface network) { switch (network) { case QMI_DMS_RADIO_INTERFACE_CDMA20001X: return MM_MODEM_MODE_2G; case QMI_DMS_RADIO_INTERFACE_EVDO: return MM_MODEM_MODE_3G; case QMI_DMS_RADIO_INTERFACE_GSM: return MM_MODEM_MODE_2G; case QMI_DMS_RADIO_INTERFACE_UMTS: return MM_MODEM_MODE_3G; case QMI_DMS_RADIO_INTERFACE_LTE: return MM_MODEM_MODE_4G; default: mm_warn ("Unhandled QMI radio interface (%u)", (guint)network); return MM_MODEM_MODE_NONE; } } /*****************************************************************************/ /* pin1 TRUE for PIN1, FALSE for PIN2 */ MMModemLock mm_modem_lock_from_qmi_uim_pin_status (QmiDmsUimPinStatus status, gboolean pin1) { switch (status) { case QMI_DMS_UIM_PIN_STATUS_NOT_INITIALIZED: return MM_MODEM_LOCK_UNKNOWN; case QMI_DMS_UIM_PIN_STATUS_ENABLED_NOT_VERIFIED: return pin1 ? MM_MODEM_LOCK_SIM_PIN : MM_MODEM_LOCK_SIM_PIN2; case QMI_DMS_UIM_PIN_STATUS_ENABLED_VERIFIED: return MM_MODEM_LOCK_NONE; case QMI_DMS_UIM_PIN_STATUS_DISABLED: return MM_MODEM_LOCK_NONE; case QMI_DMS_UIM_PIN_STATUS_BLOCKED: return pin1 ? MM_MODEM_LOCK_SIM_PUK : MM_MODEM_LOCK_SIM_PUK2; case QMI_DMS_UIM_PIN_STATUS_PERMANENTLY_BLOCKED: return MM_MODEM_LOCK_UNKNOWN; case QMI_DMS_UIM_PIN_STATUS_UNBLOCKED: /* This state is possibly given when after an Unblock() operation has been performed. * We'll assume the PIN is verified after this. */ return MM_MODEM_LOCK_NONE; case QMI_DMS_UIM_PIN_STATUS_CHANGED: /* This state is possibly given when after an ChangePin() operation has been performed. * We'll assume the PIN is verified after this. */ return MM_MODEM_LOCK_NONE; default: return MM_MODEM_LOCK_UNKNOWN; } } /*****************************************************************************/ gboolean mm_pin_enabled_from_qmi_uim_pin_status (QmiDmsUimPinStatus status) { switch (status) { case QMI_DMS_UIM_PIN_STATUS_ENABLED_NOT_VERIFIED: case QMI_DMS_UIM_PIN_STATUS_ENABLED_VERIFIED: case QMI_DMS_UIM_PIN_STATUS_BLOCKED: case QMI_DMS_UIM_PIN_STATUS_PERMANENTLY_BLOCKED: case QMI_DMS_UIM_PIN_STATUS_UNBLOCKED: case QMI_DMS_UIM_PIN_STATUS_CHANGED: /* assume the PIN to be enabled then */ return TRUE; case QMI_DMS_UIM_PIN_STATUS_DISABLED: case QMI_DMS_UIM_PIN_STATUS_NOT_INITIALIZED: /* assume the PIN to be disabled then */ return FALSE; default: /* by default assume disabled */ return FALSE; } } /*****************************************************************************/ QmiDmsUimFacility mm_3gpp_facility_to_qmi_uim_facility (MMModem3gppFacility mm) { switch (mm) { case MM_MODEM_3GPP_FACILITY_PH_SIM: /* Not really sure about this one; it may be PH_FSIM? */ return QMI_DMS_UIM_FACILITY_PF; case MM_MODEM_3GPP_FACILITY_NET_PERS: return QMI_DMS_UIM_FACILITY_PN; case MM_MODEM_3GPP_FACILITY_NET_SUB_PERS: return QMI_DMS_UIM_FACILITY_PU; case MM_MODEM_3GPP_FACILITY_PROVIDER_PERS: return QMI_DMS_UIM_FACILITY_PP; case MM_MODEM_3GPP_FACILITY_CORP_PERS: return QMI_DMS_UIM_FACILITY_PC; default: /* Never try to ask for a facility we cannot translate */ g_assert_not_reached (); } } /*****************************************************************************/ typedef struct { QmiDmsBandCapability qmi_band; MMModemBand mm_band; } DmsBandsMap; static const DmsBandsMap dms_bands_map [] = { /* CDMA bands */ { (QMI_DMS_BAND_CAPABILITY_BC_0_A_SYSTEM | QMI_DMS_BAND_CAPABILITY_BC_0_B_SYSTEM), MM_MODEM_BAND_CDMA_BC0 }, { QMI_DMS_BAND_CAPABILITY_BC_1_ALL_BLOCKS, MM_MODEM_BAND_CDMA_BC1 }, { QMI_DMS_BAND_CAPABILITY_BC_2, MM_MODEM_BAND_CDMA_BC2 }, { QMI_DMS_BAND_CAPABILITY_BC_3_A_SYSTEM, MM_MODEM_BAND_CDMA_BC3 }, { QMI_DMS_BAND_CAPABILITY_BC_4_ALL_BLOCKS, MM_MODEM_BAND_CDMA_BC4 }, { QMI_DMS_BAND_CAPABILITY_BC_5_ALL_BLOCKS, MM_MODEM_BAND_CDMA_BC5 }, { QMI_DMS_BAND_CAPABILITY_BC_6, MM_MODEM_BAND_CDMA_BC6 }, { QMI_DMS_BAND_CAPABILITY_BC_7, MM_MODEM_BAND_CDMA_BC7 }, { QMI_DMS_BAND_CAPABILITY_BC_8, MM_MODEM_BAND_CDMA_BC8 }, { QMI_DMS_BAND_CAPABILITY_BC_9, MM_MODEM_BAND_CDMA_BC9 }, { QMI_DMS_BAND_CAPABILITY_BC_10, MM_MODEM_BAND_CDMA_BC10 }, { QMI_DMS_BAND_CAPABILITY_BC_11, MM_MODEM_BAND_CDMA_BC11 }, { QMI_DMS_BAND_CAPABILITY_BC_12, MM_MODEM_BAND_CDMA_BC12 }, { QMI_DMS_BAND_CAPABILITY_BC_14, MM_MODEM_BAND_CDMA_BC14 }, { QMI_DMS_BAND_CAPABILITY_BC_15, MM_MODEM_BAND_CDMA_BC15 }, { QMI_DMS_BAND_CAPABILITY_BC_16, MM_MODEM_BAND_CDMA_BC16 }, { QMI_DMS_BAND_CAPABILITY_BC_17, MM_MODEM_BAND_CDMA_BC17 }, { QMI_DMS_BAND_CAPABILITY_BC_18, MM_MODEM_BAND_CDMA_BC18 }, { QMI_DMS_BAND_CAPABILITY_BC_19, MM_MODEM_BAND_CDMA_BC19 }, /* GSM bands */ { QMI_DMS_BAND_CAPABILITY_GSM_DCS_1800, MM_MODEM_BAND_DCS }, { (QMI_DMS_BAND_CAPABILITY_GSM_900_PRIMARY | QMI_DMS_BAND_CAPABILITY_GSM_900_EXTENDED), MM_MODEM_BAND_EGSM }, { QMI_DMS_BAND_CAPABILITY_GSM_PCS_1900, MM_MODEM_BAND_PCS }, { QMI_DMS_BAND_CAPABILITY_GSM_850, MM_MODEM_BAND_G850 }, { QMI_DMS_BAND_CAPABILITY_GSM_450, MM_MODEM_BAND_G450 }, { QMI_DMS_BAND_CAPABILITY_GSM_480, MM_MODEM_BAND_G480 }, { QMI_DMS_BAND_CAPABILITY_GSM_750, MM_MODEM_BAND_G750 }, /* UMTS/WCDMA bands */ { QMI_DMS_BAND_CAPABILITY_WCDMA_2100, MM_MODEM_BAND_UTRAN_1 }, { QMI_DMS_BAND_CAPABILITY_WCDMA_DCS_1800, MM_MODEM_BAND_UTRAN_3 }, { QMI_DMS_BAND_CAPABILITY_WCDMA_PCS_1900, MM_MODEM_BAND_UTRAN_2 }, { QMI_DMS_BAND_CAPABILITY_WCDMA_1700_US, MM_MODEM_BAND_UTRAN_4 }, { QMI_DMS_BAND_CAPABILITY_WCDMA_800, MM_MODEM_BAND_UTRAN_6 }, { QMI_DMS_BAND_CAPABILITY_WCDMA_850_US, MM_MODEM_BAND_UTRAN_5 }, { QMI_DMS_BAND_CAPABILITY_WCDMA_900, MM_MODEM_BAND_UTRAN_8 }, { QMI_DMS_BAND_CAPABILITY_WCDMA_1700_JAPAN, MM_MODEM_BAND_UTRAN_9 }, { QMI_DMS_BAND_CAPABILITY_WCDMA_2600, MM_MODEM_BAND_UTRAN_7 }, { QMI_DMS_BAND_CAPABILITY_WCDMA_1500, MM_MODEM_BAND_UTRAN_11 }, { QMI_DMS_BAND_CAPABILITY_WCDMA_850_JAPAN, MM_MODEM_BAND_UTRAN_19 }, }; static void dms_add_qmi_bands (GArray *mm_bands, QmiDmsBandCapability qmi_bands) { static QmiDmsBandCapability qmi_bands_expected = 0; QmiDmsBandCapability not_expected; guint i; g_assert (mm_bands != NULL); /* Build mask of expected bands only once */ if (G_UNLIKELY (qmi_bands_expected == 0)) { for (i = 0; i < G_N_ELEMENTS (dms_bands_map); i++) { qmi_bands_expected |= dms_bands_map[i].qmi_band; } } /* Log about the bands that cannot be represented in ModemManager */ not_expected = ((qmi_bands_expected ^ qmi_bands) & qmi_bands); if (not_expected) { gchar *aux; aux = qmi_dms_band_capability_build_string_from_mask (not_expected); mm_dbg ("Cannot add the following bands: '%s'", aux); g_free (aux); } /* And add the expected ones */ for (i = 0; i < G_N_ELEMENTS (dms_bands_map); i++) { if (qmi_bands & dms_bands_map[i].qmi_band) g_array_append_val (mm_bands, dms_bands_map[i].mm_band); } } typedef struct { QmiDmsLteBandCapability qmi_band; MMModemBand mm_band; } DmsLteBandsMap; static const DmsLteBandsMap dms_lte_bands_map [] = { { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_1, MM_MODEM_BAND_EUTRAN_1 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_2, MM_MODEM_BAND_EUTRAN_2 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_3, MM_MODEM_BAND_EUTRAN_3 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_4, MM_MODEM_BAND_EUTRAN_4 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_5, MM_MODEM_BAND_EUTRAN_5 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_6, MM_MODEM_BAND_EUTRAN_6 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_7, MM_MODEM_BAND_EUTRAN_7 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_8, MM_MODEM_BAND_EUTRAN_8 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_9, MM_MODEM_BAND_EUTRAN_9 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_10, MM_MODEM_BAND_EUTRAN_10 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_11, MM_MODEM_BAND_EUTRAN_11 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_12, MM_MODEM_BAND_EUTRAN_12 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_13, MM_MODEM_BAND_EUTRAN_13 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_14, MM_MODEM_BAND_EUTRAN_14 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_17, MM_MODEM_BAND_EUTRAN_17 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_18, MM_MODEM_BAND_EUTRAN_18 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_19, MM_MODEM_BAND_EUTRAN_19 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_20, MM_MODEM_BAND_EUTRAN_20 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_21, MM_MODEM_BAND_EUTRAN_21 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_24, MM_MODEM_BAND_EUTRAN_24 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_25, MM_MODEM_BAND_EUTRAN_25 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_33, MM_MODEM_BAND_EUTRAN_33 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_34, MM_MODEM_BAND_EUTRAN_34 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_35, MM_MODEM_BAND_EUTRAN_35 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_36, MM_MODEM_BAND_EUTRAN_36 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_37, MM_MODEM_BAND_EUTRAN_37 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_38, MM_MODEM_BAND_EUTRAN_38 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_39, MM_MODEM_BAND_EUTRAN_39 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_40, MM_MODEM_BAND_EUTRAN_40 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_41, MM_MODEM_BAND_EUTRAN_41 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_42, MM_MODEM_BAND_EUTRAN_42 }, { QMI_DMS_LTE_BAND_CAPABILITY_EUTRAN_43, MM_MODEM_BAND_EUTRAN_43 } }; static void dms_add_qmi_lte_bands (GArray *mm_bands, QmiDmsLteBandCapability qmi_bands) { /* All QMI LTE bands have a counterpart in ModemManager, no need to check * for unexpected ones */ guint i; g_assert (mm_bands != NULL); for (i = 0; i < G_N_ELEMENTS (dms_lte_bands_map); i++) { if (qmi_bands & dms_lte_bands_map[i].qmi_band) g_array_append_val (mm_bands, dms_lte_bands_map[i].mm_band); } } static void dms_add_extended_qmi_lte_bands (GArray *mm_bands, GArray *extended_qmi_bands) { guint i; g_assert (mm_bands != NULL); if (!extended_qmi_bands) return; for (i = 0; i < extended_qmi_bands->len; i++) { guint16 val; val = g_array_index (extended_qmi_bands, guint16, i); /* MM_MODEM_BAND_EUTRAN_1 = 31, * ... * MM_MODEM_BAND_EUTRAN_71 = 101 */ if (val < 1 || val > 71) mm_dbg ("Unexpected LTE band supported by module: EUTRAN %u", val); else { MMModemBand band; band = (MMModemBand)(val + MM_MODEM_BAND_EUTRAN_1 - 1); g_array_append_val (mm_bands, band); } } } GArray * mm_modem_bands_from_qmi_band_capabilities (QmiDmsBandCapability qmi_bands, QmiDmsLteBandCapability qmi_lte_bands, GArray *extended_qmi_lte_bands) { GArray *mm_bands; mm_bands = g_array_new (FALSE, FALSE, sizeof (MMModemBand)); dms_add_qmi_bands (mm_bands, qmi_bands); if (extended_qmi_lte_bands) dms_add_extended_qmi_lte_bands (mm_bands, extended_qmi_lte_bands); else dms_add_qmi_lte_bands (mm_bands, qmi_lte_bands); return mm_bands; } /*****************************************************************************/ typedef struct { QmiNasBandPreference qmi_band; MMModemBand mm_band; } NasBandsMap; static const NasBandsMap nas_bands_map [] = { /* CDMA bands */ { (QMI_NAS_BAND_PREFERENCE_BC_0_A_SYSTEM | QMI_NAS_BAND_PREFERENCE_BC_0_B_SYSTEM), MM_MODEM_BAND_CDMA_BC0 }, { QMI_NAS_BAND_PREFERENCE_BC_1_ALL_BLOCKS, MM_MODEM_BAND_CDMA_BC1 }, { QMI_NAS_BAND_PREFERENCE_BC_2, MM_MODEM_BAND_CDMA_BC2 }, { QMI_NAS_BAND_PREFERENCE_BC_3_A_SYSTEM, MM_MODEM_BAND_CDMA_BC3 }, { QMI_NAS_BAND_PREFERENCE_BC_4_ALL_BLOCKS, MM_MODEM_BAND_CDMA_BC4 }, { QMI_NAS_BAND_PREFERENCE_BC_5_ALL_BLOCKS, MM_MODEM_BAND_CDMA_BC5 }, { QMI_NAS_BAND_PREFERENCE_BC_6, MM_MODEM_BAND_CDMA_BC6 }, { QMI_NAS_BAND_PREFERENCE_BC_7, MM_MODEM_BAND_CDMA_BC7 }, { QMI_NAS_BAND_PREFERENCE_BC_8, MM_MODEM_BAND_CDMA_BC8 }, { QMI_NAS_BAND_PREFERENCE_BC_9, MM_MODEM_BAND_CDMA_BC9 }, { QMI_NAS_BAND_PREFERENCE_BC_10, MM_MODEM_BAND_CDMA_BC10 }, { QMI_NAS_BAND_PREFERENCE_BC_11, MM_MODEM_BAND_CDMA_BC11 }, { QMI_NAS_BAND_PREFERENCE_BC_12, MM_MODEM_BAND_CDMA_BC12 }, { QMI_NAS_BAND_PREFERENCE_BC_14, MM_MODEM_BAND_CDMA_BC14 }, { QMI_NAS_BAND_PREFERENCE_BC_15, MM_MODEM_BAND_CDMA_BC15 }, { QMI_NAS_BAND_PREFERENCE_BC_16, MM_MODEM_BAND_CDMA_BC16 }, { QMI_NAS_BAND_PREFERENCE_BC_17, MM_MODEM_BAND_CDMA_BC17 }, { QMI_NAS_BAND_PREFERENCE_BC_18, MM_MODEM_BAND_CDMA_BC18 }, { QMI_NAS_BAND_PREFERENCE_BC_19, MM_MODEM_BAND_CDMA_BC19 }, /* GSM bands */ { QMI_NAS_BAND_PREFERENCE_GSM_DCS_1800, MM_MODEM_BAND_DCS }, { (QMI_NAS_BAND_PREFERENCE_GSM_900_PRIMARY | QMI_NAS_BAND_PREFERENCE_GSM_900_EXTENDED), MM_MODEM_BAND_EGSM }, { QMI_NAS_BAND_PREFERENCE_GSM_PCS_1900, MM_MODEM_BAND_PCS }, { QMI_NAS_BAND_PREFERENCE_GSM_850, MM_MODEM_BAND_G850 }, { QMI_NAS_BAND_PREFERENCE_GSM_450, MM_MODEM_BAND_G450 }, { QMI_NAS_BAND_PREFERENCE_GSM_480, MM_MODEM_BAND_G480 }, { QMI_NAS_BAND_PREFERENCE_GSM_750, MM_MODEM_BAND_G750 }, /* UMTS/WCDMA bands */ { QMI_NAS_BAND_PREFERENCE_WCDMA_2100, MM_MODEM_BAND_UTRAN_1 }, { QMI_NAS_BAND_PREFERENCE_WCDMA_DCS_1800, MM_MODEM_BAND_UTRAN_3 }, { QMI_NAS_BAND_PREFERENCE_WCDMA_PCS_1900, MM_MODEM_BAND_UTRAN_2 }, { QMI_NAS_BAND_PREFERENCE_WCDMA_1700_US, MM_MODEM_BAND_UTRAN_4 }, { QMI_NAS_BAND_PREFERENCE_WCDMA_800, MM_MODEM_BAND_UTRAN_6 }, { QMI_NAS_BAND_PREFERENCE_WCDMA_850_US, MM_MODEM_BAND_UTRAN_5 }, { QMI_NAS_BAND_PREFERENCE_WCDMA_900, MM_MODEM_BAND_UTRAN_8 }, { QMI_NAS_BAND_PREFERENCE_WCDMA_1700_JAPAN, MM_MODEM_BAND_UTRAN_9 }, { QMI_NAS_BAND_PREFERENCE_WCDMA_2600, MM_MODEM_BAND_UTRAN_7 }, { QMI_NAS_BAND_PREFERENCE_WCDMA_1500, MM_MODEM_BAND_UTRAN_11 }, { QMI_NAS_BAND_PREFERENCE_WCDMA_850_JAPAN, MM_MODEM_BAND_UTRAN_19 }, }; static void nas_add_qmi_bands (GArray *mm_bands, QmiNasBandPreference qmi_bands) { static QmiNasBandPreference qmi_bands_expected = 0; QmiNasBandPreference not_expected; guint i; g_assert (mm_bands != NULL); /* Build mask of expected bands only once */ if (G_UNLIKELY (qmi_bands_expected == 0)) { for (i = 0; i < G_N_ELEMENTS (nas_bands_map); i++) { qmi_bands_expected |= nas_bands_map[i].qmi_band; } } /* Log about the bands that cannot be represented in ModemManager */ not_expected = ((qmi_bands_expected ^ qmi_bands) & qmi_bands); if (not_expected) { gchar *aux; aux = qmi_nas_band_preference_build_string_from_mask (not_expected); mm_dbg ("Cannot add the following bands: '%s'", aux); g_free (aux); } /* And add the expected ones */ for (i = 0; i < G_N_ELEMENTS (nas_bands_map); i++) { if (qmi_bands & nas_bands_map[i].qmi_band) g_array_append_val (mm_bands, nas_bands_map[i].mm_band); } } typedef struct { QmiNasLteBandPreference qmi_band; MMModemBand mm_band; } NasLteBandsMap; static const NasLteBandsMap nas_lte_bands_map [] = { { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_1, MM_MODEM_BAND_EUTRAN_1 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_2, MM_MODEM_BAND_EUTRAN_2 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_3, MM_MODEM_BAND_EUTRAN_3 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_4, MM_MODEM_BAND_EUTRAN_4 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_5, MM_MODEM_BAND_EUTRAN_5 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_6, MM_MODEM_BAND_EUTRAN_6 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_7, MM_MODEM_BAND_EUTRAN_7 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_8, MM_MODEM_BAND_EUTRAN_8 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_9, MM_MODEM_BAND_EUTRAN_9 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_10, MM_MODEM_BAND_EUTRAN_10 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_11, MM_MODEM_BAND_EUTRAN_11 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_12, MM_MODEM_BAND_EUTRAN_12 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_13, MM_MODEM_BAND_EUTRAN_13 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_14, MM_MODEM_BAND_EUTRAN_14 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_17, MM_MODEM_BAND_EUTRAN_17 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_18, MM_MODEM_BAND_EUTRAN_18 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_19, MM_MODEM_BAND_EUTRAN_19 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_20, MM_MODEM_BAND_EUTRAN_20 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_21, MM_MODEM_BAND_EUTRAN_21 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_24, MM_MODEM_BAND_EUTRAN_24 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_25, MM_MODEM_BAND_EUTRAN_25 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_33, MM_MODEM_BAND_EUTRAN_33 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_34, MM_MODEM_BAND_EUTRAN_34 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_35, MM_MODEM_BAND_EUTRAN_35 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_36, MM_MODEM_BAND_EUTRAN_36 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_37, MM_MODEM_BAND_EUTRAN_37 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_38, MM_MODEM_BAND_EUTRAN_38 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_39, MM_MODEM_BAND_EUTRAN_39 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_40, MM_MODEM_BAND_EUTRAN_40 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_41, MM_MODEM_BAND_EUTRAN_41 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_42, MM_MODEM_BAND_EUTRAN_42 }, { QMI_NAS_LTE_BAND_PREFERENCE_EUTRAN_43, MM_MODEM_BAND_EUTRAN_43 } }; static void nas_add_qmi_lte_bands (GArray *mm_bands, QmiNasLteBandPreference qmi_bands) { /* All QMI LTE bands have a counterpart in ModemManager, no need to check * for unexpected ones */ guint i; g_assert (mm_bands != NULL); for (i = 0; i < G_N_ELEMENTS (nas_lte_bands_map); i++) { if (qmi_bands & nas_lte_bands_map[i].qmi_band) g_array_append_val (mm_bands, nas_lte_bands_map[i].mm_band); } } static void nas_add_extended_qmi_lte_bands (GArray *mm_bands, const guint64 *extended_qmi_lte_bands, guint extended_qmi_lte_bands_size) { guint i; g_assert (mm_bands != NULL); for (i = 0; i < extended_qmi_lte_bands_size; i++) { guint j; for (j = 0; j < 64; j++) { guint val; if (!(extended_qmi_lte_bands[i] & (((guint64) 1) << j))) continue; val = 1 + j + (i * 64); /* MM_MODEM_BAND_EUTRAN_1 = 31, * ... * MM_MODEM_BAND_EUTRAN_71 = 101 */ if (val < 1 || val > 71) mm_dbg ("Unexpected LTE band supported by module: EUTRAN %u", val); else { MMModemBand band; band = (val + MM_MODEM_BAND_EUTRAN_1 - 1); g_array_append_val (mm_bands, band); } } } } GArray * mm_modem_bands_from_qmi_band_preference (QmiNasBandPreference qmi_bands, QmiNasLteBandPreference qmi_lte_bands, const guint64 *extended_qmi_lte_bands, guint extended_qmi_lte_bands_size) { GArray *mm_bands; mm_bands = g_array_new (FALSE, FALSE, sizeof (MMModemBand)); nas_add_qmi_bands (mm_bands, qmi_bands); if (extended_qmi_lte_bands && extended_qmi_lte_bands_size) nas_add_extended_qmi_lte_bands (mm_bands, extended_qmi_lte_bands, extended_qmi_lte_bands_size); else nas_add_qmi_lte_bands (mm_bands, qmi_lte_bands); return mm_bands; } void mm_modem_bands_to_qmi_band_preference (GArray *mm_bands, QmiNasBandPreference *qmi_bands, QmiNasLteBandPreference *qmi_lte_bands, guint64 *extended_qmi_lte_bands, guint extended_qmi_lte_bands_size) { guint i; *qmi_bands = 0; *qmi_lte_bands = 0; memset (extended_qmi_lte_bands, 0, extended_qmi_lte_bands_size * sizeof (guint64)); for (i = 0; i < mm_bands->len; i++) { MMModemBand band; band = g_array_index (mm_bands, MMModemBand, i); if (band >= MM_MODEM_BAND_EUTRAN_1 && band <= MM_MODEM_BAND_EUTRAN_71) { if (extended_qmi_lte_bands && extended_qmi_lte_bands_size) { /* Add extended LTE band preference */ guint val; guint j; guint k; /* it's really (band - MM_MODEM_BAND_EUTRAN_1 +1 -1), because * we want EUTRAN1 in index 0 */ val = band - MM_MODEM_BAND_EUTRAN_1; j = val / 64; g_assert (j < extended_qmi_lte_bands_size); k = val % 64; extended_qmi_lte_bands[j] |= ((guint64)1 << k); } else { /* Add LTE band preference */ guint j; for (j = 0; j < G_N_ELEMENTS (nas_lte_bands_map); j++) { if (nas_lte_bands_map[j].mm_band == band) { *qmi_lte_bands |= nas_lte_bands_map[j].qmi_band; break; } } if (j == G_N_ELEMENTS (nas_lte_bands_map)) mm_dbg ("Cannot add the following LTE band: '%s'", mm_modem_band_get_string (band)); } } else { /* Add non-LTE band preference */ guint j; for (j = 0; j < G_N_ELEMENTS (nas_bands_map); j++) { if (nas_bands_map[j].mm_band == band) { *qmi_bands |= nas_bands_map[j].qmi_band; break; } } if (j == G_N_ELEMENTS (nas_bands_map)) mm_dbg ("Cannot add the following band: '%s'", mm_modem_band_get_string (band)); } } } /*****************************************************************************/ typedef struct { QmiNasActiveBand qmi_band; MMModemBand mm_band; } ActiveBandsMap; static const ActiveBandsMap active_bands_map [] = { /* CDMA bands */ { QMI_NAS_ACTIVE_BAND_BC_0, MM_MODEM_BAND_CDMA_BC0 }, { QMI_NAS_ACTIVE_BAND_BC_1, MM_MODEM_BAND_CDMA_BC1 }, { QMI_NAS_ACTIVE_BAND_BC_2, MM_MODEM_BAND_CDMA_BC2 }, { QMI_NAS_ACTIVE_BAND_BC_3, MM_MODEM_BAND_CDMA_BC3 }, { QMI_NAS_ACTIVE_BAND_BC_4, MM_MODEM_BAND_CDMA_BC4 }, { QMI_NAS_ACTIVE_BAND_BC_5, MM_MODEM_BAND_CDMA_BC5 }, { QMI_NAS_ACTIVE_BAND_BC_6, MM_MODEM_BAND_CDMA_BC6 }, { QMI_NAS_ACTIVE_BAND_BC_7, MM_MODEM_BAND_CDMA_BC7 }, { QMI_NAS_ACTIVE_BAND_BC_8, MM_MODEM_BAND_CDMA_BC8 }, { QMI_NAS_ACTIVE_BAND_BC_9, MM_MODEM_BAND_CDMA_BC9 }, { QMI_NAS_ACTIVE_BAND_BC_10, MM_MODEM_BAND_CDMA_BC10 }, { QMI_NAS_ACTIVE_BAND_BC_11, MM_MODEM_BAND_CDMA_BC11 }, { QMI_NAS_ACTIVE_BAND_BC_12, MM_MODEM_BAND_CDMA_BC12 }, { QMI_NAS_ACTIVE_BAND_BC_13, MM_MODEM_BAND_CDMA_BC13 }, { QMI_NAS_ACTIVE_BAND_BC_14, MM_MODEM_BAND_CDMA_BC14 }, { QMI_NAS_ACTIVE_BAND_BC_15, MM_MODEM_BAND_CDMA_BC15 }, { QMI_NAS_ACTIVE_BAND_BC_16, MM_MODEM_BAND_CDMA_BC16 }, { QMI_NAS_ACTIVE_BAND_BC_17, MM_MODEM_BAND_CDMA_BC17 }, { QMI_NAS_ACTIVE_BAND_BC_18, MM_MODEM_BAND_CDMA_BC18 }, { QMI_NAS_ACTIVE_BAND_BC_19, MM_MODEM_BAND_CDMA_BC19 }, /* GSM bands */ { QMI_NAS_ACTIVE_BAND_GSM_850, MM_MODEM_BAND_G850 }, { QMI_NAS_ACTIVE_BAND_GSM_900_EXTENDED, MM_MODEM_BAND_EGSM }, { QMI_NAS_ACTIVE_BAND_GSM_DCS_1800, MM_MODEM_BAND_DCS }, { QMI_NAS_ACTIVE_BAND_GSM_PCS_1900, MM_MODEM_BAND_PCS }, { QMI_NAS_ACTIVE_BAND_GSM_450, MM_MODEM_BAND_G450 }, { QMI_NAS_ACTIVE_BAND_GSM_480, MM_MODEM_BAND_G480 }, { QMI_NAS_ACTIVE_BAND_GSM_750, MM_MODEM_BAND_G750 }, /* WCDMA bands */ { QMI_NAS_ACTIVE_BAND_WCDMA_2100, MM_MODEM_BAND_UTRAN_1 }, { QMI_NAS_ACTIVE_BAND_WCDMA_PCS_1900, MM_MODEM_BAND_UTRAN_2 }, { QMI_NAS_ACTIVE_BAND_WCDMA_DCS_1800, MM_MODEM_BAND_UTRAN_3 }, { QMI_NAS_ACTIVE_BAND_WCDMA_1700_US, MM_MODEM_BAND_UTRAN_4 }, { QMI_NAS_ACTIVE_BAND_WCDMA_850, MM_MODEM_BAND_UTRAN_5 }, { QMI_NAS_ACTIVE_BAND_WCDMA_800, MM_MODEM_BAND_UTRAN_6 }, { QMI_NAS_ACTIVE_BAND_WCDMA_2600, MM_MODEM_BAND_UTRAN_7 }, { QMI_NAS_ACTIVE_BAND_WCDMA_900, MM_MODEM_BAND_UTRAN_8 }, { QMI_NAS_ACTIVE_BAND_WCDMA_1700_JAPAN, MM_MODEM_BAND_UTRAN_9 }, { QMI_NAS_ACTIVE_BAND_WCDMA_1500_JAPAN, MM_MODEM_BAND_UTRAN_11 }, { QMI_NAS_ACTIVE_BAND_WCDMA_850_JAPAN, MM_MODEM_BAND_UTRAN_19 }, /* LTE bands */ { QMI_NAS_ACTIVE_BAND_EUTRAN_1, MM_MODEM_BAND_EUTRAN_1 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_2, MM_MODEM_BAND_EUTRAN_2 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_3, MM_MODEM_BAND_EUTRAN_3 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_4, MM_MODEM_BAND_EUTRAN_4 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_5, MM_MODEM_BAND_EUTRAN_5 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_6, MM_MODEM_BAND_EUTRAN_6 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_7, MM_MODEM_BAND_EUTRAN_7 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_8, MM_MODEM_BAND_EUTRAN_8 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_9, MM_MODEM_BAND_EUTRAN_9 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_10, MM_MODEM_BAND_EUTRAN_10 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_11, MM_MODEM_BAND_EUTRAN_11 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_12, MM_MODEM_BAND_EUTRAN_12 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_13, MM_MODEM_BAND_EUTRAN_13 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_14, MM_MODEM_BAND_EUTRAN_14 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_17, MM_MODEM_BAND_EUTRAN_17 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_18, MM_MODEM_BAND_EUTRAN_18 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_19, MM_MODEM_BAND_EUTRAN_19 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_20, MM_MODEM_BAND_EUTRAN_20 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_21, MM_MODEM_BAND_EUTRAN_21 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_24, MM_MODEM_BAND_EUTRAN_24 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_25, MM_MODEM_BAND_EUTRAN_25 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_33, MM_MODEM_BAND_EUTRAN_33 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_34, MM_MODEM_BAND_EUTRAN_34 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_35, MM_MODEM_BAND_EUTRAN_35 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_36, MM_MODEM_BAND_EUTRAN_36 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_37, MM_MODEM_BAND_EUTRAN_37 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_38, MM_MODEM_BAND_EUTRAN_38 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_39, MM_MODEM_BAND_EUTRAN_39 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_40, MM_MODEM_BAND_EUTRAN_40 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_41, MM_MODEM_BAND_EUTRAN_41 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_42, MM_MODEM_BAND_EUTRAN_42 }, { QMI_NAS_ACTIVE_BAND_EUTRAN_43, MM_MODEM_BAND_EUTRAN_43 } }; static void add_active_bands (GArray *mm_bands, QmiNasActiveBand qmi_bands) { guint i; g_assert (mm_bands != NULL); for (i = 0; i < G_N_ELEMENTS (active_bands_map); i++) { if (qmi_bands == active_bands_map[i].qmi_band) { guint j; /* Avoid adding duplicate band entries */ for (j = 0; j < mm_bands->len; j++) { if (g_array_index (mm_bands, MMModemBand, j) == active_bands_map[i].mm_band) return; } g_array_append_val (mm_bands, active_bands_map[i].mm_band); return; } } } GArray * mm_modem_bands_from_qmi_rf_band_information_array (GArray *info_array) { GArray *mm_bands; mm_bands = g_array_new (FALSE, FALSE, sizeof (MMModemBand)); if (info_array) { guint i; for (i = 0; i < info_array->len; i++) { QmiMessageNasGetRfBandInformationOutputListElement *item; item = &g_array_index (info_array, QmiMessageNasGetRfBandInformationOutputListElement, i); add_active_bands (mm_bands, item->active_band_class); } } return mm_bands; } /*****************************************************************************/ MMModemAccessTechnology mm_modem_access_technology_from_qmi_radio_interface (QmiNasRadioInterface interface) { switch (interface) { case QMI_NAS_RADIO_INTERFACE_CDMA_1X: return MM_MODEM_ACCESS_TECHNOLOGY_1XRTT; case QMI_NAS_RADIO_INTERFACE_CDMA_1XEVDO: return MM_MODEM_ACCESS_TECHNOLOGY_EVDO0; case QMI_NAS_RADIO_INTERFACE_GSM: return MM_MODEM_ACCESS_TECHNOLOGY_GSM; case QMI_NAS_RADIO_INTERFACE_UMTS: return MM_MODEM_ACCESS_TECHNOLOGY_UMTS; case QMI_NAS_RADIO_INTERFACE_LTE: return MM_MODEM_ACCESS_TECHNOLOGY_LTE; case QMI_NAS_RADIO_INTERFACE_TD_SCDMA: case QMI_NAS_RADIO_INTERFACE_AMPS: case QMI_NAS_RADIO_INTERFACE_NONE: default: return MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN; } } /*****************************************************************************/ MMModemAccessTechnology mm_modem_access_technologies_from_qmi_radio_interface_array (GArray *radio_interfaces) { MMModemAccessTechnology access_technology = 0; guint i; for (i = 0; i < radio_interfaces->len; i++) { QmiNasRadioInterface iface; iface = g_array_index (radio_interfaces, QmiNasRadioInterface, i); access_technology |= mm_modem_access_technology_from_qmi_radio_interface (iface); } return access_technology; } /*****************************************************************************/ MMModemAccessTechnology mm_modem_access_technology_from_qmi_data_capability (QmiNasDataCapability cap) { switch (cap) { case QMI_NAS_DATA_CAPABILITY_GPRS: return MM_MODEM_ACCESS_TECHNOLOGY_GPRS; case QMI_NAS_DATA_CAPABILITY_EDGE: return MM_MODEM_ACCESS_TECHNOLOGY_EDGE; case QMI_NAS_DATA_CAPABILITY_HSDPA: return MM_MODEM_ACCESS_TECHNOLOGY_HSDPA; case QMI_NAS_DATA_CAPABILITY_HSUPA: return MM_MODEM_ACCESS_TECHNOLOGY_HSUPA; case QMI_NAS_DATA_CAPABILITY_WCDMA: return MM_MODEM_ACCESS_TECHNOLOGY_UMTS; case QMI_NAS_DATA_CAPABILITY_CDMA: return MM_MODEM_ACCESS_TECHNOLOGY_1XRTT; case QMI_NAS_DATA_CAPABILITY_EVDO_REV_0: return MM_MODEM_ACCESS_TECHNOLOGY_EVDO0; case QMI_NAS_DATA_CAPABILITY_EVDO_REV_A: return MM_MODEM_ACCESS_TECHNOLOGY_EVDOA; case QMI_NAS_DATA_CAPABILITY_GSM: return MM_MODEM_ACCESS_TECHNOLOGY_GSM; case QMI_NAS_DATA_CAPABILITY_EVDO_REV_B: return MM_MODEM_ACCESS_TECHNOLOGY_EVDOB; case QMI_NAS_DATA_CAPABILITY_LTE: return MM_MODEM_ACCESS_TECHNOLOGY_LTE; case QMI_NAS_DATA_CAPABILITY_HSDPA_PLUS: case QMI_NAS_DATA_CAPABILITY_DC_HSDPA_PLUS: return MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS; default: return MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN; } } /*****************************************************************************/ MMModemAccessTechnology mm_modem_access_technologies_from_qmi_data_capability_array (GArray *data_capabilities) { MMModemAccessTechnology access_technology = 0; guint i; for (i = 0; i < data_capabilities->len; i++) { QmiNasDataCapability cap; cap = g_array_index (data_capabilities, QmiNasDataCapability, i); access_technology |= mm_modem_access_technology_from_qmi_data_capability (cap); } return access_technology; } /*****************************************************************************/ MMModemMode mm_modem_mode_from_qmi_nas_radio_interface (QmiNasRadioInterface iface) { switch (iface) { case QMI_NAS_RADIO_INTERFACE_CDMA_1X: case QMI_NAS_RADIO_INTERFACE_GSM: return MM_MODEM_MODE_2G; case QMI_NAS_RADIO_INTERFACE_CDMA_1XEVDO: case QMI_NAS_RADIO_INTERFACE_UMTS: return MM_MODEM_MODE_3G; case QMI_NAS_RADIO_INTERFACE_LTE: return MM_MODEM_MODE_4G; default: return MM_MODEM_MODE_NONE; } } /*****************************************************************************/ MMModemMode mm_modem_mode_from_qmi_radio_technology_preference (QmiNasRadioTechnologyPreference qmi) { MMModemMode mode = MM_MODEM_MODE_NONE; if (qmi & QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_3GPP2) { /* Ignore AMPS, we really don't report CS mode in QMI modems */ if (qmi & QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_CDMA_OR_WCDMA) mode |= MM_MODEM_MODE_2G; /* CDMA */ if (qmi & QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_HDR) mode |= MM_MODEM_MODE_3G; /* EV-DO */ } if (qmi & QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_3GPP) { if (qmi & QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_AMPS_OR_GSM) mode |= MM_MODEM_MODE_2G; /* GSM */ if (qmi & QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_CDMA_OR_WCDMA) mode |= MM_MODEM_MODE_3G; /* WCDMA */ } if (qmi & QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_LTE) mode |= MM_MODEM_MODE_4G; return mode; } QmiNasRadioTechnologyPreference mm_modem_mode_to_qmi_radio_technology_preference (MMModemMode mode, gboolean is_cdma) { QmiNasRadioTechnologyPreference pref = 0; if (is_cdma) { pref |= QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_3GPP2; if (mode & MM_MODEM_MODE_2G) pref |= QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_CDMA_OR_WCDMA; /* CDMA */ if (mode & MM_MODEM_MODE_3G) pref |= QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_HDR; /* EV-DO */ } else { pref |= QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_3GPP; if (mode & MM_MODEM_MODE_2G) pref |= QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_AMPS_OR_GSM; /* GSM */ if (mode & MM_MODEM_MODE_3G) pref |= QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_CDMA_OR_WCDMA; /* WCDMA */ } if (mode & MM_MODEM_MODE_4G) pref |= QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_LTE; return pref; } /*****************************************************************************/ MMModemMode mm_modem_mode_from_qmi_rat_mode_preference (QmiNasRatModePreference qmi) { MMModemMode mode = MM_MODEM_MODE_NONE; if (qmi & QMI_NAS_RAT_MODE_PREFERENCE_CDMA_1X) mode |= MM_MODEM_MODE_2G; if (qmi & QMI_NAS_RAT_MODE_PREFERENCE_CDMA_1XEVDO) mode |= MM_MODEM_MODE_3G; if (qmi & QMI_NAS_RAT_MODE_PREFERENCE_GSM) mode |= MM_MODEM_MODE_2G; if (qmi & QMI_NAS_RAT_MODE_PREFERENCE_UMTS) mode |= MM_MODEM_MODE_3G; if (qmi & QMI_NAS_RAT_MODE_PREFERENCE_LTE) mode |= MM_MODEM_MODE_4G; return mode; } QmiNasRatModePreference mm_modem_mode_to_qmi_rat_mode_preference (MMModemMode mode, gboolean is_cdma, gboolean is_3gpp) { QmiNasRatModePreference pref = 0; if (is_cdma) { if (mode & MM_MODEM_MODE_2G) pref |= QMI_NAS_RAT_MODE_PREFERENCE_CDMA_1X; if (mode & MM_MODEM_MODE_3G) pref |= QMI_NAS_RAT_MODE_PREFERENCE_CDMA_1XEVDO; } if (is_3gpp) { if (mode & MM_MODEM_MODE_2G) pref |= QMI_NAS_RAT_MODE_PREFERENCE_GSM; if (mode & MM_MODEM_MODE_3G) pref |= QMI_NAS_RAT_MODE_PREFERENCE_UMTS; if (mode & MM_MODEM_MODE_4G) pref |= QMI_NAS_RAT_MODE_PREFERENCE_LTE; } return pref; } /*****************************************************************************/ MMModemCapability mm_modem_capability_from_qmi_rat_mode_preference (QmiNasRatModePreference qmi) { MMModemCapability caps = MM_MODEM_CAPABILITY_NONE; if (qmi & QMI_NAS_RAT_MODE_PREFERENCE_CDMA_1X) caps |= MM_MODEM_CAPABILITY_CDMA_EVDO; if (qmi & QMI_NAS_RAT_MODE_PREFERENCE_CDMA_1XEVDO) caps |= MM_MODEM_CAPABILITY_CDMA_EVDO; if (qmi & QMI_NAS_RAT_MODE_PREFERENCE_GSM) caps |= MM_MODEM_CAPABILITY_GSM_UMTS; if (qmi & QMI_NAS_RAT_MODE_PREFERENCE_UMTS) caps |= MM_MODEM_CAPABILITY_GSM_UMTS; if (qmi & QMI_NAS_RAT_MODE_PREFERENCE_LTE) caps |= MM_MODEM_CAPABILITY_LTE; /* FIXME: LTE Advanced? */ return caps; } QmiNasRatModePreference mm_modem_capability_to_qmi_rat_mode_preference (MMModemCapability caps) { QmiNasRatModePreference qmi = 0; if (caps & MM_MODEM_CAPABILITY_CDMA_EVDO) { qmi |= QMI_NAS_RAT_MODE_PREFERENCE_CDMA_1X; qmi |= QMI_NAS_RAT_MODE_PREFERENCE_CDMA_1XEVDO; } if (caps & MM_MODEM_CAPABILITY_GSM_UMTS) { qmi |= QMI_NAS_RAT_MODE_PREFERENCE_GSM; qmi |= QMI_NAS_RAT_MODE_PREFERENCE_UMTS; } if (caps & MM_MODEM_CAPABILITY_LTE) qmi |= QMI_NAS_RAT_MODE_PREFERENCE_LTE; return qmi; } /*****************************************************************************/ GArray * mm_modem_capability_to_qmi_acquisition_order_preference (MMModemCapability caps) { GArray *array; QmiNasRadioInterface value; array = g_array_new (FALSE, FALSE, sizeof (QmiNasRadioInterface)); if (caps & MM_MODEM_CAPABILITY_LTE) { value = QMI_NAS_RADIO_INTERFACE_LTE; g_array_append_val (array, value); } if (caps & MM_MODEM_CAPABILITY_GSM_UMTS) { value = QMI_NAS_RADIO_INTERFACE_UMTS; g_array_append_val (array, value); value = QMI_NAS_RADIO_INTERFACE_GSM; g_array_append_val (array, value); } if (caps & MM_MODEM_CAPABILITY_CDMA_EVDO) { value = QMI_NAS_RADIO_INTERFACE_CDMA_1XEVDO; g_array_append_val (array, value); value = QMI_NAS_RADIO_INTERFACE_CDMA_1X; g_array_append_val (array, value); } return array; } GArray * mm_modem_mode_to_qmi_acquisition_order_preference (MMModemMode allowed, MMModemMode preferred, gboolean is_cdma, gboolean is_3gpp) { GArray *array; QmiNasRadioInterface value; array = g_array_new (FALSE, FALSE, sizeof (QmiNasRadioInterface)); if (allowed & MM_MODEM_MODE_4G) { value = QMI_NAS_RADIO_INTERFACE_LTE; if (preferred == MM_MODEM_MODE_4G) g_array_prepend_val (array, value); else g_array_append_val (array, value); } if (allowed & MM_MODEM_MODE_3G) { if (is_cdma) { value = QMI_NAS_RADIO_INTERFACE_CDMA_1XEVDO; if (preferred == MM_MODEM_MODE_3G) g_array_prepend_val (array, value); else g_array_append_val (array, value); } if (is_3gpp) { value = QMI_NAS_RADIO_INTERFACE_UMTS; if (preferred == MM_MODEM_MODE_3G) g_array_prepend_val (array, value); else g_array_append_val (array, value); } } if (allowed & MM_MODEM_MODE_2G) { if (is_cdma) { value = QMI_NAS_RADIO_INTERFACE_CDMA_1X; if (preferred == MM_MODEM_MODE_2G) g_array_prepend_val (array, value); else g_array_append_val (array, value); } if (is_3gpp) { value = QMI_NAS_RADIO_INTERFACE_GSM; if (preferred == MM_MODEM_MODE_2G) g_array_prepend_val (array, value); else g_array_append_val (array, value); } } return array; } /*****************************************************************************/ MMModemCapability mm_modem_capability_from_qmi_radio_technology_preference (QmiNasRadioTechnologyPreference qmi) { MMModemCapability caps = MM_MODEM_CAPABILITY_NONE; if (qmi & QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_3GPP2) { /* Skip AMPS */ if (qmi & QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_CDMA_OR_WCDMA) caps |= MM_MODEM_CAPABILITY_CDMA_EVDO; /* CDMA */ if (qmi & QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_HDR) caps |= MM_MODEM_CAPABILITY_CDMA_EVDO; /* EV-DO */ } if (qmi & QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_3GPP) { if (qmi & QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_AMPS_OR_GSM) caps |= MM_MODEM_CAPABILITY_GSM_UMTS; /* GSM */ if (qmi & QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_CDMA_OR_WCDMA) caps |= MM_MODEM_CAPABILITY_GSM_UMTS; /* WCDMA */ } if (qmi & QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_LTE) caps |= MM_MODEM_CAPABILITY_LTE; /* FIXME: LTE Advanced? */ return caps; } QmiNasRadioTechnologyPreference mm_modem_capability_to_qmi_radio_technology_preference (MMModemCapability caps) { QmiNasRadioTechnologyPreference qmi = 0; if (caps & MM_MODEM_CAPABILITY_GSM_UMTS) { qmi |= QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_3GPP; qmi |= QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_AMPS_OR_GSM; qmi |= QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_CDMA_OR_WCDMA; } if (caps & MM_MODEM_CAPABILITY_CDMA_EVDO) { qmi |= QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_3GPP2; qmi |= QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_CDMA_OR_WCDMA; qmi |= QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_HDR; } if (caps & MM_MODEM_CAPABILITY_LTE) qmi |= QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_LTE; return qmi; } /*****************************************************************************/ #define ALL_3GPP2_BANDS \ (QMI_NAS_BAND_PREFERENCE_BC_0_A_SYSTEM | \ QMI_NAS_BAND_PREFERENCE_BC_0_B_SYSTEM | \ QMI_NAS_BAND_PREFERENCE_BC_1_ALL_BLOCKS | \ QMI_NAS_BAND_PREFERENCE_BC_2 | \ QMI_NAS_BAND_PREFERENCE_BC_3_A_SYSTEM | \ QMI_NAS_BAND_PREFERENCE_BC_4_ALL_BLOCKS | \ QMI_NAS_BAND_PREFERENCE_BC_5_ALL_BLOCKS | \ QMI_NAS_BAND_PREFERENCE_BC_6 | \ QMI_NAS_BAND_PREFERENCE_BC_7 | \ QMI_NAS_BAND_PREFERENCE_BC_8 | \ QMI_NAS_BAND_PREFERENCE_BC_9 | \ QMI_NAS_BAND_PREFERENCE_BC_10 | \ QMI_NAS_BAND_PREFERENCE_BC_11 | \ QMI_NAS_BAND_PREFERENCE_BC_12 | \ QMI_NAS_BAND_PREFERENCE_BC_14 | \ QMI_NAS_BAND_PREFERENCE_BC_15 | \ QMI_NAS_BAND_PREFERENCE_BC_16 | \ QMI_NAS_BAND_PREFERENCE_BC_17 | \ QMI_NAS_BAND_PREFERENCE_BC_18 | \ QMI_NAS_BAND_PREFERENCE_BC_19) #define ALL_3GPP_BANDS \ (QMI_NAS_BAND_PREFERENCE_GSM_DCS_1800 | \ QMI_NAS_BAND_PREFERENCE_GSM_900_EXTENDED | \ QMI_NAS_BAND_PREFERENCE_GSM_900_PRIMARY | \ QMI_NAS_BAND_PREFERENCE_GSM_450 | \ QMI_NAS_BAND_PREFERENCE_GSM_480 | \ QMI_NAS_BAND_PREFERENCE_GSM_750 | \ QMI_NAS_BAND_PREFERENCE_GSM_850 | \ QMI_NAS_BAND_PREFERENCE_GSM_900_RAILWAYS | \ QMI_NAS_BAND_PREFERENCE_GSM_PCS_1900 | \ QMI_NAS_BAND_PREFERENCE_WCDMA_2100 | \ QMI_NAS_BAND_PREFERENCE_WCDMA_PCS_1900 | \ QMI_NAS_BAND_PREFERENCE_WCDMA_DCS_1800 | \ QMI_NAS_BAND_PREFERENCE_WCDMA_1700_US | \ QMI_NAS_BAND_PREFERENCE_WCDMA_850_US | \ QMI_NAS_BAND_PREFERENCE_WCDMA_800 | \ QMI_NAS_BAND_PREFERENCE_WCDMA_2600 | \ QMI_NAS_BAND_PREFERENCE_WCDMA_900 | \ QMI_NAS_BAND_PREFERENCE_WCDMA_1700_JAPAN) MMModemCapability mm_modem_capability_from_qmi_band_preference (QmiNasBandPreference qmi) { MMModemCapability caps = MM_MODEM_CAPABILITY_NONE; if (qmi & ALL_3GPP_BANDS) caps |= MM_MODEM_CAPABILITY_GSM_UMTS; if (qmi & ALL_3GPP2_BANDS) caps |= MM_MODEM_CAPABILITY_CDMA_EVDO; return caps; } /*****************************************************************************/ MMModemMode mm_modem_mode_from_qmi_gsm_wcdma_acquisition_order_preference (QmiNasGsmWcdmaAcquisitionOrderPreference qmi) { switch (qmi) { case QMI_NAS_GSM_WCDMA_ACQUISITION_ORDER_PREFERENCE_AUTOMATIC: return MM_MODEM_MODE_NONE; case QMI_NAS_GSM_WCDMA_ACQUISITION_ORDER_PREFERENCE_GSM: return MM_MODEM_MODE_2G; case QMI_NAS_GSM_WCDMA_ACQUISITION_ORDER_PREFERENCE_WCDMA: return MM_MODEM_MODE_3G; default: mm_dbg ("Unknown acquisition order preference: '%s'", qmi_nas_gsm_wcdma_acquisition_order_preference_get_string (qmi)); return MM_MODEM_MODE_NONE; } } QmiNasGsmWcdmaAcquisitionOrderPreference mm_modem_mode_to_qmi_gsm_wcdma_acquisition_order_preference (MMModemMode mode) { gchar *str; /* mode is not a mask in this case, only a value */ switch (mode) { case MM_MODEM_MODE_3G: return QMI_NAS_GSM_WCDMA_ACQUISITION_ORDER_PREFERENCE_WCDMA; case MM_MODEM_MODE_2G: return QMI_NAS_GSM_WCDMA_ACQUISITION_ORDER_PREFERENCE_GSM; case MM_MODEM_MODE_NONE: return QMI_NAS_GSM_WCDMA_ACQUISITION_ORDER_PREFERENCE_AUTOMATIC; default: break; } str = mm_modem_mode_build_string_from_mask (mode); mm_dbg ("Unhandled modem mode: '%s'", str); g_free (str); return QMI_NAS_GSM_WCDMA_ACQUISITION_ORDER_PREFERENCE_AUTOMATIC; } /*****************************************************************************/ MMModem3gppRegistrationState mm_modem_3gpp_registration_state_from_qmi_registration_state (QmiNasAttachState attach_state, QmiNasRegistrationState registration_state, gboolean roaming) { if (attach_state == QMI_NAS_ATTACH_STATE_UNKNOWN) return MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN; if (attach_state == QMI_NAS_ATTACH_STATE_DETACHED) return MM_MODEM_3GPP_REGISTRATION_STATE_IDLE; /* attached */ switch (registration_state) { case QMI_NAS_REGISTRATION_STATE_NOT_REGISTERED: return MM_MODEM_3GPP_REGISTRATION_STATE_IDLE; case QMI_NAS_REGISTRATION_STATE_REGISTERED: return (roaming ? MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING : MM_MODEM_3GPP_REGISTRATION_STATE_HOME); case QMI_NAS_REGISTRATION_STATE_NOT_REGISTERED_SEARCHING: return MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING; case QMI_NAS_REGISTRATION_STATE_REGISTRATION_DENIED: return MM_MODEM_3GPP_REGISTRATION_STATE_DENIED; case QMI_NAS_REGISTRATION_STATE_UNKNOWN: default: return MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN; } } /*****************************************************************************/ MMModemCdmaRegistrationState mm_modem_cdma_registration_state_from_qmi_registration_state (QmiNasRegistrationState registration_state) { switch (registration_state) { case QMI_NAS_REGISTRATION_STATE_REGISTERED: return MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED; case QMI_NAS_REGISTRATION_STATE_NOT_REGISTERED: case QMI_NAS_REGISTRATION_STATE_NOT_REGISTERED_SEARCHING: case QMI_NAS_REGISTRATION_STATE_REGISTRATION_DENIED: case QMI_NAS_REGISTRATION_STATE_UNKNOWN: default: return MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN; } } /*****************************************************************************/ MMModemCdmaActivationState mm_modem_cdma_activation_state_from_qmi_activation_state (QmiDmsActivationState state) { switch (state) { case QMI_DMS_ACTIVATION_STATE_NOT_ACTIVATED: return MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED; case QMI_DMS_ACTIVATION_STATE_ACTIVATED: return MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATED; case QMI_DMS_ACTIVATION_STATE_CONNECTING: case QMI_DMS_ACTIVATION_STATE_CONNECTED: case QMI_DMS_ACTIVATION_STATE_OTASP_AUTHENTICATED: case QMI_DMS_ACTIVATION_STATE_OTASP_NAM: case QMI_DMS_ACTIVATION_STATE_OTASP_MDN: case QMI_DMS_ACTIVATION_STATE_OTASP_IMSI: case QMI_DMS_ACTIVATION_STATE_OTASP_PRL: case QMI_DMS_ACTIVATION_STATE_OTASP_SPC: return MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATING; case QMI_DMS_ACTIVATION_STATE_OTASP_COMMITED: return MM_MODEM_CDMA_ACTIVATION_STATE_PARTIALLY_ACTIVATED; default: return MM_MODEM_CDMA_ACTIVATION_STATE_UNKNOWN; } } /*****************************************************************************/ QmiWmsStorageType mm_sms_storage_to_qmi_storage_type (MMSmsStorage storage) { switch (storage) { case MM_SMS_STORAGE_SM: return QMI_WMS_STORAGE_TYPE_UIM; case MM_SMS_STORAGE_ME: return QMI_WMS_STORAGE_TYPE_NV; default: return QMI_WMS_STORAGE_TYPE_NONE; } } MMSmsStorage mm_sms_storage_from_qmi_storage_type (QmiWmsStorageType qmi_storage) { switch (qmi_storage) { case QMI_WMS_STORAGE_TYPE_UIM: return MM_SMS_STORAGE_SM; case QMI_WMS_STORAGE_TYPE_NV: return MM_SMS_STORAGE_ME; default: return MM_SMS_STORAGE_UNKNOWN; } } /*****************************************************************************/ MMSmsState mm_sms_state_from_qmi_message_tag (QmiWmsMessageTagType tag) { switch (tag) { case QMI_WMS_MESSAGE_TAG_TYPE_MT_READ: case QMI_WMS_MESSAGE_TAG_TYPE_MT_NOT_READ: return MM_SMS_STATE_RECEIVED; case QMI_WMS_MESSAGE_TAG_TYPE_MO_SENT: return MM_SMS_STATE_SENT; case QMI_WMS_MESSAGE_TAG_TYPE_MO_NOT_SENT: return MM_SMS_STATE_STORED; default: return MM_SMS_STATE_UNKNOWN; } } /*****************************************************************************/ QmiWdsAuthentication mm_bearer_allowed_auth_to_qmi_authentication (MMBearerAllowedAuth auth) { QmiWdsAuthentication out; out = QMI_WDS_AUTHENTICATION_NONE; if (auth & MM_BEARER_ALLOWED_AUTH_PAP) out |= QMI_WDS_AUTHENTICATION_PAP; if (auth & MM_BEARER_ALLOWED_AUTH_CHAP) out |= QMI_WDS_AUTHENTICATION_CHAP; return out; } /*****************************************************************************/ /** * The only case where we need to apply some logic to decide what the current * capabilities are is when we have a multimode CDMA/EVDO+GSM/UMTS device, in * which case we'll check the SSP and TP current values to decide which * capabilities are present and which have been disabled. * * For all the other cases, the DMS capabilities are exactly the current ones, * as there would be no capability switching support. */ MMModemCapability mm_modem_capability_from_qmi_capabilities_context (MMQmiCapabilitiesContext *ctx) { MMModemCapability tmp = MM_MODEM_CAPABILITY_NONE; gchar *nas_ssp_mode_preference_str; gchar *nas_tp_str; gchar *dms_capabilities_str; gchar *tmp_str; /* If not a multimode device, we're done */ #define MULTIMODE (MM_MODEM_CAPABILITY_GSM_UMTS | MM_MODEM_CAPABILITY_CDMA_EVDO) if ((ctx->dms_capabilities & MULTIMODE) != MULTIMODE) return ctx->dms_capabilities; /* We have a multimode CDMA/EVDO+GSM/UMTS device, check SSP and TP */ /* SSP logic to gather capabilities uses the Mode Preference TLV if available */ if (ctx->nas_ssp_mode_preference_mask) tmp = mm_modem_capability_from_qmi_rat_mode_preference (ctx->nas_ssp_mode_preference_mask); /* If no value retrieved from SSP, check TP. We only process TP * values if not 'auto'. */ else if (ctx->nas_tp_mask && (ctx->nas_tp_mask != QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_AUTO)) tmp = mm_modem_capability_from_qmi_radio_technology_preference (ctx->nas_tp_mask); /* Final capabilities are the intersection between the Technology * Preference or SSP and the device's capabilities. * If the Technology Preference was "auto" or unknown we just fall back * to the Get Capabilities response. */ if (tmp == MM_MODEM_CAPABILITY_NONE) tmp = ctx->dms_capabilities; else tmp &= ctx->dms_capabilities; /* Log about the logic applied */ nas_ssp_mode_preference_str = qmi_nas_rat_mode_preference_build_string_from_mask (ctx->nas_ssp_mode_preference_mask); nas_tp_str = qmi_nas_radio_technology_preference_build_string_from_mask (ctx->nas_tp_mask); dms_capabilities_str = mm_modem_capability_build_string_from_mask (ctx->dms_capabilities); tmp_str = mm_modem_capability_build_string_from_mask (tmp); mm_dbg ("Current capabilities built: '%s'\n" " SSP mode preference: '%s'\n" " TP: '%s'\n" " DMS Capabilities: '%s'", tmp_str, nas_ssp_mode_preference_str ? nas_ssp_mode_preference_str : "unknown", nas_tp_str ? nas_tp_str : "unknown", dms_capabilities_str); g_free (nas_ssp_mode_preference_str); g_free (nas_tp_str); g_free (dms_capabilities_str); g_free (tmp_str); return tmp; } /*****************************************************************************/ MMOmaSessionType mm_oma_session_type_from_qmi_oma_session_type (QmiOmaSessionType qmi_session_type) { switch (qmi_session_type) { case QMI_OMA_SESSION_TYPE_CLIENT_INITIATED_DEVICE_CONFIGURE: return MM_OMA_SESSION_TYPE_CLIENT_INITIATED_DEVICE_CONFIGURE; case QMI_OMA_SESSION_TYPE_CLIENT_INITIATED_PRL_UPDATE: return MM_OMA_SESSION_TYPE_CLIENT_INITIATED_PRL_UPDATE; case QMI_OMA_SESSION_TYPE_CLIENT_INITIATED_HANDS_FREE_ACTIVATION: return MM_OMA_SESSION_TYPE_CLIENT_INITIATED_HANDS_FREE_ACTIVATION; case QMI_OMA_SESSION_TYPE_DEVICE_INITIATED_HANDS_FREE_ACTIVATION: return MM_OMA_SESSION_TYPE_DEVICE_INITIATED_HANDS_FREE_ACTIVATION; case QMI_OMA_SESSION_TYPE_NETWORK_INITIATED_PRL_UPDATE: return MM_OMA_SESSION_TYPE_NETWORK_INITIATED_PRL_UPDATE; case QMI_OMA_SESSION_TYPE_NETWORK_INITIATED_DEVICE_CONFIGURE: return MM_OMA_SESSION_TYPE_NETWORK_INITIATED_DEVICE_CONFIGURE; case QMI_OMA_SESSION_TYPE_DEVICE_INITIATED_PRL_UPDATE: return MM_OMA_SESSION_TYPE_DEVICE_INITIATED_PRL_UPDATE; default: return MM_OMA_SESSION_TYPE_UNKNOWN; } } QmiOmaSessionType mm_oma_session_type_to_qmi_oma_session_type (MMOmaSessionType mm_session_type) { switch (mm_session_type) { case MM_OMA_SESSION_TYPE_CLIENT_INITIATED_DEVICE_CONFIGURE: return QMI_OMA_SESSION_TYPE_CLIENT_INITIATED_DEVICE_CONFIGURE; case MM_OMA_SESSION_TYPE_CLIENT_INITIATED_PRL_UPDATE: return QMI_OMA_SESSION_TYPE_CLIENT_INITIATED_PRL_UPDATE; case MM_OMA_SESSION_TYPE_CLIENT_INITIATED_HANDS_FREE_ACTIVATION: return QMI_OMA_SESSION_TYPE_CLIENT_INITIATED_HANDS_FREE_ACTIVATION; case MM_OMA_SESSION_TYPE_DEVICE_INITIATED_HANDS_FREE_ACTIVATION: return QMI_OMA_SESSION_TYPE_DEVICE_INITIATED_HANDS_FREE_ACTIVATION; case MM_OMA_SESSION_TYPE_NETWORK_INITIATED_PRL_UPDATE: return QMI_OMA_SESSION_TYPE_NETWORK_INITIATED_PRL_UPDATE; case MM_OMA_SESSION_TYPE_NETWORK_INITIATED_DEVICE_CONFIGURE: return QMI_OMA_SESSION_TYPE_NETWORK_INITIATED_DEVICE_CONFIGURE; case MM_OMA_SESSION_TYPE_DEVICE_INITIATED_PRL_UPDATE: return QMI_OMA_SESSION_TYPE_DEVICE_INITIATED_PRL_UPDATE; default: g_assert_not_reached (); } } MMOmaSessionState mm_oma_session_state_from_qmi_oma_session_state (QmiOmaSessionState qmi_session_state) { /* Note: MM_OMA_SESSION_STATE_STARTED is not a state received from the modem */ switch (qmi_session_state) { case QMI_OMA_SESSION_STATE_COMPLETE_INFORMATION_UPDATED: case QMI_OMA_SESSION_STATE_COMPLETE_UPDATED_INFORMATION_UNAVAILABLE: return MM_OMA_SESSION_STATE_COMPLETED; case QMI_OMA_SESSION_STATE_FAILED: return MM_OMA_SESSION_STATE_FAILED; case QMI_OMA_SESSION_STATE_RETRYING: return MM_OMA_SESSION_STATE_RETRYING; case QMI_OMA_SESSION_STATE_CONNECTING: return MM_OMA_SESSION_STATE_CONNECTING; case QMI_OMA_SESSION_STATE_CONNECTED: return MM_OMA_SESSION_STATE_CONNECTED; case QMI_OMA_SESSION_STATE_AUTHENTICATED: return MM_OMA_SESSION_STATE_AUTHENTICATED; case QMI_OMA_SESSION_STATE_MDN_DOWNLOADED: return MM_OMA_SESSION_STATE_MDN_DOWNLOADED; case QMI_OMA_SESSION_STATE_MSID_DOWNLOADED: return MM_OMA_SESSION_STATE_MSID_DOWNLOADED; case QMI_OMA_SESSION_STATE_PRL_DOWNLOADED: return MM_OMA_SESSION_STATE_PRL_DOWNLOADED; case QMI_OMA_SESSION_STATE_MIP_PROFILE_DOWNLOADED: return MM_OMA_SESSION_STATE_MIP_PROFILE_DOWNLOADED; default: return MM_OMA_SESSION_STATE_UNKNOWN; } } /*****************************************************************************/ MMOmaSessionStateFailedReason mm_oma_session_state_failed_reason_from_qmi_oma_session_failed_reason (QmiOmaSessionFailedReason qmi_session_failed_reason) { switch (qmi_session_failed_reason) { case QMI_OMA_SESSION_FAILED_REASON_UNKNOWN: return MM_OMA_SESSION_STATE_FAILED_REASON_UNKNOWN; case QMI_OMA_SESSION_FAILED_REASON_NETWORK_UNAVAILABLE: return MM_OMA_SESSION_STATE_FAILED_REASON_NETWORK_UNAVAILABLE; case QMI_OMA_SESSION_FAILED_REASON_SERVER_UNAVAILABLE: return MM_OMA_SESSION_STATE_FAILED_REASON_SERVER_UNAVAILABLE; case QMI_OMA_SESSION_FAILED_REASON_AUTHENTICATION_FAILED: return MM_OMA_SESSION_STATE_FAILED_REASON_AUTHENTICATION_FAILED; case QMI_OMA_SESSION_FAILED_REASON_MAX_RETRY_EXCEEDED: return MM_OMA_SESSION_STATE_FAILED_REASON_MAX_RETRY_EXCEEDED; case QMI_OMA_SESSION_FAILED_REASON_SESSION_CANCELLED: return MM_OMA_SESSION_STATE_FAILED_REASON_SESSION_CANCELLED; default: return MM_OMA_SESSION_STATE_FAILED_REASON_UNKNOWN; } } gboolean mm_error_from_qmi_loc_indication_status (QmiLocIndicationStatus status, GError **error) { switch (status) { case QMI_LOC_INDICATION_STATUS_SUCCESS: return TRUE; case QMI_LOC_INDICATION_STATUS_GENERAL_FAILURE: g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "LOC service: general failure"); return FALSE; case QMI_LOC_INDICATION_STATUS_UNSUPPORTED: g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, "LOC service: unsupported"); return FALSE; case QMI_LOC_INDICATION_STATUS_INVALID_PARAMETER: g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, "LOC service: invalid parameter"); return FALSE; case QMI_LOC_INDICATION_STATUS_ENGINE_BUSY: g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_IN_PROGRESS, "LOC service: engine busy"); return FALSE; case QMI_LOC_INDICATION_STATUS_PHONE_OFFLINE: g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_WRONG_STATE, "LOC service: phone offline"); return FALSE; case QMI_LOC_INDICATION_STATUS_TIMEOUT: g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_ABORTED, "LOC service: timeout"); return FALSE; default: g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "LOC service: unknown failure"); return FALSE; } }