[RFC] phonebook support

Philipp Zabel philipp.zabel at gmail.com
Tue Mar 27 19:51:09 CEST 2007


Hi,

I wanted to add phonebook reading/writing support to (lib)gsmd, but I
had to notice that I don't fully understand how the internal API between
library and daemon is supposed to be used.

Does GSMD_MSG_PHONEBOOK for all phonebook related calls mean that they
all are supposed to send/receive the same info over the socket?
Currently both read and write functions are given a phonebook entry.
Should the read/write functions take care of setting the correct
phonebook type if it is given in the pb_entry, too?
What about the phonebook type_of_number field. Is this supposed to be
low-level information that can stay in gsmd or does it have to be
exposed to libgsmd / users of libgsmd even?

Attached is my work in progress. Does this look like it is heading the
right way?

cheers
Philipp

Index: gsm/src/libgsmd/libgsmd_phonebook.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gsm/src/libgsmd/libgsmd_phonebook.c	2007-03-27 19:38:26.000000000 +0200
@@ -0,0 +1,81 @@
+/* libgsmd phonebook related functions
+ *
+ * Written by Philipp Zabel <philipp.zabel at gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */ 
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <libgsmd/libgsmd.h>
+#include <libgsmd/phonebook.h>
+
+#include <gsmd/usock.h>
+#include <gsmd/event.h>
+
+#include "lgsm_internals.h"
+
+static char phonebook_buf[sizeof(struct gsmd_msg_hdr)+sizeof(struct gsmd_phonebook)];
+static char phonebook_rbuf[sizeof(struct gsmd_msg_hdr)+sizeof(struct gsmd_phonebook)];
+
+/* Get a bitmask of supported phonebook types */
+int lgsm_pb_get_types(struct lgsm_handle *lh, u_int32 *typemask)
+{
+	/* FIXME */
+}
+
+/* Get a range of supported indexes in given phonebook type, Chapter 8.12 */
+int lgsm_pb_get_range(struct lgsm_handle *lh,
+		      enum lgsm_pbook_type type,
+		      u_int32_t *from, u_int32_t *to,
+		      u_int32_t *nlength, *u_int32_t tlength)
+{
+	/* FIXME */
+}
+
+/* Get a specific phonebook entry  and store it to 'pb'
+ * pb' is caller-allocated */
+int lgsm_pb_get_entry(struct lgsm_handle *lh,
+		      struct lgsm_pb_entry *pb)
+{
+	struct gsmd_msg_hdr *gmh = (struct gsmd_msg_hdr *)phonebook_rbuf;
+	struct gsmd_phonebook *pbook = (struct gsmd_phonebook *)gmh->data;
+
+	pbook->index = pb->index;
+
+	gmh->version = GSMD_PROTO_VERSION;
+	gmh->msg_type = GSMD_MSG_PHONEBOOK;
+	gmh->msg_subtype = GSMD_PHONEBOOK_READ;
+	gmh->len = sizeof(struct gsmd_phonebook);
+
+	if (lgsm_send(lh, gmh) < len+sizeof(*gmh))
+		return -EIO;
+
+	strcpy(pb->number, pbook->number);
+	pb->type = pbook->type;
+	strcpy(pb->text, pbook->text);
+	return gmh->id;
+}
+
+/* Store a specific phonebook entry 'pb' into phone */
+int lgsm_pb_set_entry(struct lgsm_handle *lh,
+		      struct lgsm_pb_entry *pb)
+{
+//	return lgsm_send_simple(lh, GSMD_MSG_PHONEBOOK, GSMD_PHONEBOOK_WRITE);
+	return 0;
+}
Index: gsm/src/libgsmd/Makefile.am
===================================================================
--- gsm.orig/src/libgsmd/Makefile.am	2007-03-27 18:20:16.000000000 +0200
+++ gsm/src/libgsmd/Makefile.am	2007-03-27 18:20:46.000000000 +0200
@@ -5,6 +5,6 @@
 lib_LTLIBRARIES = libgsmd.la
 
 libgsmd_la_LDFLAGS = -Wc,-nostartfiles -version-info $(LIBVERSION)
-libgsmd_la_SOURCES = libgsmd.c libgsmd_input.c libgsmd_voicecall.c libgsmd_passthrough.c libgsmd_event.c libgsmd_phone.c libgsmd_network.c libgsmd_pin.c
+libgsmd_la_SOURCES = libgsmd.c libgsmd_input.c libgsmd_voicecall.c libgsmd_passthrough.c libgsmd_event.c libgsmd_phone.c libgsmd_phonebook.c libgsmd_network.c libgsmd_pin.c
 
 noinst_HEADERS = lgsm_internals.h
Index: gsm/include/gsmd/usock.h
===================================================================
--- gsm.orig/include/gsmd/usock.h	2007-03-27 18:31:12.000000000 +0200
+++ gsm/include/gsmd/usock.h	2007-03-27 19:39:08.000000000 +0200
@@ -54,6 +54,13 @@
 	GSMD_PHONE_POWERDOWN	= 2,
 };
 
+enum gsmd_msg_phonebook {
+	GSMD_PHONEBOOK_SELECT	= 1,
+	GSMD_PHONEBOOK_RANGE	= 2,
+	GSMD_PHONEBOOK_READ	= 3,
+	GSMD_PHONEBOOK_WRITE	= 4,
+};
+
 enum gsmd_msg_network {
 	GSMD_NETWORK_REGISTER	= 1,
 	GSMD_NETWORK_SIGQ_GET	= 2,
@@ -86,6 +93,15 @@
 	struct gsmd_addr addr;
 } __attribute__ ((packed));
 
+#define GSMD_PB_NUMBER_MAXLEN	44
+#define GSMD_PB_TEXT_MAXLEN	31
+struct gsmd_phonebook {
+	u_int32_t index;
+	char number[GSMD_PB_NUMBER_MAXLEN+1];
+	u_int8_t type;
+	char text[GSMD_PB_TEXT_MAXLEN+1]
+} __attribute__ ((packed));
+
 #define GSMD_PIN_MAXLEN		8
 struct gsmd_pin {
 	enum gsmd_pin_type type;
Index: gsm/include/libgsmd/phonebook.h
===================================================================
--- gsm.orig/include/libgsmd/phonebook.h	2007-03-27 18:56:24.000000000 +0200
+++ gsm/include/libgsmd/phonebook.h	2007-03-27 19:03:46.000000000 +0200
@@ -29,12 +29,14 @@
 			     u_int32_t *from, u_int32_t *to,
 			     u_int32_t *nlength, *u_int32_t tlength);
 
+#define LGSM_PB_NUMBER_MAXLEN	44
 #define LGSM_PB_TEXT_MAXLEN	31
 
 struct lgsm_pb_entry {
 	struct lgsm_pb_entry	*next;
 	enum lgsm_pbook_type 	type;
 	u_int32_t 		index;
+	char 			number[LGSM_PB_NUMBER_MAXLEN+1];
 	char 			text[LGSM_PB_TEXT_MAXLEN+1];
 };
 
Index: gsm/src/gsmd/usock.c
===================================================================
--- gsm.orig/src/gsmd/usock.c	2007-03-27 18:36:43.000000000 +0200
+++ gsm/src/gsmd/usock.c	2007-03-27 19:40:05.000000000 +0200
@@ -263,6 +263,104 @@
 	return atcmd_submit(gu->gsmd, cmd);
 }
 
+static int phonebook_entry_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
+{
+	struct gsmd_user *gu = ctx;
+	struct gsmd_phonebook *pbook;
+	struct gsmd_ucmd *ucmd;
+	char *comma;
+
+	DEBUGP("entering(cmd=%p, gu=%p)\n", cmd, gu);
+
+	ucmd = ucmd_alloc(sizeof(*pbook));
+	if (!ucmd)
+		return -ENOMEM;
+	
+	/* FIXME: pass error values back somehow */
+	ucmd->hdr.version = GSMD_PROTO_VERSION;
+	ucmd->hdr.msg_type = GSMD_MSG_PHONEBOOK;
+	ucmd->hdr.len = sizeof(*pbook);
+	ucmd->hdr.id = cmd->id;
+
+	if (cmd->buf[6] == 'W') {
+		/* response to write command */
+		ucmd->hdr.msg_subtype = GSMD_PHONEBOOK_WRITE;
+		/* FIXME: */
+		return 0;
+	} else {
+		/* response to read command */
+		char *tok = strtok(resp, ",");
+		if (!tok)
+			goto out_free_einval;
+		ucmd->hdr.msg_subtype = GSMD_PHONEBOOK_READ;
+		pbook->index = atoi(tok);
+
+		tok = strtok(NULL, ",");
+		if (!tok)
+			goto out_free_einval;
+		strncpy(pbook->number, tok, GSMD_PB_NUMBER_MAXLEN);
+		pbook->number[GSMD_PB_NUMBER_MAXLEN] = '\0';
+
+		tok = strtok(NULL, ",");
+		if (!tok)
+			goto out_free_einval;
+		pbook->type = atoi(tok);
+
+		tok = strtok(NULL, ",");
+		if (!tok)
+			goto out_free_einval;
+		strncpy(pbook->text, tok, GSMD_PB_TEXT_MAXLEN);
+		pbook->text[GSMD_PB_TEXT_MAXLEN] = '\0';
+	}
+
+	usock_cmd_enqueue(ucmd, gu);
+
+	return 0;
+
+out_free_einval:
+	gsmd_log(GSMD_ERROR, "can't understand phonebook response\n");
+	talloc_free(ucmd);
+	return -EINVAL;
+}
+
+static int usock_rcv_phonebook(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, 
+			     int len)
+{
+	struct gsmd_atcmd *cmd;
+	struct gsmd_phonebook *pbook = (struct gsmd_phonebook *) gph->data;
+
+	switch (gph->msg_subtype) {
+	case GSMD_PHONEBOOK_SELECT:
+		/* FIXME, implement +CPBS */
+		break;
+	case GSMD_PHONEBOOK_RANGE:
+		/* FIXME, implement +CPBR=? */
+		break;
+	case GSMD_PHONEBOOK_READ:
+		cmd = atcmd_fill("AT+CPBR=", 8+1+3, &phonebook_entry_cb, gu, 0);
+		snprintf(cmd->buf+8, 3, "%d", pbook->index);
+		break;
+	case GSMD_PHONEBOOK_WRITE:
+		cmd = atcmd_fill("AT+CPBW=", 8+3+1+GSMD_PB_NUMBER_MAXLEN+2+3+2+GSMD_PB_TEXT_MAXLEN+2,
+				 &phonebook_entry_cb, gu, 0);
+		snprintf(cmd->buf+8, 3, "%d", pbook->index);
+		strcat(cmd->buf, ",\"");
+		strcat(cmd->buf, pbook->number);
+		strcat(cmd->buf, "\",");
+		snprintf(cmd->buf+strlen(cmd->buf), 3, "%d", pbook->type);
+		strcat(cmd->buf, ",\"");
+		strcat(cmd->buf, pbook->text);
+		strcat(cmd->buf, "\"");
+		break;
+	default:
+		return -EINVAL;
+	}
+	if (!cmd)
+		return -ENOMEM;
+
+	return atcmd_submit(gu->gsmd, cmd);
+}
+
 static int network_vmail_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
 {
 	struct gsmd_user *gu = ctx;
@@ -419,6 +517,7 @@
 	[GSMD_MSG_VOICECALL]	= &usock_rcv_voicecall,
 	[GSMD_MSG_PIN]		= &usock_rcv_pin,
 	[GSMD_MSG_PHONE]	= &usock_rcv_phone,
+	[GSMD_MSG_PHONEBOOK]	= &usock_rcv_phonebook,
 	[GSMD_MSG_NETWORK]	= &usock_rcv_network,
 };
 





More information about the gsmd-devel mailing list