Hi Denis, +CSUS Set command directs the MT to select the SIM/UICC card installed in the indicated card slot in all future actions that require the use of SIM/UICC.
While, +XCMSCSC command is used to configure the mode settings for a SIM. It is used to set the active SIM in case of single SIM(SSIM) configuration or to set the data preferred SIM in case of multi SIM(MSIM) configuration. It is also used to configure the power options for SSIM or MSIM. Description of <power_options> is given below XCMSCSC <power_options> Integer Type; Indicates power options on slot. 0: keep the other slot powered off. 1: keep both slots powered. For dual sim use case we will need both slots powered. Although +CSUS will switch the SIM it won't perform a SIM configuration remap. So we cannot use AT+CSUS command for DSSA use case. Regards, Antara -----Original Message----- From: Denis Kenzior [mailto:[email protected]] Sent: Thursday, March 28, 2019 8:01 AM To: Borwankar, Antara <[email protected]>; [email protected] Subject: Re: [PATCH 5/6] xmm7modem: handling of dual sim single active feature Hi Antara, On 03/27/2019 07:11 AM, Antara Borwankar wrote: > Handled DSSA use case for xmm7modem. Added driver function to switch > between available card slots for SIM. > > Only one SIM will be active at a given time. On calling this function > the active SIM will be removed and the card slot made inactive and SIM > in the other card slot will be made active. > > Use case is similar to a SIM swap/change where one SIM is replaced > another SIM in the same slot. > --- > drivers/atmodem/sim.c | 80 > ++++++++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 79 insertions(+), 1 deletion(-) > > diff --git a/drivers/atmodem/sim.c b/drivers/atmodem/sim.c index > 5f66a09..88e3898 100644 > --- a/drivers/atmodem/sim.c > +++ b/drivers/atmodem/sim.c > @@ -75,6 +75,7 @@ static const char *cuad_prefix[] = { "+CUAD:", NULL }; > static const char *ccho_prefix[] = { "+CCHO:", NULL }; > static const char *crla_prefix[] = { "+CRLA:", NULL }; > static const char *cgla_prefix[] = { "+CGLA:", NULL }; > +static const char *csus_prefix[] = { "+CSUS:", NULL}; > static const char *none_prefix[] = { NULL }; > > static void append_file_path(char *buf, const unsigned char *path, > @@ -1160,6 +1161,7 @@ static void at_pin_retries_query(struct ofono_sim *sim, > DBG(""); > > switch (sd->vendor) { > + case OFONO_VENDOR_XMM: > case OFONO_VENDOR_IFX: > if (g_at_chat_send(sd->chat, "AT+XPINCNT", xpincnt_prefix, > xpincnt_cb, cbd, g_free) > 0) > @@ -1920,6 +1922,41 @@ static void at_logical_access(struct ofono_sim *sim, > int session_id, > CALLBACK_WITH_FAILURE(cb, NULL, 0, data); > } > > +static void at_csus_query_cb(gboolean ok, GAtResult *result, gpointer > +user) { > + struct ofono_sim *sim = user; > + struct sim_data *sd = ofono_sim_get_data(sim); > + GAtResultIter iter; > + int num_slots; > + > + if (!ok) > + goto done; > + > + g_at_result_iter_init(&iter, result); > + > + if (!g_at_result_iter_next(&iter, "+CSUS:")) > + goto done; > + > + /* Set num slots */ > + g_at_result_iter_next_number(&iter, &num_slots); > + > + ofono_sim_set_card_slot_num(sim, num_slots); > + > + /* SIM1 slot will be active by default */ > + ofono_sim_set_active_card_slot_num(sim, 1); Why not just run 'AT+CSUS?' and make sure that we get the info fresh from the modem. > + > + /* enable reporting of MSIM remap status information > + and enable automatic acceptance of MSIM Remap > + acknowledgement. */ > + g_at_chat_send(sd->chat, "AT+XCMSRS=2", none_prefix, > + NULL, NULL, NULL); > + > +done: > + /* Query supported <fac>s */ > + g_at_chat_send(sd->chat, "AT+CLCK=?", clck_prefix, > + at_clck_query_cb, sim, NULL); > +} > + > static int at_sim_probe(struct ofono_sim *sim, unsigned int vendor, > void *data) > { > @@ -1938,6 +1975,10 @@ static int at_sim_probe(struct ofono_sim *sim, > unsigned int vendor, > if (at_clck_cpwd_fac[i]) > sd->passwd_type_mask |= (1 << i); > > + if (sd->vendor == OFONO_VENDOR_XMM) > + return g_at_chat_send(sd->chat, "AT+CSUS=?", csus_prefix, > + at_csus_query_cb, sim, NULL) ? 0 : -1; > + Given that this is a standard command, do you really want to hide it behind VENDOR_XMM? > /* Query supported <fac>s */ > return g_at_chat_send(sd->chat, "AT+CLCK=?", clck_prefix, > at_clck_query_cb, sim, NULL) ? 0 : -1; @@ > -1957,6 +1998,42 @@ > static void at_sim_remove(struct ofono_sim *sim) > g_free(sd); > } > > +static void at_set_active_sim_cb(gboolean ok, GAtResult *result, Since this is a vendor command response, name it after the vendor command issues. E.g. something like xcmscsc_cb > + gpointer user_data) > +{ > + struct cb_data *cbd = user_data; > + ofono_sim_active_slot_change_cb_t cb = cbd->cb; > + struct ofono_error error; > + > + decode_at_error(&error, g_at_result_final_response(result)); > + > + if (cb) > + cb(&error, cbd->data); > +} > + > +static void at_set_active_sim(struct ofono_sim *sim, unsigned int index, > + ofono_sim_active_slot_change_cb_t cb, void *data) { > + struct sim_data *sd = ofono_sim_get_data(sim); > + struct cb_data *cbd = cb_data_new(cb, data); > + char cmd[43]; > + > + /* AT+XCMSCSC=[<n>][,<mode>,<slot_id>,<power_options>] doc/coding-style.txt item M2 > + <n> Enable +XCMSCSCI URC reporting, > + <mode> single sim modem (SSIM), > + <slot_id> Indicates SIM slot id, > + <power_options> keep both slots powered. */ What does keeping both slots powered do? > + snprintf(cmd, sizeof(cmd), "AT+XCMSCSC=1,0,%u,1", index); Can we use AT+CSUS=foo here? Also, you really need to make sure that this callback will still do the right thing when vendor != XMM_VENDOR. So that means returning a not supported error code for vendors other than XMM_VENDOR, or better yet falling back to AT+CSUS (if probed successfully as part of the at_sim_probe sequence) > + > + if (g_at_chat_send(sd->chat, cmd, none_prefix, at_set_active_sim_cb, > + cbd, g_free) > 0) > + return; > + > + g_free(cbd); > + > + CALLBACK_WITH_FAILURE(cb, data); > +} > + > static const struct ofono_sim_driver driver = { > .name = "atmodem", > .probe = at_sim_probe, > @@ -1982,7 +2059,8 @@ static const struct ofono_sim_driver driver = { > .session_read_binary = at_session_read_binary, > .session_read_record = at_session_read_record, > .session_read_info = at_session_read_info, > - .logical_access = at_logical_access > + .logical_access = at_logical_access, > + .set_active_sim = at_set_active_sim > }; > > static const struct ofono_sim_driver driver_noef = { > Regards, -Denis _______________________________________________ ofono mailing list [email protected] https://lists.ofono.org/mailman/listinfo/ofono
