[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