mirror of git://git.sysmocom.de/ofono
Merge sysmocom/lynxis/master into sysmocom/osmo-gsm-tester
Conflicts: plugins/gobi.c
This commit is contained in:
commit
1056147002
2
AUTHORS
2
AUTHORS
|
@ -123,3 +123,5 @@ Piotr Haber <gluedig@gmail.com>
|
|||
André Draszik <git@andred.net>
|
||||
Lukasz Nowak <lnowak@tycoint.com>
|
||||
Jonas Bonn <jonas@southpole.se>
|
||||
Matthijs Kooijman <matthijs@stdin.nl>
|
||||
Clayton Craft <clayton@craftyguy.net>
|
||||
|
|
22
Makefile.am
22
Makefile.am
|
@ -236,7 +236,8 @@ builtin_sources += $(qmi_sources) \
|
|||
drivers/qmimodem/gprs.c \
|
||||
drivers/qmimodem/gprs-context.c \
|
||||
drivers/qmimodem/radio-settings.c \
|
||||
drivers/qmimodem/location-reporting.c
|
||||
drivers/qmimodem/location-reporting.c \
|
||||
drivers/qmimodem/qmibridge.c
|
||||
|
||||
builtin_modules += gobi
|
||||
builtin_sources += plugins/gobi.c
|
||||
|
@ -267,7 +268,8 @@ builtin_sources += drivers/atmodem/atmodem.h \
|
|||
drivers/atmodem/gprs.c \
|
||||
drivers/atmodem/gprs-context.c \
|
||||
drivers/atmodem/sim-auth.c \
|
||||
drivers/atmodem/gnss.c
|
||||
drivers/atmodem/gnss.c \
|
||||
drivers/atmodem/lte.c
|
||||
|
||||
builtin_modules += nwmodem
|
||||
builtin_sources += drivers/atmodem/atutil.h \
|
||||
|
@ -398,6 +400,11 @@ builtin_sources += drivers/atmodem/atutil.h \
|
|||
drivers/gemaltomodem/gemaltomodem.c \
|
||||
drivers/gemaltomodem/location-reporting.c
|
||||
|
||||
builtin_modules += xmm7modem
|
||||
builtin_sources += drivers/atmodem/atutil.h \
|
||||
drivers/xmm7modem/xmm7modem.h \
|
||||
drivers/xmm7modem/xmm7modem.c \
|
||||
drivers/xmm7modem/radio-settings.c
|
||||
|
||||
if PHONESIM
|
||||
builtin_modules += phonesim
|
||||
|
@ -623,10 +630,11 @@ src_ofonod_SOURCES = $(builtin_sources) $(gatchat_sources) src/ofono.ver \
|
|||
src/cdma-provision.c src/handsfree.c \
|
||||
src/handsfree-audio.c src/bluetooth.h \
|
||||
src/hfp.h src/siri.c \
|
||||
src/netmon.c src/lte.c src/call-list.c
|
||||
src/netmon.c src/lte.c src/call-list.c \
|
||||
src/netmonagent.c src/netmonagent.h
|
||||
|
||||
src_ofonod_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \
|
||||
@GLIB_LIBS@ @DBUS_LIBS@ -ldl
|
||||
@GLIB_LIBS@ @DBUS_LIBS@ -ldl -lqmi-glib
|
||||
|
||||
src_ofonod_LDFLAGS = -Wl,--export-dynamic \
|
||||
-Wl,--version-script=$(srcdir)/src/ofono.ver
|
||||
|
@ -649,7 +657,7 @@ AM_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ $(builtin_cflags) \
|
|||
|
||||
AM_CPPFLAGS = -I$(builddir)/include -I$(builddir)/src -I$(srcdir)/src \
|
||||
-I$(srcdir)/gdbus -I$(srcdir)/gisi -I$(srcdir)/gatchat \
|
||||
-I$(srcdir)/btio -I$(srcdir)/gril
|
||||
-I$(srcdir)/btio -I$(srcdir)/gril -I/usr/include/libqmi-glib
|
||||
|
||||
doc_files = doc/overview.txt doc/ofono-paper.txt doc/release-faq.txt \
|
||||
doc/manager-api.txt doc/modem-api.txt doc/network-api.txt \
|
||||
|
@ -776,7 +784,9 @@ test_scripts = test/backtrace \
|
|||
test/list-allowed-access-points \
|
||||
test/enable-throttling \
|
||||
test/disable-throttling \
|
||||
test/set-lte-property
|
||||
test/set-lte-property \
|
||||
test/test-serving-cell-info
|
||||
|
||||
|
||||
if TEST
|
||||
testdir = $(pkglibdir)/test
|
||||
|
|
|
@ -22,6 +22,34 @@ Methods a{sv} GetServingCellInformation()
|
|||
are available, their valid value ranges and
|
||||
applicability to different cell types.
|
||||
|
||||
void RegisterAgent(object path)
|
||||
|
||||
Registers an agent which will be called whenever the
|
||||
modem registers to or moves to a new cell.
|
||||
|
||||
void UnregisterAgent(object path)
|
||||
|
||||
Unregisters an agent.
|
||||
|
||||
NetworkMonitorAgent Hierarchy [experimental]
|
||||
=============================
|
||||
|
||||
Service unique name
|
||||
Interface org.ofono.NetworkMonitorAgent
|
||||
Object path freely definable
|
||||
|
||||
Methods void ServingCellInformationChanged(a{sv}) [noreply]
|
||||
|
||||
This method is called whenever the serving cell
|
||||
information has been updated.
|
||||
|
||||
Possible Errors: None
|
||||
|
||||
void Release() [noreply]
|
||||
|
||||
Agent is being released, possibly because of oFono
|
||||
terminating, NetworkMonitor interface is being torn
|
||||
down or modem off. No UnregisterAgent call is needed.
|
||||
|
||||
Network Monitor Property Types
|
||||
==============================
|
||||
|
@ -77,7 +105,7 @@ byte TimingAdvance [optional, gsm]
|
|||
|
||||
Contains the Timing Advance. Valid range of values is 0-219.
|
||||
|
||||
byte Strength [optional, gsm, umts]
|
||||
byte Strength [optional, gsm, umts, lte]
|
||||
|
||||
Contains the signal strength. Valid values are 0-31. Refer to <rssi>
|
||||
in 27.007, Section 8.5.
|
||||
|
|
|
@ -52,6 +52,7 @@ static int atmodem_init(void)
|
|||
at_gprs_context_init();
|
||||
at_sim_auth_init();
|
||||
at_gnss_init();
|
||||
at_lte_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -76,6 +77,7 @@ static void atmodem_exit(void)
|
|||
at_gprs_exit();
|
||||
at_gprs_context_exit();
|
||||
at_gnss_exit();
|
||||
at_lte_exit();
|
||||
}
|
||||
|
||||
OFONO_PLUGIN_DEFINE(atmodem, "AT modem driver", VERSION,
|
||||
|
|
|
@ -74,3 +74,6 @@ extern void at_sim_auth_exit(void);
|
|||
|
||||
extern void at_gnss_init(void);
|
||||
extern void at_gnss_exit(void);
|
||||
|
||||
extern void at_lte_init(void);
|
||||
extern void at_lte_exit(void);
|
||||
|
|
|
@ -51,9 +51,7 @@ enum at_util_charset {
|
|||
typedef void (*at_util_sim_inserted_cb_t)(gboolean present, void *userdata);
|
||||
|
||||
void decode_at_error(struct ofono_error *error, const char *final);
|
||||
gint ofono_call_compare_by_status(gconstpointer a, gconstpointer b);
|
||||
gint at_util_call_compare_by_phone_number(gconstpointer a, gconstpointer b);
|
||||
gint ofono_call_compare_by_id(gconstpointer a, gconstpointer b);
|
||||
GSList *at_util_parse_clcc(GAtResult *result, unsigned int *mpty_ids);
|
||||
gboolean at_util_parse_reg(GAtResult *result, const char *prefix,
|
||||
int *mode, int *status,
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include "atmodem.h"
|
||||
#include "vendor.h"
|
||||
|
||||
#define TUN_SYSFS_DIR "/sys/devices/virtual/misc/tun"
|
||||
#define TUN_DEV "/dev/net/tun"
|
||||
|
||||
#define STATIC_IP_NETMASK "255.255.255.255"
|
||||
|
||||
|
@ -426,7 +426,7 @@ static int at_gprs_context_probe(struct ofono_gprs_context *gc,
|
|||
|
||||
DBG("");
|
||||
|
||||
if (stat(TUN_SYSFS_DIR, &st) < 0) {
|
||||
if (stat(TUN_DEV, &st) < 0) {
|
||||
ofono_error("Missing support for TUN/TAP devices");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
|
@ -327,6 +327,26 @@ static void huawei_mode_notify(GAtResult *result, gpointer user_data)
|
|||
ofono_gprs_bearer_notify(gprs, bearer);
|
||||
}
|
||||
|
||||
static void huawei_hcsq_notify(GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_gprs *gprs = user_data;
|
||||
GAtResultIter iter;
|
||||
const char *mode;
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
|
||||
if (!g_at_result_iter_next(&iter, "^HCSQ:"))
|
||||
return;
|
||||
|
||||
if (!g_at_result_iter_next_string(&iter, &mode))
|
||||
return;
|
||||
|
||||
if (!strcmp("LTE", mode))
|
||||
ofono_gprs_bearer_notify(gprs, 7); /* LTE */
|
||||
|
||||
/* in other modes, notification ^MODE is used */
|
||||
}
|
||||
|
||||
static void telit_mode_notify(GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_gprs *gprs = user_data;
|
||||
|
@ -432,6 +452,8 @@ static void gprs_initialized(gboolean ok, GAtResult *result, gpointer user_data)
|
|||
case OFONO_VENDOR_HUAWEI:
|
||||
g_at_chat_register(gd->chat, "^MODE:", huawei_mode_notify,
|
||||
FALSE, gprs, NULL);
|
||||
g_at_chat_register(gd->chat, "^HCSQ:", huawei_hcsq_notify,
|
||||
FALSE, gprs, NULL);
|
||||
break;
|
||||
case OFONO_VENDOR_UBLOX:
|
||||
case OFONO_VENDOR_UBLOX_TOBY_L2:
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2017 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <ofono/modem.h>
|
||||
#include <ofono/gprs-context.h>
|
||||
#include <ofono/log.h>
|
||||
#include <ofono/lte.h>
|
||||
|
||||
#include "gatchat.h"
|
||||
#include "gatresult.h"
|
||||
|
||||
#include "atmodem.h"
|
||||
|
||||
struct lte_driver_data {
|
||||
GAtChat *chat;
|
||||
};
|
||||
|
||||
static void at_lte_set_default_attach_info_cb(gboolean ok, GAtResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_lte_cb_t cb = cbd->cb;
|
||||
struct ofono_error error;
|
||||
|
||||
DBG("ok %d", ok);
|
||||
|
||||
decode_at_error(&error, g_at_result_final_response(result));
|
||||
cb(&error, cbd->data);
|
||||
}
|
||||
|
||||
static void at_lte_set_default_attach_info(const struct ofono_lte *lte,
|
||||
const struct ofono_lte_default_attach_info *info,
|
||||
ofono_lte_cb_t cb, void *data)
|
||||
{
|
||||
struct lte_driver_data *ldd = ofono_lte_get_data(lte);
|
||||
char buf[32 + OFONO_GPRS_MAX_APN_LENGTH + 1];
|
||||
struct cb_data *cbd = cb_data_new(cb, data);
|
||||
|
||||
DBG("LTE config with APN: %s", info->apn);
|
||||
|
||||
if (strlen(info->apn) > 0)
|
||||
snprintf(buf, sizeof(buf), "AT+CGDCONT=0,\"IP\",\"%s\"",
|
||||
info->apn);
|
||||
else
|
||||
snprintf(buf, sizeof(buf), "AT+CGDCONT=0,\"IP\"");
|
||||
|
||||
/* We can't do much in case of failure so don't check response. */
|
||||
if (g_at_chat_send(ldd->chat, buf, NULL,
|
||||
at_lte_set_default_attach_info_cb, cbd, g_free) > 0)
|
||||
return;
|
||||
|
||||
CALLBACK_WITH_FAILURE(cb, data);
|
||||
}
|
||||
|
||||
static gboolean lte_delayed_register(gpointer user_data)
|
||||
{
|
||||
struct ofono_lte *lte = user_data;
|
||||
|
||||
ofono_lte_register(lte);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int at_lte_probe(struct ofono_lte *lte, void *data)
|
||||
{
|
||||
GAtChat *chat = data;
|
||||
struct lte_driver_data *ldd;
|
||||
|
||||
DBG("at lte probe");
|
||||
|
||||
ldd = g_try_new0(struct lte_driver_data, 1);
|
||||
if (!ldd)
|
||||
return -ENOMEM;
|
||||
|
||||
ldd->chat = g_at_chat_clone(chat);
|
||||
|
||||
ofono_lte_set_data(lte, ldd);
|
||||
|
||||
g_idle_add(lte_delayed_register, lte);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void at_lte_remove(struct ofono_lte *lte)
|
||||
{
|
||||
struct lte_driver_data *ldd = ofono_lte_get_data(lte);
|
||||
|
||||
DBG("at lte remove");
|
||||
|
||||
g_at_chat_unref(ldd->chat);
|
||||
|
||||
ofono_lte_set_data(lte, NULL);
|
||||
|
||||
g_free(ldd);
|
||||
}
|
||||
|
||||
static struct ofono_lte_driver driver = {
|
||||
.name = "atmodem",
|
||||
.probe = at_lte_probe,
|
||||
.remove = at_lte_remove,
|
||||
.set_default_attach_info = at_lte_set_default_attach_info,
|
||||
};
|
||||
|
||||
void at_lte_init(void)
|
||||
{
|
||||
ofono_lte_driver_register(&driver);
|
||||
}
|
||||
|
||||
void at_lte_exit(void)
|
||||
{
|
||||
ofono_lte_driver_unregister(&driver);
|
||||
}
|
|
@ -1088,6 +1088,27 @@ static void huawei_mode_notify(GAtResult *result, gpointer user_data)
|
|||
}
|
||||
}
|
||||
|
||||
static void huawei_hcsq_notify(GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_netreg *netreg = user_data;
|
||||
struct netreg_data *nd = ofono_netreg_get_data(netreg);
|
||||
GAtResultIter iter;
|
||||
const char *mode;
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
|
||||
if (!g_at_result_iter_next(&iter, "^HCSQ:"))
|
||||
return;
|
||||
|
||||
if (!g_at_result_iter_next_string(&iter, &mode))
|
||||
return;
|
||||
|
||||
if (!strcmp("LTE", mode))
|
||||
nd->tech = ACCESS_TECHNOLOGY_EUTRAN;
|
||||
|
||||
/* for other technologies, notification ^MODE is used */
|
||||
}
|
||||
|
||||
static void huawei_nwtime_notify(GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_netreg *netreg = user_data;
|
||||
|
@ -1896,6 +1917,10 @@ static void at_creg_set_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
|||
g_at_chat_register(nd->chat, "^MODE:", huawei_mode_notify,
|
||||
FALSE, netreg, NULL);
|
||||
|
||||
/* Register for 4G system mode reports */
|
||||
g_at_chat_register(nd->chat, "^HCSQ:", huawei_hcsq_notify,
|
||||
FALSE, netreg, NULL);
|
||||
|
||||
/* Register for network time reports */
|
||||
g_at_chat_register(nd->chat, "^NWTIME:", huawei_nwtime_notify,
|
||||
FALSE, netreg, NULL);
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include "cdmamodem.h"
|
||||
#include "drivers/atmodem/vendor.h"
|
||||
|
||||
#define TUN_SYSFS_DIR "/sys/devices/virtual/misc/tun"
|
||||
#define TUN_DEV "/dev/net/tun"
|
||||
|
||||
#define STATIC_IP_NETMASK "255.255.255.255"
|
||||
|
||||
|
@ -285,7 +285,7 @@ static int cdma_connman_probe(struct ofono_cdma_connman *cm,
|
|||
|
||||
DBG("");
|
||||
|
||||
if (stat(TUN_SYSFS_DIR, &st) < 0) {
|
||||
if (stat(TUN_DEV, &st) < 0) {
|
||||
ofono_error("Missing support for TUN/TAP devices");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
#include "ifxmodem.h"
|
||||
|
||||
#define TUN_SYSFS_DIR "/sys/devices/virtual/misc/tun"
|
||||
#define TUN_DEV "/dev/net/tun"
|
||||
|
||||
#define STATIC_IP_NETMASK "255.255.255.255"
|
||||
|
||||
|
@ -470,7 +470,7 @@ static int ifx_gprs_context_probe(struct ofono_gprs_context *gc,
|
|||
|
||||
DBG("");
|
||||
|
||||
if (stat(TUN_SYSFS_DIR, &st) < 0) {
|
||||
if (stat(TUN_DEV, &st) < 0) {
|
||||
ofono_error("Missing support for TUN/TAP devices");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
|
@ -646,8 +646,31 @@ error:
|
|||
/* ISI callback: PIN state (enabled/disabled) query */
|
||||
static void sec_code_state_resp_cb(const GIsiMessage *msg, void *opaque)
|
||||
{
|
||||
check_sec_response(msg, opaque, SEC_CODE_STATE_OK_RESP,
|
||||
SEC_CODE_STATE_FAIL_RESP);
|
||||
struct isi_cb_data *cbd = opaque;
|
||||
ofono_query_facility_lock_cb_t cb = cbd->cb;
|
||||
int locked;
|
||||
uint8_t state;
|
||||
uint8_t status;
|
||||
|
||||
if (!g_isi_msg_data_get_byte(msg, 0, &state) ||
|
||||
!g_isi_msg_data_get_byte(msg, 1, &status))
|
||||
goto error;
|
||||
|
||||
if (state != SEC_CODE_STATE_OK_RESP)
|
||||
goto error;
|
||||
|
||||
if (status == SEC_CODE_ENABLE)
|
||||
locked = 1;
|
||||
else if (status == SEC_CODE_DISABLE)
|
||||
locked = 0;
|
||||
else
|
||||
goto error;
|
||||
|
||||
CALLBACK_WITH_SUCCESS(cb, locked, cbd->data);
|
||||
return;
|
||||
|
||||
error:
|
||||
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
|
||||
}
|
||||
|
||||
static void isi_query_locked(struct ofono_sim *sim,
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#define QMI_NAS_SS_INFO_IND 36 /* Current serving system info indication */
|
||||
#define QMI_NAS_GET_HOME_INFO 37 /* Get info about home network */
|
||||
|
||||
#define QMI_NAS_SET_SYSTEM_SELECTION_PREF 51
|
||||
#define QMI_NAS_GET_SYSTEM_SELECTION_PREF 52
|
||||
|
||||
/* Set NAS state report conditions */
|
||||
#define QMI_NAS_PARAM_REPORT_SIGNAL_STRENGTH 0x10
|
||||
|
@ -176,4 +178,13 @@ struct qmi_nas_home_network {
|
|||
char desc[0];
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define QMI_NAS_RAT_MODE_PREF_ANY (-1)
|
||||
#define QMI_NAS_RAT_MODE_PREF_GSM (1 << 2)
|
||||
#define QMI_NAS_RAT_MODE_PREF_UMTS (1 << 3)
|
||||
#define QMI_NAS_RAT_MODE_PREF_LTE (1 << 4)
|
||||
|
||||
#define QMI_NAS_PARAM_SYSTEM_SELECTION_PREF_MODE 0x11
|
||||
|
||||
#define QMI_NAS_RESULT_SYSTEM_SELECTION_PREF_MODE 0x11
|
||||
|
||||
int qmi_nas_rat_to_tech(uint8_t rat);
|
||||
|
|
|
@ -48,14 +48,14 @@ static bool extract_ss_info_time(
|
|||
struct qmi_result *result,
|
||||
struct ofono_network_time *time)
|
||||
{
|
||||
const struct qmi_nas_3gpp_time *time_3gpp= NULL;
|
||||
const struct qmi_nas_3gpp_time *time_3gpp = NULL;
|
||||
uint8_t dst_3gpp;
|
||||
bool dst_3gpp_valid;
|
||||
uint16_t len;
|
||||
|
||||
/* parse 3gpp time & dst */
|
||||
dst_3gpp_valid = qmi_result_get_uint8(result, QMI_NAS_RESULT_3GGP_DST,
|
||||
&dst_3gpp);
|
||||
&dst_3gpp);
|
||||
|
||||
time_3gpp = qmi_result_get(result, QMI_NAS_RESULT_3GPP_TIME, &len);
|
||||
if (time_3gpp && len == sizeof(struct qmi_nas_3gpp_time) &&
|
||||
|
@ -65,7 +65,7 @@ static bool extract_ss_info_time(
|
|||
time->mday = time_3gpp->day;
|
||||
time->hour = time_3gpp->hour;
|
||||
time->min = time_3gpp->minute;
|
||||
time->sec= time_3gpp->second;
|
||||
time->sec = time_3gpp->second;
|
||||
time->utcoff = time_3gpp->timezone * 15 * 60;
|
||||
time->dst = dst_3gpp;
|
||||
return true;
|
||||
|
@ -487,10 +487,11 @@ static void event_notify(struct qmi_result *result, void *user_data)
|
|||
if (ss) {
|
||||
int strength;
|
||||
|
||||
DBG("signal with %d dBm on %d", ss->dbm, ss->rat);
|
||||
|
||||
strength = dbm_to_strength(ss->dbm);
|
||||
|
||||
DBG("signal with %d%%(%d dBm) on %d",
|
||||
strength, ss->dbm, ss->rat);
|
||||
|
||||
ofono_netreg_strength_notify(netreg, strength);
|
||||
}
|
||||
|
||||
|
@ -510,10 +511,17 @@ static void event_notify(struct qmi_result *result, void *user_data)
|
|||
static void set_event_cb(struct qmi_result *result, void *user_data)
|
||||
{
|
||||
struct ofono_netreg *netreg = user_data;
|
||||
struct netreg_data *data = ofono_netreg_get_data(netreg);
|
||||
|
||||
DBG("");
|
||||
|
||||
ofono_netreg_register(netreg);
|
||||
|
||||
qmi_service_register(data->nas, QMI_NAS_EVENT,
|
||||
event_notify, netreg, NULL);
|
||||
|
||||
qmi_service_register(data->nas, QMI_NAS_SS_INFO_IND,
|
||||
ss_info_notify, netreg, NULL);
|
||||
}
|
||||
|
||||
static void create_nas_cb(struct qmi_service *service, void *user_data)
|
||||
|
@ -535,12 +543,6 @@ static void create_nas_cb(struct qmi_service *service, void *user_data)
|
|||
|
||||
data->nas = qmi_service_ref(service);
|
||||
|
||||
qmi_service_register(data->nas, QMI_NAS_EVENT,
|
||||
event_notify, netreg, NULL);
|
||||
|
||||
qmi_service_register(data->nas, QMI_NAS_SS_INFO_IND,
|
||||
ss_info_notify, netreg, NULL);
|
||||
|
||||
param = qmi_param_new();
|
||||
if (!param)
|
||||
goto done;
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
#include <ofono/log.h>
|
||||
|
||||
#include "qmibridge.h"
|
||||
#include "qmi.h"
|
||||
#include "ctl.h"
|
||||
|
||||
|
@ -651,6 +652,8 @@ static gboolean can_write_data(GIOChannel *channel, GIOCondition cond,
|
|||
__debug_msg(' ', req->buf, bytes_written,
|
||||
device->debug_func, device->debug_data);
|
||||
|
||||
qmibridge_decode_req(req->buf, req->len);
|
||||
|
||||
hdr = req->buf;
|
||||
|
||||
if (hdr->service == QMI_SERVICE_CONTROL)
|
||||
|
@ -838,6 +841,7 @@ static gboolean received_data(GIOChannel *channel, GIOCondition cond,
|
|||
__hexdump('<', buf, bytes_read,
|
||||
device->debug_func, device->debug_data);
|
||||
|
||||
qmibridge_decode_read(buf, bytes_read);
|
||||
offset = 0;
|
||||
|
||||
while (offset < bytes_read) {
|
||||
|
@ -1136,15 +1140,12 @@ static void discover_callback(uint16_t message, uint16_t length,
|
|||
if (type == QMI_SERVICE_CONTROL) {
|
||||
device->control_major = major;
|
||||
device->control_minor = minor;
|
||||
continue;
|
||||
}
|
||||
|
||||
list[count].type = type;
|
||||
list[count].major = major;
|
||||
list[count].minor = minor;
|
||||
list[count].name = name;
|
||||
|
||||
count++;
|
||||
list[i].type = type;
|
||||
list[i].major = major;
|
||||
list[i].minor = minor;
|
||||
list[i].name = name;
|
||||
|
||||
if (name)
|
||||
__debug_device(device, "found service [%s %d.%d]",
|
||||
|
@ -1153,6 +1154,7 @@ static void discover_callback(uint16_t message, uint16_t length,
|
|||
__debug_device(device, "found service [%d %d.%d]",
|
||||
type, major, minor);
|
||||
}
|
||||
count = service_list->count;
|
||||
|
||||
ptr = tlv_get(buffer, length, 0x10, &len);
|
||||
if (!ptr)
|
||||
|
@ -1162,11 +1164,6 @@ static void discover_callback(uint16_t message, uint16_t length,
|
|||
|
||||
service_list = ptr + *((uint8_t *) ptr) + 1;
|
||||
|
||||
for (i = 0; i < service_list->count; i++) {
|
||||
if (service_list->services[i].type == QMI_SERVICE_CONTROL)
|
||||
continue;
|
||||
}
|
||||
|
||||
done:
|
||||
device->version_list = list;
|
||||
device->version_count = count;
|
||||
|
@ -1767,6 +1764,27 @@ bool qmi_result_get_uint8(struct qmi_result *result, uint8_t type,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool qmi_result_get_int16(struct qmi_result *result, uint8_t type,
|
||||
int16_t *value)
|
||||
{
|
||||
const unsigned char *ptr;
|
||||
uint16_t len, tmp;
|
||||
|
||||
if (!result || !type)
|
||||
return false;
|
||||
|
||||
ptr = tlv_get(result->data, result->length, type, &len);
|
||||
if (!ptr)
|
||||
return false;
|
||||
|
||||
memcpy(&tmp, ptr, 2);
|
||||
|
||||
if (value)
|
||||
*value = GINT16_FROM_LE(tmp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool qmi_result_get_uint16(struct qmi_result *result, uint8_t type,
|
||||
uint16_t *value)
|
||||
{
|
||||
|
|
|
@ -136,6 +136,8 @@ const void *qmi_result_get(struct qmi_result *result, uint8_t type,
|
|||
char *qmi_result_get_string(struct qmi_result *result, uint8_t type);
|
||||
bool qmi_result_get_uint8(struct qmi_result *result, uint8_t type,
|
||||
uint8_t *value);
|
||||
bool qmi_result_get_int16(struct qmi_result *result, uint8_t type,
|
||||
int16_t *value);
|
||||
bool qmi_result_get_uint16(struct qmi_result *result, uint8_t type,
|
||||
uint16_t *value);
|
||||
bool qmi_result_get_uint32(struct qmi_result *result, uint8_t type,
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
|
||||
#include <libqmi-glib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ofono/log.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
static void ask_qmi(const char *prefix, void *data, size_t len)
|
||||
{
|
||||
/* from osmo-qcdiag */
|
||||
GByteArray *buffer;
|
||||
GError *error = NULL;
|
||||
QmiMessage *message;
|
||||
gchar *printable;
|
||||
|
||||
buffer = g_byte_array_sized_new(len);
|
||||
g_byte_array_append(buffer, data, len);
|
||||
|
||||
message = qmi_message_new_from_raw(buffer, &error);
|
||||
if (!message) {
|
||||
fprintf(stderr, "qmi_message_new_from_raw() returned NULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printable = qmi_message_get_printable(message, "QMI ");
|
||||
DBG("%s: %s", prefix, printable);
|
||||
g_free(printable);
|
||||
}
|
||||
void qmibridge_decode_read(void *data, size_t len)
|
||||
{
|
||||
ask_qmi("READ", data, len);
|
||||
}
|
||||
|
||||
void qmibridge_decode_req(void *data, size_t len)
|
||||
{
|
||||
ask_qmi("_REQ", data, len);
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
void qmibridge_decode_read(void *data, size_t len);
|
||||
void qmibridge_decode_req(void *data, size_t len);
|
|
@ -29,15 +29,202 @@
|
|||
|
||||
#include "qmi.h"
|
||||
#include "nas.h"
|
||||
#include "dms.h"
|
||||
|
||||
#include "qmimodem.h"
|
||||
|
||||
struct settings_data {
|
||||
struct qmi_service *nas;
|
||||
struct qmi_service *dms;
|
||||
uint16_t major;
|
||||
uint16_t minor;
|
||||
};
|
||||
|
||||
static void get_system_selection_pref_cb(struct qmi_result *result,
|
||||
void* user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_radio_settings_rat_mode_query_cb_t cb = cbd->cb;
|
||||
enum ofono_radio_access_mode mode = OFONO_RADIO_ACCESS_MODE_ANY;
|
||||
uint16_t pref;
|
||||
|
||||
DBG("");
|
||||
|
||||
if (qmi_result_set_error(result, NULL)) {
|
||||
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
|
||||
return;
|
||||
}
|
||||
|
||||
qmi_result_get_uint16(result,
|
||||
QMI_NAS_RESULT_SYSTEM_SELECTION_PREF_MODE, &pref);
|
||||
|
||||
switch (pref) {
|
||||
case QMI_NAS_RAT_MODE_PREF_GSM:
|
||||
mode = OFONO_RADIO_ACCESS_MODE_GSM;
|
||||
break;
|
||||
case QMI_NAS_RAT_MODE_PREF_UMTS:
|
||||
mode = OFONO_RADIO_ACCESS_MODE_UMTS;
|
||||
break;
|
||||
case QMI_NAS_RAT_MODE_PREF_LTE:
|
||||
mode = OFONO_RADIO_ACCESS_MODE_LTE;
|
||||
break;
|
||||
}
|
||||
|
||||
CALLBACK_WITH_SUCCESS(cb, mode, cbd->data);
|
||||
}
|
||||
|
||||
static void qmi_query_rat_mode(struct ofono_radio_settings *rs,
|
||||
ofono_radio_settings_rat_mode_query_cb_t cb,
|
||||
void *user_data)
|
||||
{
|
||||
struct settings_data *data = ofono_radio_settings_get_data(rs);
|
||||
struct cb_data *cbd = cb_data_new(cb, user_data);
|
||||
|
||||
DBG("");
|
||||
|
||||
if (qmi_service_send(data->nas,
|
||||
QMI_NAS_GET_SYSTEM_SELECTION_PREF, NULL,
|
||||
get_system_selection_pref_cb, cbd, g_free) > 0)
|
||||
return;
|
||||
|
||||
CALLBACK_WITH_FAILURE(cb, -1, data);
|
||||
}
|
||||
|
||||
static void set_system_selection_pref_cb(struct qmi_result *result,
|
||||
void* user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_radio_settings_rat_mode_set_cb_t cb = cbd->cb;
|
||||
|
||||
DBG("");
|
||||
|
||||
if (qmi_result_set_error(result, NULL)) {
|
||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
||||
return;
|
||||
}
|
||||
|
||||
CALLBACK_WITH_SUCCESS(cb, cbd->data);
|
||||
}
|
||||
|
||||
static void qmi_set_rat_mode(struct ofono_radio_settings *rs,
|
||||
enum ofono_radio_access_mode mode,
|
||||
ofono_radio_settings_rat_mode_set_cb_t cb,
|
||||
void *user_data)
|
||||
{
|
||||
struct settings_data *data = ofono_radio_settings_get_data(rs);
|
||||
struct cb_data *cbd = cb_data_new(cb, user_data);
|
||||
uint16_t pref = QMI_NAS_RAT_MODE_PREF_ANY;
|
||||
struct qmi_param *param;
|
||||
|
||||
DBG("");
|
||||
|
||||
switch (mode) {
|
||||
case OFONO_RADIO_ACCESS_MODE_ANY:
|
||||
pref = QMI_NAS_RAT_MODE_PREF_ANY;
|
||||
break;
|
||||
case OFONO_RADIO_ACCESS_MODE_GSM:
|
||||
pref = QMI_NAS_RAT_MODE_PREF_GSM;
|
||||
break;
|
||||
case OFONO_RADIO_ACCESS_MODE_UMTS:
|
||||
pref = QMI_NAS_RAT_MODE_PREF_UMTS;
|
||||
break;
|
||||
case OFONO_RADIO_ACCESS_MODE_LTE:
|
||||
pref = QMI_NAS_RAT_MODE_PREF_LTE;
|
||||
break;
|
||||
}
|
||||
|
||||
param = qmi_param_new();
|
||||
if (!param) {
|
||||
CALLBACK_WITH_FAILURE(cb, user_data);
|
||||
return;
|
||||
}
|
||||
|
||||
qmi_param_append_uint16(param, QMI_NAS_PARAM_SYSTEM_SELECTION_PREF_MODE,
|
||||
pref);
|
||||
|
||||
if (qmi_service_send(data->nas,
|
||||
QMI_NAS_SET_SYSTEM_SELECTION_PREF, param,
|
||||
set_system_selection_pref_cb, cbd, g_free) > 0)
|
||||
return;
|
||||
|
||||
qmi_param_free(param);
|
||||
CALLBACK_WITH_FAILURE(cb, user_data);
|
||||
g_free(cbd);
|
||||
}
|
||||
|
||||
static void get_caps_cb(struct qmi_result *result, void *user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_radio_settings_available_rats_query_cb_t cb = cbd->cb;
|
||||
const struct qmi_dms_device_caps *caps;
|
||||
unsigned int available_rats;
|
||||
uint16_t len;
|
||||
uint8_t i;
|
||||
|
||||
DBG("");
|
||||
|
||||
if (qmi_result_set_error(result, NULL))
|
||||
goto error;
|
||||
|
||||
caps = qmi_result_get(result, QMI_DMS_RESULT_DEVICE_CAPS, &len);
|
||||
if (!caps)
|
||||
goto error;
|
||||
|
||||
available_rats = 0;
|
||||
for (i = 0; i < caps->radio_if_count; i++) {
|
||||
switch (caps->radio_if[i]) {
|
||||
case QMI_DMS_RADIO_IF_GSM:
|
||||
available_rats |= OFONO_RADIO_ACCESS_MODE_GSM;
|
||||
break;
|
||||
case QMI_DMS_RADIO_IF_UMTS:
|
||||
available_rats |= OFONO_RADIO_ACCESS_MODE_UMTS;
|
||||
break;
|
||||
case QMI_DMS_RADIO_IF_LTE:
|
||||
available_rats |= OFONO_RADIO_ACCESS_MODE_LTE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CALLBACK_WITH_SUCCESS(cb, available_rats, cbd->data);
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
|
||||
}
|
||||
|
||||
static void qmi_query_available_rats(struct ofono_radio_settings *rs,
|
||||
ofono_radio_settings_available_rats_query_cb_t cb,
|
||||
void *data)
|
||||
{
|
||||
struct settings_data *rsd = ofono_radio_settings_get_data(rs);
|
||||
struct cb_data *cbd = cb_data_new(cb, data);
|
||||
|
||||
if (!rsd->dms)
|
||||
goto error;
|
||||
|
||||
if (qmi_service_send(rsd->dms, QMI_DMS_GET_CAPS, NULL,
|
||||
get_caps_cb, cbd, g_free) > 0)
|
||||
return;
|
||||
|
||||
error:
|
||||
g_free(cbd);
|
||||
CALLBACK_WITH_FAILURE(cb, -1, data);
|
||||
}
|
||||
|
||||
static void create_dms_cb(struct qmi_service *service, void *user_data)
|
||||
{
|
||||
struct ofono_radio_settings *rs = user_data;
|
||||
struct settings_data *data = ofono_radio_settings_get_data(rs);
|
||||
|
||||
DBG("");
|
||||
|
||||
if (!service)
|
||||
return;
|
||||
|
||||
data->dms = qmi_service_ref(service);
|
||||
}
|
||||
|
||||
static void create_nas_cb(struct qmi_service *service, void *user_data)
|
||||
{
|
||||
struct ofono_radio_settings *rs = user_data;
|
||||
|
@ -74,11 +261,12 @@ static int qmi_radio_settings_probe(struct ofono_radio_settings *rs,
|
|||
|
||||
ofono_radio_settings_set_data(rs, data);
|
||||
|
||||
qmi_service_create_shared(device, QMI_SERVICE_DMS,
|
||||
create_dms_cb, rs, NULL);
|
||||
qmi_service_create_shared(device, QMI_SERVICE_NAS,
|
||||
create_nas_cb, rs, NULL);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static void qmi_radio_settings_remove(struct ofono_radio_settings *rs)
|
||||
|
@ -100,6 +288,9 @@ static struct ofono_radio_settings_driver driver = {
|
|||
.name = "qmimodem",
|
||||
.probe = qmi_radio_settings_probe,
|
||||
.remove = qmi_radio_settings_remove,
|
||||
.set_rat_mode = qmi_set_rat_mode,
|
||||
.query_rat_mode = qmi_query_rat_mode,
|
||||
.query_available_rats = qmi_query_available_rats,
|
||||
};
|
||||
|
||||
void qmi_radio_settings_init(void)
|
||||
|
|
|
@ -277,7 +277,7 @@ static void qmi_bearer_query(struct ofono_sms *sms,
|
|||
|
||||
DBG("");
|
||||
|
||||
if (data->major < 1 && data->minor < 2)
|
||||
if (data->major < 1 || (data->major == 1 && data->minor < 2))
|
||||
goto error;
|
||||
|
||||
if (qmi_service_send(data->wms, QMI_WMS_GET_DOMAIN_PREF, NULL,
|
||||
|
@ -315,7 +315,7 @@ static void qmi_bearer_set(struct ofono_sms *sms, int bearer,
|
|||
|
||||
DBG("bearer %d", bearer);
|
||||
|
||||
if (data->major < 1 && data->minor < 2)
|
||||
if (data->major < 1 || (data->major == 1 && data->minor < 2))
|
||||
goto error;
|
||||
|
||||
domain = bearer_to_domain(bearer);
|
||||
|
|
|
@ -65,6 +65,9 @@ static void all_call_status_ind(struct qmi_result *result, void *user_data)
|
|||
int i;
|
||||
int size = 0;
|
||||
struct qmi_voice_all_call_status_ind status_ind;
|
||||
GSList *n, *o;
|
||||
struct ofono_call *nc, *oc;
|
||||
|
||||
|
||||
if (qmi_voice_ind_call_status(result, &status_ind) != NONE) {
|
||||
DBG("Parsing of all call status indication failed");
|
||||
|
@ -112,7 +115,7 @@ static void all_call_status_ind(struct qmi_result *result, void *user_data)
|
|||
call->type = 0; /* always voice */
|
||||
number_size = remote_party->number_size;
|
||||
if (number_size > OFONO_MAX_PHONE_NUMBER_LENGTH)
|
||||
number_size = OFONO_MAX_PHONE_NUMBER_LENGTH;
|
||||
OFONO_MAX_PHONE_NUMBER_LENGTH;
|
||||
strncpy(call->phone_number.number, remote_party->number,
|
||||
number_size);
|
||||
/* FIXME: set phone_number_type */
|
||||
|
@ -201,6 +204,7 @@ static void dial_cb(struct qmi_result *result, void *user_data)
|
|||
ofono_voicecall_cb_t cb = cbd->cb;
|
||||
uint16_t error;
|
||||
struct qmi_voice_dial_call_result dial_result;
|
||||
struct ofono_call *call;
|
||||
|
||||
if (qmi_result_set_error(result, &error)) {
|
||||
DBG("QMI Error %d", error);
|
||||
|
@ -262,9 +266,11 @@ static void dial(struct ofono_voicecall *vc, const struct ofono_phone_number *ph
|
|||
static void answer_cb(struct qmi_result *result, void *user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
struct ofono_voicecall *vc = cbd->user;
|
||||
ofono_voicecall_cb_t cb = cbd->cb;
|
||||
uint16_t error;
|
||||
struct qmi_voice_answer_call_result answer_result;
|
||||
struct ofono_call *call;
|
||||
|
||||
if (qmi_result_set_error(result, &error)) {
|
||||
DBG("QMI Error %d", error);
|
||||
|
@ -322,9 +328,11 @@ err:
|
|||
static void end_cb(struct qmi_result *result, void *user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
struct ofono_voicecall *vc = cbd->user;
|
||||
ofono_voicecall_cb_t cb = cbd->cb;
|
||||
uint16_t error;
|
||||
struct qmi_voice_end_call_result end_result;
|
||||
struct ofono_call *call;
|
||||
|
||||
if (qmi_result_set_error(result, &error)) {
|
||||
DBG("QMI Error %d", error);
|
||||
|
@ -347,6 +355,7 @@ static void release_specific(struct ofono_voicecall *vc, int id,
|
|||
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
|
||||
struct cb_data *cbd = cb_data_new(cb, data);
|
||||
struct qmi_voice_end_call_arg arg;
|
||||
int i;
|
||||
|
||||
DBG("");
|
||||
cbd->user = vc;
|
||||
|
@ -369,19 +378,21 @@ static void hangup_active(struct ofono_voicecall *vc,
|
|||
ofono_voicecall_cb_t cb, void *data)
|
||||
{
|
||||
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
|
||||
struct qmi_voice_end_call_arg arg;
|
||||
struct ofono_call *call;
|
||||
GSList *list = NULL;
|
||||
enum call_status active[] = {
|
||||
CALL_STATUS_ACTIVE,
|
||||
CALL_STATUS_DIALING,
|
||||
CALL_STATUS_ALERTING
|
||||
CALL_STATUS_ALERTING,
|
||||
CALL_STATUS_INCOMING,
|
||||
};
|
||||
int i;
|
||||
|
||||
DBG("");
|
||||
for (i = 0; i < ARRAY_SIZE(active); i++) {
|
||||
list = g_slist_find_custom(vd->call_list,
|
||||
GINT_TO_POINTER(CALL_STATUS_ACTIVE),
|
||||
GINT_TO_POINTER(active[i]),
|
||||
ofono_call_compare_by_status);
|
||||
|
||||
if (list)
|
||||
|
|
|
@ -61,6 +61,9 @@
|
|||
/* size of RIL_CellInfoTdscdma */
|
||||
#define NETMON_RIL_CELLINFO_SIZE_TDSCDMA 24
|
||||
|
||||
#define MSECS_RATE_INVALID (0x7fffffff)
|
||||
#define SECS_TO_MSECS(x) ((x) * 1000)
|
||||
|
||||
struct netmon_data {
|
||||
GRil *ril;
|
||||
};
|
||||
|
@ -96,11 +99,9 @@ static int ril_cell_type_to_size(int cell_type)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ril_netmon_update_cb(struct ril_msg *message, gpointer user_data)
|
||||
static int process_cellinfo_list(struct ril_msg *message,
|
||||
struct ofono_netmon *netmon)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_netmon_cb_t cb = cbd->cb;
|
||||
struct ofono_netmon *netmon = cbd->data;
|
||||
struct parcel rilp;
|
||||
int skip_len;
|
||||
int cell_info_cnt;
|
||||
|
@ -114,7 +115,7 @@ static void ril_netmon_update_cb(struct ril_msg *message, gpointer user_data)
|
|||
int i, j;
|
||||
|
||||
if (message->error != RIL_E_SUCCESS)
|
||||
goto error;
|
||||
return OFONO_ERROR_TYPE_FAILURE;
|
||||
|
||||
g_ril_init_parcel(message, &rilp);
|
||||
|
||||
|
@ -146,7 +147,7 @@ static void ril_netmon_update_cb(struct ril_msg *message, gpointer user_data)
|
|||
}
|
||||
|
||||
if (!registered)
|
||||
goto error;
|
||||
return OFONO_ERROR_TYPE_FAILURE;
|
||||
|
||||
if (cell_type == NETMON_RIL_CELLINFO_TYPE_GSM) {
|
||||
mcc = parcel_r_int32(&rilp);
|
||||
|
@ -216,17 +217,53 @@ static void ril_netmon_update_cb(struct ril_msg *message, gpointer user_data)
|
|||
OFONO_NETMON_INFO_BER, ber,
|
||||
OFONO_NETMON_INFO_INVALID);
|
||||
|
||||
} else {
|
||||
goto error;
|
||||
}
|
||||
|
||||
CALLBACK_WITH_SUCCESS(cb, cbd->data);
|
||||
return;
|
||||
return OFONO_ERROR_TYPE_NO_ERROR;
|
||||
}
|
||||
|
||||
static void ril_netmon_update_cb(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_netmon_cb_t cb = cbd->cb;
|
||||
struct ofono_netmon *netmon = cbd->data;
|
||||
|
||||
if (process_cellinfo_list(message, netmon) ==
|
||||
OFONO_ERROR_TYPE_NO_ERROR) {
|
||||
CALLBACK_WITH_SUCCESS(cb, cbd->data);
|
||||
return;
|
||||
}
|
||||
|
||||
error:
|
||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
||||
}
|
||||
|
||||
static void ril_cellinfo_notify(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
struct ofono_netmon *netmon = user_data;
|
||||
|
||||
process_cellinfo_list(message, netmon);
|
||||
}
|
||||
|
||||
static void setup_cell_info_notify(struct ofono_netmon *netmon)
|
||||
{
|
||||
struct netmon_data *nmd = ofono_netmon_get_data(netmon);
|
||||
struct parcel rilp;
|
||||
|
||||
parcel_init(&rilp);
|
||||
|
||||
parcel_w_int32(&rilp, 1); /* Number of elements */
|
||||
|
||||
parcel_w_int32(&rilp, MSECS_RATE_INVALID);
|
||||
|
||||
if (g_ril_send(nmd->ril, RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE,
|
||||
&rilp, NULL, NULL, NULL) == 0)
|
||||
ofono_error("%s: setup failed\n", __func__);
|
||||
|
||||
if (g_ril_register(nmd->ril, RIL_UNSOL_CELL_INFO_LIST,
|
||||
ril_cellinfo_notify, netmon) == 0)
|
||||
ofono_error("%s: setup failed\n", __func__);
|
||||
}
|
||||
|
||||
static int ril_netmon_probe(struct ofono_netmon *netmon,
|
||||
unsigned int vendor, void *user)
|
||||
{
|
||||
|
@ -237,6 +274,8 @@ static int ril_netmon_probe(struct ofono_netmon *netmon,
|
|||
|
||||
ofono_netmon_set_data(netmon, ud);
|
||||
|
||||
setup_cell_info_notify(netmon);
|
||||
|
||||
g_idle_add(ril_delayed_register, netmon);
|
||||
|
||||
return 0;
|
||||
|
@ -257,18 +296,55 @@ static void ril_netmon_request_update(struct ofono_netmon *netmon,
|
|||
struct cb_data *cbd = cb_data_new(cb, data, nmd);
|
||||
|
||||
if (g_ril_send(nmd->ril, RIL_REQUEST_GET_CELL_INFO_LIST, NULL,
|
||||
ril_netmon_update_cb, cbd, NULL) > 0)
|
||||
ril_netmon_update_cb, cbd, g_free) > 0)
|
||||
return;
|
||||
|
||||
g_free(cbd);
|
||||
CALLBACK_WITH_FAILURE(cb, data);
|
||||
}
|
||||
|
||||
static void periodic_update_cb(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_netmon_cb_t cb = cbd->cb;
|
||||
|
||||
if (message->error != RIL_E_SUCCESS)
|
||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
||||
|
||||
CALLBACK_WITH_SUCCESS(cb, cbd->data);
|
||||
}
|
||||
|
||||
static void ril_netmon_periodic_update(struct ofono_netmon *netmon,
|
||||
unsigned int enable, unsigned int period,
|
||||
ofono_netmon_cb_t cb, void *data)
|
||||
{
|
||||
struct netmon_data *nmd = ofono_netmon_get_data(netmon);
|
||||
struct cb_data *cbd = cb_data_new(cb, data, nmd);
|
||||
struct parcel rilp;
|
||||
|
||||
parcel_init(&rilp);
|
||||
|
||||
parcel_w_int32(&rilp, 1); /* Number of elements */
|
||||
|
||||
if (enable)
|
||||
parcel_w_int32(&rilp, SECS_TO_MSECS(period));
|
||||
else
|
||||
parcel_w_int32(&rilp, MSECS_RATE_INVALID);
|
||||
|
||||
if (g_ril_send(nmd->ril, RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE,
|
||||
&rilp, periodic_update_cb, cbd, g_free) > 0)
|
||||
return;
|
||||
|
||||
g_free(cbd);
|
||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
||||
}
|
||||
|
||||
static struct ofono_netmon_driver driver = {
|
||||
.name = RILMODEM,
|
||||
.probe = ril_netmon_probe,
|
||||
.remove = ril_netmon_remove,
|
||||
.request_update = ril_netmon_request_update,
|
||||
.enable_periodic_update = ril_netmon_periodic_update,
|
||||
};
|
||||
|
||||
void ril_netmon_init(void)
|
||||
|
|
|
@ -0,0 +1,233 @@
|
|||
/*
|
||||
*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2017 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <ofono/log.h>
|
||||
#include <ofono/modem.h>
|
||||
#include <ofono/radio-settings.h>
|
||||
|
||||
#include "gatchat.h"
|
||||
#include "gatresult.h"
|
||||
|
||||
#include "xmm7modem.h"
|
||||
|
||||
static const char *none_prefix[] = { NULL };
|
||||
static const char *xact_prefix[] = { "+XACT:", NULL };
|
||||
|
||||
struct radio_settings_data {
|
||||
GAtChat *chat;
|
||||
};
|
||||
|
||||
static void xact_query_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_radio_settings_rat_mode_query_cb_t cb = cbd->cb;
|
||||
enum ofono_radio_access_mode mode;
|
||||
struct ofono_error error;
|
||||
GAtResultIter iter;
|
||||
int value, preferred;
|
||||
|
||||
decode_at_error(&error, g_at_result_final_response(result));
|
||||
|
||||
if (!ok) {
|
||||
cb(&error, -1, cbd->data);
|
||||
return;
|
||||
}
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
|
||||
if (g_at_result_iter_next(&iter, "+XACT:") == FALSE)
|
||||
goto error;
|
||||
|
||||
if (g_at_result_iter_next_number(&iter, &value) == FALSE)
|
||||
goto error;
|
||||
|
||||
if (g_at_result_iter_next_number(&iter, &preferred) == FALSE)
|
||||
goto error;
|
||||
|
||||
switch (value) {
|
||||
case 0:
|
||||
mode = OFONO_RADIO_ACCESS_MODE_GSM;
|
||||
break;
|
||||
case 1:
|
||||
mode = OFONO_RADIO_ACCESS_MODE_UMTS;
|
||||
break;
|
||||
case 2:
|
||||
mode = OFONO_RADIO_ACCESS_MODE_LTE;
|
||||
break;
|
||||
case 3:
|
||||
mode = OFONO_RADIO_ACCESS_MODE_UMTS;
|
||||
break;
|
||||
case 4:
|
||||
mode = OFONO_RADIO_ACCESS_MODE_LTE;
|
||||
break;
|
||||
case 5:
|
||||
mode = OFONO_RADIO_ACCESS_MODE_LTE;
|
||||
break;
|
||||
case 6:
|
||||
mode = OFONO_RADIO_ACCESS_MODE_ANY;
|
||||
break;
|
||||
default:
|
||||
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
|
||||
return;
|
||||
}
|
||||
|
||||
cb(&error, mode, cbd->data);
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
|
||||
}
|
||||
|
||||
static void xmm_query_rat_mode(struct ofono_radio_settings *rs,
|
||||
ofono_radio_settings_rat_mode_query_cb_t cb,
|
||||
void *data)
|
||||
{
|
||||
struct radio_settings_data *rsd = ofono_radio_settings_get_data(rs);
|
||||
struct cb_data *cbd = cb_data_new(cb, data);
|
||||
|
||||
if (g_at_chat_send(rsd->chat, "AT+XACT?", xact_prefix,
|
||||
xact_query_cb, cbd, g_free) > 0)
|
||||
return;
|
||||
|
||||
CALLBACK_WITH_FAILURE(cb, -1, data);
|
||||
g_free(cbd);
|
||||
}
|
||||
|
||||
static void xact_modify_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_radio_settings_rat_mode_set_cb_t cb = cbd->cb;
|
||||
struct ofono_error error;
|
||||
|
||||
decode_at_error(&error, g_at_result_final_response(result));
|
||||
cb(&error, cbd->data);
|
||||
}
|
||||
|
||||
static void xmm_set_rat_mode(struct ofono_radio_settings *rs,
|
||||
enum ofono_radio_access_mode mode,
|
||||
ofono_radio_settings_rat_mode_set_cb_t cb,
|
||||
void *data)
|
||||
{
|
||||
struct radio_settings_data *rsd = ofono_radio_settings_get_data(rs);
|
||||
struct cb_data *cbd = cb_data_new(cb, data);
|
||||
char buf[20];
|
||||
int value = 6, preferred = 2;
|
||||
|
||||
switch (mode) {
|
||||
case OFONO_RADIO_ACCESS_MODE_ANY:
|
||||
value = 6;
|
||||
break;
|
||||
case OFONO_RADIO_ACCESS_MODE_GSM:
|
||||
value = 0;
|
||||
break;
|
||||
case OFONO_RADIO_ACCESS_MODE_UMTS:
|
||||
value = 1;
|
||||
break;
|
||||
case OFONO_RADIO_ACCESS_MODE_LTE:
|
||||
value = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (value == 6)
|
||||
snprintf(buf, sizeof(buf), "AT+XACT=%u,%u", value, preferred);
|
||||
else
|
||||
snprintf(buf, sizeof(buf), "AT+XACT=%u", value);
|
||||
|
||||
if (g_at_chat_send(rsd->chat, buf, none_prefix,
|
||||
xact_modify_cb, cbd, g_free) > 0)
|
||||
return;
|
||||
|
||||
CALLBACK_WITH_FAILURE(cb, data);
|
||||
g_free(cbd);
|
||||
}
|
||||
|
||||
static void xact_support_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_radio_settings *rs = user_data;
|
||||
|
||||
if (!ok) {
|
||||
ofono_radio_settings_remove(rs);
|
||||
return;
|
||||
}
|
||||
|
||||
ofono_radio_settings_register(rs);
|
||||
}
|
||||
|
||||
static int xmm_radio_settings_probe(struct ofono_radio_settings *rs,
|
||||
unsigned int vendor, void *user)
|
||||
{
|
||||
GAtChat *chat = user;
|
||||
struct radio_settings_data *rsd;
|
||||
|
||||
rsd = g_try_new0(struct radio_settings_data, 1);
|
||||
if (rsd == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
rsd->chat = g_at_chat_clone(chat);
|
||||
|
||||
ofono_radio_settings_set_data(rs, rsd);
|
||||
|
||||
g_at_chat_send(rsd->chat, "AT+XACT=?", xact_prefix,
|
||||
xact_support_cb, rs, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xmm_radio_settings_remove(struct ofono_radio_settings *rs)
|
||||
{
|
||||
struct radio_settings_data *rsd = ofono_radio_settings_get_data(rs);
|
||||
|
||||
ofono_radio_settings_set_data(rs, NULL);
|
||||
|
||||
g_at_chat_unref(rsd->chat);
|
||||
g_free(rsd);
|
||||
}
|
||||
|
||||
static struct ofono_radio_settings_driver driver = {
|
||||
.name = "xmm7modem",
|
||||
.probe = xmm_radio_settings_probe,
|
||||
.remove = xmm_radio_settings_remove,
|
||||
.query_rat_mode = xmm_query_rat_mode,
|
||||
.set_rat_mode = xmm_set_rat_mode
|
||||
};
|
||||
|
||||
void xmm_radio_settings_init(void)
|
||||
{
|
||||
ofono_radio_settings_driver_register(&driver);
|
||||
}
|
||||
|
||||
void xmm_radio_settings_exit(void)
|
||||
{
|
||||
ofono_radio_settings_driver_unregister(&driver);
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2017 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <gatchat.h>
|
||||
|
||||
#define OFONO_API_SUBJECT_TO_CHANGE
|
||||
#include <ofono/plugin.h>
|
||||
#include <ofono/types.h>
|
||||
#include <ofono/modem.h>
|
||||
|
||||
#include "xmm7modem.h"
|
||||
|
||||
static int xmm7modem_init(void)
|
||||
{
|
||||
xmm_radio_settings_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xmm7modem_exit(void)
|
||||
{
|
||||
xmm_radio_settings_exit();
|
||||
}
|
||||
|
||||
OFONO_PLUGIN_DEFINE(xmm7modem, "Intel xmm7xxx series modem driver",
|
||||
VERSION, OFONO_PLUGIN_PRIORITY_DEFAULT,
|
||||
xmm7modem_init, xmm7modem_exit)
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2017 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <drivers/atmodem/atutil.h>
|
||||
|
||||
#define XMM7MODEM "xmm7modem"
|
||||
|
||||
extern void xmm_radio_settings_init(void);
|
||||
extern void xmm_radio_settings_exit(void);
|
|
@ -338,6 +338,8 @@ const char *ril_request_id_to_string(int req)
|
|||
return "RIL_REQUEST_GET_CELL_INFO_LIST";
|
||||
case RIL_REQUEST_SET_INITIAL_ATTACH_APN:
|
||||
return "RIL_REQUEST_SET_INITIAL_ATTACH_APN";
|
||||
case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE:
|
||||
return "RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE";
|
||||
default:
|
||||
return "<INVALID>";
|
||||
}
|
||||
|
@ -416,6 +418,8 @@ const char *ril_unsol_request_to_string(int request)
|
|||
return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
|
||||
case RIL_UNSOL_RIL_CONNECTED:
|
||||
return "UNSOL_RIL_CONNECTED";
|
||||
case RIL_UNSOL_CELL_INFO_LIST:
|
||||
return "RIL_UNSOL_CELL_INFO_LIST";
|
||||
default:
|
||||
return "<unknown request>";
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#define __PARCEL_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct parcel {
|
||||
char *data;
|
||||
|
|
|
@ -348,6 +348,7 @@
|
|||
#define RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS 107
|
||||
#define RIL_REQUEST_VOICE_RADIO_TECH 108
|
||||
#define RIL_REQUEST_GET_CELL_INFO_LIST 109
|
||||
#define RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE 110
|
||||
#define RIL_REQUEST_SET_INITIAL_ATTACH_APN 111
|
||||
|
||||
/* RIL Unsolicited Messages */
|
||||
|
@ -388,6 +389,7 @@
|
|||
#define RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE 1033
|
||||
#define RIL_UNSOL_RIL_CONNECTED 1034
|
||||
#define RIL_UNSOL_VOICE_RADIO_TECH_CHANGED 1035
|
||||
#define RIL_UNSOL_CELL_INFO_LIST 1036
|
||||
|
||||
/* Suplementary services Service class*/
|
||||
#define SERVICE_CLASS_NONE 0
|
||||
|
|
|
@ -61,6 +61,7 @@ extern "C" {
|
|||
#define OFONO_HANDSFREE_INTERFACE OFONO_SERVICE ".Handsfree"
|
||||
#define OFONO_SIRI_INTERFACE OFONO_SERVICE ".Siri"
|
||||
#define OFONO_NETMON_INTERFACE OFONO_SERVICE ".NetworkMonitor"
|
||||
#define OFONO_NETMON_AGENT_INTERFACE OFONO_SERVICE ".NetworkMonitorAgent"
|
||||
#define OFONO_LTE_INTERFACE OFONO_SERVICE ".LongTermEvolution"
|
||||
|
||||
/* CDMA Interfaces */
|
||||
|
|
|
@ -29,7 +29,13 @@ extern "C" {
|
|||
#include <ofono/types.h>
|
||||
|
||||
struct ofono_gprs_context;
|
||||
struct ofono_modem;
|
||||
|
||||
/*
|
||||
* ETSI 123.003, Section 9.1:
|
||||
* the APN has, after encoding as defined in the paragraph below, a maximum
|
||||
* length of 100 octets
|
||||
*/
|
||||
#define OFONO_GPRS_MAX_APN_LENGTH 100
|
||||
#define OFONO_GPRS_MAX_USERNAME_LENGTH 63
|
||||
#define OFONO_GPRS_MAX_PASSWORD_LENGTH 255
|
||||
|
|
|
@ -39,6 +39,10 @@ struct ofono_netmon_driver {
|
|||
void (*remove)(struct ofono_netmon *netmon);
|
||||
void (*request_update)(struct ofono_netmon *netmon,
|
||||
ofono_netmon_cb_t cb, void *data);
|
||||
void (*enable_periodic_update)(struct ofono_netmon *netmon,
|
||||
unsigned int enable,
|
||||
unsigned int period,
|
||||
ofono_netmon_cb_t cb, void *data);
|
||||
};
|
||||
|
||||
enum ofono_netmon_cell_type {
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <gatchat.h>
|
||||
|
|
|
@ -252,6 +252,15 @@ error:
|
|||
shutdown_device(modem);
|
||||
}
|
||||
|
||||
static void create_shared_dms(void *user_data)
|
||||
{
|
||||
struct ofono_modem *modem = user_data;
|
||||
struct gobi_data *data = ofono_modem_get_data(modem);
|
||||
|
||||
qmi_service_create_shared(data->device, QMI_SERVICE_DMS,
|
||||
create_dms_cb, modem, NULL);
|
||||
}
|
||||
|
||||
static void discover_cb(uint8_t count, const struct qmi_version *list,
|
||||
void *user_data)
|
||||
{
|
||||
|
@ -266,6 +275,13 @@ static void discover_cb(uint8_t count, const struct qmi_version *list,
|
|||
list[i].type);
|
||||
|
||||
switch (list[i].type) {
|
||||
case QMI_SERVICE_CONTROL:
|
||||
/* sync command resets the QMI state */
|
||||
if (list[i].major > 1 || list[i].minor >= 5)
|
||||
ofono_modem_set_boolean(modem,
|
||||
"SupportQMISync",
|
||||
TRUE);
|
||||
break;
|
||||
case QMI_SERVICE_DMS:
|
||||
data->features |= GOBI_DMS;
|
||||
break;
|
||||
|
@ -314,18 +330,10 @@ static void discover_cb(uint8_t count, const struct qmi_version *list,
|
|||
return;
|
||||
}
|
||||
|
||||
qmi_service_create_shared(data->device, QMI_SERVICE_DMS,
|
||||
create_dms_cb, modem, NULL);
|
||||
}
|
||||
|
||||
static void sync_cb(void *user_data)
|
||||
{
|
||||
struct ofono_modem *modem = user_data;
|
||||
struct gobi_data *data = ofono_modem_get_data(modem);
|
||||
|
||||
DBG("modem in sync");
|
||||
|
||||
qmi_device_discover(data->device, discover_cb, modem, NULL);
|
||||
if (ofono_modem_get_boolean(modem, "SupportQMISync") == TRUE)
|
||||
qmi_device_sync(data->device, create_shared_dms, modem);
|
||||
else
|
||||
create_shared_dms(modem);
|
||||
}
|
||||
|
||||
static int gobi_enable(struct ofono_modem *modem)
|
||||
|
@ -355,7 +363,7 @@ static int gobi_enable(struct ofono_modem *modem)
|
|||
|
||||
qmi_device_set_close_on_unref(data->device, true);
|
||||
|
||||
qmi_device_sync(data->device, sync_cb, modem);
|
||||
qmi_device_discover(data->device, discover_cb, modem, NULL);
|
||||
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
|
|
|
@ -261,18 +261,34 @@ static gboolean setup_sierra(struct modem_info *modem)
|
|||
if (g_strcmp0(info->interface, "255/255/255") == 0) {
|
||||
if (g_strcmp0(info->number, "01") == 0)
|
||||
diag = info->devnode;
|
||||
if (g_strcmp0(info->number, "03") == 0)
|
||||
else if (g_strcmp0(info->number, "03") == 0)
|
||||
mdm = info->devnode;
|
||||
else if (g_strcmp0(info->number, "04") == 0)
|
||||
app = info->devnode;
|
||||
else if (g_strcmp0(info->number, "07") == 0)
|
||||
net = info->devnode;
|
||||
else if (g_strcmp0(info->number, "0a") == 0) {
|
||||
if (g_strcmp0(info->subsystem, "net") == 0)
|
||||
else if (g_strcmp0(info->subsystem, "net") == 0) {
|
||||
/*
|
||||
* When using the voice firmware on a mc7304
|
||||
* the second cdc-wdm interface doesn't handle
|
||||
* qmi messages properly.
|
||||
* Some modems still have a working second
|
||||
* cdc-wdm interface, some are not. But always
|
||||
* the first interface works.
|
||||
*/
|
||||
if (g_strcmp0(info->number, "08") == 0) {
|
||||
net = info->devnode;
|
||||
else if (g_strcmp0(info->subsystem,
|
||||
"usbmisc") == 0)
|
||||
} else if (g_strcmp0(info->number, "0a") == 0) {
|
||||
if (net == NULL)
|
||||
net = info->devnode;
|
||||
}
|
||||
} else if (g_strcmp0(info->subsystem, "usbmisc") == 0) {
|
||||
if (g_strcmp0(info->number, "08") == 0) {
|
||||
qmi = info->devnode;
|
||||
} else if (g_strcmp0(info->number, "0a") == 0) {
|
||||
if (qmi == NULL)
|
||||
qmi = info->devnode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -860,7 +876,7 @@ static gboolean setup_quectel(struct modem_info *modem)
|
|||
|
||||
static gboolean setup_quectelqmi(struct modem_info *modem)
|
||||
{
|
||||
const char *qmi = NULL, *net = NULL, *gps = NULL;
|
||||
const char *qmi = NULL, *net = NULL, *gps = NULL, *aux = NULL;
|
||||
GSList *list;
|
||||
|
||||
DBG("%s", modem->syspath);
|
||||
|
@ -878,8 +894,11 @@ static gboolean setup_quectelqmi(struct modem_info *modem)
|
|||
else if (g_strcmp0(info->subsystem, "usbmisc") == 0)
|
||||
qmi = info->devnode;
|
||||
} else if (g_strcmp0(info->interface, "255/0/0") == 0 &&
|
||||
g_strcmp0(info->number, "02") == 0) {
|
||||
g_strcmp0(info->number, "01") == 0) {
|
||||
gps = info->devnode;
|
||||
} else if (g_strcmp0(info->interface, "255/0/0") == 0 &&
|
||||
g_strcmp0(info->number, "02") == 0) {
|
||||
aux = info->devnode;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -893,8 +912,12 @@ static gboolean setup_quectelqmi(struct modem_info *modem)
|
|||
ofono_modem_set_string(modem->modem, "Device", qmi);
|
||||
ofono_modem_set_string(modem->modem, "NetworkInterface", net);
|
||||
|
||||
DBG("gps=%s aux=%s", gps, aux);
|
||||
|
||||
if (gps)
|
||||
ofono_modem_set_string(modem->modem, "GPS", gps);
|
||||
if (aux)
|
||||
ofono_modem_set_string(modem->modem, "Aux", aux);
|
||||
|
||||
ofono_modem_set_driver(modem->modem, "gobi");
|
||||
|
||||
|
|
25
src/common.c
25
src/common.c
|
@ -704,6 +704,9 @@ gboolean is_valid_apn(const char *apn)
|
|||
int i;
|
||||
int last_period = 0;
|
||||
|
||||
if (apn == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (apn[0] == '.' || apn[0] == '\0')
|
||||
return FALSE;
|
||||
|
||||
|
@ -742,6 +745,28 @@ void ofono_call_init(struct ofono_call *call)
|
|||
call->clip_validity = CLIP_VALIDITY_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
const char *call_status_to_string(enum call_status status)
|
||||
{
|
||||
switch (status) {
|
||||
case CALL_STATUS_ACTIVE:
|
||||
return "active";
|
||||
case CALL_STATUS_HELD:
|
||||
return "held";
|
||||
case CALL_STATUS_DIALING:
|
||||
return "dialing";
|
||||
case CALL_STATUS_ALERTING:
|
||||
return "alerting";
|
||||
case CALL_STATUS_INCOMING:
|
||||
return "incoming";
|
||||
case CALL_STATUS_WAITING:
|
||||
return "waiting";
|
||||
case CALL_STATUS_DISCONNECTED:
|
||||
return "disconnected";
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
gint ofono_call_compare(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
const struct ofono_call *ca = a;
|
||||
|
|
|
@ -184,6 +184,7 @@ const char *registration_tech_to_string(int tech);
|
|||
const char *packet_bearer_to_string(int bearer);
|
||||
|
||||
gboolean is_valid_apn(const char *apn);
|
||||
const char *call_status_to_string(enum call_status status);
|
||||
|
||||
gint ofono_call_compare(gconstpointer a, gconstpointer b);
|
||||
gint ofono_call_compare_by_status(gconstpointer a, gconstpointer b);
|
||||
|
|
|
@ -2596,10 +2596,14 @@ void ofono_gprs_detached_notify(struct ofono_gprs *gprs)
|
|||
|
||||
void ofono_gprs_status_notify(struct ofono_gprs *gprs, int status)
|
||||
{
|
||||
DBG("%s status %d", __ofono_atom_get_path(gprs->atom), status);
|
||||
DBG("%s status %s (%d)", __ofono_atom_get_path(gprs->atom),
|
||||
registration_status_to_string(status), status);
|
||||
|
||||
gprs->status = status;
|
||||
|
||||
if (status == 0)
|
||||
ofono_gprs_detached_notify(gprs);
|
||||
|
||||
if (status != NETWORK_REGISTRATION_STATUS_REGISTERED &&
|
||||
status != NETWORK_REGISTRATION_STATUS_ROAMING) {
|
||||
gprs_attached_update(gprs);
|
||||
|
|
126
src/netmon.c
126
src/netmon.c
|
@ -34,6 +34,7 @@
|
|||
#include <gdbus.h>
|
||||
|
||||
#include "ofono.h"
|
||||
#include "netmonagent.h"
|
||||
|
||||
#define CELL_INFO_DICT_APPEND(p_dict, key, info, type, dbus_type) do { \
|
||||
type value; \
|
||||
|
@ -51,6 +52,7 @@ struct ofono_netmon {
|
|||
DBusMessage *reply;
|
||||
void *driver_data;
|
||||
struct ofono_atom *atom;
|
||||
struct netmon_agent *agent;
|
||||
};
|
||||
|
||||
static const char *cell_type_to_tech_name(enum ofono_netmon_cell_type type)
|
||||
|
@ -72,6 +74,7 @@ void ofono_netmon_serving_cell_notify(struct ofono_netmon *netmon,
|
|||
int info_type, ...)
|
||||
{
|
||||
va_list arglist;
|
||||
DBusMessage *agent_notify = NULL;
|
||||
DBusMessageIter iter;
|
||||
DBusMessageIter dict;
|
||||
enum ofono_netmon_info next_info_type = info_type;
|
||||
|
@ -79,13 +82,18 @@ void ofono_netmon_serving_cell_notify(struct ofono_netmon *netmon,
|
|||
char *mcc;
|
||||
char *mnc;
|
||||
int intval;
|
||||
netmon->reply = dbus_message_new_method_return(netmon->pending);
|
||||
|
||||
if (netmon->reply == NULL)
|
||||
if (netmon->pending != NULL) {
|
||||
netmon->reply = dbus_message_new_method_return(netmon->pending);
|
||||
dbus_message_iter_init_append(netmon->reply, &iter);
|
||||
} else if (netmon->agent != NULL) {
|
||||
agent_notify = netmon_agent_new_method_call(netmon->agent,
|
||||
"ServingCellInformationChanged");
|
||||
|
||||
dbus_message_iter_init_append(agent_notify, &iter);
|
||||
} else
|
||||
return;
|
||||
|
||||
dbus_message_iter_init_append(netmon->reply, &iter);
|
||||
|
||||
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
|
||||
OFONO_PROPERTIES_ARRAY_SIGNATURE,
|
||||
&dict);
|
||||
|
@ -243,6 +251,9 @@ done:
|
|||
va_end(arglist);
|
||||
|
||||
dbus_message_iter_close_container(&iter, &dict);
|
||||
|
||||
if (agent_notify)
|
||||
netmon_agent_send_no_reply(netmon->agent, agent_notify);
|
||||
}
|
||||
|
||||
static void serving_cell_info_callback(const struct ofono_error *error,
|
||||
|
@ -291,10 +302,117 @@ static DBusMessage *netmon_get_serving_cell_info(DBusConnection *conn,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void periodic_updates_enabled_cb(const struct ofono_error *error,
|
||||
void *data)
|
||||
{
|
||||
struct ofono_netmon *netmon = data;
|
||||
|
||||
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
|
||||
ofono_error("Error enabling periodic updates");
|
||||
|
||||
netmon_agent_free(netmon->agent);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void periodic_updates_disabled_cb(const struct ofono_error *error,
|
||||
void *data)
|
||||
{
|
||||
if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
|
||||
ofono_error("Error disabling periodic updates");
|
||||
}
|
||||
|
||||
static void agent_removed_cb(gpointer user_data)
|
||||
{
|
||||
struct ofono_netmon *netmon = user_data;
|
||||
|
||||
netmon->agent = NULL;
|
||||
|
||||
netmon->driver->enable_periodic_update(netmon, 0, 0,
|
||||
periodic_updates_disabled_cb,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static DBusMessage *netmon_register_agent(DBusConnection *conn,
|
||||
DBusMessage *msg, void *data)
|
||||
{
|
||||
struct ofono_netmon *netmon = data;
|
||||
const char *agent_path;
|
||||
const unsigned int enable = 1;
|
||||
unsigned int period;
|
||||
|
||||
if (netmon->agent)
|
||||
return __ofono_error_busy(msg);
|
||||
|
||||
if (!netmon->driver->enable_periodic_update)
|
||||
return __ofono_error_not_implemented(msg);
|
||||
|
||||
if (dbus_message_get_args(msg, NULL,
|
||||
DBUS_TYPE_OBJECT_PATH, &agent_path,
|
||||
DBUS_TYPE_UINT32, &period,
|
||||
DBUS_TYPE_INVALID) == FALSE)
|
||||
return __ofono_error_invalid_args(msg);
|
||||
|
||||
if (!__ofono_dbus_valid_object_path(agent_path))
|
||||
return __ofono_error_invalid_format(msg);
|
||||
|
||||
if (!period)
|
||||
return __ofono_error_invalid_args(msg);
|
||||
|
||||
/* minimum period is 5 seconds, to avoid frequent updates*/
|
||||
if (period < 5)
|
||||
period = 5;
|
||||
|
||||
netmon->agent = netmon_agent_new(agent_path,
|
||||
dbus_message_get_sender(msg));
|
||||
|
||||
if (netmon->agent == NULL)
|
||||
return __ofono_error_failed(msg);
|
||||
|
||||
netmon_agent_set_removed_notify(netmon->agent, agent_removed_cb, netmon);
|
||||
|
||||
netmon->driver->enable_periodic_update(netmon, enable, period,
|
||||
periodic_updates_enabled_cb, netmon);
|
||||
|
||||
return dbus_message_new_method_return(msg);
|
||||
}
|
||||
|
||||
static DBusMessage *netmon_unregister_agent(DBusConnection *conn,
|
||||
DBusMessage *msg, void *data)
|
||||
{
|
||||
struct ofono_netmon *netmon = data;
|
||||
const char *agent_path;
|
||||
const char *agent_bus = dbus_message_get_sender(msg);
|
||||
|
||||
if (!netmon->driver->enable_periodic_update)
|
||||
return __ofono_error_not_implemented(msg);
|
||||
|
||||
if (dbus_message_get_args(msg, NULL,
|
||||
DBUS_TYPE_OBJECT_PATH, &agent_path,
|
||||
DBUS_TYPE_INVALID) == FALSE)
|
||||
return __ofono_error_invalid_args(msg);
|
||||
|
||||
if (netmon->agent == NULL)
|
||||
return __ofono_error_failed(msg);
|
||||
|
||||
if (!netmon_agent_matches(netmon->agent, agent_path, agent_bus))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
netmon_agent_free(netmon->agent);
|
||||
|
||||
return dbus_message_new_method_return(msg);
|
||||
}
|
||||
|
||||
static const GDBusMethodTable netmon_methods[] = {
|
||||
{ GDBUS_ASYNC_METHOD("GetServingCellInformation",
|
||||
NULL, GDBUS_ARGS({ "cellinfo", "a{sv}" }),
|
||||
netmon_get_serving_cell_info) },
|
||||
{ GDBUS_METHOD("RegisterAgent",
|
||||
GDBUS_ARGS({ "path", "o"}, { "period", "u"}), NULL,
|
||||
netmon_register_agent) },
|
||||
{ GDBUS_METHOD("UnregisterAgent",
|
||||
GDBUS_ARGS({ "agent", "o" }), NULL,
|
||||
netmon_unregister_agent) },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <gdbus.h>
|
||||
|
||||
#include "ofono.h"
|
||||
#include "netmonagent.h"
|
||||
|
||||
struct netmon_agent {
|
||||
char *path;
|
||||
char *bus;
|
||||
guint disconnect_watch;
|
||||
ofono_destroy_func removed_cb;
|
||||
void *removed_data;
|
||||
};
|
||||
|
||||
DBusMessage *netmon_agent_new_method_call(struct netmon_agent *agent,
|
||||
const char *method)
|
||||
{
|
||||
DBusMessage *msg = dbus_message_new_method_call(agent->bus,
|
||||
agent->path,
|
||||
OFONO_NETMON_AGENT_INTERFACE,
|
||||
method);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
void netmon_agent_send_no_reply(struct netmon_agent *agent,
|
||||
DBusMessage *message)
|
||||
{
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
|
||||
dbus_message_set_no_reply(message, TRUE);
|
||||
|
||||
g_dbus_send_message(conn, message);
|
||||
}
|
||||
|
||||
static inline void netmon_agent_send_release(struct netmon_agent *agent)
|
||||
{
|
||||
DBusMessage *msg = netmon_agent_new_method_call(agent, "Release");
|
||||
|
||||
netmon_agent_send_no_reply(agent, msg);
|
||||
}
|
||||
|
||||
ofono_bool_t netmon_agent_matches(struct netmon_agent *agent,
|
||||
const char *path, const char *sender)
|
||||
{
|
||||
return g_str_equal(agent->path, path) &&
|
||||
g_str_equal(agent->bus, sender);
|
||||
}
|
||||
|
||||
ofono_bool_t netmon_agent_sender_matches(struct netmon_agent *agent,
|
||||
const char *sender)
|
||||
{
|
||||
return g_str_equal(agent->bus, sender);
|
||||
}
|
||||
|
||||
void netmon_agent_set_removed_notify(struct netmon_agent *agent,
|
||||
ofono_destroy_func destroy,
|
||||
void *user_data)
|
||||
{
|
||||
agent->removed_cb = destroy;
|
||||
agent->removed_data = user_data;
|
||||
}
|
||||
|
||||
void netmon_agent_free(struct netmon_agent *agent)
|
||||
{
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
|
||||
if (agent == NULL)
|
||||
return;
|
||||
|
||||
if (agent->disconnect_watch) {
|
||||
netmon_agent_send_release(agent);
|
||||
g_dbus_remove_watch(conn, agent->disconnect_watch);
|
||||
agent->disconnect_watch = 0;
|
||||
}
|
||||
|
||||
if (agent->removed_cb)
|
||||
agent->removed_cb(agent->removed_data);
|
||||
|
||||
g_free(agent->path);
|
||||
g_free(agent->bus);
|
||||
g_free(agent);
|
||||
}
|
||||
|
||||
static void netmon_agent_disconnect_cb(DBusConnection *conn, void *user_data)
|
||||
{
|
||||
struct netmon_agent *agent = user_data;
|
||||
|
||||
ofono_debug("Agent exited without calling UnregisterAgent");
|
||||
|
||||
agent->disconnect_watch = 0;
|
||||
|
||||
netmon_agent_free(agent);
|
||||
}
|
||||
|
||||
struct netmon_agent *netmon_agent_new(const char *path,
|
||||
const char *sender)
|
||||
{
|
||||
struct netmon_agent *agent = g_try_new0(struct netmon_agent, 1);
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
|
||||
if (agent == NULL)
|
||||
return NULL;
|
||||
|
||||
agent->bus = g_strdup(sender);
|
||||
agent->path = g_strdup(path);
|
||||
|
||||
agent->disconnect_watch = g_dbus_add_disconnect_watch(conn, sender,
|
||||
netmon_agent_disconnect_cb,
|
||||
agent, NULL);
|
||||
|
||||
return agent;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
struct netmon_agent;
|
||||
|
||||
struct netmon_agent *netmon_agent_new(const char *path, const char *sender);
|
||||
|
||||
void netmon_agent_free(struct netmon_agent *agent);
|
||||
|
||||
void netmon_agent_set_removed_notify(struct netmon_agent *agent,
|
||||
ofono_destroy_func removed_cb,
|
||||
void *user_data);
|
||||
|
||||
ofono_bool_t netmon_agent_matches(struct netmon_agent *agent,
|
||||
const char *path, const char *sender);
|
||||
|
||||
ofono_bool_t netmon_agent_sender_matches(struct netmon_agent *agent,
|
||||
const char *sender);
|
||||
|
||||
DBusMessage *netmon_agent_new_method_call(struct netmon_agent *netmon,
|
||||
const char *method);
|
||||
|
||||
void netmon_agent_send_no_reply(struct netmon_agent *agent,
|
||||
DBusMessage *message);
|
||||
|
||||
void netmon_agent_test(struct netmon_agent *agent);
|
|
@ -1186,6 +1186,9 @@ static void notify_status_watches(struct ofono_netreg *netreg)
|
|||
const char *mcc = NULL;
|
||||
const char *mnc = NULL;
|
||||
|
||||
if (netreg->status_watches == NULL)
|
||||
return;
|
||||
|
||||
if (netreg->current_operator) {
|
||||
mcc = netreg->current_operator->mcc;
|
||||
mnc = netreg->current_operator->mnc;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
<allow send_interface="org.ofono.SmartMessagingAgent"/>
|
||||
<allow send_interface="org.ofono.PositioningRequestAgent"/>
|
||||
<allow send_interface="org.ofono.HandsfreeAudioAgent"/>
|
||||
<allow send_interface="org.ofono.NetworkMonitorAgent"/>
|
||||
</policy>
|
||||
|
||||
<policy at_console="true">
|
||||
|
|
|
@ -167,7 +167,7 @@ static gboolean radio_band_umts_from_string(const char *str,
|
|||
enum ofono_radio_band_umts *band)
|
||||
{
|
||||
if (g_str_equal(str, "any")) {
|
||||
*band = OFONO_RADIO_BAND_GSM_ANY;
|
||||
*band = OFONO_RADIO_BAND_UMTS_ANY;
|
||||
return TRUE;
|
||||
} else if (g_str_equal(str, "850")) {
|
||||
*band = OFONO_RADIO_BAND_UMTS_850;
|
||||
|
|
|
@ -1171,7 +1171,8 @@ static gboolean compute_incoming_msgid(GSList *sms_list,
|
|||
static void dispatch_app_datagram(struct ofono_sms *sms,
|
||||
const struct ofono_uuid *uuid,
|
||||
int dst, int src,
|
||||
unsigned char *buf, unsigned len,
|
||||
const unsigned char *buf,
|
||||
unsigned int len,
|
||||
const struct sms_address *addr,
|
||||
const struct sms_scts *scts)
|
||||
{
|
||||
|
|
14
src/ussd.c
14
src/ussd.c
|
@ -511,6 +511,20 @@ void ofono_ussd_notify(struct ofono_ussd *ussd, int status, int dcs,
|
|||
DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID);
|
||||
|
||||
ussd_change_state(ussd, new_state);
|
||||
goto free;
|
||||
} else if (ussd->state == USSD_STATE_USER_ACTION &&
|
||||
status != OFONO_USSD_STATUS_ACTION_REQUIRED) {
|
||||
ussd_change_state(ussd, USSD_STATE_IDLE);
|
||||
|
||||
if (status == OFONO_USSD_STATUS_NOTIFY && str && str[0]) {
|
||||
const char *path = __ofono_atom_get_path(ussd->atom);
|
||||
|
||||
g_dbus_emit_signal(conn, path,
|
||||
OFONO_SUPPLEMENTARY_SERVICES_INTERFACE,
|
||||
"NotificationReceived", DBUS_TYPE_STRING,
|
||||
&str, DBUS_TYPE_INVALID);
|
||||
}
|
||||
|
||||
goto free;
|
||||
} else {
|
||||
ofono_error("Received an unsolicited USSD but can't handle.");
|
||||
|
|
|
@ -2252,7 +2252,7 @@ void ofono_voicecall_notify(struct ofono_voicecall *vc,
|
|||
|
||||
DBG("Got a voicecall event, status: %s (%d), id: %u, number: %s"
|
||||
" called_number: %s, called_name %s",
|
||||
ofono_call_status_to_string(call->status),
|
||||
call_status_to_string(call->status),
|
||||
call->status, call->id, call->phone_number.number,
|
||||
call->called_number.number, call->name);
|
||||
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
from gi.repository import GLib
|
||||
|
||||
import sys
|
||||
import dbus
|
||||
import dbus.service
|
||||
import dbus.mainloop.glib
|
||||
|
||||
NETMON_INTERFACE = "org.ofono.NetworkMonitor"
|
||||
AGENT_INTERFACE = "org.ofono.NetworkMonitorAgent"
|
||||
|
||||
class NetworkMonitorAgent(dbus.service.Object):
|
||||
@dbus.service.method(AGENT_INTERFACE,
|
||||
in_signature="", out_signature="")
|
||||
def Release(self):
|
||||
print("Agent Released")
|
||||
mainloop.quit()
|
||||
|
||||
@dbus.service.method(AGENT_INTERFACE,
|
||||
in_signature="a{sv}", out_signature="")
|
||||
def ServingCellInformationChanged(self, servingcell):
|
||||
print("ServingCellInformationChanged notification recieved")
|
||||
|
||||
tech = 'Technology'
|
||||
mcc = 'MobileCountryCode'
|
||||
mnc = 'MobileNetworkCode'
|
||||
lac = 'LocationAreaCode'
|
||||
cid = 'CellId'
|
||||
psc = 'PrimaryScramblingCode'
|
||||
rssi = 'Strength'
|
||||
ber = 'BitErrorRate'
|
||||
|
||||
if tech in servingcell:
|
||||
print(" [ Radio Access Technology = %s]" \
|
||||
% (servingcell[tech]))
|
||||
|
||||
if mcc in servingcell:
|
||||
print(" [ Mobile Country Code = %s]" \
|
||||
% (servingcell[mcc]))
|
||||
|
||||
if mnc in servingcell:
|
||||
print(" [ Mobile Network Code = %s]" \
|
||||
% (servingcell[mnc]))
|
||||
|
||||
if lac in servingcell:
|
||||
print(" [ Location Area Code = %d]" \
|
||||
% (servingcell[lac]))
|
||||
|
||||
if cid in servingcell:
|
||||
print(" [ Cell Identity = %d]" \
|
||||
% (servingcell[cid]))
|
||||
|
||||
if psc in servingcell:
|
||||
print(" [ Primary Scrambling Code = %d]" \
|
||||
% (servingcell[psc]))
|
||||
|
||||
if rssi in servingcell:
|
||||
print(" [ Signal Strength = %d]" \
|
||||
% (servingcell[rssi]))
|
||||
|
||||
if ber in servingcell:
|
||||
print(" [ Bit Error Rate = %d]" \
|
||||
% (servingcell[ber]))
|
||||
|
||||
print('')
|
||||
|
||||
if __name__ == '__main__':
|
||||
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: %s <update_period_in_seconds>" %\
|
||||
(sys.argv[0]))
|
||||
sys.exit(1)
|
||||
|
||||
bus = dbus.SystemBus()
|
||||
manager = dbus.Interface(bus.get_object("org.ofono", "/"),
|
||||
"org.ofono.Manager")
|
||||
|
||||
modems = manager.GetModems()
|
||||
path = modems[0][0]
|
||||
nm = dbus.Interface(bus.get_object('org.ofono', path),
|
||||
NETMON_INTERFACE)
|
||||
|
||||
path = "/test/netmonagent"
|
||||
agent = NetworkMonitorAgent(bus, path)
|
||||
|
||||
try:
|
||||
period = int(sys.argv[1])
|
||||
except:
|
||||
print("Error: Invalid argument %s" % (sys.argv[1]))
|
||||
sys.exit(1)
|
||||
|
||||
nm.RegisterAgent(path, period)
|
||||
print("Agent registered")
|
||||
mainloop = GLib.MainLoop()
|
||||
mainloop.run()
|
|
@ -178,12 +178,12 @@ static void test_ber_tlv_builder_efpnn(void)
|
|||
ber_tlv_builder_optimize(&builder, NULL, NULL);
|
||||
|
||||
eons_info = sim_eons_new(1);
|
||||
sim_eons_add_pnn_record(eons_info, 1, efpnn0, sizeof(efpnn0));
|
||||
sim_eons_add_pnn_record(eons_info, 1, efpnn0, 8 + 10);
|
||||
g_assert(!sim_eons_pnn_is_empty(eons_info));
|
||||
sim_eons_free(eons_info);
|
||||
|
||||
eons_info = sim_eons_new(1);
|
||||
sim_eons_add_pnn_record(eons_info, 1, efpnn1, sizeof(efpnn1));
|
||||
sim_eons_add_pnn_record(eons_info, 1, efpnn1, 8 + 6);
|
||||
g_assert(!sim_eons_pnn_is_empty(eons_info));
|
||||
sim_eons_free(eons_info);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue