uqmid: read IMEI, IMEISV, MEID (CDMA IMEI)
authorAlexander Couzens <[email protected]>
Sun, 8 Sep 2024 14:12:00 +0000 (16:12 +0200)
committerDavid Bauer <[email protected]>
Sat, 31 May 2025 20:41:00 +0000 (22:41 +0200)
Signed-off-by: Alexander Couzens <[email protected]>
uqmid/modem.h
uqmid/modem_fsm.c
uqmid/modem_fsm.h
uqmid/ubus.c

index 78cc7fe20f45ae9bc3c5538374224d76d9a0d5da..12c0b41c87703e8c3ef00cd00d3a10a4683504aa 100644 (file)
 #include <libubus.h>
 #include <netinet/in.h>
 
-#define IMEI_LEN 15
 #define PATH_LEN 128
 
-
 // try to get osmocom fsm into here?
 struct modem_config {
        bool configured;
@@ -46,11 +44,17 @@ struct wwan_conf {
        bool pass_through;
 };
 
+
 struct modem {
        char *name;
        /*! path to the device. /dev/cdc-wdm */
        char *device;
-       char imei[IMEI_LEN];
+       /*! IMEI including LUN check digit */
+       char *imei;
+       /*! 2 digit software version */
+       char *imeisv;
+       /*! CDMA MEID id - hopefully we never need this */
+       char *meid;
        char path[PATH_LEN];
 
        /* Either usb or usbmisc of cdc-wdm0 */
index 98ae7c51b3cc922ce58a47bbb2c18c080baa56f7..8bb11a84a5776fe661f681fb63b9ab472a1dca69 100644 (file)
@@ -272,6 +272,37 @@ static void get_revision_cb(struct qmi_service *service, struct qmi_request *req
        osmo_fsm_inst_dispatch(modem->fi, MODEM_EV_RX_REVISION, NULL);
 }
 
+static void get_ids_cb(struct qmi_service *service, struct qmi_request *req, struct qmi_msg *msg)
+{
+       struct modem *modem = req->cb_data;
+       int ret = 0;
+
+       struct qmi_dms_get_ids_response res = {};
+       ret = qmi_parse_dms_get_ids_response(msg, &res);
+
+       if (ret) {
+               /* FIXME: No revision. Ignoring */
+               modem_log(modem, LOGL_ERROR, "Failed to get a IMEI.");
+               osmo_fsm_inst_dispatch(modem->fi, MODEM_EV_RX_IMEI, NULL);
+               return;
+       }
+
+       TALLOC_FREE(modem->meid);
+       TALLOC_FREE(modem->imei);
+       TALLOC_FREE(modem->imeisv);
+
+       if (res.data.meid)
+               modem->meid = talloc_strdup(modem, res.data.meid);
+
+       if (res.data.imei)
+               modem->imei = talloc_strdup(modem, res.data.imei);
+
+       if (res.data.imei_software_version)
+               modem->imeisv = talloc_strdup(modem, res.data.imei_software_version);
+
+       osmo_fsm_inst_dispatch(modem->fi, MODEM_EV_RX_IMEI, NULL);
+}
+
 static void modem_st_get_model_onenter(struct osmo_fsm_inst *fi, uint32_t old_state)
 {
        struct modem *modem = fi->priv;
@@ -305,6 +336,9 @@ static void modem_st_get_model(struct osmo_fsm_inst *fi, uint32_t event, void *d
                uqmi_service_send_simple(service, qmi_set_dms_get_revision_request, get_revision_cb, modem);
                break;
        case MODEM_EV_RX_REVISION:
+               uqmi_service_send_simple(service, qmi_set_dms_get_ids_request, get_ids_cb, modem);
+               break;
+       case MODEM_EV_RX_IMEI:
                osmo_fsm_inst_state_chg(fi, MODEM_ST_POWEROFF, 3, 0);
                break;
        }
@@ -1082,7 +1116,8 @@ static const struct osmo_fsm_state modem_states[] = {
        [MODEM_ST_GET_MODEL] = {
                .in_event_mask = S(MODEM_EV_RX_MODEL) |
                                 S(MODEM_EV_RX_MANUFACTURER) |
-                                S(MODEM_EV_RX_REVISION),
+                                S(MODEM_EV_RX_REVISION) |
+                                S(MODEM_EV_RX_IMEI),
                .out_state_mask = S(MODEM_ST_POWEROFF) | S(MODEM_ST_DESTROY),
                .name = "GET_MODEL",
                .action = modem_st_get_model,
index 2fc874c33d76b9f6e1a1c80ba5438dbe4b15d01b..587d8f1e15682afe7de658ed15802644d48f8ff0 100644 (file)
@@ -33,6 +33,7 @@ enum modem_fsm_event {
        MODEM_EV_RX_MODEL,
        MODEM_EV_RX_MANUFACTURER,
        MODEM_EV_RX_REVISION,
+       MODEM_EV_RX_IMEI,
 
        MODEM_EV_RX_POWEROFF,
        MODEM_EV_RX_POWERON,
index 5d8035a83a1aadcc95bdfe9b0ed4691a3b55433c..6e6ad5fcb6772627b7a48c0fd31d03d9105e3aff 100644 (file)
@@ -419,6 +419,8 @@ static int modem_dump_state(struct ubus_context *ctx, struct ubus_object *obj, s
        BLOBMSG_ADD_STR_CHECK(&b, "model", modem->model);
        BLOBMSG_ADD_STR_CHECK(&b, "rev", modem->rev);
        BLOBMSG_ADD_STR_CHECK(&b, "imei", modem->imei);
+       BLOBMSG_ADD_STR_CHECK(&b, "imeisv", modem->imeisv);
+       BLOBMSG_ADD_STR_CHECK(&b, "meid", modem->meid);
        BLOBMSG_ADD_STR_CHECK(&b, "imsi", modem->imsi);
        BLOBMSG_ADD_STR_CHECK(&b, "iccid", modem->iccid);
        /* session state */