summaryrefslogtreecommitdiffstats
path: root/misc.c
diff options
context:
space:
mode:
authorWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2017-09-06 00:19:36 +0200
committerWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2017-09-06 00:19:36 +0200
commitf35a9bbd1ebb52433f313c675fbe01bb1ca96d7d (patch)
treec1aff224fd4a2ea2e5e06805c7caff5406b0ab42 /misc.c
parent06cf4fe68ad096961b4b9c653ba2bc31d270f009 (diff)
downloadqmi-ril-f35a9bbd1ebb52433f313c675fbe01bb1ca96d7d.tar.gz
qmi-ril-f35a9bbd1ebb52433f313c675fbe01bb1ca96d7d.tar.bz2
qmi-ril-f35a9bbd1ebb52433f313c675fbe01bb1ca96d7d.zip
initial version of QMI-RILHEADmaster
The RIL uses libqmi. qmicli and ModemManager were used as references for using libqmi. The request processing is modelled after Samsung-RIL and a lot of code could be reused for QMI-RIL. Establishing a data connection succeeds and mobile data is working in early testing. However, there is not yet a routine for handling interruptions and notifying Android about them. Information about the serving network including signal strength are retrieved and an unlocked SIM card is recognized. Reading data from the SIM and requesting the usual device information should work as well. Support for voice calls and SMS is completely missing at this point. Signed-off-by: Wolfgang Wiedmeyer <wolfgit@wiedmeyer.de>
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c289
1 files changed, 289 insertions, 0 deletions
diff --git a/misc.c b/misc.c
new file mode 100644
index 0000000..9eda760
--- /dev/null
+++ b/misc.c
@@ -0,0 +1,289 @@
+/*
+ * This file is part of QMI-RIL.
+ *
+ * Copyright (C) 2017 Wolfgang Wiedmeyer <wolfgit@wiedmeyer.de>
+ *
+ * QMI-RIL is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * QMI-RIL 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 QMI-RIL. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+
+#define LOG_TAG "RIL"
+#include <utils/Log.h>
+
+#include <qmi-ril.h>
+
+static void
+get_software_version_ready(QmiClientDms *client, GAsyncResult *res,
+ RIL_Token token)
+{
+ const gchar *version;
+ QmiMessageDmsGetSoftwareVersionOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_get_software_version_finish(client, res,
+ &error);
+ if (!output) {
+ RIL_LOGE("%s: error: operation failed: %s", __func__,
+ error->message);
+ goto error;
+ }
+
+ if (!qmi_message_dms_get_software_version_output_get_result (output, &error)) {
+ RIL_LOGE("error: couldn't get software version: %s",
+ error->message);
+ goto error;
+ }
+
+ qmi_message_dms_get_software_version_output_get_version(
+ output, &version, NULL);
+
+ RIL_LOGD("Software version: %s", version);
+
+ ril_request_complete(token, RIL_E_SUCCESS, (void *) version, sizeof(version));
+
+ goto complete;
+
+error:
+ ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0);
+
+complete:
+ if (error)
+ g_error_free(error);
+ if (output)
+ qmi_message_dms_get_software_version_output_unref(output);
+}
+
+int ril_request_baseband_version(void *data, size_t size, RIL_Token token)
+{
+ struct ril_request *request;
+ int rc;
+
+ rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ if (rc < 0)
+ return RIL_REQUEST_UNHANDLED;
+
+ request = ril_request_find_request_status(RIL_REQUEST_BASEBAND_VERSION,
+ RIL_REQUEST_HANDLED);
+ if (request != NULL)
+ return RIL_REQUEST_UNHANDLED;
+
+ qmi_client_dms_get_software_version(ctx->DmsClient, NULL, 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_software_version_ready,
+ token);
+
+ return RIL_REQUEST_HANDLED;
+}
+
+static void uim_get_imsi_ready(QmiClientDms *client, GAsyncResult *res,
+ RIL_Token token)
+{
+ const gchar *str = NULL;
+ QmiMessageDmsUimGetImsiOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_uim_get_imsi_finish (client, res, &error);
+ if (!output) {
+ RIL_LOGE("%s: error: operation failed: %s", __func__,
+ error->message);
+ goto error;
+ }
+
+ if (!qmi_message_dms_uim_get_imsi_output_get_result (output, &error)) {
+ RIL_LOGE("error: couldn't get IMSI: %s", error->message);
+ goto error;
+ }
+
+ qmi_message_dms_uim_get_imsi_output_get_imsi(output, &str, NULL);
+
+ RIL_LOGD("UIM IMSI retrieved: '%s'", str);
+
+ ril_request_complete(token, RIL_E_SUCCESS, (void *) str, sizeof(str));
+
+ goto complete;
+
+error:
+ ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0);
+
+complete:
+ if (error)
+ g_error_free(error);
+ if (output)
+ qmi_message_dms_uim_get_imsi_output_unref(output);
+}
+
+int ril_request_get_imsi(void *data, size_t size, RIL_Token token)
+{
+ struct ril_request *request;
+ int rc;
+
+ rc = ril_radio_state_check(RADIO_STATE_SIM_READY);
+ if (rc < 0)
+ return RIL_REQUEST_UNHANDLED;
+
+ request = ril_request_find_request_status(RIL_REQUEST_GET_IMSI, RIL_REQUEST_HANDLED);
+ if (request != NULL)
+ return RIL_REQUEST_UNHANDLED;
+
+ qmi_client_dms_uim_get_imsi(ctx->DmsClient, NULL, 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)uim_get_imsi_ready,
+ token);
+
+ return RIL_REQUEST_HANDLED;
+}
+
+static void get_ids_ready(QmiClientDms *client, GAsyncResult *res,
+ RIL_Token token)
+{
+ struct ril_request *request;
+ const gchar *imei_buf;
+ char *imei = NULL;
+ char *imeisv = NULL;
+ unsigned int imeisvlen;
+ QmiMessageDmsGetIdsOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_dms_get_ids_finish (client, res, &error);
+ if (!output) {
+ RIL_LOGE("%s: error: operation failed: %s", __func__,
+ error->message);
+ goto error;
+ }
+
+ if (!qmi_message_dms_get_ids_output_get_result(output, &error)) {
+ RIL_LOGE("error: couldn't get IDs: %s", error->message);
+ goto error;
+ }
+
+ qmi_message_dms_get_ids_output_get_imei(output, &imei_buf, NULL);
+
+ imei = (char*) imei_buf;
+
+ // not yet a way to retrieve the IMEISV, so set 00 as SVN
+ imeisvlen = strlen(imei) - 1 + 3;
+ imeisv = (char*) malloc(imeisvlen);
+ strcpy(imeisv, imei);
+ imeisv = strcat(imeisv, "00");
+ imeisv[imeisvlen] = '\0';
+
+ RIL_LOGD("Device IDs retrieved:\n"
+ "\tIMEI: '%s'\n"
+ "\tIMEISV: '%s'", imei, imeisv);
+
+ request = ril_request_find_request_status(RIL_REQUEST_GET_IMEI, RIL_REQUEST_HANDLED);
+ if (request != NULL)
+ ril_request_complete(request->token, RIL_E_SUCCESS, (void *) imei, sizeof(imei));
+
+ request = ril_request_find_request_status(RIL_REQUEST_GET_IMEISV, RIL_REQUEST_HANDLED);
+ if (request != NULL)
+ ril_request_complete(request->token, RIL_E_SUCCESS, (void *) imeisv, sizeof(imeisv));
+
+ goto complete;
+
+error:
+ request = ril_request_find_request_status(RIL_REQUEST_GET_IMEI, RIL_REQUEST_HANDLED);
+ if (request != NULL)
+ ril_request_complete(request->token, RIL_E_GENERIC_FAILURE, NULL, 0);
+
+ request = ril_request_find_request_status(RIL_REQUEST_GET_IMEISV, RIL_REQUEST_HANDLED);
+ if (request != NULL)
+ ril_request_complete(request->token, RIL_E_GENERIC_FAILURE, NULL, 0);
+
+complete:
+ free(imei);
+ free(imeisv);
+
+ if (error)
+ g_error_free(error);
+ if (output)
+ qmi_message_dms_get_ids_output_unref(output);
+}
+
+int ril_request_get_imei(void *data, size_t size, RIL_Token token)
+{
+ struct ril_request *request;
+ int rc;
+
+ rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ if (rc < 0)
+ return RIL_REQUEST_UNHANDLED;
+
+ request = ril_request_find_request_status(RIL_REQUEST_GET_IMEI, RIL_REQUEST_HANDLED);
+ if (request != NULL)
+ return RIL_REQUEST_UNHANDLED;
+
+ // The response to the IMEISV request will hold IMEI as well
+ request = ril_request_find_request_status(RIL_REQUEST_GET_IMEISV, RIL_REQUEST_HANDLED);
+ if (request != NULL)
+ return RIL_REQUEST_HANDLED;
+
+ qmi_client_dms_get_ids(ctx->DmsClient, NULL, 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_ids_ready,
+ token);
+
+ return RIL_REQUEST_HANDLED;
+}
+
+int ril_request_get_imeisv(void *data, size_t size, RIL_Token token)
+{
+ struct ril_request *request;
+ int rc;
+
+ rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ if (rc < 0)
+ return RIL_REQUEST_UNHANDLED;
+
+ request = ril_request_find_request_status(RIL_REQUEST_GET_IMEISV, RIL_REQUEST_HANDLED);
+ if (request != NULL)
+ return RIL_REQUEST_UNHANDLED;
+
+ // The response to the IMEI request will hold IMEISV as well
+ request = ril_request_find_request_status(RIL_REQUEST_GET_IMEI, RIL_REQUEST_HANDLED);
+ if (request != NULL)
+ return RIL_REQUEST_HANDLED;
+
+ qmi_client_dms_get_ids(ctx->DmsClient, NULL, 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_ids_ready,
+ token);
+
+ return RIL_REQUEST_HANDLED;
+}
+
+int ril_request_screen_state(void *data, size_t size, RIL_Token token)
+{
+ int value;
+ int rc;
+
+ if (data == NULL || size < sizeof(int)) {
+ ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0);
+ return RIL_REQUEST_COMPLETED;
+ }
+
+ rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ if (rc < 0)
+ return RIL_REQUEST_UNHANDLED;
+
+ value = *((int *) data);
+
+ if (value)
+ ril_request_unsolicited(RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, NULL, 0);
+
+ ril_request_complete(token, RIL_E_SUCCESS, NULL, 0);
+
+ return RIL_REQUEST_COMPLETED;
+}