uqmid: add uqmi_sim_decode_imsi() to decode EF.IMSI from UIM
authorAlexander Couzens <[email protected]>
Sun, 18 Aug 2024 22:48:30 +0000 (00:48 +0200)
committerDavid Bauer <[email protected]>
Sat, 31 May 2025 20:41:00 +0000 (22:41 +0200)
SIM or USIM based files are encoded in BCD format and
QMI doesn't offer a direct method to get the IMSI when only the UIM
service is available.

Signed-off-by: Alexander Couzens <[email protected]>
uqmid/CMakeLists.txt
uqmid/sim.c
uqmid/sim.h
uqmid/test_sim.c [new file with mode: 0644]

index 3dd063a1480bc057bf57dad5c6ae1e593922ca86..b2e672e71fee3e1226eb68f4c62dedb69b056113 100644 (file)
@@ -17,3 +17,9 @@ INSTALL(TARGETS uqmid
 ADD_EXECUTABLE(testgsmtap gsmtap_util.c utils/test_gsmtap.c)
 TARGET_LINK_LIBRARIES(testgsmtap ${LIBS} ${UQMID_LIBS})
 TARGET_INCLUDE_DIRECTORIES(testgsmtap PRIVATE ${ubus_include_dir} ${ubox_include_dir} ${blobmsg_json_include_dir} ${json_include_dir} ${talloc_include_dir} ${CMAKE_SOURCE_DIR})
+
+ADD_EXECUTABLE(test_sim test_sim.c sim.c)
+TARGET_LINK_LIBRARIES(test_sim osmofsm)
+ADD_TEST(NAME TestInstantiator
+         COMMAND TestInstantiator)
+
index 92a0b21b440ce1b6e88383029b48b5113313ca7a..afbabc4d1c28858197b7eeca7b534778489ee5a0 100644 (file)
 
 #include "sim.h"
 #include "qmi-enums-uim.h"
+#include "osmocom/utils.h"
+
+#include <errno.h>
+#include <stdbool.h>
 
 enum uqmi_sim_state uim_card_application_state_to_uqmi_state(int app_state)
 {
@@ -57,3 +61,28 @@ enum uqmi_sim_state uim_pin_to_uqmi_state(int upin_state)
                return UQMI_SIM_UNKNOWN;
        }
 }
+
+int uqmi_sim_decode_imsi(uint8_t *imsi_ef, uint8_t imsi_ef_size, char *imsi_str, uint8_t imsi_str_len)
+{
+       uint8_t imsi_len;
+       uint8_t imsi_enc_len;
+       uint8_t oe;
+       // int offset = 0, i;
+       if (imsi_ef_size < 9)
+               return -EINVAL;
+
+       imsi_enc_len = imsi_ef[0];
+       if (imsi_enc_len > 8 || imsi_enc_len == 0)
+               return -EINVAL;
+
+       imsi_len = imsi_enc_len * 2 - 1;
+       oe = (imsi_ef[1] >> 3) & 0x1;
+       if (!oe)
+               imsi_len--;
+
+       /* additional 0 byte */
+       if (imsi_str_len < imsi_len + 1)
+               return -ENOMEM;
+
+       return osmo_bcd2str(imsi_str, imsi_str_len, imsi_ef + 1, 1, imsi_len + 1, false);
+}
index 8b7bf653b843cf65e04b4ebaf37b8f4f7230581f..1f26dc668fa122ba920c1f80ad80c2ccaec4b4f8 100644 (file)
@@ -35,4 +35,6 @@ enum uqmi_sim_state {
 enum uqmi_sim_state uim_card_application_state_to_uqmi_state(int app_state);
 enum uqmi_sim_state uim_pin_to_uqmi_state(int upin_state);
 
+int uqmi_sim_decode_imsi(uint8_t *imsi_ef, uint8_t imsi_ef_size, char *imsi_str, uint8_t imsi_str_len);
+
 #endif /* __UTILS_H */
diff --git a/uqmid/test_sim.c b/uqmid/test_sim.c
new file mode 100644 (file)
index 0000000..a1a23b3
--- /dev/null
@@ -0,0 +1,17 @@
+
+#include "sim.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+int main() {
+       int ret;
+       uint8_t imsi_ef[] = { 0x08, 0x29, 0x82, 0x60, 0x82, 0x00, 0x00, 0x20, 0x80 };
+       char imsi_str[16];
+       ret = uqmi_sim_decode_imsi(&imsi_ef[0], 9, &imsi_str[0], sizeof(imsi_str));
+       if (ret >= 0)
+               fprintf(stderr, "Decoded imsi %s\n", imsi_str);
+       assert(ret >= 0);
+       assert(strncmp(&imsi_str[0], "228062800000208", sizeof(15)) == 0);
+}