summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlaforge <laforge@99fdad57-331a-0410-800a-d7fa5415bdb3>2007-03-10 02:22:04 +0000
committerlaforge <laforge@99fdad57-331a-0410-800a-d7fa5415bdb3>2007-03-10 02:22:04 +0000
commit2797211645d452446cb7b329ee9d3d3a923f8520 (patch)
tree5f8dc89cc720f7ea3ce0d6c2b31489addb37c3b8
parenta831d70619f614254692b75c1aca39f21c15fb55 (diff)
* properly implement PIN/PUK handling throughout gsmd/libgsmd/util
git-svn-id: http://svn.openmoko.org/trunk/src/target/gsm@1314 99fdad57-331a-0410-800a-d7fa5415bdb3
-rw-r--r--include/gsmd/usock.h7
-rw-r--r--include/libgsmd/libgsmd.h4
-rw-r--r--include/libgsmd/pin.h8
-rw-r--r--src/gsmd/usock.c46
-rw-r--r--src/gsmd/vendor_ti.c5
-rw-r--r--src/libgsmd/Makefile.am2
-rw-r--r--src/libgsmd/libgsmd.c20
-rw-r--r--src/libgsmd/libgsmd_pin.c78
-rw-r--r--src/util/pin.c31
9 files changed, 168 insertions, 33 deletions
diff --git a/include/gsmd/usock.h b/include/gsmd/usock.h
index 530eed7..cb5e0b9 100644
--- a/include/gsmd/usock.h
+++ b/include/gsmd/usock.h
@@ -86,6 +86,13 @@ struct gsmd_voicemail {
struct gsmd_addr addr;
} __attribute__ ((packed));
+#define GSMD_PIN_MAXLEN 8
+struct gsmd_pin {
+ enum gsmd_pin_type type;
+ char pin[GSMD_PIN_MAXLEN+1];
+ char newpin[GSMD_PIN_MAXLEN+1];
+} __attribute__ ((packed));
+
struct gsmd_evt_auxdata {
union {
struct {
diff --git a/include/libgsmd/libgsmd.h b/include/libgsmd/libgsmd.h
index a89f4b6..8c34c6a 100644
--- a/include/libgsmd/libgsmd.h
+++ b/include/libgsmd/libgsmd.h
@@ -63,5 +63,7 @@ extern int lgsm_passthrough_send(struct lgsm_handle *lh, const char *tx);
extern int lgsm_passthrough(struct lgsm_handle *lh, const char *tx, char *rx, unsigned int *rx_len);
extern int lgsm_subscriptions(struct lgsm_handle *lh, u_int32_t subscriptions);
-extern int lgsm_pin(struct lgsm_handle *lh, char *pin);
+extern struct gsmd_msg_hdr *lgsm_gmh_fill(int type, int subtype, int payload_len);
+extern int lgsm_send(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh);
+
#endif
diff --git a/include/libgsmd/pin.h b/include/libgsmd/pin.h
new file mode 100644
index 0000000..304455f
--- /dev/null
+++ b/include/libgsmd/pin.h
@@ -0,0 +1,8 @@
+#ifndef _LGSM_PIN_H
+#define _LGSM_PIN_H
+
+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);
+
+#endif
diff --git a/src/gsmd/usock.c b/src/gsmd/usock.c
index 0337b5e..31292e8 100644
--- a/src/gsmd/usock.c
+++ b/src/gsmd/usock.c
@@ -38,6 +38,7 @@
#include <gsmd/atcmd.h>
#include <gsmd/usock.h>
#include <gsmd/talloc.h>
+#include <gsmd/ts0707.h>
static void *__ucmd_ctx, *__gu_ctx;
@@ -173,13 +174,37 @@ static int null_cmd_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
return 0;
}
+/* 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");
+
+ /* 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;
+ }
+ return 0;
+}
+
static int usock_rcv_pin(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
int len)
{
- u_int8_t *pin = (u_int8_t *)gph + sizeof(*gph);
- int pin_len = len - sizeof(*gph);
+ struct gsmd_pin *gp = (struct gsmd_pin *) ((void *)gph + sizeof(*gph));
struct gsmd_atcmd *cmd;
+ if (gph->len < sizeof(*gp) || len < sizeof(*gp)+sizeof(*gph))
+ return -EINVAL;
+
+ gsmd_log(GSMD_DEBUG, "pin type=%u, pin='%s', newpin='%s'\n",
+ gp->type, gp->pin, gp->newpin);
+
switch (gph->msg_subtype) {
case GSMD_PIN_INPUT:
/* FIXME */
@@ -190,12 +215,23 @@ static int usock_rcv_pin(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
return -EINVAL;
}
- cmd = atcmd_fill("AT+CPIN=\"", 9+1+1+strlen(pin),
- &null_cmd_cb, gu, 0);
+ cmd = atcmd_fill("AT+CPIN=\"", 9+GSMD_PIN_MAXLEN+3+GSMD_PIN_MAXLEN+2,
+ &pin_cmd_cb, gu, 0);
if (!cmd)
return -ENOMEM;
- strcat(cmd->buf, pin);
+ strcat(cmd->buf, gp->pin);
+
+ switch (gp->type) {
+ case GSMD_PIN_SIM_PUK:
+ case GSMD_PIN_SIM_PUK2:
+ strcat(cmd->buf, "\",\"");
+ strcat(cmd->buf, gp->newpin);
+ break;
+ default:
+ break;
+ }
+
strcat(cmd->buf, "\"");
return atcmd_submit(gu->gsmd, cmd);
diff --git a/src/gsmd/vendor_ti.c b/src/gsmd/vendor_ti.c
index 53c0365..6617edf 100644
--- a/src/gsmd/vendor_ti.c
+++ b/src/gsmd/vendor_ti.c
@@ -235,6 +235,11 @@ static const struct gsmd_unsolicit ticalypso_unsolicit[] = {
/* %CGEV: reports GPRS network events */
};
+static int cpi_detect_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
+{
+
+}
+
static int ticalypso_detect(struct gsmd *g)
{
/* FIXME: do actual detection of vendor if we have multiple vendors */
diff --git a/src/libgsmd/Makefile.am b/src/libgsmd/Makefile.am
index a1ee710..5ea36f1 100644
--- a/src/libgsmd/Makefile.am
+++ b/src/libgsmd/Makefile.am
@@ -5,6 +5,6 @@ AM_CFLAGS = -std=gnu99
lib_LTLIBRARIES = libgsmd.la
libgsmd_la_LDFLAGS = -Wc,-nostartfiles -version-info $(LIBVERSION)
-libgsmd_la_SOURCES = libgsmd.c libgsmd_input.c libgsmd_voicecall.c libgsmd_passthrough.c libgsmd_event.c libgsmd_phone.c libgsmd_network.c
+libgsmd_la_SOURCES = libgsmd.c libgsmd_input.c libgsmd_voicecall.c libgsmd_passthrough.c libgsmd_event.c libgsmd_phone.c libgsmd_network.c libgsmd_pin.c
noinst_HEADERS = lgsm_internals.h
diff --git a/src/libgsmd/libgsmd.c b/src/libgsmd/libgsmd.c
index 59f04ed..11760b4 100644
--- a/src/libgsmd/libgsmd.c
+++ b/src/libgsmd/libgsmd.c
@@ -197,7 +197,7 @@ struct gsmd_msg_hdr *lgsm_gmh_fill(int type, int subtype, int payload_len)
if (!gmh)
return NULL;
- memset(gmh, 0, sizeof(*gmh));
+ memset(gmh, 0, sizeof(*gmh)+payload_len);
gmh->version = GSMD_PROTO_VERSION;
gmh->msg_type = type;
@@ -207,21 +207,3 @@ struct gsmd_msg_hdr *lgsm_gmh_fill(int type, int subtype, int payload_len)
return gmh;
}
-
-int lgsm_pin(struct lgsm_handle *lh, char *pin)
-{
- int rc;
- struct gsmd_msg_hdr *gmh;
-
- gmh = lgsm_gmh_fill(GSMD_MSG_PIN, GSMD_PIN_INPUT, strlen(pin)+1);
- if (!gmh)
- return -ENOMEM;
-
- gmh->data[0] = '\0';
- strcat(gmh->data, pin);
-
- rc = lgsm_send(lh, gmh);
- free(gmh);
-
- return rc;
-}
diff --git a/src/libgsmd/libgsmd_pin.c b/src/libgsmd/libgsmd_pin.c
new file mode 100644
index 0000000..e645dd5
--- /dev/null
+++ b/src/libgsmd/libgsmd_pin.c
@@ -0,0 +1,78 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <sys/types.h>
+#include <gsmd/event.h>
+#include <libgsmd/libgsmd.h>
+
+static const char *pin_type_names[__NUM_GSMD_PIN] = {
+ [GSMD_PIN_NONE] = "NONE",
+ [GSMD_PIN_SIM_PIN] = "SIM PIN",
+ [GSMD_PIN_SIM_PUK] = "SIM PUK",
+ [GSMD_PIN_PH_SIM_PIN] = "Phone-to-SIM PIN",
+ [GSMD_PIN_PH_FSIM_PIN] = "Phone-to-very-first SIM PIN",
+ [GSMD_PIN_PH_FSIM_PUK] = "Phone-to-very-first SIM PUK",
+ [GSMD_PIN_SIM_PIN2] = "SIM PIN2",
+ [GSMD_PIN_SIM_PUK2] = "SIM PUK2",
+ [GSMD_PIN_PH_NET_PIN] = "Network personalization PIN",
+ [GSMD_PIN_PH_NET_PUK] = "Network personalizaiton PUK",
+ [GSMD_PIN_PH_NETSUB_PIN]= "Network subset personalisation PIN",
+ [GSMD_PIN_PH_NETSUB_PUK]= "Network subset personalisation PUK",
+ [GSMD_PIN_PH_SP_PIN] = "Service provider personalisation PIN",
+ [GSMD_PIN_PH_SP_PUK] = "Service provider personalisation PUK",
+ [GSMD_PIN_PH_CORP_PIN] = "Corporate personalisation PIN",
+ [GSMD_PIN_PH_CORP_PUK] = "Corporate personalisation PUK",
+};
+
+const char *lgsm_pin_name(enum gsmd_pin_type ptype)
+{
+ if (ptype >= __NUM_GSMD_PIN)
+ return "unknown";
+
+ return pin_type_names[ptype];
+}
+
+int lgsm_pin(struct lgsm_handle *lh, unsigned int type, char *pin, char *newpin)
+{
+ int rc;
+ struct {
+ struct gsmd_msg_hdr gmh;
+ struct gsmd_pin gp;
+ } __attribute__ ((packed)) *gm;
+
+ if (strlen(pin) > GSMD_PIN_MAXLEN ||
+ (newpin && strlen(newpin) > GSMD_PIN_MAXLEN) ||
+ type >= __NUM_GSMD_PIN)
+ return -EINVAL;
+
+ gm = (void *) lgsm_gmh_fill(GSMD_MSG_PIN, GSMD_PIN_INPUT,
+ sizeof(struct gsmd_pin));
+ if (!gm)
+ return -ENOMEM;
+
+ gm->gp.type = type;
+
+ gm->gp.pin[0] = '\0';
+ strcat(gm->gp.pin, pin);
+
+ switch (type) {
+ case GSMD_PIN_SIM_PUK:
+ case GSMD_PIN_SIM_PUK2:
+ /* 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)
+ return -EINVAL;
+ gm->gp.newpin[0] = '\0';
+ strcat(gm->gp.newpin, newpin);
+ break;
+ default:
+ break;
+ }
+ printf("sending pin='%s', newpin='%s'\n", gm->gp.pin, gm->gp.newpin);
+ rc = lgsm_send(lh, &gm->gmh);
+ free(gm);
+
+ return rc;
+}
diff --git a/src/util/pin.c b/src/util/pin.c
index 7bfd8da..fdd0099 100644
--- a/src/util/pin.c
+++ b/src/util/pin.c
@@ -25,29 +25,46 @@
#include <libgsmd/libgsmd.h>
#include <libgsmd/event.h>
+#include <libgsmd/pin.h>
-#define PIN_SIZE 32
+#define PIN_SIZE 8
static 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)
{
int rc;
+ int type = aux->u.pin.type;
+ char *newpin = NULL;
- printf("EVENT: PIN request (type=%u) ", aux->u.pin.type);
+ printf("EVENT: PIN request (type='%s') ", lgsm_pin_name(aux->u.pin.type));
/* FIXME: read pin from STDIN and send it back via lgsm_pin */
- if (aux->u.pin.type == 1 && pin) {
+ if (type == 1 && pin) {
printf("Auto-responding with pin `%s'\n", pin);
- lgsm_pin(lh, pin);
+ lgsm_pin(lh, type, pin, NULL);
} else {
do {
- printf("Please enter PIN: ");
- rc = fscanf(stdin, "%32s", &pinbuf);
+ printf("Please enter %s: ", lgsm_pin_name(type));
+ rc = fscanf(stdin, "%8s", &pinbuf);
} while (rc < 1);
- return lgsm_pin(lh, pinbuf);
+ switch (type) {
+ case GSMD_PIN_SIM_PUK:
+ case GSMD_PIN_SIM_PUK2:
+ do {
+ printf("Please enter new PIN: ");
+ rc = fscanf(stdin, "%8s", &pinbuf2);
+ newpin = pinbuf2;
+ } while (rc < 1);
+ break;
+ default:
+ break;
+ }
+
+ return lgsm_pin(lh, type, pinbuf, newpin);
}
return 0;
personal git repositories of Harald Welte. Your mileage may vary