forked from sailfishos/ofono
Compare commits
62 Commits
mer/1.23+g
...
mer/1.24+g
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7684dd4295 | ||
|
|
f24a5be4ec | ||
|
|
c45e207f12 | ||
|
|
005f36bb89 | ||
|
|
3d01485a05 | ||
|
|
cc7b30414f | ||
|
|
1617b325de | ||
|
|
a8838c2287 | ||
|
|
c8cd552851 | ||
|
|
6995d8c42c | ||
|
|
17052d41de | ||
|
|
70a93dcc5b | ||
|
|
e3ea3abaa0 | ||
|
|
f60c44b034 | ||
|
|
a679258b4a | ||
|
|
0ed72bcffa | ||
|
|
7d5a660604 | ||
|
|
d67240c717 | ||
|
|
b12016eb45 | ||
|
|
bfec98afdf | ||
|
|
7376781211 | ||
|
|
732160519a | ||
|
|
f71d2a2b70 | ||
|
|
793e9fcae4 | ||
|
|
ae204ebf82 | ||
|
|
30b09b35af | ||
|
|
1495f222b0 | ||
|
|
b9b2765b21 | ||
|
|
29ecf1a59a | ||
|
|
f1d3367e0a | ||
|
|
7131403177 | ||
|
|
ff99f16ccb | ||
|
|
ccec9504a5 | ||
|
|
e37ca6d384 | ||
|
|
ab5b76d6cf | ||
|
|
35ef8fb8a1 | ||
|
|
d0a617d469 | ||
|
|
1ba3b32273 | ||
|
|
14b764ac64 | ||
|
|
b808bfad17 | ||
|
|
82d62a8f50 | ||
|
|
23d6263e3c | ||
|
|
ac3192204c | ||
|
|
5ad2617ecd | ||
|
|
890842b3af | ||
|
|
06de44299a | ||
|
|
77b2eec613 | ||
|
|
12ccd7cd46 | ||
|
|
8f09880d52 | ||
|
|
ee5f91221b | ||
|
|
c03c6f4215 | ||
|
|
c49e2d8723 | ||
|
|
deecd829a6 | ||
|
|
3acf91c6a9 | ||
|
|
85b61c8964 | ||
|
|
8986749585 | ||
|
|
1c0f5094a6 | ||
|
|
4208b6d9ea | ||
|
|
59e304d474 | ||
|
|
30a2424507 | ||
|
|
e4f3ec6322 | ||
|
|
95fd4efc37 |
2
ofono/.gitignore
vendored
2
ofono/.gitignore
vendored
@@ -9,7 +9,7 @@ Makefile.in
|
||||
aclocal.m4
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
config.h.in*
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
|
||||
@@ -130,3 +130,8 @@ Joey Hewitt <joey@joeyhewitt.com>
|
||||
Richard Röjfors <richard.rojfors@gmail.com>
|
||||
Philippe De Swert <philippe.deswert@nomovok.com>
|
||||
Gabriel Lucas <gabriel.lucas@smile.fr>
|
||||
Mariem Cherif <mariem.cherif@ardia.com.tn>
|
||||
Bassem Boubaker <bassem.boubaker@actia.fr>
|
||||
Bob Ham <bob.ham@puri.sm>
|
||||
Varun Gargi <varun.gargi@intel.com>
|
||||
Florent Beillonnet <florent.beillonnet@gmail.com>
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
ver 1.24:
|
||||
Fix issue with property changed signals and CDMA networks.
|
||||
Fix issue with handling SIM filesystem and SIM removal.
|
||||
Fix issue with handling PIN state and incorrect codes.
|
||||
Fix issue with handling of parsing AID type.
|
||||
Fix issue with SIM detection and QMI devices.
|
||||
Fix issue with PIN handling and QMI devices.
|
||||
Fix issue with USSD handling and QMI devices.
|
||||
Fix issue with handling USSD TERMINATED response.
|
||||
Fix issue with handling USSD reset and STK REFRESH.
|
||||
Add support for detecting Gemalto ALS3 modems.
|
||||
Add support for SIMCom based SIM7100E modems.
|
||||
|
||||
ver 1.23:
|
||||
Fix issue with handling SIM AID sessions.
|
||||
Add support for QMI LTE bearer handling.
|
||||
|
||||
@@ -573,6 +573,12 @@ builtin_sources += plugins/samsung.c
|
||||
builtin_modules += sim900
|
||||
builtin_sources += plugins/sim900.c
|
||||
|
||||
builtin_modules += sim7100
|
||||
builtin_sources += plugins/sim7100.c
|
||||
|
||||
builtin_modules += connman
|
||||
builtin_sources += plugins/connman.c
|
||||
|
||||
builtin_modules += telit
|
||||
builtin_sources += plugins/telit.c
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
AC_PREREQ(2.60)
|
||||
AC_INIT(ofono, 1.23)
|
||||
AC_INIT(ofono, 1.24)
|
||||
|
||||
AM_INIT_AUTOMAKE([foreign subdir-objects color-tests])
|
||||
AC_CONFIG_HEADERS(config.h)
|
||||
|
||||
@@ -48,6 +48,51 @@ struct cbs_data {
|
||||
unsigned int vendor;
|
||||
};
|
||||
|
||||
static void at_xmm_etw_sec_notify(GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_cbs *cbs = user_data;
|
||||
const char *hexpdu;
|
||||
int pdulen;
|
||||
GAtResultIter iter;
|
||||
unsigned char pdu[88];
|
||||
long hexpdulen;
|
||||
|
||||
DBG("");
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
|
||||
if (!g_at_result_iter_next(&iter, "+XETWSECWARN:"))
|
||||
return;
|
||||
|
||||
if (!g_at_result_iter_next_number(&iter, &pdulen))
|
||||
return;
|
||||
|
||||
if (pdulen != 88) {
|
||||
ofono_error("Got a CBM message with invalid PDU size!");
|
||||
return;
|
||||
}
|
||||
|
||||
hexpdu = g_at_result_pdu(result);
|
||||
if (hexpdu == NULL) {
|
||||
ofono_error("Got a CBM, but no PDU. Are we in text mode?");
|
||||
return;
|
||||
}
|
||||
|
||||
DBG("Got new Cell Broadcast via XETWSECWARN: %s, %d", hexpdu, pdulen);
|
||||
|
||||
if (decode_hex_own_buf(hexpdu, -1, &hexpdulen, 0, pdu) == NULL) {
|
||||
ofono_error("Unable to hex-decode the PDU");
|
||||
return;
|
||||
}
|
||||
|
||||
if (hexpdulen != pdulen) {
|
||||
ofono_error("hexpdu length not equal to reported pdu length");
|
||||
return;
|
||||
}
|
||||
|
||||
ofono_cbs_notify(cbs, pdu, pdulen);
|
||||
}
|
||||
|
||||
static void at_cbm_notify(GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_cbs *cbs = user_data;
|
||||
@@ -124,6 +169,10 @@ static void at_cbs_set_topics(struct ofono_cbs *cbs, const char *topics,
|
||||
g_at_chat_send(data->chat, "AT+CSCB=0", none_prefix,
|
||||
NULL, NULL, NULL);
|
||||
break;
|
||||
case OFONO_VENDOR_XMM:
|
||||
g_at_chat_send(data->chat, "AT+XETWNTFYSTART=2", none_prefix,
|
||||
NULL, NULL, NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -151,6 +200,10 @@ static void at_cbs_clear_topics(struct ofono_cbs *cbs,
|
||||
|
||||
DBG("");
|
||||
|
||||
if (data->vendor == OFONO_VENDOR_XMM)
|
||||
g_at_chat_send(data->chat, "AT+XETWNTFYSTOP=2", none_prefix,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
if (g_at_chat_send(data->chat, "AT+CSCB=0", none_prefix,
|
||||
at_cscb_set_cb, cbd, g_free) > 0)
|
||||
return;
|
||||
@@ -175,6 +228,10 @@ static void at_cbs_register(gboolean ok, GAtResult *result, gpointer user)
|
||||
*/
|
||||
g_at_chat_register(data->chat, "+CBM:", at_cbm_notify, TRUE, cbs, NULL);
|
||||
|
||||
if (data->vendor == OFONO_VENDOR_XMM)
|
||||
g_at_chat_register(data->chat, "+XETWSECWARN:",
|
||||
at_xmm_etw_sec_notify, TRUE, cbs, NULL);
|
||||
|
||||
ofono_cbs_register(cbs);
|
||||
}
|
||||
|
||||
@@ -223,6 +280,13 @@ static int at_cbs_probe(struct ofono_cbs *cbs, unsigned int vendor,
|
||||
|
||||
ofono_cbs_set_data(cbs, data);
|
||||
|
||||
if (vendor == OFONO_VENDOR_XMM) {
|
||||
g_at_chat_send(data->chat, "AT+XCMAS=1", cscb_prefix,
|
||||
NULL, NULL, NULL);
|
||||
g_at_chat_send(data->chat, "AT+XETWCFG=1,1,0,0; ", none_prefix,
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
g_at_chat_send(data->chat, "AT+CSCB=?", cscb_prefix,
|
||||
at_cscb_support_cb, cbs, NULL);
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ static gboolean lte_delayed_register(gpointer user_data)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int at_lte_probe(struct ofono_lte *lte, void *data)
|
||||
static int at_lte_probe(struct ofono_lte *lte, unsigned int vendor, void *data)
|
||||
{
|
||||
GAtChat *chat = data;
|
||||
struct lte_driver_data *ldd;
|
||||
|
||||
@@ -48,6 +48,7 @@ static const char *cops_prefix[] = { "+COPS:", NULL };
|
||||
static const char *csq_prefix[] = { "+CSQ:", NULL };
|
||||
static const char *cind_prefix[] = { "+CIND:", NULL };
|
||||
static const char *cmer_prefix[] = { "+CMER:", NULL };
|
||||
static const char *smoni_prefix[] = { "^SMONI:", NULL };
|
||||
static const char *zpas_prefix[] = { "+ZPAS:", NULL };
|
||||
static const char *option_tech_prefix[] = { "_OCTI:", "_OUWCTI:", NULL };
|
||||
|
||||
@@ -178,6 +179,31 @@ static int option_parse_tech(GAtResult *result)
|
||||
return tech;
|
||||
}
|
||||
|
||||
static int cinterion_parse_tech(GAtResult *result)
|
||||
{
|
||||
int tech = -1;
|
||||
GAtResultIter iter;
|
||||
const char *technology;
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
|
||||
if (!g_at_result_iter_next(&iter, "^SMONI: "))
|
||||
return tech;
|
||||
|
||||
if (!g_at_result_iter_next_unquoted_string(&iter, &technology))
|
||||
return tech;
|
||||
|
||||
if (strcmp(technology, "2G") == 0) {
|
||||
tech = ACCESS_TECHNOLOGY_GSM_EGPRS;
|
||||
} else if (strcmp(technology, "3G") == 0) {
|
||||
tech = ACCESS_TECHNOLOGY_UTRAN;
|
||||
} else if (strcmp(technology, "4G") == 0) {
|
||||
tech = ACCESS_TECHNOLOGY_EUTRAN;
|
||||
}
|
||||
|
||||
return tech;
|
||||
}
|
||||
|
||||
static void at_creg_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
@@ -205,6 +231,18 @@ static void at_creg_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
cb(&error, status, lac, ci, tech, cbd->data);
|
||||
}
|
||||
|
||||
static void cinterion_query_tech_cb(gboolean ok, GAtResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct tech_query *tq = user_data;
|
||||
int tech;
|
||||
|
||||
tech = cinterion_parse_tech(result);
|
||||
|
||||
ofono_netreg_status_notify(tq->netreg,
|
||||
tq->status, tq->lac, tq->ci, tech);
|
||||
}
|
||||
|
||||
static void zte_tech_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
@@ -1518,6 +1556,12 @@ static void creg_notify(GAtResult *result, gpointer user_data)
|
||||
option_query_tech_cb, tq, g_free) > 0)
|
||||
return;
|
||||
break;
|
||||
case OFONO_VENDOR_CINTERION:
|
||||
if (g_at_chat_send(nd->chat, "AT^SMONI",
|
||||
smoni_prefix,
|
||||
cinterion_query_tech_cb, tq, g_free) > 0)
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
g_free(tq);
|
||||
|
||||
@@ -1359,12 +1359,12 @@ static void at_pin_send_puk(struct ofono_sim *sim, const char *puk,
|
||||
char buf[64];
|
||||
int ret;
|
||||
|
||||
cbd->user = sd;
|
||||
cbd->user = sim;
|
||||
|
||||
snprintf(buf, sizeof(buf), "AT+CPIN=\"%s\",\"%s\"", puk, passwd);
|
||||
|
||||
ret = g_at_chat_send(sd->chat, buf, none_prefix,
|
||||
at_pin_send_cb, cbd, NULL);
|
||||
at_pin_send_cb, cbd, g_free);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ static void at_csca_set(struct ofono_sms *sms,
|
||||
{
|
||||
struct sms_data *data = ofono_sms_get_data(sms);
|
||||
struct cb_data *cbd = cb_data_new(cb, user_data);
|
||||
char buf[64];
|
||||
char buf[128];
|
||||
|
||||
snprintf(buf, sizeof(buf), "AT+CSCA=\"%s\",%d", sca->number, sca->type);
|
||||
|
||||
|
||||
@@ -1120,6 +1120,7 @@ static int at_voicecall_probe(struct ofono_voicecall *vc, unsigned int vendor,
|
||||
|
||||
switch (vd->vendor) {
|
||||
case OFONO_VENDOR_QUALCOMM_MSM:
|
||||
case OFONO_VENDOR_SIMCOM:
|
||||
g_at_chat_send(vd->chat, "AT+COLP=0", NULL, NULL, NULL, NULL);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -129,6 +129,7 @@ static void get_ids_cb(struct qmi_result *result, void *user_data)
|
||||
str = qmi_result_get_string(result, QMI_DMS_RESULT_ESN);
|
||||
/* Telit qmi modems return a "0" string when ESN is not available. */
|
||||
if (!str || strcmp(str, "0") == 0) {
|
||||
qmi_free(str);
|
||||
str = qmi_result_get_string(result, QMI_DMS_RESULT_IMEI);
|
||||
if (!str) {
|
||||
CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
|
||||
|
||||
@@ -212,7 +212,8 @@ error:
|
||||
ofono_lte_register(lte);
|
||||
}
|
||||
|
||||
static int qmimodem_lte_probe(struct ofono_lte *lte, void *data)
|
||||
static int qmimodem_lte_probe(struct ofono_lte *lte,
|
||||
unsigned int vendor, void *data)
|
||||
{
|
||||
struct qmi_device *device = data;
|
||||
struct lte_data *ldd;
|
||||
|
||||
@@ -47,6 +47,13 @@ struct discovery {
|
||||
qmi_destroy_func_t destroy;
|
||||
};
|
||||
|
||||
struct qmi_version {
|
||||
uint8_t type;
|
||||
uint16_t major;
|
||||
uint16_t minor;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct qmi_device {
|
||||
int ref_count;
|
||||
int fd;
|
||||
@@ -80,7 +87,6 @@ struct qmi_device {
|
||||
struct qmi_service {
|
||||
int ref_count;
|
||||
struct qmi_device *device;
|
||||
bool shared;
|
||||
uint8_t type;
|
||||
uint16_t major;
|
||||
uint16_t minor;
|
||||
@@ -161,25 +167,25 @@ void qmi_free(void *ptr)
|
||||
|
||||
static struct qmi_request *__request_alloc(uint8_t service,
|
||||
uint8_t client, uint16_t message,
|
||||
uint16_t headroom, const void *data,
|
||||
const void *data,
|
||||
uint16_t length, qmi_message_func_t func,
|
||||
void *user_data, void **head)
|
||||
void *user_data)
|
||||
{
|
||||
struct qmi_request *req;
|
||||
struct qmi_mux_hdr *hdr;
|
||||
struct qmi_message_hdr *msg;
|
||||
uint16_t headroom;
|
||||
|
||||
req = g_try_new0(struct qmi_request, 1);
|
||||
if (!req)
|
||||
return NULL;
|
||||
req = g_new0(struct qmi_request, 1);
|
||||
|
||||
if (service == QMI_SERVICE_CONTROL)
|
||||
headroom = QMI_CONTROL_HDR_SIZE;
|
||||
else
|
||||
headroom = QMI_SERVICE_HDR_SIZE;
|
||||
|
||||
req->len = QMI_MUX_HDR_SIZE + headroom + QMI_MESSAGE_HDR_SIZE + length;
|
||||
|
||||
req->buf = g_try_malloc(req->len);
|
||||
if (!req->buf) {
|
||||
g_free(req);
|
||||
return NULL;
|
||||
}
|
||||
req->buf = g_malloc(req->len);
|
||||
|
||||
req->client = client;
|
||||
|
||||
@@ -203,8 +209,6 @@ static struct qmi_request *__request_alloc(uint8_t service,
|
||||
req->callback = func;
|
||||
req->user_data = user_data;
|
||||
|
||||
*head = req->buf + QMI_MUX_HDR_SIZE;
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
@@ -256,9 +260,6 @@ static gboolean __service_compare_shared(gpointer key, gpointer value,
|
||||
struct qmi_service *service = value;
|
||||
uint8_t type = GPOINTER_TO_UINT(user_data);
|
||||
|
||||
if (!service->shared)
|
||||
return FALSE;
|
||||
|
||||
if (service->type == type)
|
||||
return TRUE;
|
||||
|
||||
@@ -695,14 +696,37 @@ static void wakeup_writer(struct qmi_device *device)
|
||||
can_write_data, device, write_watch_destroy);
|
||||
}
|
||||
|
||||
static void __request_submit(struct qmi_device *device,
|
||||
struct qmi_request *req, uint16_t transaction)
|
||||
static uint16_t __request_submit(struct qmi_device *device,
|
||||
struct qmi_request *req)
|
||||
{
|
||||
req->tid = transaction;
|
||||
struct qmi_mux_hdr *mux;
|
||||
|
||||
mux = req->buf;
|
||||
|
||||
if (mux->service == QMI_SERVICE_CONTROL) {
|
||||
struct qmi_control_hdr *hdr;
|
||||
|
||||
hdr = req->buf + QMI_MUX_HDR_SIZE;
|
||||
hdr->type = 0x00;
|
||||
hdr->transaction = device->next_control_tid++;
|
||||
if (device->next_control_tid == 0)
|
||||
device->next_control_tid = 1;
|
||||
req->tid = hdr->transaction;
|
||||
} else {
|
||||
struct qmi_service_hdr *hdr;
|
||||
hdr = req->buf + QMI_MUX_HDR_SIZE;
|
||||
hdr->type = 0x00;
|
||||
hdr->transaction = device->next_service_tid++;
|
||||
if (device->next_service_tid < 256)
|
||||
device->next_service_tid = 256;
|
||||
req->tid = hdr->transaction;
|
||||
}
|
||||
|
||||
g_queue_push_tail(device->req_queue, req);
|
||||
|
||||
wakeup_writer(device);
|
||||
|
||||
return req->tid;
|
||||
}
|
||||
|
||||
static void service_notify(gpointer key, gpointer value, gpointer user_data)
|
||||
@@ -961,6 +985,9 @@ struct qmi_device *qmi_device_new(int fd)
|
||||
device->service_list = g_hash_table_new_full(g_direct_hash,
|
||||
g_direct_equal, NULL, service_destroy);
|
||||
|
||||
device->next_control_tid = 1;
|
||||
device->next_service_tid = 256;
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
@@ -1078,6 +1105,41 @@ static const void *tlv_get(const void *data, uint16_t size,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool qmi_device_get_service_version(struct qmi_device *device, uint8_t type,
|
||||
uint16_t *major, uint16_t *minor)
|
||||
{
|
||||
struct qmi_version *info;
|
||||
int i;
|
||||
|
||||
for (i = 0, info = device->version_list;
|
||||
i < device->version_count;
|
||||
i++, info++) {
|
||||
if (info->type == type) {
|
||||
*major = info->major;
|
||||
*minor = info->minor;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool qmi_device_has_service(struct qmi_device *device, uint8_t type)
|
||||
{
|
||||
struct qmi_version *info;
|
||||
int i;
|
||||
|
||||
for (i = 0, info = device->version_list;
|
||||
i < device->version_count;
|
||||
i++, info++) {
|
||||
if (info->type == type) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
struct discover_data {
|
||||
struct discovery super;
|
||||
struct qmi_device *device;
|
||||
@@ -1177,7 +1239,7 @@ done:
|
||||
device->version_count = count;
|
||||
|
||||
if (data->func)
|
||||
data->func(count, list, data->user_data);
|
||||
data->func(data->user_data);
|
||||
|
||||
__qmi_device_discovery_complete(data->device, &data->super);
|
||||
}
|
||||
@@ -1213,8 +1275,7 @@ static gboolean discover_reply(gpointer user_data)
|
||||
}
|
||||
|
||||
if (data->func)
|
||||
data->func(device->version_count,
|
||||
device->version_list, data->user_data);
|
||||
data->func(data->user_data);
|
||||
|
||||
__qmi_device_discovery_complete(data->device, &data->super);
|
||||
__request_free(req, NULL);
|
||||
@@ -1227,7 +1288,7 @@ bool qmi_device_discover(struct qmi_device *device, qmi_discover_func_t func,
|
||||
{
|
||||
struct discover_data *data;
|
||||
struct qmi_request *req;
|
||||
struct qmi_control_hdr *hdr;
|
||||
uint8_t tid;
|
||||
|
||||
if (!device)
|
||||
return false;
|
||||
@@ -1251,21 +1312,12 @@ bool qmi_device_discover(struct qmi_device *device, qmi_discover_func_t func,
|
||||
}
|
||||
|
||||
req = __request_alloc(QMI_SERVICE_CONTROL, 0x00,
|
||||
QMI_CTL_GET_VERSION_INFO, QMI_CONTROL_HDR_SIZE,
|
||||
NULL, 0, discover_callback, data, (void **) &hdr);
|
||||
if (!req) {
|
||||
g_free(data);
|
||||
return false;
|
||||
}
|
||||
QMI_CTL_GET_VERSION_INFO,
|
||||
NULL, 0, discover_callback, data);
|
||||
|
||||
if (device->next_control_tid < 1)
|
||||
device->next_control_tid = 1;
|
||||
tid = __request_submit(device, req);
|
||||
|
||||
hdr->type = 0x00;
|
||||
hdr->transaction = device->next_control_tid++;
|
||||
data->tid = hdr->transaction;
|
||||
|
||||
__request_submit(device, req, hdr->transaction);
|
||||
data->tid = tid;
|
||||
|
||||
data->timeout = g_timeout_add_seconds(5, discover_reply, data);
|
||||
__qmi_device_discovery_started(device, &data->super);
|
||||
@@ -1279,24 +1331,13 @@ static void release_client(struct qmi_device *device,
|
||||
{
|
||||
unsigned char release_req[] = { 0x01, 0x02, 0x00, type, client_id };
|
||||
struct qmi_request *req;
|
||||
struct qmi_control_hdr *hdr;
|
||||
|
||||
req = __request_alloc(QMI_SERVICE_CONTROL, 0x00,
|
||||
QMI_CTL_RELEASE_CLIENT_ID, QMI_CONTROL_HDR_SIZE,
|
||||
QMI_CTL_RELEASE_CLIENT_ID,
|
||||
release_req, sizeof(release_req),
|
||||
func, user_data, (void **) &hdr);
|
||||
if (!req) {
|
||||
func(0x0000, 0x0000, NULL, user_data);
|
||||
return;
|
||||
}
|
||||
func, user_data);
|
||||
|
||||
if (device->next_control_tid < 1)
|
||||
device->next_control_tid = 1;
|
||||
|
||||
hdr->type = 0x00;
|
||||
hdr->transaction = device->next_control_tid++;
|
||||
|
||||
__request_submit(device, req, hdr->transaction);
|
||||
__request_submit(device, req);
|
||||
}
|
||||
|
||||
static void shutdown_destroy(gpointer user_data)
|
||||
@@ -1374,7 +1415,6 @@ bool qmi_device_sync(struct qmi_device *device,
|
||||
qmi_sync_func_t func, void *user_data)
|
||||
{
|
||||
struct qmi_request *req;
|
||||
struct qmi_control_hdr *hdr;
|
||||
struct sync_data *func_data;
|
||||
|
||||
if (!device)
|
||||
@@ -1387,17 +1427,11 @@ bool qmi_device_sync(struct qmi_device *device,
|
||||
func_data->user_data = user_data;
|
||||
|
||||
req = __request_alloc(QMI_SERVICE_CONTROL, 0x00,
|
||||
QMI_CTL_SYNC, QMI_CONTROL_HDR_SIZE,
|
||||
QMI_CTL_SYNC,
|
||||
NULL, 0,
|
||||
qmi_device_sync_callback, func_data, (void **) &hdr);
|
||||
qmi_device_sync_callback, func_data);
|
||||
|
||||
if (device->next_control_tid < 1)
|
||||
device->next_control_tid = 1;
|
||||
|
||||
hdr->type = 0x00;
|
||||
hdr->transaction = device->next_control_tid++;
|
||||
|
||||
__request_submit(device, req, hdr->transaction);
|
||||
__request_submit(device, req);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1898,7 +1932,6 @@ bool qmi_result_get_uint64(struct qmi_result *result, uint8_t type,
|
||||
struct service_create_data {
|
||||
struct discovery super;
|
||||
struct qmi_device *device;
|
||||
bool shared;
|
||||
uint8_t type;
|
||||
uint16_t major;
|
||||
uint16_t minor;
|
||||
@@ -1969,7 +2002,6 @@ static void service_create_callback(uint16_t message, uint16_t length,
|
||||
|
||||
service->ref_count = 1;
|
||||
service->device = data->device;
|
||||
service->shared = data->shared;
|
||||
|
||||
service->type = data->type;
|
||||
service->major = data->major;
|
||||
@@ -1992,100 +2024,52 @@ done:
|
||||
__qmi_device_discovery_complete(data->device, &data->super);
|
||||
}
|
||||
|
||||
static void service_create_discover(uint8_t count,
|
||||
const struct qmi_version *list, void *user_data)
|
||||
{
|
||||
struct service_create_data *data = user_data;
|
||||
struct qmi_device *device = data->device;
|
||||
struct qmi_request *req;
|
||||
struct qmi_control_hdr *hdr;
|
||||
unsigned char client_req[] = { 0x01, 0x01, 0x00, data->type };
|
||||
unsigned int i;
|
||||
|
||||
__debug_device(device, "service create [type=%d]", data->type);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (list[i].type == data->type) {
|
||||
data->major = list[i].major;
|
||||
data->minor = list[i].minor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
req = __request_alloc(QMI_SERVICE_CONTROL, 0x00,
|
||||
QMI_CTL_GET_CLIENT_ID, QMI_CONTROL_HDR_SIZE,
|
||||
client_req, sizeof(client_req),
|
||||
service_create_callback, data, (void **) &hdr);
|
||||
if (!req) {
|
||||
if (data->timeout > 0)
|
||||
g_source_remove(data->timeout);
|
||||
|
||||
data->timeout = g_timeout_add_seconds(0,
|
||||
service_create_reply, data);
|
||||
__qmi_device_discovery_started(device, &data->super);
|
||||
return;
|
||||
}
|
||||
|
||||
if (device->next_control_tid < 1)
|
||||
device->next_control_tid = 1;
|
||||
|
||||
hdr->type = 0x00;
|
||||
hdr->transaction = device->next_control_tid++;
|
||||
|
||||
__request_submit(device, req, hdr->transaction);
|
||||
}
|
||||
|
||||
static bool service_create(struct qmi_device *device, bool shared,
|
||||
static bool service_create(struct qmi_device *device,
|
||||
uint8_t type, qmi_create_func_t func,
|
||||
void *user_data, qmi_destroy_func_t destroy)
|
||||
{
|
||||
struct service_create_data *data;
|
||||
unsigned char client_req[] = { 0x01, 0x01, 0x00, type };
|
||||
struct qmi_request *req;
|
||||
int i;
|
||||
|
||||
data = g_try_new0(struct service_create_data, 1);
|
||||
if (!data)
|
||||
return false;
|
||||
|
||||
if (!device->version_list)
|
||||
return false;
|
||||
|
||||
data->super.destroy = service_create_data_free;
|
||||
data->device = device;
|
||||
data->shared = shared;
|
||||
data->type = type;
|
||||
data->func = func;
|
||||
data->user_data = user_data;
|
||||
data->destroy = destroy;
|
||||
|
||||
if (device->version_list) {
|
||||
service_create_discover(device->version_count,
|
||||
device->version_list, data);
|
||||
goto done;
|
||||
__debug_device(device, "service create [type=%d]", type);
|
||||
|
||||
for (i = 0; i < device->version_count; i++) {
|
||||
if (device->version_list[i].type == data->type) {
|
||||
data->major = device->version_list[i].major;
|
||||
data->minor = device->version_list[i].minor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (qmi_device_discover(device, service_create_discover, data, NULL))
|
||||
goto done;
|
||||
req = __request_alloc(QMI_SERVICE_CONTROL, 0x00,
|
||||
QMI_CTL_GET_CLIENT_ID,
|
||||
client_req, sizeof(client_req),
|
||||
service_create_callback, data);
|
||||
|
||||
g_free(data);
|
||||
__request_submit(device, req);
|
||||
|
||||
return false;
|
||||
|
||||
done:
|
||||
data->timeout = g_timeout_add_seconds(8, service_create_reply, data);
|
||||
__qmi_device_discovery_started(device, &data->super);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool qmi_service_create(struct qmi_device *device,
|
||||
uint8_t type, qmi_create_func_t func,
|
||||
void *user_data, qmi_destroy_func_t destroy)
|
||||
{
|
||||
if (!device || !func)
|
||||
return false;
|
||||
|
||||
if (type == QMI_SERVICE_CONTROL)
|
||||
return false;
|
||||
|
||||
return service_create(device, false, type, func, user_data, destroy);
|
||||
}
|
||||
|
||||
struct service_create_shared_data {
|
||||
struct discovery super;
|
||||
struct qmi_service *service;
|
||||
@@ -2161,7 +2145,15 @@ bool qmi_service_create_shared(struct qmi_device *device,
|
||||
return 0;
|
||||
}
|
||||
|
||||
return service_create(device, true, type, func, user_data, destroy);
|
||||
return service_create(device, type, func, user_data, destroy);
|
||||
}
|
||||
|
||||
bool qmi_service_create(struct qmi_device *device,
|
||||
uint8_t type, qmi_create_func_t func,
|
||||
void *user_data, qmi_destroy_func_t destroy)
|
||||
{
|
||||
return qmi_service_create_shared(device, type, func,
|
||||
user_data, destroy);
|
||||
}
|
||||
|
||||
static void service_release_callback(uint16_t message, uint16_t length,
|
||||
@@ -2238,8 +2230,6 @@ bool qmi_service_get_version(struct qmi_service *service,
|
||||
}
|
||||
|
||||
struct service_send_data {
|
||||
struct qmi_service *service;
|
||||
struct qmi_param *param;
|
||||
qmi_result_func_t func;
|
||||
void *user_data;
|
||||
qmi_destroy_func_t destroy;
|
||||
@@ -2250,8 +2240,6 @@ static void service_send_free(struct service_send_data *data)
|
||||
if (data->destroy)
|
||||
data->destroy(data->user_data);
|
||||
|
||||
qmi_param_free(data->param);
|
||||
|
||||
g_free(data);
|
||||
}
|
||||
|
||||
@@ -2292,7 +2280,7 @@ uint16_t qmi_service_send(struct qmi_service *service,
|
||||
struct qmi_device *device;
|
||||
struct service_send_data *data;
|
||||
struct qmi_request *req;
|
||||
struct qmi_service_hdr *hdr;
|
||||
uint16_t tid;
|
||||
|
||||
if (!service)
|
||||
return 0;
|
||||
@@ -2308,31 +2296,21 @@ uint16_t qmi_service_send(struct qmi_service *service,
|
||||
if (!data)
|
||||
return 0;
|
||||
|
||||
data->service = service;
|
||||
data->param = param;
|
||||
data->func = func;
|
||||
data->user_data = user_data;
|
||||
data->destroy = destroy;
|
||||
|
||||
req = __request_alloc(service->type, service->client_id,
|
||||
message, QMI_SERVICE_HDR_SIZE,
|
||||
data->param ? data->param->data : NULL,
|
||||
data->param ? data->param->length : 0,
|
||||
service_send_callback, data, (void **) &hdr);
|
||||
if (!req) {
|
||||
g_free(data);
|
||||
return 0;
|
||||
}
|
||||
message,
|
||||
param ? param->data : NULL,
|
||||
param ? param->length : 0,
|
||||
service_send_callback, data);
|
||||
|
||||
if (device->next_service_tid < 256)
|
||||
device->next_service_tid = 256;
|
||||
qmi_param_free(param);
|
||||
|
||||
hdr->type = 0x00;
|
||||
hdr->transaction = device->next_service_tid++;
|
||||
tid = __request_submit(device, req);
|
||||
|
||||
__request_submit(device, req, hdr->transaction);
|
||||
|
||||
return hdr->transaction;
|
||||
return tid;
|
||||
}
|
||||
|
||||
bool qmi_service_cancel(struct qmi_service *service, uint16_t id)
|
||||
|
||||
@@ -61,13 +61,6 @@ enum qmi_device_expected_data_format {
|
||||
QMI_DEVICE_EXPECTED_DATA_FORMAT_RAW_IP,
|
||||
};
|
||||
|
||||
struct qmi_version {
|
||||
uint8_t type;
|
||||
uint16_t major;
|
||||
uint16_t minor;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
void qmi_free(void *ptr);
|
||||
|
||||
typedef void (*qmi_destroy_func_t)(void *user_data);
|
||||
@@ -78,8 +71,7 @@ struct qmi_device;
|
||||
typedef void (*qmi_debug_func_t)(const char *str, void *user_data);
|
||||
typedef void (*qmi_sync_func_t)(void *user_data);
|
||||
typedef void (*qmi_shutdown_func_t)(void *user_data);
|
||||
typedef void (*qmi_discover_func_t)(uint8_t count,
|
||||
const struct qmi_version *list, void *user_data);
|
||||
typedef void (*qmi_discover_func_t)(void *user_data);
|
||||
|
||||
struct qmi_device *qmi_device_new(int fd);
|
||||
|
||||
@@ -96,6 +88,10 @@ bool qmi_device_discover(struct qmi_device *device, qmi_discover_func_t func,
|
||||
bool qmi_device_shutdown(struct qmi_device *device, qmi_shutdown_func_t func,
|
||||
void *user_data, qmi_destroy_func_t destroy);
|
||||
|
||||
bool qmi_device_has_service(struct qmi_device *device, uint8_t type);
|
||||
bool qmi_device_get_service_version(struct qmi_device *device, uint8_t type,
|
||||
uint16_t *major, uint16_t *minor);
|
||||
|
||||
bool qmi_device_sync(struct qmi_device *device,
|
||||
qmi_sync_func_t func, void *user_data);
|
||||
bool qmi_device_is_sync_supported(struct qmi_device *device);
|
||||
|
||||
@@ -493,8 +493,15 @@ static bool get_card_status(const struct qmi_uim_slot_info *slot,
|
||||
case 0x03: /* PUK1 or PUK for UPIN is required */
|
||||
sim_stat->passwd_state = OFONO_SIM_PASSWORD_SIM_PUK;
|
||||
break;
|
||||
case 0x00: /* Unknown */
|
||||
case 0x01: /* Detected */
|
||||
case 0x04: /* Personalization state must be checked. */
|
||||
/* This is temporary, we could retry and get another result */
|
||||
case 0x05: /* PIN1 blocked */
|
||||
case 0x06: /* Illegal */
|
||||
/*
|
||||
* This could be temporary, we should retry and
|
||||
* expect another result
|
||||
*/
|
||||
sim_stat->passwd_state = OFONO_SIM_PASSWORD_INVALID;
|
||||
need_retry = true;
|
||||
break;
|
||||
@@ -557,7 +564,7 @@ static enum get_card_status_result handle_get_card_status_result(
|
||||
|
||||
index = GUINT16_FROM_LE(status->index_gw_pri);
|
||||
|
||||
if ((index & 0xff) == i && (index >> 8) == n) {
|
||||
if ((index & 0xff) == n && (index >> 8) == i) {
|
||||
if (get_card_status(slot, info1, info2,
|
||||
sim_stat))
|
||||
res = GET_CARD_STATUS_RESULT_TEMP_ERROR;
|
||||
@@ -595,20 +602,32 @@ static void query_passwd_state_cb(struct qmi_result *result,
|
||||
struct sim_status sim_stat;
|
||||
enum get_card_status_result res;
|
||||
struct cb_data *retry_cbd;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < OFONO_SIM_PASSWORD_INVALID; i++)
|
||||
sim_stat.retries[i] = -1;
|
||||
|
||||
res = handle_get_card_status_result(result, &sim_stat);
|
||||
switch (res) {
|
||||
case GET_CARD_STATUS_RESULT_OK:
|
||||
DBG("passwd state %d", sim_stat.passwd_state);
|
||||
data->retry_count = 0;
|
||||
CALLBACK_WITH_SUCCESS(cb, sim_stat.passwd_state, cbd->data);
|
||||
if (sim_stat.passwd_state == OFONO_SIM_PASSWORD_INVALID) {
|
||||
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
|
||||
ofono_sim_inserted_notify(sim, FALSE);
|
||||
} else
|
||||
CALLBACK_WITH_SUCCESS(cb, sim_stat.passwd_state,
|
||||
cbd->data);
|
||||
break;
|
||||
case GET_CARD_STATUS_RESULT_TEMP_ERROR:
|
||||
data->retry_count++;
|
||||
if (data->retry_count > MAX_RETRY_COUNT) {
|
||||
DBG("Failed after %d attempts", data->retry_count);
|
||||
DBG("Failed after %d attempts. Card state:%d",
|
||||
data->retry_count,
|
||||
sim_stat.card_state);
|
||||
data->retry_count = 0;
|
||||
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
|
||||
ofono_sim_inserted_notify(sim, FALSE);
|
||||
} else {
|
||||
DBG("Retry command");
|
||||
retry_cbd = cb_data_new(cb, cbd->data);
|
||||
@@ -622,6 +641,7 @@ static void query_passwd_state_cb(struct qmi_result *result,
|
||||
DBG("Command failed");
|
||||
data->retry_count = 0;
|
||||
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
|
||||
ofono_sim_inserted_notify(sim, FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -650,9 +670,13 @@ static void query_pin_retries_cb(struct qmi_result *result, void *user_data)
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_sim_pin_retries_cb_t cb = cbd->cb;
|
||||
struct sim_status sim_stat;
|
||||
unsigned int i;
|
||||
|
||||
DBG("");
|
||||
|
||||
for (i = 0; i < OFONO_SIM_PASSWORD_INVALID; i++)
|
||||
sim_stat.retries[i] = -1;
|
||||
|
||||
if (handle_get_card_status_result(result, &sim_stat) !=
|
||||
GET_CARD_STATUS_RESULT_OK) {
|
||||
CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
|
||||
|
||||
@@ -251,6 +251,7 @@ static void qmi_ussd_request(struct ofono_ussd *ussd, int dcs,
|
||||
qmi_ussd->dcs = QMI_USSD_DCS_ASCII;
|
||||
qmi_ussd->length = len;
|
||||
memcpy(qmi_ussd->data, utf8, utf8_len);
|
||||
g_free(utf8);
|
||||
|
||||
param = qmi_param_new();
|
||||
if (param == NULL)
|
||||
@@ -265,7 +266,6 @@ static void qmi_ussd_request(struct ofono_ussd *ussd, int dcs,
|
||||
|
||||
qmi_param_free(param);
|
||||
error:
|
||||
g_free(utf8);
|
||||
g_free(cbd);
|
||||
CALLBACK_WITH_FAILURE(cb, data);
|
||||
}
|
||||
|
||||
@@ -960,12 +960,6 @@ static gboolean ril_data_call_setup_submit(struct ril_data_request *req)
|
||||
RADIO_TECH_LTE : priv->network->data.ril_tech;
|
||||
if (tech > 2) {
|
||||
tech += 2;
|
||||
} else {
|
||||
/*
|
||||
* This value used to be hardcoded, let's keep using it
|
||||
* as the default.
|
||||
*/
|
||||
tech = RADIO_TECH_HSPA;
|
||||
}
|
||||
|
||||
if (setup->username && setup->username[0]) {
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
#include <ofono/call-forwarding.h>
|
||||
#include "common.h"
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wrestrict"
|
||||
|
||||
#include "gril.h"
|
||||
|
||||
#include "rilmodem.h"
|
||||
|
||||
@@ -108,7 +108,8 @@ static gboolean lte_delayed_register(gpointer user_data)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int ril_lte_probe(struct ofono_lte *lte, void *user_data)
|
||||
static int ril_lte_probe(struct ofono_lte *lte,
|
||||
unsigned int vendor, void *user_data)
|
||||
{
|
||||
GRil *ril = user_data;
|
||||
struct ril_lte_data *ld;
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
#include <ofono/modem.h>
|
||||
#include <ofono/netreg.h>
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wrestrict"
|
||||
|
||||
#include <gril/gril.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
@@ -91,7 +91,8 @@ static gboolean lte_delayed_register(gpointer user_data)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int ublox_lte_probe(struct ofono_lte *lte, void *data)
|
||||
static int ublox_lte_probe(struct ofono_lte *lte,
|
||||
unsigned int vendor, void *data)
|
||||
{
|
||||
GAtChat *chat = data;
|
||||
struct lte_driver_data *ldd;
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
#include <string.h>
|
||||
#include <alloca.h>
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wpragmas"
|
||||
#pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "ringbuffer.h"
|
||||
|
||||
@@ -38,7 +38,7 @@ typedef void (*ofono_lte_cb_t)(const struct ofono_error *error, void *data);
|
||||
|
||||
struct ofono_lte_driver {
|
||||
const char *name;
|
||||
int (*probe)(struct ofono_lte *lte, void *data);
|
||||
int (*probe)(struct ofono_lte *lte, unsigned int vendor, void *data);
|
||||
void (*remove)(struct ofono_lte *lte);
|
||||
void (*set_default_attach_info)(const struct ofono_lte *lte,
|
||||
const struct ofono_lte_default_attach_info *info,
|
||||
@@ -50,6 +50,7 @@ int ofono_lte_driver_register(const struct ofono_lte_driver *d);
|
||||
void ofono_lte_driver_unregister(const struct ofono_lte_driver *d);
|
||||
|
||||
struct ofono_lte *ofono_lte_create(struct ofono_modem *modem,
|
||||
unsigned int vendor,
|
||||
const char *driver, void *data);
|
||||
|
||||
void ofono_lte_register(struct ofono_lte *lte);
|
||||
|
||||
@@ -53,6 +53,11 @@
|
||||
|
||||
#define HARDWARE_MONITOR_INTERFACE OFONO_SERVICE ".cinterion.HardwareMonitor"
|
||||
|
||||
/* Supported gemalto's modem */
|
||||
#define GEMALTO_MODEL_PHS8P "0053"
|
||||
/* ALS3, PLS8-E, and PLS8-X family */
|
||||
#define GEMALTO_MODEL_ALS3_PLS8x "0061"
|
||||
|
||||
static const char *none_prefix[] = { NULL };
|
||||
static const char *sctm_prefix[] = { "^SCTM:", NULL };
|
||||
static const char *sbv_prefix[] = { "^SBV:", NULL };
|
||||
@@ -70,6 +75,8 @@ struct gemalto_data {
|
||||
gboolean have_sim;
|
||||
struct at_util_sim_state_query *sim_state_query;
|
||||
struct gemalto_hardware_monitor *hm;
|
||||
guint modem_ready_id;
|
||||
guint trial_cmd_id;
|
||||
};
|
||||
|
||||
static int gemalto_probe(struct ofono_modem *modem)
|
||||
@@ -107,10 +114,26 @@ static GAtChat *open_device(const char *device)
|
||||
GAtSyntax *syntax;
|
||||
GIOChannel *channel;
|
||||
GAtChat *chat;
|
||||
GHashTable *options;
|
||||
|
||||
options = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
if (options == NULL)
|
||||
return NULL;
|
||||
|
||||
g_hash_table_insert(options, "Baud", "115200");
|
||||
g_hash_table_insert(options, "StopBits", "1");
|
||||
g_hash_table_insert(options, "DataBits", "8");
|
||||
g_hash_table_insert(options, "Parity", "none");
|
||||
g_hash_table_insert(options, "XonXoff", "off");
|
||||
g_hash_table_insert(options, "RtsCts", "on");
|
||||
g_hash_table_insert(options, "Local", "on");
|
||||
g_hash_table_insert(options, "Read", "on");
|
||||
|
||||
DBG("Opening device %s", device);
|
||||
|
||||
channel = g_at_tty_open(device, NULL);
|
||||
channel = g_at_tty_open(device, options);
|
||||
g_hash_table_destroy(options);
|
||||
|
||||
if (channel == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -125,6 +148,72 @@ static GAtChat *open_device(const char *device)
|
||||
return chat;
|
||||
}
|
||||
|
||||
static void sim_ready_cb(gboolean present, gpointer user_data)
|
||||
{
|
||||
struct ofono_modem *modem = user_data;
|
||||
struct gemalto_data *data = ofono_modem_get_data(modem);
|
||||
struct ofono_sim *sim = data->sim;
|
||||
|
||||
at_util_sim_state_query_free(data->sim_state_query);
|
||||
data->sim_state_query = NULL;
|
||||
|
||||
DBG("sim present: %d", present);
|
||||
|
||||
ofono_sim_inserted_notify(sim, present);
|
||||
}
|
||||
|
||||
static void gemalto_ciev_notify(GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_modem *modem = user_data;
|
||||
struct gemalto_data *data = ofono_modem_get_data(modem);
|
||||
struct ofono_sim *sim = data->sim;
|
||||
|
||||
const char *sim_status = "simstatus";
|
||||
const char *ind_str;
|
||||
int status;
|
||||
GAtResultIter iter;
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
|
||||
/* Example: +CIEV: simstatus,<status> */
|
||||
if (!g_at_result_iter_next(&iter, "+CIEV:"))
|
||||
return;
|
||||
|
||||
if (!g_at_result_iter_next_unquoted_string(&iter, &ind_str))
|
||||
return;
|
||||
|
||||
if (!g_str_equal(sim_status, ind_str))
|
||||
return;
|
||||
|
||||
if (!g_at_result_iter_next_number(&iter, &status))
|
||||
return;
|
||||
|
||||
DBG("sim status %d", status);
|
||||
|
||||
switch (status) {
|
||||
/* SIM is removed from the holder */
|
||||
case 0:
|
||||
ofono_sim_inserted_notify(sim, FALSE);
|
||||
break;
|
||||
|
||||
/* SIM is inserted inside the holder */
|
||||
case 1:
|
||||
/* The SIM won't be ready yet */
|
||||
data->sim_state_query = at_util_sim_state_query_new(data->app,
|
||||
1, 20, sim_ready_cb, modem,
|
||||
NULL);
|
||||
break;
|
||||
|
||||
/* USIM initialization completed. UE has finished reading USIM data. */
|
||||
case 5:
|
||||
ofono_sim_initialized_notify(sim);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void sim_state_cb(gboolean present, gpointer user_data)
|
||||
{
|
||||
struct ofono_modem *modem = user_data;
|
||||
@@ -135,6 +224,13 @@ static void sim_state_cb(gboolean present, gpointer user_data)
|
||||
|
||||
data->have_sim = present;
|
||||
ofono_modem_set_powered(modem, TRUE);
|
||||
|
||||
/* Register for specific sim status reports */
|
||||
g_at_chat_register(data->app, "+CIEV:",
|
||||
gemalto_ciev_notify, FALSE, modem, NULL);
|
||||
|
||||
g_at_chat_send(data->app, "AT^SIND=\"simstatus\",1", none_prefix,
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void cfun_enable(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
@@ -300,6 +396,79 @@ static int gemalto_hardware_monitor_enable(struct ofono_modem *modem)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gemalto_initialize(struct ofono_modem *modem)
|
||||
{
|
||||
struct gemalto_data *data = ofono_modem_get_data(modem);
|
||||
const char *mdm;
|
||||
|
||||
DBG("");
|
||||
|
||||
mdm = ofono_modem_get_string(modem, "Modem");
|
||||
|
||||
if (mdm == NULL)
|
||||
return;
|
||||
|
||||
/* Open devices */
|
||||
data->mdm = open_device(mdm);
|
||||
if (data->mdm == NULL) {
|
||||
g_at_chat_unref(data->app);
|
||||
data->app = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (getenv("OFONO_AT_DEBUG")) {
|
||||
g_at_chat_set_debug(data->app, gemalto_debug, "App");
|
||||
g_at_chat_set_debug(data->mdm, gemalto_debug, "Mdm");
|
||||
}
|
||||
|
||||
g_at_chat_send(data->mdm, "ATE0", none_prefix, NULL, NULL, NULL);
|
||||
g_at_chat_send(data->app, "ATE0 +CMEE=1", none_prefix,
|
||||
NULL, NULL, NULL);
|
||||
g_at_chat_send(data->mdm, "AT&C0", none_prefix, NULL, NULL, NULL);
|
||||
g_at_chat_send(data->app, "AT&C0", none_prefix, NULL, NULL, NULL);
|
||||
|
||||
g_at_chat_send(data->app, "AT+CFUN=4", none_prefix,
|
||||
cfun_enable, modem, NULL);
|
||||
|
||||
gemalto_hardware_monitor_enable(modem);
|
||||
}
|
||||
|
||||
static void gemalto_modem_ready(GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_modem *modem = user_data;
|
||||
struct gemalto_data *data = ofono_modem_get_data(modem);
|
||||
const char *app = ofono_modem_get_string(modem, "Application");
|
||||
|
||||
DBG("");
|
||||
|
||||
/*
|
||||
* As the modem wasn't ready to handle AT commands when we opened
|
||||
* it, we have to close and reopen the device app.
|
||||
*/
|
||||
data->modem_ready_id = 0;
|
||||
data->trial_cmd_id = 0;
|
||||
|
||||
g_at_chat_unref(data->app);
|
||||
|
||||
data->app = open_device(app);
|
||||
if (data->app == NULL) {
|
||||
ofono_modem_set_powered(modem, FALSE);
|
||||
} else {
|
||||
gemalto_initialize(modem);
|
||||
}
|
||||
}
|
||||
|
||||
static void gemalto_at_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_modem *modem = user_data;
|
||||
struct gemalto_data *data = ofono_modem_get_data(modem);
|
||||
|
||||
g_at_chat_unregister(data->app, data->modem_ready_id);
|
||||
data->modem_ready_id = 0;
|
||||
|
||||
gemalto_initialize(modem);
|
||||
}
|
||||
|
||||
static int gemalto_enable(struct ofono_modem *modem)
|
||||
{
|
||||
struct gemalto_data *data = ofono_modem_get_data(modem);
|
||||
@@ -318,28 +487,11 @@ static int gemalto_enable(struct ofono_modem *modem)
|
||||
if (data->app == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
data->mdm = open_device(mdm);
|
||||
if (data->mdm == NULL) {
|
||||
g_at_chat_unref(data->app);
|
||||
data->app = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (getenv("OFONO_AT_DEBUG")) {
|
||||
g_at_chat_set_debug(data->app, gemalto_debug, "App");
|
||||
g_at_chat_set_debug(data->mdm, gemalto_debug, "Mdm");
|
||||
}
|
||||
|
||||
g_at_chat_send(data->mdm, "ATE0", none_prefix, NULL, NULL, NULL);
|
||||
g_at_chat_send(data->app, "ATE0 +CMEE=1", none_prefix,
|
||||
NULL, NULL, NULL);
|
||||
g_at_chat_send(data->mdm, "AT&C0", none_prefix, NULL, NULL, NULL);
|
||||
g_at_chat_send(data->app, "AT&C0", none_prefix, NULL, NULL, NULL);
|
||||
|
||||
g_at_chat_send(data->app, "AT+CFUN=4", none_prefix,
|
||||
cfun_enable, modem, NULL);
|
||||
|
||||
gemalto_hardware_monitor_enable(modem);
|
||||
/* Try the AT command. If it doesn't work, wait for ^SYSSTART */
|
||||
data->modem_ready_id = g_at_chat_register(data->app, "^SYSSTART",
|
||||
gemalto_modem_ready, FALSE, modem, NULL);
|
||||
data->trial_cmd_id = g_at_chat_send(data->app, "ATE0 AT",
|
||||
none_prefix, gemalto_at_cb, modem, NULL);
|
||||
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
@@ -414,17 +566,16 @@ static void gemalto_set_online(struct ofono_modem *modem, ofono_bool_t online,
|
||||
static void gemalto_pre_sim(struct ofono_modem *modem)
|
||||
{
|
||||
struct gemalto_data *data = ofono_modem_get_data(modem);
|
||||
struct ofono_sim *sim;
|
||||
|
||||
DBG("%p", modem);
|
||||
|
||||
ofono_devinfo_create(modem, 0, "atmodem", data->app);
|
||||
ofono_location_reporting_create(modem, 0, "gemaltomodem", data->app);
|
||||
sim = ofono_sim_create(modem, OFONO_VENDOR_CINTERION, "atmodem",
|
||||
data->sim = ofono_sim_create(modem, OFONO_VENDOR_CINTERION, "atmodem",
|
||||
data->app);
|
||||
|
||||
if (sim && data->have_sim == TRUE)
|
||||
ofono_sim_inserted_notify(sim, TRUE);
|
||||
if (data->sim && data->have_sim == TRUE)
|
||||
ofono_sim_inserted_notify(data->sim, TRUE);
|
||||
}
|
||||
|
||||
static void gemalto_post_sim(struct ofono_modem *modem)
|
||||
@@ -432,6 +583,7 @@ static void gemalto_post_sim(struct ofono_modem *modem)
|
||||
struct gemalto_data *data = ofono_modem_get_data(modem);
|
||||
struct ofono_gprs *gprs;
|
||||
struct ofono_gprs_context *gc;
|
||||
const char *model = ofono_modem_get_string(modem, "Model");
|
||||
|
||||
DBG("%p", modem);
|
||||
|
||||
@@ -444,6 +596,10 @@ static void gemalto_post_sim(struct ofono_modem *modem)
|
||||
|
||||
if (gprs && gc)
|
||||
ofono_gprs_add_context(gprs, gc);
|
||||
|
||||
if (!g_strcmp0(model, GEMALTO_MODEL_ALS3_PLS8x))
|
||||
ofono_lte_create(modem, OFONO_VENDOR_CINTERION,
|
||||
"atmodem", data->app);
|
||||
}
|
||||
|
||||
static void gemalto_post_online(struct ofono_modem *modem)
|
||||
|
||||
@@ -264,56 +264,38 @@ static void create_shared_dms(void *user_data)
|
||||
create_dms_cb, modem, NULL);
|
||||
}
|
||||
|
||||
static void discover_cb(uint8_t count, const struct qmi_version *list,
|
||||
void *user_data)
|
||||
static void discover_cb(void *user_data)
|
||||
{
|
||||
struct ofono_modem *modem = user_data;
|
||||
struct gobi_data *data = ofono_modem_get_data(modem);
|
||||
uint8_t i;
|
||||
uint16_t major, minor;
|
||||
|
||||
DBG("");
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
DBG("%s %d.%d - %d", list[i].name, list[i].major, list[i].minor,
|
||||
list[i].type);
|
||||
|
||||
switch (list[i].type) {
|
||||
case QMI_SERVICE_DMS:
|
||||
data->features |= GOBI_DMS;
|
||||
break;
|
||||
case QMI_SERVICE_NAS:
|
||||
data->features |= GOBI_NAS;
|
||||
break;
|
||||
case QMI_SERVICE_WMS:
|
||||
data->features |= GOBI_WMS;
|
||||
break;
|
||||
case QMI_SERVICE_WDS:
|
||||
data->features |= GOBI_WDS;
|
||||
break;
|
||||
case QMI_SERVICE_WDA:
|
||||
data->features |= GOBI_WDA;
|
||||
break;
|
||||
case QMI_SERVICE_PDS:
|
||||
data->features |= GOBI_PDS;
|
||||
break;
|
||||
case QMI_SERVICE_PBM:
|
||||
data->features |= GOBI_PBM;
|
||||
break;
|
||||
case QMI_SERVICE_UIM:
|
||||
data->features |= GOBI_UIM;
|
||||
break;
|
||||
case QMI_SERVICE_CAT:
|
||||
data->features |= GOBI_CAT;
|
||||
break;
|
||||
case QMI_SERVICE_CAT_OLD:
|
||||
if (list[i].major > 0)
|
||||
data->features |= GOBI_CAT_OLD;
|
||||
break;
|
||||
case QMI_SERVICE_VOICE:
|
||||
if (qmi_device_has_service(data->device, QMI_SERVICE_DMS))
|
||||
data->features |= GOBI_DMS;
|
||||
if (qmi_device_has_service(data->device, QMI_SERVICE_NAS))
|
||||
data->features |= GOBI_NAS;
|
||||
if (qmi_device_has_service(data->device, QMI_SERVICE_WMS))
|
||||
data->features |= GOBI_WMS;
|
||||
if (qmi_device_has_service(data->device, QMI_SERVICE_WDS))
|
||||
data->features |= GOBI_WDS;
|
||||
if (qmi_device_has_service(data->device, QMI_SERVICE_WDA))
|
||||
data->features |= GOBI_WDA;
|
||||
if (qmi_device_has_service(data->device, QMI_SERVICE_PDS))
|
||||
data->features |= GOBI_PDS;
|
||||
if (qmi_device_has_service(data->device, QMI_SERVICE_PBM))
|
||||
data->features |= GOBI_PBM;
|
||||
if (qmi_device_has_service(data->device, QMI_SERVICE_UIM))
|
||||
data->features |= GOBI_UIM;
|
||||
if (qmi_device_has_service(data->device, QMI_SERVICE_CAT))
|
||||
data->features |= GOBI_CAT;
|
||||
if (qmi_device_get_service_version(data->device,
|
||||
QMI_SERVICE_CAT_OLD, &major, &minor))
|
||||
if (major > 0)
|
||||
data->features |= GOBI_CAT_OLD;
|
||||
if (qmi_device_has_service(data->device, QMI_SERVICE_VOICE))
|
||||
data->features |= GOBI_VOICE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(data->features & GOBI_DMS)) {
|
||||
if (++data->discover_attempts < 3) {
|
||||
@@ -484,7 +466,7 @@ static void gobi_post_sim(struct ofono_modem *modem)
|
||||
|
||||
DBG("%p", modem);
|
||||
|
||||
ofono_lte_create(modem, "qmimodem", data->device);
|
||||
ofono_lte_create(modem, 0, "qmimodem", data->device);
|
||||
|
||||
if (data->features & GOBI_CAT)
|
||||
ofono_stk_create(modem, 0, "qmimodem", data->device);
|
||||
|
||||
@@ -422,6 +422,8 @@ static struct ofono_modem_driver mbim_driver = {
|
||||
|
||||
static int mbim_init(void)
|
||||
{
|
||||
l_debug("------------------->Foobar");
|
||||
|
||||
return ofono_modem_driver_register(&mbim_driver);
|
||||
}
|
||||
|
||||
|
||||
@@ -458,7 +458,7 @@ static void ril_post_sim(struct ofono_modem *modem)
|
||||
}
|
||||
|
||||
if (ofono_modem_get_boolean(modem, MODEM_PROP_LTE_CAPABLE))
|
||||
ofono_lte_create(modem, "rilmodem", rd->ril);
|
||||
ofono_lte_create(modem, 0, "rilmodem", rd->ril);
|
||||
|
||||
ofono_stk_create(modem, 0, "rilmodem", rd->ril);
|
||||
}
|
||||
|
||||
273
ofono/plugins/sim7100.c
Normal file
273
ofono/plugins/sim7100.c
Normal file
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2009 Collabora Ltd. All rights reserved.
|
||||
* Copyright 2018 Purism SPC
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file was originally copied from g1.c and
|
||||
* modified by Bob Ham <bob.ham@puri.sm>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <gatchat.h>
|
||||
#include <gattty.h>
|
||||
|
||||
#define OFONO_API_SUBJECT_TO_CHANGE
|
||||
#include <ofono/plugin.h>
|
||||
#include <ofono/log.h>
|
||||
#include <ofono/modem.h>
|
||||
#include <ofono/call-barring.h>
|
||||
#include <ofono/call-forwarding.h>
|
||||
#include <ofono/call-meter.h>
|
||||
#include <ofono/call-settings.h>
|
||||
#include <ofono/devinfo.h>
|
||||
#include <ofono/message-waiting.h>
|
||||
#include <ofono/netreg.h>
|
||||
#include <ofono/phonebook.h>
|
||||
#include <ofono/sim.h>
|
||||
#include <ofono/sms.h>
|
||||
#include <ofono/ussd.h>
|
||||
#include <ofono/voicecall.h>
|
||||
#include <ofono/gprs.h>
|
||||
#include <ofono/gprs-context.h>
|
||||
|
||||
#include <drivers/atmodem/vendor.h>
|
||||
|
||||
struct sim7100_data {
|
||||
GAtChat *at;
|
||||
GAtChat *ppp;
|
||||
};
|
||||
|
||||
static void sim7100_debug(const char *str, void *user_data)
|
||||
{
|
||||
const char *prefix = user_data;
|
||||
|
||||
ofono_info("%s%s", prefix, str);
|
||||
}
|
||||
|
||||
/* Detect hardware, and initialize if found */
|
||||
static int sim7100_probe(struct ofono_modem *modem)
|
||||
{
|
||||
struct sim7100_data *data;
|
||||
|
||||
DBG("");
|
||||
|
||||
data = g_try_new0(struct sim7100_data, 1);
|
||||
if (data == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
ofono_modem_set_data(modem, data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sim7100_remove(struct ofono_modem *modem)
|
||||
{
|
||||
struct sim7100_data *data = ofono_modem_get_data(modem);
|
||||
|
||||
DBG("");
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
if (data->at)
|
||||
g_at_chat_unref(data->at);
|
||||
|
||||
if (data->ppp)
|
||||
g_at_chat_unref(data->ppp);
|
||||
|
||||
ofono_modem_set_data(modem, NULL);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void cfun_set_on_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_modem *modem = user_data;
|
||||
|
||||
DBG("");
|
||||
|
||||
if (ok)
|
||||
ofono_modem_set_powered(modem, TRUE);
|
||||
}
|
||||
|
||||
static int open_device(struct ofono_modem *modem, const char *devkey,
|
||||
GAtChat **chatp)
|
||||
{
|
||||
GIOChannel *channel;
|
||||
GAtSyntax *syntax;
|
||||
GAtChat *chat;
|
||||
const char *device;
|
||||
|
||||
DBG("devkey=%s", devkey);
|
||||
|
||||
device = ofono_modem_get_string(modem, devkey);
|
||||
if (device == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
channel = g_at_tty_open(device, NULL);
|
||||
if (channel == NULL)
|
||||
return -EIO;
|
||||
|
||||
syntax = g_at_syntax_new_gsm_permissive();
|
||||
chat = g_at_chat_new(channel, syntax);
|
||||
g_at_syntax_unref(syntax);
|
||||
g_io_channel_unref(channel);
|
||||
|
||||
if (chat == NULL)
|
||||
return -EIO;
|
||||
|
||||
if (getenv("OFONO_AT_DEBUG"))
|
||||
g_at_chat_set_debug(chat, sim7100_debug, "");
|
||||
|
||||
*chatp = chat;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sim7100_enable(struct ofono_modem *modem)
|
||||
{
|
||||
struct sim7100_data *data = ofono_modem_get_data(modem);
|
||||
int err;
|
||||
|
||||
DBG("");
|
||||
|
||||
err = open_device(modem, "AT", &data->at);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = open_device(modem, "PPP", &data->ppp);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* ensure modem is in a known state; verbose on, echo/quiet off */
|
||||
g_at_chat_send(data->at, "ATE0Q0V1", NULL, NULL, NULL, NULL);
|
||||
|
||||
/* power up modem */
|
||||
g_at_chat_send(data->at, "AT+CFUN=1", NULL, cfun_set_on_cb,
|
||||
modem, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cfun_set_off_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_modem *modem = user_data;
|
||||
struct sim7100_data *data = ofono_modem_get_data(modem);
|
||||
|
||||
DBG("");
|
||||
|
||||
g_at_chat_unref(data->ppp);
|
||||
g_at_chat_unref(data->at);
|
||||
data->at = data->ppp = NULL;
|
||||
|
||||
if (ok)
|
||||
ofono_modem_set_powered(modem, FALSE);
|
||||
}
|
||||
|
||||
static int sim7100_disable(struct ofono_modem *modem)
|
||||
{
|
||||
struct sim7100_data *data = ofono_modem_get_data(modem);
|
||||
|
||||
DBG("");
|
||||
|
||||
/* power down modem */
|
||||
g_at_chat_cancel_all(data->ppp);
|
||||
g_at_chat_cancel_all(data->at);
|
||||
g_at_chat_unregister_all(data->ppp);
|
||||
g_at_chat_unregister_all(data->at);
|
||||
g_at_chat_send(data->at, "AT+CFUN=0", NULL, cfun_set_off_cb,
|
||||
modem, NULL);
|
||||
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
|
||||
static void sim7100_pre_sim(struct ofono_modem *modem)
|
||||
{
|
||||
struct sim7100_data *data = ofono_modem_get_data(modem);
|
||||
struct ofono_sim *sim;
|
||||
|
||||
DBG("");
|
||||
|
||||
ofono_devinfo_create(modem, 0, "atmodem", data->at);
|
||||
sim = ofono_sim_create(modem, 0, "atmodem", data->at);
|
||||
ofono_voicecall_create(modem, OFONO_VENDOR_SIMCOM, "atmodem", data->at);
|
||||
|
||||
if (sim)
|
||||
ofono_sim_inserted_notify(sim, TRUE);
|
||||
}
|
||||
|
||||
static void sim7100_post_sim(struct ofono_modem *modem)
|
||||
{
|
||||
struct sim7100_data *data = ofono_modem_get_data(modem);
|
||||
struct ofono_message_waiting *mw;
|
||||
struct ofono_gprs *gprs = NULL;
|
||||
struct ofono_gprs_context *gc = NULL;
|
||||
|
||||
DBG("");
|
||||
|
||||
ofono_ussd_create(modem, 0, "atmodem", data->at);
|
||||
ofono_call_forwarding_create(modem, 0, "atmodem", data->at);
|
||||
ofono_call_settings_create(modem, 0, "atmodem", data->at);
|
||||
ofono_netreg_create(modem, 0, "atmodem", data->at);
|
||||
ofono_call_meter_create(modem, 0, "atmodem", data->at);
|
||||
ofono_call_barring_create(modem, 0, "atmodem", data->at);
|
||||
ofono_sms_create(modem, OFONO_VENDOR_SIMCOM, "atmodem", data->at);
|
||||
ofono_phonebook_create(modem, 0, "atmodem", data->at);
|
||||
|
||||
gprs = ofono_gprs_create(modem, 0, "atmodem", data->at);
|
||||
gc = ofono_gprs_context_create(modem, 0, "atmodem", data->ppp);
|
||||
|
||||
if (gprs && gc)
|
||||
ofono_gprs_add_context(gprs, gc);
|
||||
|
||||
mw = ofono_message_waiting_create(modem);
|
||||
if (mw)
|
||||
ofono_message_waiting_register(mw);
|
||||
}
|
||||
|
||||
static struct ofono_modem_driver sim7100_driver = {
|
||||
.name = "sim7100",
|
||||
.probe = sim7100_probe,
|
||||
.remove = sim7100_remove,
|
||||
.enable = sim7100_enable,
|
||||
.disable = sim7100_disable,
|
||||
.pre_sim = sim7100_pre_sim,
|
||||
.post_sim = sim7100_post_sim,
|
||||
};
|
||||
|
||||
static int sim7100_init(void)
|
||||
{
|
||||
return ofono_modem_driver_register(&sim7100_driver);
|
||||
}
|
||||
|
||||
static void sim7100_exit(void)
|
||||
{
|
||||
ofono_modem_driver_unregister(&sim7100_driver);
|
||||
}
|
||||
|
||||
OFONO_PLUGIN_DEFINE(sim7100, "SIMCom SIM7100E modem driver", VERSION,
|
||||
OFONO_PLUGIN_PRIORITY_DEFAULT, sim7100_init, sim7100_exit)
|
||||
@@ -319,7 +319,7 @@ static void ublox_post_sim(struct ofono_modem *modem)
|
||||
--ncontexts;
|
||||
}
|
||||
|
||||
ofono_lte_create(modem, "ubloxmodem", data->aux);
|
||||
ofono_lte_create(modem, 0, "ubloxmodem", data->aux);
|
||||
}
|
||||
|
||||
static void ublox_post_online(struct ofono_modem *modem)
|
||||
|
||||
@@ -710,7 +710,7 @@ static gboolean setup_telitqmi(struct modem_info *modem)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean setup_simcom(struct modem_info *modem)
|
||||
static gboolean setup_sim900(struct modem_info *modem)
|
||||
{
|
||||
const char *mdm = NULL, *aux = NULL, *gps = NULL, *diag = NULL;
|
||||
GSList *list;
|
||||
@@ -1132,6 +1132,7 @@ static gboolean setup_gemalto(struct modem_info* modem)
|
||||
DBG("%s %s %s %s %s", info->devnode, info->interface,
|
||||
info->number, info->label, info->subsystem);
|
||||
|
||||
/* PHS8-P */
|
||||
if (g_strcmp0(info->interface, "255/255/255") == 0) {
|
||||
if (g_strcmp0(info->number, "01") == 0)
|
||||
gps = info->devnode;
|
||||
@@ -1144,6 +1145,20 @@ static gboolean setup_gemalto(struct modem_info* modem)
|
||||
else if (g_strcmp0(info->subsystem, "usbmisc") == 0)
|
||||
qmi = info->devnode;
|
||||
}
|
||||
|
||||
/* Cinterion ALS3, PLS8-E, PLS8-X */
|
||||
if (g_strcmp0(info->interface, "2/2/1") == 0) {
|
||||
if (g_strcmp0(info->number, "00") == 0)
|
||||
mdm = info->devnode;
|
||||
else if (g_strcmp0(info->number, "02") == 0)
|
||||
app = info->devnode;
|
||||
else if (g_strcmp0(info->number, "04") == 0)
|
||||
gps = info->devnode;
|
||||
}
|
||||
if (g_strcmp0(info->interface, "2/6/0") == 0) {
|
||||
if (g_strcmp0(info->subsystem, "net") == 0)
|
||||
net = info->devnode;
|
||||
}
|
||||
}
|
||||
|
||||
DBG("application=%s gps=%s modem=%s network=%s qmi=%s",
|
||||
@@ -1156,6 +1171,7 @@ static gboolean setup_gemalto(struct modem_info* modem)
|
||||
ofono_modem_set_string(modem->modem, "GPS", gps);
|
||||
ofono_modem_set_string(modem->modem, "Modem", mdm);
|
||||
ofono_modem_set_string(modem->modem, "Device", qmi);
|
||||
ofono_modem_set_string(modem->modem, "Model", modem->model);
|
||||
ofono_modem_set_string(modem->modem, "NetworkInterface", net);
|
||||
|
||||
return TRUE;
|
||||
@@ -1196,6 +1212,54 @@ static gboolean setup_xmm7xxx(struct modem_info *modem)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean setup_sim7100(struct modem_info *modem)
|
||||
{
|
||||
const char *at = NULL, *ppp = NULL, *gps = NULL, *diag = NULL, *audio = NULL;
|
||||
GSList *list;
|
||||
|
||||
DBG("%s", modem->syspath);
|
||||
|
||||
for (list = modem->devices; list; list = list->next) {
|
||||
struct device_info *info = list->data;
|
||||
|
||||
DBG("%s %s", info->devnode, info->number);
|
||||
|
||||
/*
|
||||
* Serial port layout:
|
||||
* 0: QCDM/DIAG
|
||||
* 1: NMEA
|
||||
* 2: AT
|
||||
* 3: AT/PPP
|
||||
* 4: audio
|
||||
*
|
||||
* -- https://www.spinics.net/lists/linux-usb/msg135728.html
|
||||
*/
|
||||
if (g_strcmp0(info->number, "00") == 0)
|
||||
diag = info->devnode;
|
||||
else if (g_strcmp0(info->number, "01") == 0)
|
||||
gps = info->devnode;
|
||||
else if (g_strcmp0(info->number, "02") == 0)
|
||||
at = info->devnode;
|
||||
else if (g_strcmp0(info->number, "03") == 0)
|
||||
ppp = info->devnode;
|
||||
else if (g_strcmp0(info->number, "04") == 0)
|
||||
audio = info->devnode;
|
||||
}
|
||||
|
||||
if (at == NULL)
|
||||
return FALSE;
|
||||
|
||||
DBG("at=%s ppp=%s gps=%s diag=%s, audio=%s", at, ppp, gps, diag, audio);
|
||||
|
||||
ofono_modem_set_string(modem->modem, "AT", at);
|
||||
ofono_modem_set_string(modem->modem, "PPP", ppp);
|
||||
ofono_modem_set_string(modem->modem, "GPS", gps);
|
||||
ofono_modem_set_string(modem->modem, "Diag", diag);
|
||||
ofono_modem_set_string(modem->modem, "Audio", audio);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static struct {
|
||||
const char *name;
|
||||
gboolean (*setup)(struct modem_info *modem);
|
||||
@@ -1215,7 +1279,8 @@ static struct {
|
||||
{ "nokia", setup_nokia },
|
||||
{ "telit", setup_telit, "device/interface" },
|
||||
{ "telitqmi", setup_telitqmi },
|
||||
{ "simcom", setup_simcom },
|
||||
{ "sim900", setup_sim900 },
|
||||
{ "sim7100", setup_sim7100 },
|
||||
{ "zte", setup_zte },
|
||||
{ "icera", setup_icera },
|
||||
{ "samsung", setup_samsung },
|
||||
@@ -1579,7 +1644,8 @@ static struct {
|
||||
{ "alcatel", "option", "1bbb", "0017" },
|
||||
{ "novatel", "option", "1410" },
|
||||
{ "zte", "option", "19d2" },
|
||||
{ "simcom", "option", "05c6", "9000" },
|
||||
{ "sim900", "option", "05c6", "9000" },
|
||||
{ "sim7100", "option", "1e0e", "9001" },
|
||||
{ "telit", "usbserial", "1bc7" },
|
||||
{ "telit", "option", "1bc7" },
|
||||
{ "telit", "cdc_acm", "1bc7", "0021" },
|
||||
@@ -1600,10 +1666,12 @@ static struct {
|
||||
{ "gemalto", "option", "1e2d", "0053" },
|
||||
{ "gemalto", "cdc_wdm", "1e2d", "0053" },
|
||||
{ "gemalto", "qmi_wwan", "1e2d", "0053" },
|
||||
{ "gemalto", "cdc_acm", "1e2d", "0061" },
|
||||
{ "gemalto", "cdc_ether", "1e2d", "0061" },
|
||||
{ "telit", "cdc_ncm", "1bc7", "0036" },
|
||||
{ "telit", "cdc_acm", "1bc7", "0036" },
|
||||
{ "xmm7xxx", "cdc_acm", "8087", "0930" },
|
||||
{ "xmm7xxx", "cdc_ncm", "8087", "0930" },
|
||||
{ "xmm7xxx", "cdc_acm", "8087" },
|
||||
{ "xmm7xxx", "cdc_ncm", "8087" },
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -1733,7 +1801,11 @@ static gboolean create_modem(gpointer key, gpointer value, gpointer user_data)
|
||||
if (driver_list[i].setup(modem) == TRUE) {
|
||||
ofono_modem_set_string(modem->modem, "SystemPath",
|
||||
syspath);
|
||||
ofono_modem_register(modem->modem);
|
||||
if (ofono_modem_register(modem->modem) < 0) {
|
||||
DBG("could not register modem '%s'", modem->driver);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,7 +323,7 @@ static void xmm7xxx_post_sim(struct ofono_modem *modem)
|
||||
{
|
||||
struct xmm7xxx_data *data = ofono_modem_get_data(modem);
|
||||
|
||||
ofono_lte_create(modem, "atmodem", data->chat);
|
||||
ofono_lte_create(modem, 0, "atmodem", data->chat);
|
||||
ofono_radio_settings_create(modem, 0, "xmm7modem", data->chat);
|
||||
ofono_sim_auth_create(modem);
|
||||
}
|
||||
|
||||
@@ -268,7 +268,7 @@ static void set_new_cond_list(struct ofono_call_forwarding *cf,
|
||||
const char *number;
|
||||
dbus_uint16_t timeout;
|
||||
char attr[64];
|
||||
char tattr[64];
|
||||
char tattr[72];
|
||||
gboolean update_sim = FALSE;
|
||||
gboolean old_cfu;
|
||||
gboolean new_cfu;
|
||||
|
||||
@@ -115,6 +115,8 @@ static const GDBusMethodTable cdma_netreg_manager_methods[] = {
|
||||
};
|
||||
|
||||
static const GDBusSignalTable cdma_netreg_manager_signals[] = {
|
||||
{ GDBUS_SIGNAL("PropertyChanged",
|
||||
GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
@@ -994,18 +994,17 @@ static void bac_cb(GAtServer *server, GAtServerRequestType type,
|
||||
/*
|
||||
* CVSD codec is mandatory and must come first.
|
||||
* See HFP v1.6 4.34.1
|
||||
* However, some headsets send the list in wrong order,
|
||||
* but function fine otherwise, so to get those working
|
||||
* let's not be pedantic about the codec order.
|
||||
*/
|
||||
if (g_at_result_iter_next_number(&iter, &val) == FALSE ||
|
||||
val != HFP_CODEC_CVSD)
|
||||
goto fail;
|
||||
|
||||
em->bac_received = TRUE;
|
||||
|
||||
em->negotiated_codec = 0;
|
||||
em->r_codecs[CVSD_OFFSET].supported = TRUE;
|
||||
|
||||
while (g_at_result_iter_next_number(&iter, &val)) {
|
||||
switch (val) {
|
||||
case HFP_CODEC_CVSD:
|
||||
em->bac_received = TRUE;
|
||||
em->negotiated_codec = 0;
|
||||
em->r_codecs[CVSD_OFFSET].supported = TRUE;
|
||||
break;
|
||||
case HFP_CODEC_MSBC:
|
||||
em->r_codecs[MSBC_OFFSET].supported = TRUE;
|
||||
break;
|
||||
@@ -1015,6 +1014,11 @@ static void bac_cb(GAtServer *server, GAtServerRequestType type,
|
||||
}
|
||||
}
|
||||
|
||||
if (!em->bac_received) {
|
||||
DBG("Mandatory codec %d not received.", HFP_CODEC_CVSD);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
|
||||
|
||||
/*
|
||||
|
||||
@@ -244,6 +244,7 @@ static void lte_atom_remove(struct ofono_atom *atom)
|
||||
}
|
||||
|
||||
struct ofono_lte *ofono_lte_create(struct ofono_modem *modem,
|
||||
unsigned int vendor,
|
||||
const char *driver, void *data)
|
||||
{
|
||||
struct ofono_lte *lte;
|
||||
@@ -266,7 +267,7 @@ struct ofono_lte *ofono_lte_create(struct ofono_modem *modem,
|
||||
if (g_strcmp0(drv->name, driver))
|
||||
continue;
|
||||
|
||||
if (drv->probe(lte, data) < 0)
|
||||
if (drv->probe(lte, vendor, data) < 0)
|
||||
continue;
|
||||
|
||||
lte->driver = drv;
|
||||
|
||||
@@ -960,7 +960,8 @@ static void sim_enter_pin_cb(const struct ofono_error *error, void *data)
|
||||
|
||||
__ofono_dbus_pending_reply(&sim->pending, reply);
|
||||
|
||||
if (sim->initialized)
|
||||
/* If PIN entry fails, then recheck the PIN type */
|
||||
if (sim->initialized || error->type != OFONO_ERROR_TYPE_NO_ERROR)
|
||||
goto recheck;
|
||||
|
||||
if (sim->pin_type == OFONO_SIM_PASSWORD_SIM_PIN ||
|
||||
|
||||
@@ -405,18 +405,18 @@ static void sim_fs_op_read_block_cb(const struct ofono_error *error,
|
||||
}
|
||||
|
||||
start_block = op->offset / 256;
|
||||
end_block = (op->offset + (op->num_bytes - 1)) / 256;
|
||||
end_block = op->num_bytes ? (op->offset + op->num_bytes - 1) / 256 :
|
||||
start_block;
|
||||
|
||||
if (op->current == start_block) {
|
||||
bufoff = 0;
|
||||
dataoff = op->offset % 256;
|
||||
tocopy = MIN(256 - op->offset % 256,
|
||||
op->num_bytes - op->current * 256);
|
||||
tocopy = MIN(256 - dataoff, op->num_bytes);
|
||||
} else {
|
||||
bufoff = (op->current - start_block - 1) * 256 +
|
||||
bufoff = (op->current - start_block) * 256 -
|
||||
op->offset % 256;
|
||||
dataoff = 0;
|
||||
tocopy = MIN(256, op->num_bytes - op->current * 256);
|
||||
tocopy = MIN(256, op->num_bytes - bufoff);
|
||||
}
|
||||
|
||||
DBG("bufoff: %d, dataoff: %d, tocopy: %d",
|
||||
@@ -485,13 +485,12 @@ static gboolean sim_fs_op_read_block(gpointer user_data)
|
||||
bufoff = 0;
|
||||
seekoff = SIM_CACHE_HEADER_SIZE + op->current * 256 +
|
||||
op->offset % 256;
|
||||
toread = MIN(256 - op->offset % 256,
|
||||
op->num_bytes - op->current * 256);
|
||||
toread = MIN(256 - op->offset % 256, op->num_bytes);
|
||||
} else {
|
||||
bufoff = (op->current - start_block - 1) * 256 +
|
||||
bufoff = (op->current - start_block) * 256 -
|
||||
op->offset % 256;
|
||||
seekoff = SIM_CACHE_HEADER_SIZE + op->current * 256;
|
||||
toread = MIN(256, op->num_bytes - op->current * 256);
|
||||
toread = MIN(256, op->num_bytes - bufoff);
|
||||
}
|
||||
|
||||
DBG("bufoff: %d, seekoff: %d, toread: %d",
|
||||
|
||||
@@ -329,7 +329,7 @@ static void parse_device_caps(const void *data)
|
||||
assert(r);
|
||||
|
||||
assert(device_type == 1);
|
||||
assert(cellular_class = 1);
|
||||
assert(cellular_class == 1);
|
||||
assert(voice_class == 1);
|
||||
assert(sim_class == 2);
|
||||
assert(data_class == 0x3f);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
Name: ofono
|
||||
Summary: Open Source Telephony
|
||||
Version: 1.23
|
||||
Version: 1.24
|
||||
Release: 1
|
||||
License: GPLv2
|
||||
URL: https://git.sailfishos.org/mer-core/ofono
|
||||
URL: https://github.com/sailfishos/ofono
|
||||
Source: %{name}-%{version}.tar.bz2
|
||||
|
||||
%define libgrilio_version 1.0.38
|
||||
@@ -130,6 +130,9 @@ systemctl daemon-reload ||:
|
||||
%postun
|
||||
systemctl daemon-reload ||:
|
||||
|
||||
%transfiletriggerin -- %{_libdir}/ofono/plugins
|
||||
systemctl try-restart ofono.service ||:
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
%license COPYING
|
||||
|
||||
2
upstream
2
upstream
Submodule upstream updated: 8766cedac6...2c3668f87d
Reference in New Issue
Block a user