424 lines
11 KiB
Diff
424 lines
11 KiB
Diff
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);
|