summaryrefslogtreecommitdiff
path: root/packages/gsm/files/027_phonebook-find-and-read-range-support.patch
diff options
context:
space:
mode:
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.patch423
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);