summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortick <tick@99fdad57-331a-0410-800a-d7fa5415bdb3>2007-12-01 01:55:39 +0000
committertick <tick@99fdad57-331a-0410-800a-d7fa5415bdb3>2007-12-01 01:55:39 +0000
commitd88e15979081740b86f48a78c81df56f5122a2c4 (patch)
tree1fb1484659cb51743726501c46d0e55edfefcc79
parentf07e7027fe91ac71a8ab760f863c3a05a1d1499d (diff)
gsmd: Submitting a PIN for authentication needs to respond with status too.(Andrzej Zaborowski)
git-svn-id: http://svn.openmoko.org/trunk/src/target/gsm@3545 99fdad57-331a-0410-800a-d7fa5415bdb3
-rw-r--r--include/gsmd/unsolicited.h1
-rw-r--r--include/libgsmd/pin.h3
-rw-r--r--src/gsmd/unsolicited.c108
-rw-r--r--src/gsmd/usock.c27
-rw-r--r--src/libgsmd/libgsmd_pin.c14
-rw-r--r--src/util/pin.c15
-rw-r--r--src/util/shell.c36
-rw-r--r--src/util/shell.h2
8 files changed, 101 insertions, 105 deletions
diff --git a/include/gsmd/unsolicited.h b/include/gsmd/unsolicited.h
index 544c1ce..fa0ee32 100644
--- a/include/gsmd/unsolicited.h
+++ b/include/gsmd/unsolicited.h
@@ -15,6 +15,7 @@ extern int generate_event_from_cme(struct gsmd *g, unsigned int cme_error);
extern void unsolicited_generic_init(struct gsmd *g);
extern int unsolicited_register_array(const struct gsmd_unsolicit *arr,
int len);
+extern const int pintype_from_cme[];
#endif /* __GSMD__ */
diff --git a/include/libgsmd/pin.h b/include/libgsmd/pin.h
index 304455f..d125e40 100644
--- a/include/libgsmd/pin.h
+++ b/include/libgsmd/pin.h
@@ -3,6 +3,7 @@
extern const char *lgsm_pin_name(enum gsmd_pin_type ptype);
-extern int lgsm_pin(struct lgsm_handle *lh, unsigned int type, char *pin, char *newpin);
+extern int lgsm_pin(struct lgsm_handle *lh, unsigned int type,
+ const char *pin, const char *newpin);
#endif
diff --git a/src/gsmd/unsolicited.c b/src/gsmd/unsolicited.c
index 4819571..b4bf260 100644
--- a/src/gsmd/unsolicited.c
+++ b/src/gsmd/unsolicited.c
@@ -487,12 +487,40 @@ static int is_in_array(unsigned int val, unsigned int *arr, unsigned int arr_len
return 0;
}
+const int pintype_from_cme[GSM0707_CME_UNKNOWN] = {
+ [GSM0707_CME_PH_SIM_PIN_REQUIRED] = GSMD_PIN_PH_SIM_PIN,
+ [GSM0707_CME_PH_FSIM_PIN_REQUIRED] = GSMD_PIN_PH_FSIM_PIN,
+ [GSM0707_CME_PH_FSIM_PUK_REQUIRED] = GSMD_PIN_PH_FSIM_PUK,
+ [GSM0707_CME_SIM_PIN_REQUIRED] = GSMD_PIN_SIM_PIN,
+ [GSM0707_CME_SIM_PUK_REQUIRED] = GSMD_PIN_SIM_PUK,
+ [GSM0707_CME_SIM_PIN2_REQUIRED] = GSMD_PIN_SIM_PIN2,
+ [GSM0707_CME_SIM_PUK2_REQUIRED] = GSMD_PIN_SIM_PUK2,
+ [GSM0707_CME_NETPERS_PIN_REQUIRED] = GSMD_PIN_PH_NET_PIN,
+ [GSM0707_CME_NETPERS_PUK_REQUIRED] = GSMD_PIN_PH_NET_PUK,
+ [GSM0707_CME_NETSUBSET_PIN_REQUIRED] = GSMD_PIN_PH_NETSUB_PIN,
+ [GSM0707_CME_NETSUBSET_PUK_REQUIRED] = GSMD_PIN_PH_NETSUB_PUK,
+ [GSM0707_CME_PROVIDER_PIN_REQUIRED] = GSMD_PIN_PH_SP_PIN,
+ [GSM0707_CME_PROVIDER_PUK_REQUIRED] = GSMD_PIN_PH_SP_PUK,
+ [GSM0707_CME_CORPORATE_PIN_REQUIRED] = GSMD_PIN_PH_CORP_PIN,
+ [GSM0707_CME_CORPORATE_PUK_REQUIRED] = GSMD_PIN_PH_CORP_PUK,
+ /* FIXME: */
+ [GSM0707_CME_SIM_FAILURE] = 0,
+ [GSM0707_CME_SIM_BUSY] = 0,
+ [GSM0707_CME_SIM_WRONG] = 0,
+ [GSM0707_CME_MEMORY_FULL] = 0,
+ [GSM0707_CME_MEMORY_FAILURE] = 0,
+ [GSM0707_CME_PHONE_FAILURE] = 0,
+ [GSM0707_CME_PHONE_NOCONNECT] = 0,
+ [GSM0707_CME_PHONE_ADAPT_RESERVED] = 0,
+ [GSM0707_CME_SIM_NOT_INSERTED] = 0,
+};
+
int generate_event_from_cme(struct gsmd *g, unsigned int cme_error)
{
struct gsmd_ucmd *gu;
struct gsmd_evt_auxdata *eaux;
- if (!is_in_array(cme_error, errors_creating_events,
+ if (!is_in_array(cme_error, errors_creating_events,
ARRAY_SIZE(errors_creating_events))) {
gu = usock_build_event(GSMD_MSG_EVENT, GSMD_EVT_IN_ERROR, sizeof(*eaux));
@@ -501,78 +529,18 @@ int generate_event_from_cme(struct gsmd *g, unsigned int cme_error)
eaux = ((void *)gu) + sizeof(*gu);
eaux->u.cme_err.number = cme_error;
return usock_evt_send(g, gu, GSMD_EVT_IN_ERROR);
- }
- else {
- gu = usock_build_event(GSMD_MSG_EVENT, GSMD_EVT_PIN, sizeof(*eaux));
+ } else {
+ if (cme_error >= GSM0707_CME_UNKNOWN ||
+ !pintype_from_cme[cme_error])
+ return 0;
+
+ gu = usock_build_event(GSMD_MSG_EVENT, GSMD_EVT_PIN,
+ sizeof(*eaux));
if (!gu)
return -1;
+
eaux = ((void *)gu) + sizeof(*gu);
-
- switch (cme_error) {
- case GSM0707_CME_PH_SIM_PIN_REQUIRED:
- eaux->u.pin.type = GSMD_PIN_PH_SIM_PIN;
- break;
- case GSM0707_CME_PH_FSIM_PIN_REQUIRED:
- eaux->u.pin.type = GSMD_PIN_PH_FSIM_PIN;
- break;
- case GSM0707_CME_PH_FSIM_PUK_REQUIRED:
- eaux->u.pin.type = GSMD_PIN_PH_FSIM_PUK;
- break;
- case GSM0707_CME_SIM_PIN_REQUIRED:
- eaux->u.pin.type = GSMD_PIN_SIM_PIN;
- break;
- case GSM0707_CME_SIM_PUK_REQUIRED:
- eaux->u.pin.type = GSMD_PIN_SIM_PUK;
- break;
- case GSM0707_CME_SIM_PIN2_REQUIRED:
- eaux->u.pin.type = GSMD_PIN_SIM_PIN2;
- break;
- case GSM0707_CME_SIM_PUK2_REQUIRED:
- eaux->u.pin.type = GSMD_PIN_SIM_PUK2;
- break;
- case GSM0707_CME_NETPERS_PIN_REQUIRED:
- eaux->u.pin.type = GSMD_PIN_PH_NET_PIN;
- break;
- case GSM0707_CME_NETPERS_PUK_REQUIRED:
- eaux->u.pin.type = GSMD_PIN_PH_NET_PUK;
- break;
- case GSM0707_CME_NETSUBSET_PIN_REQUIRED:
- eaux->u.pin.type = GSMD_PIN_PH_NETSUB_PIN;
- break;
- case GSM0707_CME_NETSUBSET_PUK_REQUIRED:
- eaux->u.pin.type = GSMD_PIN_PH_NETSUB_PUK;
- break;
- case GSM0707_CME_PROVIDER_PIN_REQUIRED:
- eaux->u.pin.type = GSMD_PIN_PH_SP_PIN;
- break;
- case GSM0707_CME_PROVIDER_PUK_REQUIRED:
- eaux->u.pin.type = GSMD_PIN_PH_SP_PUK;
- break;
- case GSM0707_CME_CORPORATE_PIN_REQUIRED:
- eaux->u.pin.type = GSMD_PIN_PH_CORP_PIN;
- break;
- case GSM0707_CME_CORPORATE_PUK_REQUIRED:
- eaux->u.pin.type = GSMD_PIN_PH_CORP_PUK;
- break;
-
- case GSM0707_CME_SIM_FAILURE:
- case GSM0707_CME_SIM_BUSY:
- case GSM0707_CME_SIM_WRONG:
- case GSM0707_CME_MEMORY_FULL:
- case GSM0707_CME_MEMORY_FAILURE:
- case GSM0707_CME_PHONE_FAILURE:
- case GSM0707_CME_PHONE_NOCONNECT:
- case GSM0707_CME_PHONE_ADAPT_RESERVED:
- case GSM0707_CME_SIM_NOT_INSERTED:
- /* FIXME */
- talloc_free(gu);
- return 0;
- break;
- default:
- talloc_free(gu);
- return 0;
- break;
- }
+ eaux->u.pin.type = pintype_from_cme[cme_error];
return usock_evt_send(g, gu, GSMD_EVT_PIN);
}
}
diff --git a/src/gsmd/usock.c b/src/gsmd/usock.c
index cf3aea9..73bb3c3 100644
--- a/src/gsmd/usock.c
+++ b/src/gsmd/usock.c
@@ -185,19 +185,18 @@ static int null_cmd_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
/* PIN command callback. Gets called for response to AT+CPIN cmcd */
static int pin_cmd_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
{
- gsmd_log(GSMD_DEBUG, "pin cmd cb\n");
+ struct gsmd_user *gu = ctx;
+ struct gsmd_ucmd *ucmd = gsmd_ucmd_fill(sizeof(int), GSMD_MSG_PIN,
+ GSMD_PIN_INPUT, 0);
- /* We need to verify if there is some error */
- switch (cmd->ret) {
- case 0:
- break;
- case GSM0707_CME_INCORRECT_PASSWORD:
- /* prompt for pin again */
- break;
- default:
- /* something went wrong */
- break;
- }
+ if (!ucmd)
+ return -ENOMEM;
+
+ /* Pass a GSM07.07 CME code directly, don't issue a new PIN
+ * request because the client waits for a response to her
+ * PIN submission rather than an event. */
+ ((int *) ucmd->buf)[0] = cmd->ret;
+ usock_cmd_enqueue(ucmd, gu);
return 0;
}
@@ -409,7 +408,7 @@ struct gsmd_ucmd *gsmd_ucmd_fill(int len, u_int8_t msg_type,
ucmd = ucmd_alloc(len);
if (!ucmd)
return NULL;
-
+
ucmd->hdr.version = GSMD_PROTO_VERSION;
ucmd->hdr.msg_type = msg_type;
ucmd->hdr.msg_subtype = msg_subtype;
@@ -651,7 +650,7 @@ static int network_ownnumbers_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
num->service = GSMD_SERVICE_UNKNOWN;
num->name[len] = 0;
num->addr.type = type;
- num->is_last = (cmd->ret == 0, NULL);
+ num->is_last = (cmd->ret == 0);
usock_cmd_enqueue(ucmd, gu);
diff --git a/src/libgsmd/libgsmd_pin.c b/src/libgsmd/libgsmd_pin.c
index 5ae6625..f99084a 100644
--- a/src/libgsmd/libgsmd_pin.c
+++ b/src/libgsmd/libgsmd_pin.c
@@ -55,7 +55,8 @@ const char *lgsm_pin_name(enum gsmd_pin_type ptype)
return pin_type_names[ptype];
}
-int lgsm_pin(struct lgsm_handle *lh, unsigned int type, char *pin, char *newpin)
+int lgsm_pin(struct lgsm_handle *lh, unsigned int type,
+ const char *pin, const char *newpin)
{
int rc;
struct {
@@ -74,9 +75,7 @@ int lgsm_pin(struct lgsm_handle *lh, unsigned int type, char *pin, char *newpin)
return -ENOMEM;
gm->gp.type = type;
-
- gm->gp.pin[0] = '\0';
- strcat(gm->gp.pin, pin);
+ strcpy(gm->gp.pin, pin);
switch (type) {
case GSMD_PIN_SIM_PUK:
@@ -84,10 +83,11 @@ int lgsm_pin(struct lgsm_handle *lh, unsigned int type, char *pin, char *newpin)
/* GSM 07.07 explicitly states that only those two PUK types
* require a new pin to be specified! Don't know if this is a
* bug or a feature. */
- if (!newpin)
+ if (!newpin) {
+ free(gm);
return -EINVAL;
- gm->gp.newpin[0] = '\0';
- strcat(gm->gp.newpin, newpin);
+ }
+ strcpy(gm->gp.newpin, newpin);
break;
default:
break;
diff --git a/src/util/pin.c b/src/util/pin.c
index fdd0099..b873535 100644
--- a/src/util/pin.c
+++ b/src/util/pin.c
@@ -27,24 +27,28 @@
#include <libgsmd/event.h>
#include <libgsmd/pin.h>
+#include "shell.h"
+
#define PIN_SIZE 8
-static char *pin;
+static const char *pin;
static char pinbuf[PIN_SIZE+1];
static char pinbuf2[PIN_SIZE+1];
-static int pin_handler(struct lgsm_handle *lh, int evt, struct gsmd_evt_auxdata *aux)
+static int pin_handler(struct lgsm_handle *lh,
+ int evt, struct gsmd_evt_auxdata *aux)
{
int rc;
int type = aux->u.pin.type;
char *newpin = NULL;
- printf("EVENT: PIN request (type='%s') ", lgsm_pin_name(aux->u.pin.type));
+ printf("EVENT: PIN request (type='%s') ", lgsm_pin_name(type));
/* FIXME: read pin from STDIN and send it back via lgsm_pin */
if (type == 1 && pin) {
printf("Auto-responding with pin `%s'\n", pin);
- lgsm_pin(lh, type, pin, NULL);
+ pending_responses ++;
+ return lgsm_pin(lh, type, pin, NULL);
} else {
do {
printf("Please enter %s: ", lgsm_pin_name(type));
@@ -64,10 +68,9 @@ static int pin_handler(struct lgsm_handle *lh, int evt, struct gsmd_evt_auxdata
break;
}
+ pending_responses ++;
return lgsm_pin(lh, type, pinbuf, newpin);
}
-
- return 0;
}
int pin_init(struct lgsm_handle *lh, const char *pin_preset)
diff --git a/src/util/shell.c b/src/util/shell.c
index 031ed34..373ce33 100644
--- a/src/util/shell.c
+++ b/src/util/shell.c
@@ -44,7 +44,7 @@
static int nFIND = 0;
static int nREADRG = 0;
-static int pending_responses = 0;
+int pending_responses = 0;
/* this is the handler for receiving passthrough responses */
static int pt_msghandler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
@@ -373,6 +373,32 @@ static int phone_msghandler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
return 0;
}
+static int pin_msghandler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
+{
+ int result = *(int *) gmh->data;
+
+ if (result)
+ printf("PIN error %i\n", result);
+ else
+ printf("PIN accepted!\n");
+ pending_responses --;
+ return 0;
+}
+
+static const struct msghandler_s {
+ int type;
+ lgsm_msg_handler *fn;
+} msghandlers[] = {
+ { GSMD_MSG_PASSTHROUGH, pt_msghandler },
+ { GSMD_MSG_PHONEBOOK, pb_msghandler },
+ { GSMD_MSG_SMS, sms_msghandler },
+ { GSMD_MSG_NETWORK, net_msghandler },
+ { GSMD_MSG_PHONE, phone_msghandler },
+ { GSMD_MSG_PIN, pin_msghandler },
+
+ { 0, 0 }
+};
+
static int shell_help(void)
{
printf( "\tA\tAnswer incoming call\n"
@@ -424,12 +450,10 @@ int shell_main(struct lgsm_handle *lgsmh, int sync)
fd_set readset;
char *ptr, *fcomma, *lcomma;
int gsm_fd = lgsm_fd(lgsmh);
+ const struct msghandler_s *hndl;
- lgsm_register_handler(lgsmh, GSMD_MSG_PASSTHROUGH, &pt_msghandler);
- lgsm_register_handler(lgsmh, GSMD_MSG_PHONEBOOK, &pb_msghandler);
- lgsm_register_handler(lgsmh, GSMD_MSG_SMS, &sms_msghandler);
- lgsm_register_handler(lgsmh, GSMD_MSG_NETWORK, &net_msghandler);
- lgsm_register_handler(lgsmh, GSMD_MSG_PHONE, &phone_msghandler);
+ for (hndl = msghandlers; hndl->fn; hndl ++)
+ lgsm_register_handler(lgsmh, hndl->type, hndl->fn);
fcntl(0, F_SETFD, O_NONBLOCK);
fcntl(gsm_fd, F_SETFD, O_NONBLOCK);
diff --git a/src/util/shell.h b/src/util/shell.h
index f0bebb3..81a8dc3 100644
--- a/src/util/shell.h
+++ b/src/util/shell.h
@@ -1,2 +1,2 @@
-
extern int shell_main(struct lgsm_handle *lgsmh, int sync);
+extern int pending_responses;
personal git repositories of Harald Welte. Your mileage may vary