diff options
Diffstat (limited to 'packages/gsm/files/027_phonebook-find-and-read-range-support.patch')
-rw-r--r-- | packages/gsm/files/027_phonebook-find-and-read-range-support.patch | 423 |
1 files changed, 423 insertions, 0 deletions
diff --git a/packages/gsm/files/027_phonebook-find-and-read-range-support.patch b/packages/gsm/files/027_phonebook-find-and-read-range-support.patch new file mode 100644 index 0000000000..ea0f12daac --- /dev/null +++ b/packages/gsm/files/027_phonebook-find-and-read-range-support.patch @@ -0,0 +1,423 @@ +From: Sean Chiang <sean_chiang@openmoko.com> +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. + +Signed-off-by: Jim Huang <jserv@openmoko.org> +--- + include/gsmd/gsmd.h | 3 + include/gsmd/usock.h | 20 +++- + include/libgsmd/phonebook.h | 6 + + src/gsmd/usock.c | 184 +++++++++++++++++++++++++++++++++++----- + src/libgsmd/libgsmd_phonebook.c | 48 ++++++++++ + 5 files changed, 238 insertions(+), 23 deletions(-) + +Index: gsm/include/libgsmd/phonebook.h +=================================================================== +--- gsm.orig/include/libgsmd/phonebook.h 2007-08-31 16:15:29.000000000 +0800 ++++ gsm/include/libgsmd/phonebook.h 2007-09-17 23:48:41.000000000 +0800 +@@ -106,4 +106,10 @@ + /* 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 +Index: gsm/include/gsmd/gsmd.h +=================================================================== +--- gsm.orig/include/gsmd/gsmd.h 2007-08-31 16:15:29.000000000 +0800 ++++ gsm/include/gsmd/gsmd.h 2007-09-17 23:48:41.000000000 +0800 +@@ -92,6 +92,9 @@ + 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 */ +Index: gsm/include/gsmd/usock.h +=================================================================== +--- gsm.orig/include/gsmd/usock.h 2007-08-31 16:15:29.000000000 +0800 ++++ gsm/include/gsmd/usock.h 2007-09-17 23:48:56.000000000 +0800 +@@ -194,6 +194,8 @@ + 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 */ +@@ -431,7 +433,6 @@ + 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 { +@@ -471,8 +472,18 @@ + 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 */ +@@ -517,6 +528,11 @@ + 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); +Index: gsm/src/libgsmd/libgsmd_phonebook.c +=================================================================== +--- gsm.orig/src/libgsmd/libgsmd_phonebook.c 2007-08-31 16:15:29.000000000 +0800 ++++ gsm/src/libgsmd/libgsmd_phonebook.c 2007-09-17 23:48:41.000000000 +0800 +@@ -33,7 +33,7 @@ + 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 @@ + { + 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; ++} +Index: gsm/src/gsmd/usock.c +=================================================================== +--- gsm.orig/src/gsmd/usock.c 2007-08-31 16:15:30.000000000 +0800 ++++ gsm/src/gsmd/usock.c 2007-09-17 23:53:34.000000000 +0800 +@@ -1035,21 +1035,56 @@ + + 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: <index1>,<number>,<type>,<text>[[...] ++ * <CR><LF>+CPBF: <index2>,<unmber>,<type>,<text>]] ++ */ ++ 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 = (struct gsmd_phonebooks *) malloc(sizeof(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); ++ + return 0; + } + +@@ -1102,22 +1137,51 @@ + { + 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: <index1>,<number>,<type>,<text>[[...] ++ * <CR><LF>+CPBR: <index2>,<unmber>,<type>,<text>]] + */ +- 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; ++ ++ *num = 0; ++ ++ ptr1 = strtok(resp, "\n"); ++ ++ while(ptr1) { ++ gps = (struct gsmd_phonebooks *) malloc(sizeof(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); + +@@ -1209,22 +1273,38 @@ + 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: (<storage>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 @@ + 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 @@ + 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 @@ + 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); |