From 5e988040575d346c4ca41061248e72d676467ed0 Mon Sep 17 00:00:00 2001 From: jserv Date: Wed, 17 Oct 2007 06:18:34 +0000 Subject: Improvement for find and read phonebooks in gsmd. From: Sean Chiang Subject: [PATCH] Improvement for find and read phonebooks in gsmd This patch is an improvement for find and read phonebooks. After clients make a request to find / read phonebooks, then clients should make a request to retrieve all the records. git-svn-id: http://svn.openmoko.org/trunk/src/target/gsm@3202 99fdad57-331a-0410-800a-d7fa5415bdb3 --- include/gsmd/gsmd.h | 3 + include/gsmd/usock.h | 20 ++++- include/libgsmd/phonebook.h | 6 ++ src/gsmd/usock.c | 188 +++++++++++++++++++++++++++++++++++----- src/libgsmd/libgsmd_phonebook.c | 48 +++++++++- 5 files changed, 240 insertions(+), 25 deletions(-) diff --git a/include/gsmd/gsmd.h b/include/gsmd/gsmd.h index f1773c3..ed334f1 100644 --- a/include/gsmd/gsmd.h +++ b/include/gsmd/gsmd.h @@ -92,6 +92,9 @@ struct gsmd_user { struct gsmd *gsmd; struct gsmd_fd gfd; /* the socket */ u_int32_t subscriptions; /* bitmaks of subscribed event groups */ + + struct llist_head pb_readrg_list; /* our READRG phonebook list */ + struct llist_head pb_find_list; /* our FIND phonebook list */ }; #define GSMD_DEBUG 1 /* debugging information */ diff --git a/include/gsmd/usock.h b/include/gsmd/usock.h index c2f03f5..66cdf48 100644 --- a/include/gsmd/usock.h +++ b/include/gsmd/usock.h @@ -194,6 +194,8 @@ enum gsmd_msg_phonebook { GSMD_PHONEBOOK_GET_SUPPORT = 6, GSMD_PHONEBOOK_LIST_STORAGE = 7, GSMD_PHONEBOOK_SET_STORAGE = 8, + GSMD_PHONEBOOK_RETRIEVE_READRG = 9, + GSMD_PHONEBOOK_RETRIEVE_FIND = 10, }; /* Type-of-Address, Numbering-Plan-Identification field, GSM 03.40, 9.1.2.5 */ @@ -432,7 +434,6 @@ struct gsmd_phonebook { char text[GSMD_PB_TEXT_MAXLEN+1]; } __attribute__ ((packed)); - /* Refer to GSM 07.07 subclause 8.13 */ /* FIXME: the tlength depends on SIM, use +CPBR=? to get */ struct gsmd_phonebook_find { @@ -472,8 +473,18 @@ struct gsmd_msg_prefoper { char opname_longalpha[16]; }; +/* Refer to GSM 07.07 subclause 8.11 */ +struct gsmd_phonebook_mem { + u_int8_t type[3]; + u_int8_t pad; + u_int16_t used; + u_int16_t total; +} __attribute__ ((packed)); + struct gsmd_phonebook_storage { - char storage[3]; + /* FIXME the amount of phonebook storage should be dynamic */ + u_int8_t num; + struct gsmd_phonebook_mem mem[20]; } __attribute__ ((packed)); /* Subscriber number information from 3GPP TS 07.07, Clause 7.1 */ @@ -518,6 +529,11 @@ struct gsmd_ucmd { char buf[]; } __attribute__ ((packed)); +struct gsmd_phonebooks { + struct llist_head list; + struct gsmd_phonebook pb; +} __attribute__ ((packed)); + extern struct gsmd_ucmd *ucmd_alloc(int extra_size); extern int usock_init(struct gsmd *g); extern void usock_cmd_enqueue(struct gsmd_ucmd *ucmd, struct gsmd_user *gu); diff --git a/include/libgsmd/phonebook.h b/include/libgsmd/phonebook.h index badb76f..6e2d2b1 100644 --- a/include/libgsmd/phonebook.h +++ b/include/libgsmd/phonebook.h @@ -106,4 +106,10 @@ extern int lgsm_pb_write_entry(struct lgsm_handle *lh, /* Get the location range/nlength/tlength supported */ extern int lgsm_pb_get_support(struct lgsm_handle *lh); +/* Retrieve the records of READRG request */ +extern int lgsm_pb_retrieve_readrg(struct lgsm_handle *lh, int num); + +/* Retrieve the records of FIND request */ +extern int lgsm_pb_retrieve_find(struct lgsm_handle *lh, int num); + #endif diff --git a/src/gsmd/usock.c b/src/gsmd/usock.c index 56ef3f4..a53c8a1 100644 --- a/src/gsmd/usock.c +++ b/src/gsmd/usock.c @@ -41,7 +41,7 @@ #include #include -static void *__ucmd_ctx, *__gu_ctx; +static void *__ucmd_ctx, *__gu_ctx, *__pb_ctx; struct gsmd_ucmd *ucmd_alloc(int extra_size) { @@ -1035,21 +1035,56 @@ static int usock_rcv_sms(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, static int phonebook_find_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) { - struct gsmd_user *gu = ctx; - struct gsmd_ucmd *ucmd; - + struct gsmd_user *gu = ctx; + struct gsmd_ucmd *ucmd; + struct gsmd_phonebooks *gps; + char *fcomma, *lcomma, *ptr1, *ptr2 = NULL; + int *num; + DEBUGP("resp: %s\n", resp); - /* FIXME: using link list, also we need to handle the case of - * no query result */ - ucmd = gsmd_ucmd_fill(strlen(resp) + 1, GSMD_MSG_PHONEBOOK, + /* + * [+CPBF: ,,,[[...] + * +CPBF: ,,,]] + */ + ucmd = gsmd_ucmd_fill(sizeof(int), GSMD_MSG_PHONEBOOK, GSMD_PHONEBOOK_FIND, 0); if (!ucmd) return -ENOMEM; - strcpy(ucmd->buf, resp); + num = (int*) ucmd->buf; + + *num = 0; + + ptr1 = strtok(resp, "\n"); + + while (ptr1) { + gps = talloc(__pb_ctx, struct gsmd_phonebooks); + ptr2 = strchr(ptr1, ' '); + gps->pb.index = atoi(ptr2+1); + + fcomma = strchr(ptr1, '"'); + lcomma = strchr(fcomma+1, '"'); + strncpy(gps->pb.numb, fcomma + 1, (lcomma-fcomma-1)); + gps->pb.numb[(lcomma - fcomma) - 1] = '\0'; + + gps->pb.type = atoi(lcomma + 2); + + ptr2 = strrchr(ptr1, ','); + fcomma = ptr2 + 1; + lcomma = strchr(fcomma + 1, '"'); + strncpy(gps->pb.text, fcomma + 1, (lcomma - fcomma - 1)); + gps->pb.text[(lcomma - fcomma) - 1] = '\0'; + + llist_add_tail(&gps->list, &gu->pb_find_list); + + (*num)++; + + ptr1 = strtok(NULL, "\n"); + } usock_cmd_enqueue(ucmd, gu); + talloc_free(__pb_ctx); return 0; } @@ -1102,25 +1137,54 @@ static int phonebook_readrg_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) { struct gsmd_user *gu = ctx; struct gsmd_ucmd *ucmd; + struct gsmd_phonebooks *gps; + char *fcomma, *lcomma, *ptr1, *ptr2 = NULL; + int *num; DEBUGP("resp: %s\n", resp); /* - * +CPBR: 4,"1234",129,"6C5F745E7965" - * +CPBR: 5,"5678",129,"800062115BB6" - * +CPBR: 6,"7890",129,"810280AA591A" - * +CPBR: 8,"36874",129,"005300650061006E" - * + * [+CPBR: ,,,[[...] + * +CPBR: ,,,]] */ - ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_PHONEBOOK, + ucmd = gsmd_ucmd_fill(sizeof(int), GSMD_MSG_PHONEBOOK, GSMD_PHONEBOOK_READRG, 0); if (!ucmd) return -ENOMEM; - strcpy(ucmd->buf, resp); + num = (int*) ucmd->buf; - usock_cmd_enqueue(ucmd, gu); + *num = 0; + + ptr1 = strtok(resp, "\n"); + + while (ptr1) { + gps = talloc(__pb_ctx, struct gsmd_phonebooks); + ptr2 = strchr(ptr1, ' '); + gps->pb.index = atoi(ptr2+1); + + fcomma = strchr(ptr1, '"'); + lcomma = strchr(fcomma+1, '"'); + strncpy(gps->pb.numb, fcomma + 1, (lcomma-fcomma-1)); + gps->pb.numb[(lcomma - fcomma) - 1] = '\0'; + gps->pb.type = atoi(lcomma + 2); + + ptr2 = strrchr(ptr1, ','); + fcomma = ptr2 + 1; + lcomma = strchr(fcomma + 1, '"'); + strncpy(gps->pb.text, fcomma + 1, (lcomma - fcomma - 1)); + gps->pb.text[(lcomma - fcomma) - 1] = '\0'; + + llist_add_tail(&gps->list, &gu->pb_readrg_list); + + (*num)++; + + ptr1 = strtok(NULL, "\n"); + } + + usock_cmd_enqueue(ucmd, gu); + talloc_free(__pb_ctx); return 0; } @@ -1209,22 +1273,38 @@ static int phonebook_get_support_cb(struct gsmd_atcmd *cmd, void *ctx, char *res static int phonebook_list_storage_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) { - /* +CPBS: ("EN","BD","FD","DC","LD","RC","LR","MT","AD", - * "SM","SD","MC","LM","AF","ON","UD") */ /* TODO; using link list ; need to handle command error */ struct gsmd_user *gu = ctx; struct gsmd_ucmd *ucmd; + struct gsmd_phonebook_storage *gps; + char *ptr; DEBUGP("resp: %s\n", resp); - ucmd = gsmd_ucmd_fill(strlen(resp) + 1, + /* + * +CPBS: (s) + */ + + ucmd = gsmd_ucmd_fill(sizeof(*gps), GSMD_MSG_PHONEBOOK, GSMD_PHONEBOOK_LIST_STORAGE, 0); if (!ucmd) return -ENOMEM; - strcpy(ucmd->buf, resp); + gps = (struct gsmd_phonebook_storage *) ucmd->buf; + gps->num = 0; + + if (!strncmp(resp, "+CPBS", 5)) { + char* delim = "(,"; + ptr = strpbrk(resp, delim); + while ( ptr ) { + strncpy(gps->mem[gps->num].type, ptr+2, 2); + gps->mem[gps->num].type[2] = '\0'; + ptr = strpbrk(ptr+2, delim); + gps->num++; + } + } usock_cmd_enqueue(ucmd, gu); @@ -1235,11 +1315,13 @@ static int usock_rcv_phonebook(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,int len) { struct gsmd_atcmd *cmd = NULL; + struct gsmd_ucmd *ucmd = NULL; struct gsmd_phonebook_readrg *gpr; struct gsmd_phonebook *gp; struct gsmd_phonebook_find *gpf; - int *index; - int atcmd_len; + struct gsmd_phonebooks *cur, *cur2; + int *index, *num; + int atcmd_len, i; char *storage; char buf[1024]; @@ -1343,6 +1425,66 @@ static int usock_rcv_phonebook(struct gsmd_user *gu, cmd = atcmd_fill("AT+CPBR=?", 9+1, &phonebook_get_support_cb, gu, gph->id); break; + case GSMD_PHONEBOOK_RETRIEVE_READRG: + if (len < sizeof(*gph) + sizeof(int)) + return -EINVAL; + + num = (int *) ((void *)gph + sizeof(*gph)); + + ucmd = gsmd_ucmd_fill(sizeof(struct gsmd_phonebook)*(*num), + GSMD_MSG_PHONEBOOK, + GSMD_PHONEBOOK_RETRIEVE_READRG, 0); + if (!ucmd) + return -ENOMEM; + + gp = (struct gsmd_phonebook*) ucmd->buf; + + if (!llist_empty(&gu->pb_readrg_list)) { + + llist_for_each_entry_safe(cur, cur2, + &gu->pb_readrg_list, list) { + gp->index = cur->pb.index; + strcpy(gp->numb, cur->pb.numb); + gp->type = cur->pb.type; + strcpy(gp->text, cur->pb.text); + gp++; + + llist_del(&cur->list); + free(cur); + } + } + + usock_cmd_enqueue(ucmd, gu); + + break; + case GSMD_PHONEBOOK_RETRIEVE_FIND: + if (len < sizeof(*gph) + sizeof(int)) + return -EINVAL; + + num = (int *) ((void *)gph + sizeof(*gph)); + + ucmd = gsmd_ucmd_fill(sizeof(struct gsmd_phonebook)*(*num), GSMD_MSG_PHONEBOOK, + GSMD_PHONEBOOK_RETRIEVE_FIND, 0); + if (!ucmd) + return -ENOMEM; + + gp = (struct gsmd_phonebook*) ucmd->buf; + + if (!llist_empty(&gu->pb_find_list)) { + llist_for_each_entry_safe(cur, cur2, &gu->pb_find_list, list) { + gp->index = cur->pb.index; + strcpy(gp->numb, cur->pb.numb); + gp->type = cur->pb.type; + strcpy(gp->text, cur->pb.text); + gp++; + + llist_del(&cur->list); + free(cur); + } + } + + usock_cmd_enqueue(ucmd, gu); + break; default: return -EINVAL; } @@ -1468,6 +1610,8 @@ static int gsmd_usock_cb(int fd, unsigned int what, void *data) newuser->gsmd = g; newuser->subscriptions = 0xffffffff; INIT_LLIST_HEAD(&newuser->finished_ucmds); + INIT_LLIST_HEAD(&newuser->pb_readrg_list); + INIT_LLIST_HEAD(&newuser->pb_find_list); llist_add(&newuser->list, &g->users); gsmd_register_fd(&newuser->gfd); diff --git a/src/libgsmd/libgsmd_phonebook.c b/src/libgsmd/libgsmd_phonebook.c index 671566b..1f59e34 100644 --- a/src/libgsmd/libgsmd_phonebook.c +++ b/src/libgsmd/libgsmd_phonebook.c @@ -33,7 +33,7 @@ int lgsm_pb_set_storage(struct lgsm_handle *lh, char *storage) gmh->data[2] = '\0'; rc = lgsm_send(lh, gmh); - if (rc < gmh->len + 3) { + if (rc < gmh->len + sizeof(*gmh)) { lgsm_gmh_free(gmh); return -EIO; } @@ -177,3 +177,49 @@ int lgsm_pb_get_support(struct lgsm_handle *lh) { return lgsm_send_simple(lh, GSMD_MSG_PHONEBOOK, GSMD_PHONEBOOK_GET_SUPPORT); } + +int lgsm_pb_retrieve_readrg(struct lgsm_handle *lh, int num) +{ + struct gsmd_msg_hdr *gmh; + int rc; + + gmh = lgsm_gmh_fill(GSMD_MSG_PHONEBOOK, + GSMD_PHONEBOOK_RETRIEVE_READRG, sizeof(int)); + if (!gmh) + return -ENOMEM; + + *(int *)(gmh->data) = num; + + rc = lgsm_send(lh, gmh); + if (rc < gmh->len + sizeof(*gmh)) { + lgsm_gmh_free(gmh); + return -EIO; + } + + lgsm_gmh_free(gmh); + + return 0; +} + +int lgsm_pb_retrieve_find(struct lgsm_handle *lh, int num) +{ + struct gsmd_msg_hdr *gmh; + int rc; + + gmh = lgsm_gmh_fill(GSMD_MSG_PHONEBOOK, + GSMD_PHONEBOOK_RETRIEVE_FIND, sizeof(int)); + if (!gmh) + return -ENOMEM; + + *(int *)(gmh->data) = num; + + rc = lgsm_send(lh, gmh); + if (rc < gmh->len + sizeof(*gmh)) { + lgsm_gmh_free(gmh); + return -EIO; + } + + lgsm_gmh_free(gmh); + + return 0; +} -- cgit v1.2.3