[OpenWrt-Devel,1/1] uqmi: uim: add support for Get Card Status request

Message ID 1502704926-9432-1-git-send-email-dnlplm@gmail.com
State Changes Requested
Delegated to: John Crispin
Headers show

Commit Message

Daniele Palmas Aug. 14, 2017, 10:02 a.m.
This patch adds support for UIM Get Card Status request

Signed-off-by: Daniele Palmas <dnlplm@gmail.com>
---
 commands-uim.c | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 commands-uim.h |   4 +-
 2 files changed, 146 insertions(+), 1 deletion(-)

Comments

John Crispin Feb. 18, 2018, 9:44 a.m. | #1
On 14/08/17 12:02, Daniele Palmas wrote:
> This patch adds support for UIM Get Card Status request
>
> Signed-off-by: Daniele Palmas <dnlplm@gmail.com>
> ---

Hi Daniele,

sorry for the late reply, nitpicks inline, if you could fix those and 
resend the patch please ..

     John

>   commands-uim.c | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   commands-uim.h |   4 +-
>   2 files changed, 146 insertions(+), 1 deletion(-)
>
> diff --git a/commands-uim.c b/commands-uim.c
> index 859da68..4263cf3 100644
> --- a/commands-uim.c
> +++ b/commands-uim.c
> @@ -54,3 +54,146 @@ cmd_uim_verify_pin2_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct
>   	qmi_set_uim_verify_pin_request(msg, &data);
>   	return QMI_CMD_REQUEST;
>   }
> +
> +static void
> +cmd_uim_get_card_status_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg)
> +{
> +	
[...]

> +	qmi_parse_uim_get_card_status_response(msg, &res);
> +
> +	c = blobmsg_open_table(&status, NULL);
> +
> +	if (res.set.card_status) {
there is a lot of indenting here, could you instead change the code to

if (!res.set.card_status)
	return
...

if (res.data.card_status.cards_n <= 0)
	return;
...
...

that will make the code easier to read

	John




> +		blobmsg_add_u32(&status, "num_slots", res.data.card_status.cards_n);
> +
> +		if (res.data.card_status.index_gw_primary != 0xFFFF)
> +			blobmsg_add_u32(&status, "index_gw_pri", res.data.card_status.index_gw_primary);
> +		if (res.data.card_status.index_1x_primary != 0xFFFF)
> +			blobmsg_add_u32(&status, "index_1x_pri", res.data.card_status.index_1x_primary);
> +		if (res.data.card_status.index_gw_secondary_ != 0xFFFF)
> +			blobmsg_add_u32(&status, "index_gw_sec", res.data.card_status.index_gw_secondary_);
> +		if (res.data.card_status.index_1x_secondary != 0xFFFF)
> +			blobmsg_add_u32(&status, "index_1x_sec", res.data.card_status.index_1x_secondary);
> +
> +		if (res.data.card_status.cards_n > 0) {
> +			a = blobmsg_open_array(&status, "card_info");
> +
> +			for (i = 0; i < res.data.card_status.cards_n; i++) {
> +				card_info = blobmsg_open_table(&status, NULL);
> +
> +				blobmsg_add_u32(&status, "app_n", res.data.card_status.cards[i].applications_n);
> +
> +				if (res.data.card_status.cards[i].card_state > QMI_UIM_CARD_STATE_ERROR)
> +					res.data.card_status.cards[i].card_state = QMI_UIM_CARD_STATE_ERROR;
> +				else if (res.data.card_status.cards[i].card_state == QMI_UIM_CARD_STATE_ERROR) {
> +					if (res.data.card_status.cards[i].error_code > QMI_UIM_CARD_ERROR_TECHNICAL)
> +						res.data.card_status.cards[i].error_code = QMI_UIM_CARD_ERROR_UNKNOWN;
> +					blobmsg_add_string(&status, "card_error", card_error[res.data.card_status.cards[i].error_code]);
> +				}
> +
> +				blobmsg_add_string(&status, "card_state", card_state[res.data.card_status.cards[i].card_state]);
> +
> +				if (res.data.card_status.cards[i].upin_state > QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED)
> +					res.data.card_status.cards[i].upin_state = QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED;
> +				blobmsg_add_string(&status, "upin_state", pin_state[res.data.card_status.cards[i].upin_state]);
> +
> +				if (res.data.card_status.cards[i].upin_state != QMI_UIM_PIN_STATE_NOT_INITIALIZED) {
> +					blobmsg_add_u32(&status, "upin_retries", res.data.card_status.cards[i].upin_retries);
> +					blobmsg_add_u32(&status, "upuk_retries", res.data.card_status.cards[i].upuk_retries);
> +				}
> +
> +				if (res.data.card_status.cards[i].applications_n > 0) {
> +					a_app = blobmsg_open_array(&status, "app_info");
> +
> +					for (j = 0; j < res.data.card_status.cards[i].applications_n; j++) {
> +						app_info = blobmsg_open_table(&status, NULL);
> +
> +						if (res.data.card_status.cards[i].applications[j].type > QMI_UIM_CARD_APPLICATION_TYPE_ISIM)
> +							res.data.card_status.cards[i].applications[j].type = QMI_UIM_CARD_APPLICATION_TYPE_UNKNOWN;
> +						blobmsg_add_string(&status, "app_type", app_type[res.data.card_status.cards[i].applications[j].type]);
> +
> +						if (res.data.card_status.cards[i].applications[j].state > QMI_UIM_CARD_APPLICATION_STATE_READY)
> +							res.data.card_status.cards[i].applications[j].state = QMI_UIM_CARD_APPLICATION_STATE_UNKNOWN;
> +						blobmsg_add_string(&status, "app_state", app_state[res.data.card_status.cards[i].applications[j].state]);
> +						blobmsg_add_u8(&status, "upin", res.data.card_status.cards[i].applications[j].upin_replaces_pin1);
> +
> +						if (res.data.card_status.cards[i].applications[j].upin_replaces_pin1 == 0) {
> +							if (res.data.card_status.cards[i].applications[j].pin1_state > QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED)
> +								res.data.card_status.cards[i].applications[j].pin1_state = QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED;
> +							blobmsg_add_string(&status, "pin1_state", pin_state[res.data.card_status.cards[i].applications[j].pin1_state]);
> +							blobmsg_add_u32(&status, "pin1_retries", res.data.card_status.cards[i].applications[j].pin1_retries);
> +							blobmsg_add_u32(&status, "puk1_retries", res.data.card_status.cards[i].applications[j].puk1_retries);
> +							if (res.data.card_status.cards[i].applications[j].pin2_state > QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED)
> +								res.data.card_status.cards[i].applications[j].pin2_state = QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED;
> +							blobmsg_add_string(&status, "pin2_state", pin_state[res.data.card_status.cards[i].applications[j].pin2_state]);
> +							blobmsg_add_u32(&status, "pin2_retries", res.data.card_status.cards[i].applications[j].pin2_retries);
> +							blobmsg_add_u32(&status, "puk2_retries", res.data.card_status.cards[i].applications[j].puk2_retries);
> +						}
> +
> +						blobmsg_close_table(&status, app_info);
> +					}
> +
> +					blobmsg_close_array(&status, a_app);
> +				}
> +				blobmsg_close_table(&status, card_info);
> +			}
> +
> +			blobmsg_close_array(&status, a);
> +		}
> +
> +	}
> +
> +	blobmsg_close_table(&status, c);
> +}
> +
> +static enum qmi_cmd_result
> +cmd_uim_get_card_status_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
> +{
> +	qmi_set_uim_get_card_status_request(msg);
> +	return QMI_CMD_REQUEST;
> +}
> \ No newline at end of file
> diff --git a/commands-uim.h b/commands-uim.h
> index 86ebae4..b668263 100644
> --- a/commands-uim.h
> +++ b/commands-uim.h
> @@ -21,10 +21,12 @@
>   
>   #define __uqmi_uim_commands												\
>   	__uqmi_command(uim_verify_pin1, uim-verify-pin1, required, QMI_SERVICE_UIM), \
> -	__uqmi_command(uim_verify_pin2, uim-verify-pin2, required, QMI_SERVICE_UIM) \
> +	__uqmi_command(uim_verify_pin2, uim-verify-pin2, required, QMI_SERVICE_UIM), \
> +	__uqmi_command(uim_get_card_status, uim-get-card-status, no, QMI_SERVICE_UIM) \
>   
>   
>   #define uim_helptext \
>   		"  --uim-verify-pin1 <pin>:          Verify PIN1 (new devices)\n" \
>   		"  --uim-verify-pin2 <pin>:          Verify PIN2 (new devices)\n" \
> +		"  --uim-get-card-status:            Get Card Status\n" \
>
Daniele Palmas Feb. 20, 2018, 8:15 a.m. | #2
Hi John,

2018-02-18 10:44 GMT+01:00 John Crispin <john@phrozen.org>:
>
>
> On 14/08/17 12:02, Daniele Palmas wrote:
>>
>> This patch adds support for UIM Get Card Status request
>>
>> Signed-off-by: Daniele Palmas <dnlplm@gmail.com>
>> ---
>
>
> Hi Daniele,
>
> sorry for the late reply, nitpicks inline, if you could fix those and resend
> the patch please ..
>

Thanks for the review! I've just sent a v2 to fix those.

By the way, if you think it's worth I have patches for adding more
features that I can (slowly) send for review.

Regards,
Daniele

>     John
>
>>   commands-uim.c | 143
>> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>   commands-uim.h |   4 +-
>>   2 files changed, 146 insertions(+), 1 deletion(-)
>>
>> diff --git a/commands-uim.c b/commands-uim.c
>> index 859da68..4263cf3 100644
>> --- a/commands-uim.c
>> +++ b/commands-uim.c
>> @@ -54,3 +54,146 @@ cmd_uim_verify_pin2_prepare(struct qmi_dev *qmi,
>> struct qmi_request *req, struct
>>         qmi_set_uim_verify_pin_request(msg, &data);
>>         return QMI_CMD_REQUEST;
>>   }
>> +
>> +static void
>> +cmd_uim_get_card_status_cb(struct qmi_dev *qmi, struct qmi_request *req,
>> struct qmi_msg *msg)
>> +{
>> +
>
> [...]
>
>> +       qmi_parse_uim_get_card_status_response(msg, &res);
>> +
>> +       c = blobmsg_open_table(&status, NULL);
>> +
>> +       if (res.set.card_status) {
>
> there is a lot of indenting here, could you instead change the code to
>
> if (!res.set.card_status)
>         return
> ...
>
> if (res.data.card_status.cards_n <= 0)
>         return;
> ...
> ...
>
> that will make the code easier to read
>
>         John
>
>
>
>
>
>> +               blobmsg_add_u32(&status, "num_slots",
>> res.data.card_status.cards_n);
>> +
>> +               if (res.data.card_status.index_gw_primary != 0xFFFF)
>> +                       blobmsg_add_u32(&status, "index_gw_pri",
>> res.data.card_status.index_gw_primary);
>> +               if (res.data.card_status.index_1x_primary != 0xFFFF)
>> +                       blobmsg_add_u32(&status, "index_1x_pri",
>> res.data.card_status.index_1x_primary);
>> +               if (res.data.card_status.index_gw_secondary_ != 0xFFFF)
>> +                       blobmsg_add_u32(&status, "index_gw_sec",
>> res.data.card_status.index_gw_secondary_);
>> +               if (res.data.card_status.index_1x_secondary != 0xFFFF)
>> +                       blobmsg_add_u32(&status, "index_1x_sec",
>> res.data.card_status.index_1x_secondary);
>> +
>> +               if (res.data.card_status.cards_n > 0) {
>> +                       a = blobmsg_open_array(&status, "card_info");
>> +
>> +                       for (i = 0; i < res.data.card_status.cards_n; i++)
>> {
>> +                               card_info = blobmsg_open_table(&status,
>> NULL);
>> +
>> +                               blobmsg_add_u32(&status, "app_n",
>> res.data.card_status.cards[i].applications_n);
>> +
>> +                               if
>> (res.data.card_status.cards[i].card_state > QMI_UIM_CARD_STATE_ERROR)
>> +
>> res.data.card_status.cards[i].card_state = QMI_UIM_CARD_STATE_ERROR;
>> +                               else if
>> (res.data.card_status.cards[i].card_state == QMI_UIM_CARD_STATE_ERROR) {
>> +                                       if
>> (res.data.card_status.cards[i].error_code > QMI_UIM_CARD_ERROR_TECHNICAL)
>> +
>> res.data.card_status.cards[i].error_code = QMI_UIM_CARD_ERROR_UNKNOWN;
>> +                                       blobmsg_add_string(&status,
>> "card_error", card_error[res.data.card_status.cards[i].error_code]);
>> +                               }
>> +
>> +                               blobmsg_add_string(&status, "card_state",
>> card_state[res.data.card_status.cards[i].card_state]);
>> +
>> +                               if
>> (res.data.card_status.cards[i].upin_state >
>> QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED)
>> +
>> res.data.card_status.cards[i].upin_state =
>> QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED;
>> +                               blobmsg_add_string(&status, "upin_state",
>> pin_state[res.data.card_status.cards[i].upin_state]);
>> +
>> +                               if
>> (res.data.card_status.cards[i].upin_state !=
>> QMI_UIM_PIN_STATE_NOT_INITIALIZED) {
>> +                                       blobmsg_add_u32(&status,
>> "upin_retries", res.data.card_status.cards[i].upin_retries);
>> +                                       blobmsg_add_u32(&status,
>> "upuk_retries", res.data.card_status.cards[i].upuk_retries);
>> +                               }
>> +
>> +                               if
>> (res.data.card_status.cards[i].applications_n > 0) {
>> +                                       a_app =
>> blobmsg_open_array(&status, "app_info");
>> +
>> +                                       for (j = 0; j <
>> res.data.card_status.cards[i].applications_n; j++) {
>> +                                               app_info =
>> blobmsg_open_table(&status, NULL);
>> +
>> +                                               if
>> (res.data.card_status.cards[i].applications[j].type >
>> QMI_UIM_CARD_APPLICATION_TYPE_ISIM)
>> +
>> res.data.card_status.cards[i].applications[j].type =
>> QMI_UIM_CARD_APPLICATION_TYPE_UNKNOWN;
>> +
>> blobmsg_add_string(&status, "app_type",
>> app_type[res.data.card_status.cards[i].applications[j].type]);
>> +
>> +                                               if
>> (res.data.card_status.cards[i].applications[j].state >
>> QMI_UIM_CARD_APPLICATION_STATE_READY)
>> +
>> res.data.card_status.cards[i].applications[j].state =
>> QMI_UIM_CARD_APPLICATION_STATE_UNKNOWN;
>> +
>> blobmsg_add_string(&status, "app_state",
>> app_state[res.data.card_status.cards[i].applications[j].state]);
>> +                                               blobmsg_add_u8(&status,
>> "upin", res.data.card_status.cards[i].applications[j].upin_replaces_pin1);
>> +
>> +                                               if
>> (res.data.card_status.cards[i].applications[j].upin_replaces_pin1 == 0) {
>> +                                                       if
>> (res.data.card_status.cards[i].applications[j].pin1_state >
>> QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED)
>> +
>> res.data.card_status.cards[i].applications[j].pin1_state =
>> QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED;
>> +
>> blobmsg_add_string(&status, "pin1_state",
>> pin_state[res.data.card_status.cards[i].applications[j].pin1_state]);
>> +
>> blobmsg_add_u32(&status, "pin1_retries",
>> res.data.card_status.cards[i].applications[j].pin1_retries);
>> +
>> blobmsg_add_u32(&status, "puk1_retries",
>> res.data.card_status.cards[i].applications[j].puk1_retries);
>> +                                                       if
>> (res.data.card_status.cards[i].applications[j].pin2_state >
>> QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED)
>> +
>> res.data.card_status.cards[i].applications[j].pin2_state =
>> QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED;
>> +
>> blobmsg_add_string(&status, "pin2_state",
>> pin_state[res.data.card_status.cards[i].applications[j].pin2_state]);
>> +
>> blobmsg_add_u32(&status, "pin2_retries",
>> res.data.card_status.cards[i].applications[j].pin2_retries);
>> +
>> blobmsg_add_u32(&status, "puk2_retries",
>> res.data.card_status.cards[i].applications[j].puk2_retries);
>> +                                               }
>> +
>> +
>> blobmsg_close_table(&status, app_info);
>> +                                       }
>> +
>> +                                       blobmsg_close_array(&status,
>> a_app);
>> +                               }
>> +                               blobmsg_close_table(&status, card_info);
>> +                       }
>> +
>> +                       blobmsg_close_array(&status, a);
>> +               }
>> +
>> +       }
>> +
>> +       blobmsg_close_table(&status, c);
>> +}
>> +
>> +static enum qmi_cmd_result
>> +cmd_uim_get_card_status_prepare(struct qmi_dev *qmi, struct qmi_request
>> *req, struct qmi_msg *msg, char *arg)
>> +{
>> +       qmi_set_uim_get_card_status_request(msg);
>> +       return QMI_CMD_REQUEST;
>> +}
>> \ No newline at end of file
>> diff --git a/commands-uim.h b/commands-uim.h
>> index 86ebae4..b668263 100644
>> --- a/commands-uim.h
>> +++ b/commands-uim.h
>> @@ -21,10 +21,12 @@
>>     #define __uqmi_uim_commands
>> \
>>         __uqmi_command(uim_verify_pin1, uim-verify-pin1, required,
>> QMI_SERVICE_UIM), \
>> -       __uqmi_command(uim_verify_pin2, uim-verify-pin2, required,
>> QMI_SERVICE_UIM) \
>> +       __uqmi_command(uim_verify_pin2, uim-verify-pin2, required,
>> QMI_SERVICE_UIM), \
>> +       __uqmi_command(uim_get_card_status, uim-get-card-status, no,
>> QMI_SERVICE_UIM) \
>>       #define uim_helptext \
>>                 "  --uim-verify-pin1 <pin>:          Verify PIN1 (new
>> devices)\n" \
>>                 "  --uim-verify-pin2 <pin>:          Verify PIN2 (new
>> devices)\n" \
>> +               "  --uim-get-card-status:            Get Card Status\n" \
>>
>
>
John Crispin Feb. 20, 2018, 8:19 a.m. | #3
On 20/02/18 09:15, Daniele Palmas wrote:
> Hi John,
>
> 2018-02-18 10:44 GMT+01:00 John Crispin <john@phrozen.org>:
>>
>> On 14/08/17 12:02, Daniele Palmas wrote:
>>> This patch adds support for UIM Get Card Status request
>>>
>>> Signed-off-by: Daniele Palmas <dnlplm@gmail.com>
>>> ---
>>
>> Hi Daniele,
>>
>> sorry for the late reply, nitpicks inline, if you could fix those and resend
>> the patch please ..
>>
> Thanks for the review! I've just sent a v2 to fix those.
>
> By the way, if you think it's worth I have patches for adding more
> features that I can (slowly) send for review.
>
> Regards,
> Daniele

Hi Daniele,

sure, send them our way !

     John

>
>>      John
>>
>>>    commands-uim.c | 143
>>> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>>    commands-uim.h |   4 +-
>>>    2 files changed, 146 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/commands-uim.c b/commands-uim.c
>>> index 859da68..4263cf3 100644
>>> --- a/commands-uim.c
>>> +++ b/commands-uim.c
>>> @@ -54,3 +54,146 @@ cmd_uim_verify_pin2_prepare(struct qmi_dev *qmi,
>>> struct qmi_request *req, struct
>>>          qmi_set_uim_verify_pin_request(msg, &data);
>>>          return QMI_CMD_REQUEST;
>>>    }
>>> +
>>> +static void
>>> +cmd_uim_get_card_status_cb(struct qmi_dev *qmi, struct qmi_request *req,
>>> struct qmi_msg *msg)
>>> +{
>>> +
>> [...]
>>
>>> +       qmi_parse_uim_get_card_status_response(msg, &res);
>>> +
>>> +       c = blobmsg_open_table(&status, NULL);
>>> +
>>> +       if (res.set.card_status) {
>> there is a lot of indenting here, could you instead change the code to
>>
>> if (!res.set.card_status)
>>          return
>> ...
>>
>> if (res.data.card_status.cards_n <= 0)
>>          return;
>> ...
>> ...
>>
>> that will make the code easier to read
>>
>>          John
>>
>>
>>
>>
>>
>>> +               blobmsg_add_u32(&status, "num_slots",
>>> res.data.card_status.cards_n);
>>> +
>>> +               if (res.data.card_status.index_gw_primary != 0xFFFF)
>>> +                       blobmsg_add_u32(&status, "index_gw_pri",
>>> res.data.card_status.index_gw_primary);
>>> +               if (res.data.card_status.index_1x_primary != 0xFFFF)
>>> +                       blobmsg_add_u32(&status, "index_1x_pri",
>>> res.data.card_status.index_1x_primary);
>>> +               if (res.data.card_status.index_gw_secondary_ != 0xFFFF)
>>> +                       blobmsg_add_u32(&status, "index_gw_sec",
>>> res.data.card_status.index_gw_secondary_);
>>> +               if (res.data.card_status.index_1x_secondary != 0xFFFF)
>>> +                       blobmsg_add_u32(&status, "index_1x_sec",
>>> res.data.card_status.index_1x_secondary);
>>> +
>>> +               if (res.data.card_status.cards_n > 0) {
>>> +                       a = blobmsg_open_array(&status, "card_info");
>>> +
>>> +                       for (i = 0; i < res.data.card_status.cards_n; i++)
>>> {
>>> +                               card_info = blobmsg_open_table(&status,
>>> NULL);
>>> +
>>> +                               blobmsg_add_u32(&status, "app_n",
>>> res.data.card_status.cards[i].applications_n);
>>> +
>>> +                               if
>>> (res.data.card_status.cards[i].card_state > QMI_UIM_CARD_STATE_ERROR)
>>> +
>>> res.data.card_status.cards[i].card_state = QMI_UIM_CARD_STATE_ERROR;
>>> +                               else if
>>> (res.data.card_status.cards[i].card_state == QMI_UIM_CARD_STATE_ERROR) {
>>> +                                       if
>>> (res.data.card_status.cards[i].error_code > QMI_UIM_CARD_ERROR_TECHNICAL)
>>> +
>>> res.data.card_status.cards[i].error_code = QMI_UIM_CARD_ERROR_UNKNOWN;
>>> +                                       blobmsg_add_string(&status,
>>> "card_error", card_error[res.data.card_status.cards[i].error_code]);
>>> +                               }
>>> +
>>> +                               blobmsg_add_string(&status, "card_state",
>>> card_state[res.data.card_status.cards[i].card_state]);
>>> +
>>> +                               if
>>> (res.data.card_status.cards[i].upin_state >
>>> QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED)
>>> +
>>> res.data.card_status.cards[i].upin_state =
>>> QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED;
>>> +                               blobmsg_add_string(&status, "upin_state",
>>> pin_state[res.data.card_status.cards[i].upin_state]);
>>> +
>>> +                               if
>>> (res.data.card_status.cards[i].upin_state !=
>>> QMI_UIM_PIN_STATE_NOT_INITIALIZED) {
>>> +                                       blobmsg_add_u32(&status,
>>> "upin_retries", res.data.card_status.cards[i].upin_retries);
>>> +                                       blobmsg_add_u32(&status,
>>> "upuk_retries", res.data.card_status.cards[i].upuk_retries);
>>> +                               }
>>> +
>>> +                               if
>>> (res.data.card_status.cards[i].applications_n > 0) {
>>> +                                       a_app =
>>> blobmsg_open_array(&status, "app_info");
>>> +
>>> +                                       for (j = 0; j <
>>> res.data.card_status.cards[i].applications_n; j++) {
>>> +                                               app_info =
>>> blobmsg_open_table(&status, NULL);
>>> +
>>> +                                               if
>>> (res.data.card_status.cards[i].applications[j].type >
>>> QMI_UIM_CARD_APPLICATION_TYPE_ISIM)
>>> +
>>> res.data.card_status.cards[i].applications[j].type =
>>> QMI_UIM_CARD_APPLICATION_TYPE_UNKNOWN;
>>> +
>>> blobmsg_add_string(&status, "app_type",
>>> app_type[res.data.card_status.cards[i].applications[j].type]);
>>> +
>>> +                                               if
>>> (res.data.card_status.cards[i].applications[j].state >
>>> QMI_UIM_CARD_APPLICATION_STATE_READY)
>>> +
>>> res.data.card_status.cards[i].applications[j].state =
>>> QMI_UIM_CARD_APPLICATION_STATE_UNKNOWN;
>>> +
>>> blobmsg_add_string(&status, "app_state",
>>> app_state[res.data.card_status.cards[i].applications[j].state]);
>>> +                                               blobmsg_add_u8(&status,
>>> "upin", res.data.card_status.cards[i].applications[j].upin_replaces_pin1);
>>> +
>>> +                                               if
>>> (res.data.card_status.cards[i].applications[j].upin_replaces_pin1 == 0) {
>>> +                                                       if
>>> (res.data.card_status.cards[i].applications[j].pin1_state >
>>> QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED)
>>> +
>>> res.data.card_status.cards[i].applications[j].pin1_state =
>>> QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED;
>>> +
>>> blobmsg_add_string(&status, "pin1_state",
>>> pin_state[res.data.card_status.cards[i].applications[j].pin1_state]);
>>> +
>>> blobmsg_add_u32(&status, "pin1_retries",
>>> res.data.card_status.cards[i].applications[j].pin1_retries);
>>> +
>>> blobmsg_add_u32(&status, "puk1_retries",
>>> res.data.card_status.cards[i].applications[j].puk1_retries);
>>> +                                                       if
>>> (res.data.card_status.cards[i].applications[j].pin2_state >
>>> QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED)
>>> +
>>> res.data.card_status.cards[i].applications[j].pin2_state =
>>> QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED;
>>> +
>>> blobmsg_add_string(&status, "pin2_state",
>>> pin_state[res.data.card_status.cards[i].applications[j].pin2_state]);
>>> +
>>> blobmsg_add_u32(&status, "pin2_retries",
>>> res.data.card_status.cards[i].applications[j].pin2_retries);
>>> +
>>> blobmsg_add_u32(&status, "puk2_retries",
>>> res.data.card_status.cards[i].applications[j].puk2_retries);
>>> +                                               }
>>> +
>>> +
>>> blobmsg_close_table(&status, app_info);
>>> +                                       }
>>> +
>>> +                                       blobmsg_close_array(&status,
>>> a_app);
>>> +                               }
>>> +                               blobmsg_close_table(&status, card_info);
>>> +                       }
>>> +
>>> +                       blobmsg_close_array(&status, a);
>>> +               }
>>> +
>>> +       }
>>> +
>>> +       blobmsg_close_table(&status, c);
>>> +}
>>> +
>>> +static enum qmi_cmd_result
>>> +cmd_uim_get_card_status_prepare(struct qmi_dev *qmi, struct qmi_request
>>> *req, struct qmi_msg *msg, char *arg)
>>> +{
>>> +       qmi_set_uim_get_card_status_request(msg);
>>> +       return QMI_CMD_REQUEST;
>>> +}
>>> \ No newline at end of file
>>> diff --git a/commands-uim.h b/commands-uim.h
>>> index 86ebae4..b668263 100644
>>> --- a/commands-uim.h
>>> +++ b/commands-uim.h
>>> @@ -21,10 +21,12 @@
>>>      #define __uqmi_uim_commands
>>> \
>>>          __uqmi_command(uim_verify_pin1, uim-verify-pin1, required,
>>> QMI_SERVICE_UIM), \
>>> -       __uqmi_command(uim_verify_pin2, uim-verify-pin2, required,
>>> QMI_SERVICE_UIM) \
>>> +       __uqmi_command(uim_verify_pin2, uim-verify-pin2, required,
>>> QMI_SERVICE_UIM), \
>>> +       __uqmi_command(uim_get_card_status, uim-get-card-status, no,
>>> QMI_SERVICE_UIM) \
>>>        #define uim_helptext \
>>>                  "  --uim-verify-pin1 <pin>:          Verify PIN1 (new
>>> devices)\n" \
>>>                  "  --uim-verify-pin2 <pin>:          Verify PIN2 (new
>>> devices)\n" \
>>> +               "  --uim-get-card-status:            Get Card Status\n" \
>>>
>>

Patch

diff --git a/commands-uim.c b/commands-uim.c
index 859da68..4263cf3 100644
--- a/commands-uim.c
+++ b/commands-uim.c
@@ -54,3 +54,146 @@  cmd_uim_verify_pin2_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct
 	qmi_set_uim_verify_pin_request(msg, &data);
 	return QMI_CMD_REQUEST;
 }
+
+static void
+cmd_uim_get_card_status_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg)
+{
+	struct qmi_uim_get_card_status_response res;
+
+	static const char *app_type[] = {
+		[QMI_UIM_CARD_APPLICATION_TYPE_UNKNOWN] = "unknown",
+		[QMI_UIM_CARD_APPLICATION_TYPE_SIM] = "sim",
+		[QMI_UIM_CARD_APPLICATION_TYPE_USIM] = "usim",
+		[QMI_UIM_CARD_APPLICATION_TYPE_RUIM] = "ruim",
+		[QMI_UIM_CARD_APPLICATION_TYPE_CSIM] = "csim",
+		[QMI_UIM_CARD_APPLICATION_TYPE_ISIM] = "isim",
+	};
+	static const char *card_state[] = {
+		[QMI_UIM_CARD_STATE_ABSENT] = "absent",
+		[QMI_UIM_CARD_STATE_PRESENT] = "present",
+		[QMI_UIM_CARD_STATE_ERROR] = "error",
+	};
+	static const char *pin_state[] = {
+		[QMI_UIM_PIN_STATE_NOT_INITIALIZED] = "not initialized",
+		[QMI_UIM_PIN_STATE_ENABLED_NOT_VERIFIED] = "enabled not verified",
+		[QMI_UIM_PIN_STATE_ENABLED_VERIFIED] = "enabled verified",
+		[QMI_UIM_PIN_STATE_DISABLED] = "disabled",
+		[QMI_UIM_PIN_STATE_BLOCKED] = "blocked",
+		[QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED] = "permanently blocked",
+	};
+	static const char *card_error[] = {
+		[QMI_UIM_CARD_ERROR_UNKNOWN] = "unknown",
+		[QMI_UIM_CARD_ERROR_POWER_DOWN] = "power down",
+		[QMI_UIM_CARD_ERROR_POLL] = "poll",
+		[QMI_UIM_CARD_ERROR_NO_ATR_RECEIVED] = "no atr received",
+		[QMI_UIM_CARD_ERROR_VOLTAGE_MISMATCH] = "voltage mismatch",
+		[QMI_UIM_CARD_ERROR_PARITY] = "parity",
+		[QMI_UIM_CARD_ERROR_POSSIBLY_REMOVED] = "possibly removed",
+		[QMI_UIM_CARD_ERROR_TECHNICAL] = "technical",
+	};
+	static const char *app_state[] = {
+		[QMI_UIM_CARD_APPLICATION_STATE_UNKNOWN] = "unknown",
+		[QMI_UIM_CARD_APPLICATION_STATE_DETECTED] = "detected",
+		[QMI_UIM_CARD_APPLICATION_STATE_PIN1_OR_UPIN_PIN_REQUIRED] = "pin",
+		[QMI_UIM_CARD_APPLICATION_STATE_PUK1_OR_UPIN_PUK_REQUIRED] = "puk",
+		[QMI_UIM_CARD_APPLICATION_STATE_CHECK_PERSONALIZATION_STATE] = "perso",
+		[QMI_UIM_CARD_APPLICATION_STATE_PIN1_BLOCKED] = "pin1 blocked",
+		[QMI_UIM_CARD_APPLICATION_STATE_ILLEGAL] = "illegal",
+		[QMI_UIM_CARD_APPLICATION_STATE_READY] = "ready",
+	};
+	void *c, *a, *card_info, *a_app, *app_info;
+	int i, j;
+
+	qmi_parse_uim_get_card_status_response(msg, &res);
+
+	c = blobmsg_open_table(&status, NULL);
+
+	if (res.set.card_status) {
+		blobmsg_add_u32(&status, "num_slots", res.data.card_status.cards_n);
+
+		if (res.data.card_status.index_gw_primary != 0xFFFF)
+			blobmsg_add_u32(&status, "index_gw_pri", res.data.card_status.index_gw_primary);
+		if (res.data.card_status.index_1x_primary != 0xFFFF)
+			blobmsg_add_u32(&status, "index_1x_pri", res.data.card_status.index_1x_primary);
+		if (res.data.card_status.index_gw_secondary_ != 0xFFFF)
+			blobmsg_add_u32(&status, "index_gw_sec", res.data.card_status.index_gw_secondary_);
+		if (res.data.card_status.index_1x_secondary != 0xFFFF)
+			blobmsg_add_u32(&status, "index_1x_sec", res.data.card_status.index_1x_secondary);
+
+		if (res.data.card_status.cards_n > 0) {
+			a = blobmsg_open_array(&status, "card_info");
+
+			for (i = 0; i < res.data.card_status.cards_n; i++) {
+				card_info = blobmsg_open_table(&status, NULL);
+
+				blobmsg_add_u32(&status, "app_n", res.data.card_status.cards[i].applications_n);
+
+				if (res.data.card_status.cards[i].card_state > QMI_UIM_CARD_STATE_ERROR)
+					res.data.card_status.cards[i].card_state = QMI_UIM_CARD_STATE_ERROR;
+				else if (res.data.card_status.cards[i].card_state == QMI_UIM_CARD_STATE_ERROR) {
+					if (res.data.card_status.cards[i].error_code > QMI_UIM_CARD_ERROR_TECHNICAL)
+						res.data.card_status.cards[i].error_code = QMI_UIM_CARD_ERROR_UNKNOWN;
+					blobmsg_add_string(&status, "card_error", card_error[res.data.card_status.cards[i].error_code]);
+				}
+
+				blobmsg_add_string(&status, "card_state", card_state[res.data.card_status.cards[i].card_state]);
+
+				if (res.data.card_status.cards[i].upin_state > QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED)
+					res.data.card_status.cards[i].upin_state = QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED;
+				blobmsg_add_string(&status, "upin_state", pin_state[res.data.card_status.cards[i].upin_state]);
+
+				if (res.data.card_status.cards[i].upin_state != QMI_UIM_PIN_STATE_NOT_INITIALIZED) {
+					blobmsg_add_u32(&status, "upin_retries", res.data.card_status.cards[i].upin_retries);
+					blobmsg_add_u32(&status, "upuk_retries", res.data.card_status.cards[i].upuk_retries);
+				}
+
+				if (res.data.card_status.cards[i].applications_n > 0) {
+					a_app = blobmsg_open_array(&status, "app_info");
+
+					for (j = 0; j < res.data.card_status.cards[i].applications_n; j++) {
+						app_info = blobmsg_open_table(&status, NULL);
+
+						if (res.data.card_status.cards[i].applications[j].type > QMI_UIM_CARD_APPLICATION_TYPE_ISIM)
+							res.data.card_status.cards[i].applications[j].type = QMI_UIM_CARD_APPLICATION_TYPE_UNKNOWN;
+						blobmsg_add_string(&status, "app_type", app_type[res.data.card_status.cards[i].applications[j].type]);
+
+						if (res.data.card_status.cards[i].applications[j].state > QMI_UIM_CARD_APPLICATION_STATE_READY)
+							res.data.card_status.cards[i].applications[j].state = QMI_UIM_CARD_APPLICATION_STATE_UNKNOWN;
+						blobmsg_add_string(&status, "app_state", app_state[res.data.card_status.cards[i].applications[j].state]);
+						blobmsg_add_u8(&status, "upin", res.data.card_status.cards[i].applications[j].upin_replaces_pin1);
+
+						if (res.data.card_status.cards[i].applications[j].upin_replaces_pin1 == 0) {
+							if (res.data.card_status.cards[i].applications[j].pin1_state > QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED)
+								res.data.card_status.cards[i].applications[j].pin1_state = QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED;
+							blobmsg_add_string(&status, "pin1_state", pin_state[res.data.card_status.cards[i].applications[j].pin1_state]);
+							blobmsg_add_u32(&status, "pin1_retries", res.data.card_status.cards[i].applications[j].pin1_retries);
+							blobmsg_add_u32(&status, "puk1_retries", res.data.card_status.cards[i].applications[j].puk1_retries);
+							if (res.data.card_status.cards[i].applications[j].pin2_state > QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED)
+								res.data.card_status.cards[i].applications[j].pin2_state = QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED;
+							blobmsg_add_string(&status, "pin2_state", pin_state[res.data.card_status.cards[i].applications[j].pin2_state]);
+							blobmsg_add_u32(&status, "pin2_retries", res.data.card_status.cards[i].applications[j].pin2_retries);
+							blobmsg_add_u32(&status, "puk2_retries", res.data.card_status.cards[i].applications[j].puk2_retries);
+						}
+
+						blobmsg_close_table(&status, app_info);
+					}
+
+					blobmsg_close_array(&status, a_app);
+				}
+				blobmsg_close_table(&status, card_info);
+			}
+
+			blobmsg_close_array(&status, a);
+		}
+
+	}
+
+	blobmsg_close_table(&status, c);
+}
+
+static enum qmi_cmd_result
+cmd_uim_get_card_status_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
+{
+	qmi_set_uim_get_card_status_request(msg);
+	return QMI_CMD_REQUEST;
+}
\ No newline at end of file
diff --git a/commands-uim.h b/commands-uim.h
index 86ebae4..b668263 100644
--- a/commands-uim.h
+++ b/commands-uim.h
@@ -21,10 +21,12 @@ 
 
 #define __uqmi_uim_commands												\
 	__uqmi_command(uim_verify_pin1, uim-verify-pin1, required, QMI_SERVICE_UIM), \
-	__uqmi_command(uim_verify_pin2, uim-verify-pin2, required, QMI_SERVICE_UIM) \
+	__uqmi_command(uim_verify_pin2, uim-verify-pin2, required, QMI_SERVICE_UIM), \
+	__uqmi_command(uim_get_card_status, uim-get-card-status, no, QMI_SERVICE_UIM) \
 
 
 #define uim_helptext \
 		"  --uim-verify-pin1 <pin>:          Verify PIN1 (new devices)\n" \
 		"  --uim-verify-pin2 <pin>:          Verify PIN2 (new devices)\n" \
+		"  --uim-get-card-status:            Get Card Status\n" \