diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/gsmd/usock.c | 46 | ||||
| -rw-r--r-- | src/gsmd/vendor_ti.c | 5 | ||||
| -rw-r--r-- | src/libgsmd/Makefile.am | 2 | ||||
| -rw-r--r-- | src/libgsmd/libgsmd.c | 20 | ||||
| -rw-r--r-- | src/libgsmd/libgsmd_pin.c | 78 | ||||
| -rw-r--r-- | src/util/pin.c | 31 | 
6 files changed, 150 insertions, 32 deletions
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;  | 
