From ad708e46d7a8adc45aa8b9ec2ff7b110303f708f Mon Sep 17 00:00:00 2001 From: laforge Date: Fri, 17 Aug 2007 08:36:48 +0000 Subject: Add retrieving phone's own subscriber number. (Andrzej Zaborowski) git-svn-id: http://svn.openmoko.org/trunk/src/target/gsm@2733 99fdad57-331a-0410-800a-d7fa5415bdb3 --- include/gsmd/usock.h | 18 ++++++++++++++++ include/libgsmd/misc.h | 3 +++ src/gsmd/usock.c | 49 +++++++++++++++++++++++++++++++++++++++++++ src/libgsmd/libgsmd_network.c | 5 +++++ src/util/event.c | 1 + src/util/shell.c | 22 +++++++++++++++++++ 6 files changed, 98 insertions(+) diff --git a/include/gsmd/usock.h b/include/gsmd/usock.h index 3472189..19c616c 100644 --- a/include/gsmd/usock.h +++ b/include/gsmd/usock.h @@ -478,6 +478,24 @@ struct gsmd_phonebook_storage { char storage[3]; } __attribute__ ((packed)); +/* Subscriber number information from 3GPP TS 07.07, Clause 7.1 */ +enum gsmd_subscriber_service { + GSMD_SERVICE_UNKNOWN = -1, + GSMD_SERVICE_ASYNC_MODEM = 0, + GSMD_SERVICE_SYNC_MODEM, + GSMD_SERVICE_PAD_ACCESS, + GSMD_SERVICE_PACKET_ACCESS, + GSMD_SERVICE_VOICE, + GSMD_SERVICE_FAX, +}; + +struct gsmd_own_number { + int is_last; + enum gsmd_subscriber_service service; + struct gsmd_addr addr; + char name[0]; +}; + struct gsmd_msg_hdr { u_int8_t version; u_int8_t msg_type; diff --git a/include/libgsmd/misc.h b/include/libgsmd/misc.h index d673c31..8fa1ba6 100644 --- a/include/libgsmd/misc.h +++ b/include/libgsmd/misc.h @@ -68,6 +68,9 @@ extern int lgsm_prefoper_delete(struct lgsm_handle *lh, int index); extern int lgsm_prefoper_add(struct lgsm_handle *lh, gsmd_oper_numeric oper); extern int lgsm_prefoper_get_space(struct lgsm_handle *lh); +/* Get subscriber's own phone number */ +extern int lgsm_get_subscriber_num(struct lgsm_handle *lh); + /* CLIP, CLIR, COLP, Call Forwarding, Call Waiting, Call Deflecting */ /* TBD */ diff --git a/src/gsmd/usock.c b/src/gsmd/usock.c index 8525c0a..56ef3f4 100644 --- a/src/gsmd/usock.c +++ b/src/gsmd/usock.c @@ -548,6 +548,51 @@ static int network_pref_num_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) return 0; } +static int network_ownnumbers_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) +{ + struct gsmd_user *gu = (struct gsmd_user *) ctx; + struct gsmd_ucmd *ucmd; + struct gsmd_own_number *num; + int len, ret, type; + char dummy; + + if (cmd->ret && cmd->ret != -255) + return 0; + + if (sscanf(resp, "+CNUM: \"%*[^\"]\"%c%n", &dummy, &len) > 0) + len -= strlen("+CNUM: \"\","); + else + len = 0; + + ucmd = gsmd_ucmd_fill(sizeof(*num) + len + 1, + GSMD_MSG_NETWORK, GSMD_NETWORK_GET_NUMBER, cmd->id); + if (!ucmd) + return -ENOMEM; + + num = (struct gsmd_own_number *) ucmd->buf; + if (len) + ret = sscanf(resp, "+CNUM: \"%[^\"]\",\"%32[^\"]\",%i,%*i,%i,", + num->name, num->addr.number, + &type, &num->service) - 1; + else + ret = sscanf(resp, "+CNUM: ,\"%32[^\"]\",%i,%*i,%i,", + num->addr.number, + &type, &num->service); + if (ret < 2) { + talloc_free(ucmd); + return -EINVAL; + } + if (ret < 3) + num->service = GSMD_SERVICE_UNKNOWN; + num->name[len] = 0; + num->addr.type = type; + num->is_last = (cmd->ret == 0); + + usock_cmd_enqueue(ucmd, gu); + + return 0; +} + static int usock_rcv_network(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int len) { @@ -607,6 +652,10 @@ static int usock_rcv_network(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, cmd = atcmd_fill("AT+CPOL=?", 9 + 1, &network_pref_num_cb, gu, 0); break; + case GSMD_NETWORK_GET_NUMBER: + cmd = atcmd_fill("AT+CNUM", 7 + 1, + &network_ownnumbers_cb, gu, 0); + break; default: return -EINVAL; } diff --git a/src/libgsmd/libgsmd_network.c b/src/libgsmd/libgsmd_network.c index 0b458de..333debd 100644 --- a/src/libgsmd/libgsmd_network.c +++ b/src/libgsmd/libgsmd_network.c @@ -128,3 +128,8 @@ int lgsm_prefoper_get_space(struct lgsm_handle *lh) { return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_PREF_SPACE); } + +int lgsm_get_subscriber_num(struct lgsm_handle *lh) +{ + return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_GET_NUMBER); +} diff --git a/src/util/event.c b/src/util/event.c index a206bbc..ea8ad3b 100644 --- a/src/util/event.c +++ b/src/util/event.c @@ -26,6 +26,7 @@ #include #include #include +#include static int incall_handler(struct lgsm_handle *lh, int evt, struct gsmd_evt_auxdata *aux) { diff --git a/src/util/shell.c b/src/util/shell.c index 431b0aa..19abba2 100644 --- a/src/util/shell.c +++ b/src/util/shell.c @@ -298,12 +298,22 @@ static int net_msghandler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh) const char *oper = (char *) gmh + sizeof(*gmh); const struct gsmd_msg_oper *opers = (struct gsmd_msg_oper *) ((void *) gmh + sizeof(*gmh)); + const struct gsmd_own_number *num = (struct gsmd_own_number *) + ((void *) gmh + sizeof(*gmh)); static const char *oper_stat[] = { [GSMD_OPER_UNKNOWN] = "of unknown status", [GSMD_OPER_AVAILABLE] = "available", [GSMD_OPER_CURRENT] = "our current operator", [GSMD_OPER_FORBIDDEN] = "forbidden", }; + static const char *srvname[] = { + [GSMD_SERVICE_ASYNC_MODEM] = "asynchronous modem", + [GSMD_SERVICE_SYNC_MODEM] = "synchronous modem", + [GSMD_SERVICE_PAD_ACCESS] = "PAD Access (asynchronous)", + [GSMD_SERVICE_PACKET_ACCESS] = "Packet Access (synchronous)", + [GSMD_SERVICE_VOICE] = "voice", + [GSMD_SERVICE_FAX] = "fax", + }; switch (gmh->msg_subtype) { case GSMD_NETWORK_SIGQ_GET: @@ -333,6 +343,15 @@ static int net_msghandler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh) opers->opname_shortalpha, oper_stat[opers->stat]); break; + case GSMD_NETWORK_GET_NUMBER: + printf("\t%s\t%10s%s%s%s\n", num->addr.number, num->name, + (num->service == GSMD_SERVICE_UNKNOWN) ? + "" : " related to ", + (num->service == GSMD_SERVICE_UNKNOWN) ? + "" : srvname[num->service], + (num->service == GSMD_SERVICE_UNKNOWN) ? + "" : " services"); + break; default: return -EINVAL; } @@ -352,6 +371,7 @@ static int shell_help(void) "\tL\tDetect available operators\n" "\tQ\tRead signal quality\n" "\tT\tSend DTMF Tone\n" + "\tn\tPrint subscriber numbers\n" "\tpd\tPB Delete (pb=index)\n" "\tpr\tPB Read (pr=index)\n" "\tprr\tPB Read Range (prr=index1,index2)\n" @@ -630,6 +650,8 @@ int shell_main(struct lgsm_handle *lgsmh) printf("No.\n"); else lgsm_sms_set_smsc(lgsmh, ptr + 1); + } else if (!strcmp(buf, "n")) { + lgsm_get_subscriber_num(lgsmh); } else { printf("Unknown command `%s'\n", buf); } -- cgit v1.2.3