From d88e15979081740b86f48a78c81df56f5122a2c4 Mon Sep 17 00:00:00 2001 From: tick Date: Sat, 1 Dec 2007 01:55:39 +0000 Subject: 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 --- include/gsmd/unsolicited.h | 1 + include/libgsmd/pin.h | 3 +- src/gsmd/unsolicited.c | 108 ++++++++++++++++----------------------------- src/gsmd/usock.c | 27 ++++++------ src/libgsmd/libgsmd_pin.c | 14 +++--- src/util/pin.c | 15 ++++--- src/util/shell.c | 36 ++++++++++++--- src/util/shell.h | 2 +- 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 #include +#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; -- cgit v1.2.3