<div dir="ltr">This is final patch version. I did some tests and it seems works fine. One thing that I can't test is how SAP connection works because I have no working sap-server setup. If anyone have please test. Now the `sim sap MS_NAME` command just enables SAP connection and `sim remove MS_MANE` closes connection if it's active.<br><br>What I have done:<br>- Fixed GPSD configuration r/w errors;<br>- Fixed sap_socket_path configuration r/w errors;<br>- SAP interface starts only if it is configured as SIM source;<br>- Now SAP interface is selectable as SIM source using the sim command in VTY.<br><br>diff --git a/src/host/layer23/include/osmocom/bb/common/sap_interface.h b/src/host/layer23/include/osmocom/bb/common/sap_interface.h<br>index bf19356..e4e64ce 100644<br>--- a/src/host/layer23/include/osmocom/bb/common/sap_interface.h<br>+++ b/src/host/layer23/include/osmocom/bb/common/sap_interface.h<br>@@ -11,6 +11,7 @@ int osmosap_sapsocket(struct osmocom_ms *ms, const char *path);<br> int osmosap_init(struct osmocom_ms *ms);<br> <br> enum osmosap_state {<br>+    SAP_SOCKET_ERROR,<br>     SAP_NOT_CONNECTED,<br>     SAP_IDLE,<br>     SAP_CONNECTION_UNDER_NEGOTIATION,<br>diff --git a/src/host/layer23/include/osmocom/bb/mobile/subscriber.h b/src/host/layer23/include/osmocom/bb/mobile/subscriber.h<br>index 79a2ecc..ac785d4 100644<br>--- a/src/host/layer23/include/osmocom/bb/mobile/subscriber.h<br>+++ b/src/host/layer23/include/osmocom/bb/mobile/subscriber.h<br>@@ -23,7 +23,8 @@ struct gsm_sub_plmn_na {<br> enum {<br>     GSM_SIM_TYPE_NONE = 0,<br>     GSM_SIM_TYPE_READER,<br>-    GSM_SIM_TYPE_TEST<br>+    GSM_SIM_TYPE_TEST,<br>+    GSM_SIM_TYPE_SAP<br> };<br> <br> struct gsm_subscriber {<br>@@ -86,6 +87,8 @@ int gsm_subscr_init(struct osmocom_ms *ms);<br> int gsm_subscr_exit(struct osmocom_ms *ms);<br> int gsm_subscr_testcard(struct osmocom_ms *ms, uint16_t mcc, uint16_t mnc,<br>     uint16_t lac, uint32_t tmsi, uint8_t imsi_attached);<br>+int gsm_subscr_sapcard(struct osmocom_ms *ms);<br>+int gsm_subscr_remove_sapcard(struct osmocom_ms *ms);<br> int gsm_subscr_simcard(struct osmocom_ms *ms);<br> void gsm_subscr_sim_pin(struct osmocom_ms *ms, char *pin1, char *pin2,<br>     int8_t mode);<br>diff --git a/src/host/layer23/src/common/sap_interface.c b/src/host/layer23/src/common/sap_interface.c<br>index a56f4f2..052646a 100644<br>--- a/src/host/layer23/src/common/sap_interface.c<br>+++ b/src/host/layer23/src/common/sap_interface.c<br>@@ -515,7 +515,7 @@ int sap_open(struct osmocom_ms *ms, const char *socket_path)<br>     rc = connect(ms->sap_wq.bfd.fd, (struct sockaddr *) &local, sizeof(local));<br>     if (rc < 0) {<br>         fprintf(stderr, "Failed to connect to '%s'\n", local.sun_path);<br>-        set->sap_socket_path[0] = 0;<br>+        ms->sap_entity.sap_state = SAP_SOCKET_ERROR;<br>         close(ms->sap_wq.bfd.fd);<br>         return rc;<br>     }<br>@@ -582,22 +582,11 @@ int osmosap_sapsocket(struct osmocom_ms *ms, const char *path)<br> int osmosap_init(struct osmocom_ms *ms)<br> {<br>     struct osmosap_entity *sap = &ms->sap_entity;<br>-    int rc;<br> <br>+    LOGP(DSAP, LOGL_INFO, "init SAP client\n");<br>     sap->sap_state = SAP_NOT_CONNECTED;<br>     sap->max_msg_size = GSM_SAP_LENGTH;<br> <br>-    LOGP(DSAP, LOGL_INFO, "init SAP client\n");<br>-<br>-    if(ms->settings.sap_socket_path){<br>-        rc = sap_open(ms, ms->settings.sap_socket_path);<br>-        if (rc < 0) {<br>-            fprintf(stderr, "Failed during sap_open(), no SAP based SIM reader\n");<br>-            ms->sap_wq.bfd.fd = -1;<br>-            return rc;<br>-        }<br>-    }<br>-<br>     return 0;<br> }<br> <br>diff --git a/src/host/layer23/src/common/sim.c b/src/host/layer23/src/common/sim.c<br>index 8e8d7bf..9aad966 100644<br>--- a/src/host/layer23/src/common/sim.c<br>+++ b/src/host/layer23/src/common/sim.c<br>@@ -188,12 +188,12 @@ static int sim_apdu_send(struct osmocom_ms *ms, uint8_t *data, uint16_t length)<br> <br>     /* adding SAP client support<br>      * it makes more sense to do it here then in L1CTL */<br>-    if(ms->settings.sap_socket_path[0] == 0) {<br>-        LOGP(DSIM, LOGL_INFO, "Using built-in SIM reader\n");<br>-        l1ctl_tx_sim_req(ms, data, length);<br>-    } else {<br>+    if (ms->subscr.sim_type == GSM_SIM_TYPE_SAP) {<br>         LOGP(DSIM, LOGL_INFO, "Using SAP backend\n");<br>         osmosap_send_apdu(ms, data, length);<br>+    } else {<br>+        LOGP(DSIM, LOGL_INFO, "Using built-in SIM reader\n");<br>+        l1ctl_tx_sim_req(ms, data, length);<br>     }<br> <br>     return 0;<br>diff --git a/src/host/layer23/src/mobile/app_mobile.c b/src/host/layer23/src/mobile/app_mobile.c<br>index 3895ad6..e076741 100644<br>--- a/src/host/layer23/src/mobile/app_mobile.c<br>+++ b/src/host/layer23/src/mobile/app_mobile.c<br>@@ -115,6 +115,9 @@ int mobile_signal_cb(unsigned int subsys, unsigned int signal,<br>                 set->test_rplmn_mnc, set->test_lac,<br>                 set->test_tmsi, set->test_imsi_attached);<br>             break;<br>+        case GSM_SIM_TYPE_SAP:<br>+            gsm_subscr_sapcard(ms);<br>+            break;<br>         default:<br>             /* no SIM, trigger PLMN selection process */<br>             nmsg = gsm322_msgb_alloc(GSM322_EVENT_SWITCH_ON);<br>diff --git a/src/host/layer23/src/mobile/subscriber.c b/src/host/layer23/src/mobile/subscriber.c<br>index ba3c328..455db50 100644<br>--- a/src/host/layer23/src/mobile/subscriber.c<br>+++ b/src/host/layer23/src/mobile/subscriber.c<br>@@ -28,6 +28,7 @@<br> <br> #include <osmocom/bb/common/logging.h><br> #include <osmocom/bb/common/osmocom_data.h><br>+#include <osmocom/bb/common/sap_interface.h><br> #include <osmocom/bb/common/networks.h><br> #include <osmocom/bb/mobile/vty.h><br> <br>@@ -1256,3 +1257,55 @@ void gsm_subscr_dump(struct gsm_subscriber *subscr,<br>     }<br> }<br> <br>+/*<br>+ * SAP interface integration<br>+ */<br>+<br>+/* Attach SIM card over SAP */<br>+int gsm_subscr_sapcard(struct osmocom_ms *ms)<br>+{<br>+    struct gsm_subscriber *subscr = &ms->subscr;<br>+    struct msgb *nmsg;<br>+    int rc;<br>+<br>+    if (subscr->sim_valid) {<br>+        LOGP(DMM, LOGL_ERROR, "Cannot insert card, until current card "<br>+            "is detached.\n");<br>+        return -EBUSY;<br>+    }<br>+<br>+    /* reset subscriber */<br>+    gsm_subscr_exit(ms);<br>+    gsm_subscr_init(ms);<br>+<br>+    subscr->sim_type = GSM_SIM_TYPE_SAP;<br>+    sprintf(subscr->sim_name, "sap");<br>+    subscr->sim_valid = 1;<br>+<br>+    /* Try to connect to the SAP interface */<br>+    vty_notify(ms, NULL);<br>+    vty_notify(ms, "Connecting to the SAP interface...\n");<br>+    rc = sap_open(ms, ms->settings.sap_socket_path);<br>+    if (rc < 0) {<br>+        LOGP(DSAP, LOGL_ERROR, "Failed during sap_open(), no SAP based SIM reader\n");<br>+        vty_notify(ms, "SAP connection error!\n");<br>+        ms->sap_wq.bfd.fd = -1;<br>+<br>+        /* Detach SIM */<br>+        subscr->sim_valid = 0;<br>+        nmsg = gsm48_mmr_msgb_alloc(GSM48_MMR_NREG_REQ);<br>+        if (!nmsg)<br>+            return -ENOMEM;<br>+        gsm48_mmr_downmsg(ms, nmsg);<br>+<br>+        return rc;<br>+    }<br>+<br>+    return 0;<br>+}<br>+<br>+/* Deattach sapcard */<br>+int gsm_subscr_remove_sapcard(struct osmocom_ms *ms)<br>+{<br>+    return sap_close(ms);<br>+}<br>diff --git a/src/host/layer23/src/mobile/vty_interface.c b/src/host/layer23/src/mobile/vty_interface.c<br>index 5782a17..5a1414d 100644<br>--- a/src/host/layer23/src/mobile/vty_interface.c<br>+++ b/src/host/layer23/src/mobile/vty_interface.c<br>@@ -534,6 +534,29 @@ DEFUN(sim_test_att, sim_test_att_cmd,<br>     return _sim_test_cmd(vty, argc, argv, 1);<br> }<br> <br>+DEFUN(sim_sap, sim_sap_cmd, "sim sap MS_NAME",<br>+    "SIM actions\nAttach SIM over SAP interface\n"<br>+    "Name of MS (see \"show ms\")\n")<br>+{<br>+    struct osmocom_ms *ms;<br>+<br>+    ms = get_ms(argv[0], vty);<br>+    if (!ms)<br>+        return CMD_WARNING;<br>+<br>+    if (ms->subscr.sim_valid) {<br>+        vty_out(vty, "SIM already attached, remove first!%s",<br>+            VTY_NEWLINE);<br>+        return CMD_WARNING;<br>+    }<br>+<br>+    if (gsm_subscr_sapcard(ms) != 0) {<br>+        return CMD_WARNING;<br>+    }<br>+<br>+    return CMD_SUCCESS;<br>+}<br>+<br> DEFUN(sim_reader, sim_reader_cmd, "sim reader MS_NAME",<br>     "SIM actions\nAttach SIM from reader\nName of MS (see \"show ms\")")<br> {<br>@@ -568,8 +591,11 @@ DEFUN(sim_remove, sim_remove_cmd, "sim remove MS_NAME",<br>         return CMD_WARNING;<br>     }<br> <br>-    gsm_subscr_remove(ms);<br>+    if (ms->subscr.sim_type == GSM_SIM_TYPE_SAP) {<br>+        gsm_subscr_remove_sapcard(ms);<br>+    }<br> <br>+    gsm_subscr_remove(ms);<br>     return CMD_SUCCESS;<br> }<br> <br>@@ -1067,7 +1093,7 @@ DEFUN(cfg_no_gps_enable, cfg_no_gps_enable_cmd, "no gps enable",<br> }<br> <br> #ifdef _HAVE_GPSD<br>-DEFUN(cfg_gps_host, cfg_gps_host_cmd, "gps host HOST:PORT",<br>+DEFUN(cfg_gpsd_host, cfg_gpsd_host_cmd, "gpsd host HOST:PORT",<br>     "GPS receiver\nSelect gpsd host and port\n"<br>     "IP and port (optional) of the host running gpsd")<br> {<br>@@ -1075,7 +1101,7 @@ DEFUN(cfg_gps_host, cfg_gps_host_cmd, "gps host HOST:PORT",<br>     if (colon != NULL) {<br>         memcpy(g.gpsd_host, argv[0], colon - argv[0] - 1);<br>         g.gpsd_host[colon - argv[0]] = '\0';<br>-        memcpy(g.gpsd_port, colon, strlen(colon));<br>+        memcpy(g.gpsd_port, colon + 1, strlen(colon));<br>         g.gpsd_port[strlen(colon)] = '\0';<br>     } else {<br>         snprintf(g.gpsd_host, ARRAY_SIZE(g.gpsd_host), "%s", argv[0]);<br>@@ -1295,6 +1321,9 @@ static void config_write_ms(struct vty *vty, struct osmocom_ms *ms)<br>         case GSM_SIM_TYPE_TEST:<br>         vty_out(vty, " sim test%s", VTY_NEWLINE);<br>         break;<br>+        case GSM_SIM_TYPE_SAP:<br>+        vty_out(vty, " sim sap%s", VTY_NEWLINE);<br>+        break;<br>     }<br>     vty_out(vty, " network-selection-mode %s%s", (set->plmn_mode<br>             == PLMN_MODE_AUTO) ? "auto" : "manual", VTY_NEWLINE);<br>@@ -1499,8 +1528,7 @@ static int config_write(struct vty *vty)<br>     struct osmocom_ms *ms;<br> <br> #ifdef _HAVE_GPSD<br>-    vty_out(vty, "gpsd host %s%s", g.gpsd_host, VTY_NEWLINE);<br>-    vty_out(vty, "gpsd port %s%s", g.gpsd_port, VTY_NEWLINE);<br>+    vty_out(vty, "gpsd host %s:%s%s", g.gpsd_host, g.gpsd_port, VTY_NEWLINE);<br> #endif<br>     vty_out(vty, "gps device %s%s", g.device, VTY_NEWLINE);<br>     if (g.baud)<br>@@ -1558,9 +1586,10 @@ DEFUN(cfg_ms_sap, cfg_ms_sap_cmd, "sap-socket PATH",<br>     return CMD_SUCCESS;<br> }<br> <br>-DEFUN(cfg_ms_sim, cfg_ms_sim_cmd, "sim (none|reader|test)",<br>+DEFUN(cfg_ms_sim, cfg_ms_sim_cmd, "sim (none|reader|test|sap)",<br>     "Set SIM card to attach when powering on\nAttach no SIM\n"<br>-    "Attach SIM from reader\nAttach bulit in test SIM")<br>+    "Attach SIM from reader\nAttach bulit in test SIM\n"<br>+    "Attach SIM over SAP interface")<br> {<br>     struct osmocom_ms *ms = vty->index;<br>     struct gsm_settings *set = &ms->settings;<br>@@ -1575,6 +1604,9 @@ DEFUN(cfg_ms_sim, cfg_ms_sim_cmd, "sim (none|reader|test)",<br>     case 't':<br>         set->sim_type = GSM_SIM_TYPE_TEST;<br>         break;<br>+    case 's':<br>+        set->sim_type = GSM_SIM_TYPE_SAP;<br>+        break;<br>     default:<br>         vty_out(vty, "unknown SIM type%s", VTY_NEWLINE);<br>         return CMD_WARNING;<br>@@ -2802,6 +2834,7 @@ int ms_vty_init(void)<br> <br>     install_element(ENABLE_NODE, &sim_test_cmd);<br>     install_element(ENABLE_NODE, &sim_test_att_cmd);<br>+    install_element(ENABLE_NODE, &sim_sap_cmd);<br>     install_element(ENABLE_NODE, &sim_reader_cmd);<br>     install_element(ENABLE_NODE, &sim_remove_cmd);<br>     install_element(ENABLE_NODE, &sim_pin_cmd);<br>@@ -2822,7 +2855,7 @@ int ms_vty_init(void)<br>     install_element(ENABLE_NODE, &delete_forbidden_plmn_cmd);<br> <br> #ifdef _HAVE_GPSD<br>-    install_element(CONFIG_NODE, &cfg_gps_host_cmd);<br>+    install_element(CONFIG_NODE, &cfg_gpsd_host_cmd);<br> #endif<br>     install_element(CONFIG_NODE, &cfg_gps_device_cmd);<br>     install_element(CONFIG_NODE, &cfg_gps_baud_cmd);<br><br></div>