r114 - in trunk/src/target/gsm: include/gsmd include/libgsmd src/gsmd src/libgsmd src/util

laforge at gta01.hmw-consulting.de laforge at gta01.hmw-consulting.de
Mon Oct 23 22:28:39 CEST 2006


Author: laforge
Date: 2006-10-23 20:28:37 +0000 (Mon, 23 Oct 2006)
New Revision: 114

Added:
   trunk/src/target/gsm/src/libgsmd/libgsmd_event.c
   trunk/src/target/gsm/src/util/event.c
   trunk/src/target/gsm/src/util/event.h
   trunk/src/target/gsm/src/util/pin.c
   trunk/src/target/gsm/src/util/pin.h
Modified:
   trunk/src/target/gsm/include/gsmd/event.h
   trunk/src/target/gsm/include/gsmd/usock.h
   trunk/src/target/gsm/include/libgsmd/event.h
   trunk/src/target/gsm/include/libgsmd/libgsmd.h
   trunk/src/target/gsm/src/gsmd/gsmd.h
   trunk/src/target/gsm/src/gsmd/unsolicited.c
   trunk/src/target/gsm/src/gsmd/usock.c
   trunk/src/target/gsm/src/libgsmd/Makefile.am
   trunk/src/target/gsm/src/libgsmd/lgsm_internals.h
   trunk/src/target/gsm/src/libgsmd/libgsmd.c
   trunk/src/target/gsm/src/libgsmd/libgsmd_passthrough.c
   trunk/src/target/gsm/src/libgsmd/libgsmd_voicecall.c
   trunk/src/target/gsm/src/util/Makefile.am
   trunk/src/target/gsm/src/util/libgsmd-tool.c
   trunk/src/target/gsm/src/util/shell.c
Log:
more gsmd/libgsm implementation


Modified: trunk/src/target/gsm/include/gsmd/event.h
===================================================================
--- trunk/src/target/gsm/include/gsmd/event.h	2006-10-23 15:11:34 UTC (rev 113)
+++ trunk/src/target/gsm/include/gsmd/event.h	2006-10-23 20:28:37 UTC (rev 114)
@@ -14,6 +14,7 @@
 	GSMD_EVT_OUT_COLP	= 9,	/* Outgoing COLP */
 	GSMD_EVT_CALL_WAIT	= 10,	/* Call Waiting */
 	GSMD_EVT_TIMEZONE	= 11,	/* Timezone change */
+	GSMD_EVT_SUBSCRIPTIONS	= 12,	/* To which events are we subscribed to */
 	__NUM_GSMD_EVT
 };
 

Modified: trunk/src/target/gsm/include/gsmd/usock.h
===================================================================
--- trunk/src/target/gsm/include/gsmd/usock.h	2006-10-23 15:11:34 UTC (rev 113)
+++ trunk/src/target/gsm/include/gsmd/usock.h	2006-10-23 20:28:37 UTC (rev 114)
@@ -30,15 +30,10 @@
 	GSMD_PASSTHROUGH_RESP	= 2,
 };
 
-enum gsmd_event_type {
-	GSMD_EVENT_NONE		= 0,
-	GSMD_EVENT_SUBSCRIPTIONS= 1,
-	GSMD_EVENT_HAPPENED	= 2,
-};
-
 enum gsmd_msg_voicecall_type {
 	GSMD_VOICECALL_DIAL	= 1,
 	GSMD_VOICECALL_HANGUP	= 2,
+	GSMD_VOICECALL_ANSWER	= 3,
 };
 
 /* Handset / MT related commands */
@@ -53,7 +48,7 @@
 
 /* Length from 3GPP TS 04.08, Clause 10.5.4.7 */
 
-#define GSMD_ADDR_MAXLEN	13
+#define GSMD_ADDR_MAXLEN	32
 struct gsmd_addr {
 	u_int8_t type;
 	char number[GSMD_ADDR_MAXLEN+1];
@@ -95,6 +90,7 @@
 	u_int8_t _pad;
 	u_int16_t id;
 	u_int16_t len;
+	u_int8_t data[];
 } __attribute__((packed));
 
 

Modified: trunk/src/target/gsm/include/libgsmd/event.h
===================================================================
--- trunk/src/target/gsm/include/libgsmd/event.h	2006-10-23 15:11:34 UTC (rev 113)
+++ trunk/src/target/gsm/include/libgsmd/event.h	2006-10-23 20:28:37 UTC (rev 114)
@@ -4,11 +4,15 @@
 #include <gsmd/event.h>
 
 /* Prototype of libgsmd callback handler function */
-typedef int evt_cb_func(struct lgsm_handle *lh, enum gsmd_events evt, 
-			void *user);
+typedef int lgsm_evt_handler(struct lgsm_handle *lh, int evt_type, struct gsmd_evt_auxdata *aux);
 
 /* Register an event callback handler with libgsmd */
-extern int lgsm_register_evt_cb(struct lgsm_handle *lh, 
-				evt_cb_func *cb, void *user);
+extern int lgsm_evt_handler_register(struct lgsm_handle *lh, int evt_type,
+				     lgsm_evt_handler *handler);
+extern void lgsm_evt_handler_unregister(struct lgsm_handle *lh, int evt_type);
 
+extern int lgsm_evt_init(struct lgsm_handle *lh);
+extern void lgsm_evt_exit(struct lgsm_handle *lh);
+
+
 #endif

Modified: trunk/src/target/gsm/include/libgsmd/libgsmd.h
===================================================================
--- trunk/src/target/gsm/include/libgsmd/libgsmd.h	2006-10-23 15:11:34 UTC (rev 113)
+++ trunk/src/target/gsm/include/libgsmd/libgsmd.h	2006-10-23 20:28:37 UTC (rev 114)
@@ -9,6 +9,8 @@
 #include <sys/types.h>
 #include <errno.h>
 
+#include <gsmd/usock.h>
+
 /* Generic Information
  *
  * Return value:
@@ -28,6 +30,21 @@
 /* Opaque data structure, content only known to libgsm implementation */
 struct lgsm_handle;
 
+/* Refer to GSM 04.08 [8] subclause 10.5.4.7 */
+enum lgsm_addr_type {
+	LGSM_ATYPE_ISDN_UNKN		= 161,
+	//LGSM_ATYPE_ISDN_INTL		= ,
+	//LGSM_ATYPE_ISDN_NATIONAL	= ,
+};
+
+#define LGSM_ADDR_MAXLEN	31
+struct lgsm_addr {
+	enum lgsm_addr_type type;
+	char addr[LGSM_ADDR_MAXLEN+1];
+};
+
+typedef int lgsm_msg_handler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh);
+
 #define LGSMD_DEVICE_GSMD	"gsmd"
 
 /* initialize usage of libgsmd, obtain handle for othe API calls */
@@ -39,18 +56,12 @@
 /* Obtain file descriptor (e.g. for select-loop under app control) */
 extern int lgsm_fd(struct lgsm_handle *lh);
 
-/* Refer to GSM 04.08 [8] subclause 10.5.4.7 */
-enum lgsm_addr_type {
-	LGSM_ATYPE_ISDN_UNKN		= 161,
-	//LGSM_ATYPE_ISDN_INTL		= ,
-	//LGSM_ATYPE_ISDN_NATIONAL	= ,
-};
+extern int lgsm_register_handler(struct lgsm_handle *lh, int type, lgsm_msg_handler *handler);
+extern void lgsm_unregister_handler(struct lgsm_handle *lh, int type);
 
-#define LGSM_ADDR_MAXLEN	31
-struct lgsm_addr {
-	char addr[LGSM_ADDR_MAXLEN+1];
-	enum lgsm_addr_type tyoe;
-};
+extern int lgsm_passthrough_send(struct lgsm_handle *lh, const char *tx);
+extern int lgsm_passthrough(struct lgsm_handle *lh, const char *tx, char *rx, unsigned int *rx_len);
+extern int lgsm_subscriptions(struct lgsm_handle *lh, u_int32_t subscriptions);
 
-extern int lgsm_passthrough(struct lgsm_handle *lh, const char *tx, char *rx, unsigned int *rx_len);
+extern int lgsm_pin(struct lgsm_handle *lh, char *pin);
 #endif

Modified: trunk/src/target/gsm/src/gsmd/gsmd.h
===================================================================
--- trunk/src/target/gsm/src/gsmd/gsmd.h	2006-10-23 15:11:34 UTC (rev 113)
+++ trunk/src/target/gsm/src/gsmd/gsmd.h	2006-10-23 20:28:37 UTC (rev 114)
@@ -76,7 +76,7 @@
 /* write a message to the daemons' logfile */
 void __gsmd_log(int level, const char *file, int line, const char *function, const char *message, ...);
 /* macro for logging including filename and line number */
-#define gsmd_log(level, format, args...) \
+#define gsmd_log(level, format, args ...) \
 	__gsmd_log(level, __FILE__, __LINE__, __FUNCTION__, format, ## args)
 
 #define DEBUGP(x, args ...)	gsmd_log(GSMD_DEBUG, x, ## args)

Modified: trunk/src/target/gsm/src/gsmd/unsolicited.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/unsolicited.c	2006-10-23 15:11:34 UTC (rev 113)
+++ trunk/src/target/gsm/src/gsmd/unsolicited.c	2006-10-23 20:28:37 UTC (rev 114)
@@ -217,6 +217,7 @@
 
 	if (!comma)
 		return -EINVAL;
+
 	
 	if (comma - param > GSMD_ADDR_MAXLEN)
 		return -EINVAL;
@@ -308,7 +309,7 @@
 /* called by midlevel parser if a response seems unsolicited */
 int unsolicited_parse(struct gsmd *g, char *buf, int len, const char *param)
 {
-	int i;
+	int i, rc;
 
 	for (i = 0; i < ARRAY_SIZE(gsm0707_unsolicit); i++) {
 		const char *colon;
@@ -316,14 +317,20 @@
 			     strlen(gsm0707_unsolicit[i].prefix)))
 			continue;
 		
-		colon = strchr(buf, ':') + 1;
+		colon = strchr(buf, ':') + 2;
 		if (colon > buf+len)
 			colon = NULL;
 
-		return gsm0707_unsolicit[i].parse(buf, len, colon, g);
+		rc = gsm0707_unsolicit[i].parse(buf, len, colon, g);
+		if (rc < 0) 
+			gsmd_log(GSMD_ERROR, "error %d during parse of "
+				 "unsolicied response `%s'\n", rc, buf);
+		return rc;
 	}
 
 	/* FIXME: call vendor-specific unsolicited code parser */
+	gsmd_log(GSMD_NOTICE, "no parser for unsolicited response `%s'\n", buf);
+
 	return -ENOENT;
 }
 

Modified: trunk/src/target/gsm/src/gsmd/usock.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/usock.c	2006-10-23 15:11:34 UTC (rev 113)
+++ trunk/src/target/gsm/src/gsmd/usock.c	2006-10-23 20:28:37 UTC (rev 114)
@@ -30,13 +30,15 @@
 static int usock_cmd_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
 {
 	struct gsmd_user *gu = ctx;
-	struct gsmd_ucmd *ucmd = malloc(sizeof(*ucmd)+cmd->buflen);
+	int rlen = strlen(resp)+1;
+	struct gsmd_ucmd *ucmd = malloc(sizeof(*ucmd)+rlen);
 
 	DEBUGP("entering(cmd=%p, gu=%p)\n", cmd, gu);
 
 	if (!ucmd)
 		return -ENOMEM;
 	
+	/* FIXME: pass error values back somehow */
 	ucmd->hdr.version = GSMD_PROTO_VERSION;
 	ucmd->hdr.msg_type = GSMD_MSG_PASSTHROUGH;
 	ucmd->hdr.msg_subtype = GSMD_PASSTHROUGH_RESP;
@@ -70,49 +72,77 @@
 	if (len < sizeof(*gph) + sizeof(u_int32_t))
 		return -EINVAL;
 
-	if (gph->msg_subtype != GSMD_EVENT_SUBSCRIPTIONS)
+	if (gph->msg_subtype != GSMD_EVT_SUBSCRIPTIONS)
 		return -EINVAL;
 
 	gu->subscriptions = *evtmask;
 }
 
-static int usock_rcv_voicecall(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int len)
+static int usock_rcv_voicecall(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
+				int len)
 {
-	struct gsmd_atcmd *cmd;
+	struct gsmd_atcmd *cmd = NULL;
+	struct gsmd_addr *ga;
 
 	switch (gph->msg_subtype) {
 	case GSMD_VOICECALL_DIAL:
-		/* FIXME */
+		if (len < sizeof(*gph) + sizeof(*ga))
+			return -EINVAL;
+		ga = (struct gsmd_addr *) (void *)gph + sizeof(*gph);
+		ga->number[GSMD_ADDR_MAXLEN] = '\0';
+		cmd = atcmd_fill("ATD", 5 + strlen(ga->number),
+				 &usock_cmd_cb, gu, gph->id);
+		sprintf(cmd->buf, "ATD%s;", ga->number);
+		/* FIXME: number type! */
 		break;
 	case GSMD_VOICECALL_HANGUP:
 		cmd = atcmd_fill("ATH0", 5, &usock_cmd_cb, gu, gph->id);
 		break;
+	case GSMD_VOICECALL_ANSWER:
+		cmd = atcmd_fill("ATA", 4, &usock_cmd_cb, gu, gph->id);
+		break;
 	default:
 		return -EINVAL;
 	}
 
+	if (cmd)
+		return atcmd_submit(gu->gsmd, cmd);
+	else
+		return 0;
+}
+
+static int null_cmd_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
+{
+	gsmd_log(GSMD_DEBUG, "null cmd cb\n");
 	return 0;
 }
 
-#define GSMD_PIN_MAXLEN 16
-
-static int usock_rcv_pin(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int len)
+static int usock_rcv_pin(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, 
+			 int len)
 {
 	u_int8_t *pin = (u_int8_t *)gph + sizeof(*gph);
 	int pin_len = len - sizeof(*gph);
-	char pinbuf[GSMD_PIN_MAXLEN + 11]; /* `AT+CPIN=""\0' */
+	struct gsmd_atcmd *cmd;
 
-	snprintf(pinbuf, sizeof(pinbuf), "AT+CPIN=\"%s\"", pin);
-
 	switch (gph->msg_subtype) {
 	case GSMD_PIN_INPUT:
 		/* FIXME */
 		break;
 	default:
+		gsmd_log(GSMD_ERROR, "unknown pin type %u\n",
+			 gph->msg_subtype);
 		return -EINVAL;
 	}
 
-	return 0;
+	cmd = atcmd_fill("AT+CPIN=\"", 9+1+1+strlen(pin),
+			 &null_cmd_cb, gu, 0);
+	if (!cmd)
+		return -ENOMEM;
+
+	strcat(cmd->buf, pin);
+	strcat(cmd->buf, "\"");
+
+	return atcmd_submit(gu->gsmd, cmd);
 }
 
 static usock_msg_handler *pcmd_type_handlers[__NUM_GSMD_MSGS] = {

Modified: trunk/src/target/gsm/src/libgsmd/Makefile.am
===================================================================
--- trunk/src/target/gsm/src/libgsmd/Makefile.am	2006-10-23 15:11:34 UTC (rev 113)
+++ trunk/src/target/gsm/src/libgsmd/Makefile.am	2006-10-23 20:28:37 UTC (rev 114)
@@ -5,5 +5,5 @@
 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_la_SOURCES = libgsmd.c libgsmd_input.c libgsmd_voicecall.c libgsmd_passthrough.c libgsmd_event.c
 

Modified: trunk/src/target/gsm/src/libgsmd/lgsm_internals.h
===================================================================
--- trunk/src/target/gsm/src/libgsmd/lgsm_internals.h	2006-10-23 15:11:34 UTC (rev 113)
+++ trunk/src/target/gsm/src/libgsmd/lgsm_internals.h	2006-10-23 20:28:37 UTC (rev 114)
@@ -3,11 +3,13 @@
 
 #include <gsmd/usock.h>
 
-typedef int lgsm_msg_handler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh);
-
 struct lgsm_handle {
 	int fd;
 	lgsm_msg_handler *handler[__NUM_GSMD_MSGS];
 };
 
+int lgsm_send(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh);
+struct gsmd_msg_hdr *lgsm_gmh_fill(int type, int subtype, int payload_len);
+#define lgsm_gmh_free(x)	free(x)
+
 #endif /* _LGSM_INTERNALS_H */

Modified: trunk/src/target/gsm/src/libgsmd/libgsmd.c
===================================================================
--- trunk/src/target/gsm/src/libgsmd/libgsmd.c	2006-10-23 15:11:34 UTC (rev 113)
+++ trunk/src/target/gsm/src/libgsmd/libgsmd.c	2006-10-23 20:28:37 UTC (rev 114)
@@ -87,6 +87,22 @@
 		fprintf(stderr, "unable to handle packet type=%u\n", gmh->msg_type);
 }
 
+int lgsm_register_handler(struct lgsm_handle *lh, int type, lgsm_msg_handler *handler)
+{
+	if (type >= __NUM_GSMD_MSGS)
+		return -EINVAL;
+
+	lh->handler[type] = handler;
+
+	return 0;
+}
+
+void lgsm_unregister_handler(struct lgsm_handle *lh, int type)
+{
+	if (type < __NUM_GSMD_MSGS)
+		lh->handler[type] = NULL;
+}
+
 /* blocking read and processing of packets until packet matching 'id' is found */
 int lgsm_blocking_wait_packet(struct lgsm_handle *lh, u_int16_t id, 
 			      struct gsmd_msg_hdr *gmh, int rlen)
@@ -131,6 +147,8 @@
 		return NULL;
 	}
 
+	lgsm_evt_init(lh);
+
 	return lh;
 }
 
@@ -140,3 +158,47 @@
 
 	return 0;
 }
+
+
+static u_int16_t next_msg_id;
+
+int lgsm_send(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
+{
+	gmh->id = next_msg_id++;
+	return send(lh->fd, (char *) gmh, sizeof(*gmh) + gmh->len, 0);
+}
+
+struct gsmd_msg_hdr *lgsm_gmh_fill(int type, int subtype, int payload_len)
+{
+	struct gsmd_msg_hdr *gmh = malloc(sizeof(*gmh)+payload_len);
+	if (!gmh)
+		return NULL;
+
+	memset(gmh, 0, sizeof(*gmh));
+
+	gmh->version = GSMD_PROTO_VERSION;
+	gmh->msg_type = type;
+	gmh->msg_subtype = subtype;
+	gmh->len = payload_len;
+
+	return gmh;
+}
+
+
+int lgsm_pin(struct lgsm_handle *lh, char *pin)
+{
+	int rc;
+	struct gsmd_msg_hdr *gmh;
+
+	gmh = lgsm_gmh_fill(GSMD_MSG_PIN, GSMD_PIN_INPUT, strlen(pin)+1);
+	if (!gmh)
+		return -ENOMEM;
+
+	gmh->data[0] = '\0';
+	strcat(gmh->data, pin);
+
+	rc = lgsm_send(lh, gmh);
+	free(gmh);
+
+	return rc;
+}

Added: trunk/src/target/gsm/src/libgsmd/libgsmd_event.c
===================================================================
--- trunk/src/target/gsm/src/libgsmd/libgsmd_event.c	2006-10-23 15:11:34 UTC (rev 113)
+++ trunk/src/target/gsm/src/libgsmd/libgsmd_event.c	2006-10-23 20:28:37 UTC (rev 114)
@@ -0,0 +1,57 @@
+/* libgsmd event demultiplexer handler */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <libgsmd/voicecall.h>
+#include <libgsmd/event.h>
+
+#include <gsmd/usock.h>
+#include <gsmd/event.h>
+
+#include "lgsm_internals.h"
+
+static lgsm_evt_handler *evt_handlers[__NUM_GSMD_EVT];
+
+int lgsm_evt_handler_register(struct lgsm_handle *lh, int evt_type,
+			      lgsm_evt_handler *handler)
+{
+	if (evt_type >= __NUM_GSMD_EVT)
+		return -EINVAL;
+
+	evt_handlers[evt_type] = handler;
+
+	return 0;
+}
+
+void lgsm_evt_handler_unregister(struct lgsm_handle *lh, int evt_type)
+{
+	if (evt_type < __NUM_GSMD_EVT)
+		evt_handlers[evt_type] = NULL;
+}
+
+
+static int evt_demux_msghandler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
+{
+	struct gsmd_evt_auxdata *aux = gmh->data;
+
+	if (gmh->len < sizeof(*aux))
+		return -EIO;
+	
+	if (gmh->msg_type != GSMD_MSG_EVENT || 
+	    gmh->msg_subtype >= __NUM_GSMD_EVT)
+		return -EINVAL;
+
+	return evt_handlers[gmh->msg_subtype](lh, gmh->msg_subtype, aux);
+}
+
+int lgsm_evt_init(struct lgsm_handle *lh)
+{
+	return lgsm_register_handler(lh, GSMD_MSG_EVENT, &evt_demux_msghandler);
+}
+
+void lgsm_evt_exit(struct lgsm_handle *lh)
+{
+	lgsm_unregister_handler(lh, GSMD_MSG_EVENT);
+}

Modified: trunk/src/target/gsm/src/libgsmd/libgsmd_passthrough.c
===================================================================
--- trunk/src/target/gsm/src/libgsmd/libgsmd_passthrough.c	2006-10-23 15:11:34 UTC (rev 113)
+++ trunk/src/target/gsm/src/libgsmd/libgsmd_passthrough.c	2006-10-23 20:28:37 UTC (rev 114)
@@ -12,26 +12,15 @@
 
 #include "lgsm_internals.h"
 
-static u_int16_t next_msg_id;
-
-static int lgsm_send(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
-{
-	gmh->id = next_msg_id++;
-	return send(lh->fd, (char *) gmh, sizeof(*gmh) + gmh->len, 0);
-}
-
 #define PT_BUF_SIZE	1024
 static char passthrough_buf[sizeof(struct gsmd_msg_hdr)+PT_BUF_SIZE];
 static char passthrough_rbuf[sizeof(struct gsmd_msg_hdr)+PT_BUF_SIZE];
 
-int lgsm_passthrough(struct lgsm_handle *lh, const char *tx, char *rx, unsigned int *rx_len)
+int lgsm_passthrough_send(struct lgsm_handle *lh, const char *tx)
 {
 	struct gsmd_msg_hdr *gmh = (struct gsmd_msg_hdr *)passthrough_buf;
-	struct gsmd_msg_hdr *rgmh = (struct gsmd_msg_hdr *)passthrough_rbuf;
 	char *tx_buf = (char *)gmh + sizeof(*gmh);
-	char *rx_buf = (char *)rgmh + sizeof(*rgmh);
 	int len = strlen(tx);
-	int rc;
 
 	if (len > PT_BUF_SIZE)
 		return -EINVAL;
@@ -42,13 +31,27 @@
 	gmh->len = len+1;
 	strcpy(tx_buf, tx);
 
-	rc = lgsm_send(lh, gmh);
-	if (rc < len+sizeof(*gmh))
+	if (lgsm_send(lh, gmh) < len+sizeof(*gmh))
+		return -EIO;
+
+	return gmh->id;
+}
+
+int lgsm_passthrough(struct lgsm_handle *lh, const char *tx, char *rx, unsigned int *rx_len)
+{
+	struct gsmd_msg_hdr *rgmh = (struct gsmd_msg_hdr *)passthrough_rbuf;
+	char *rx_buf = (char *)rgmh + sizeof(*rgmh);
+	int rc;
+
+	rc = lgsm_passthrough_send(lh, tx);
+	if (rc < 0)
 		return rc;
 
-	/* since we synchronously want to wait for a response, we need to _internally_ loop over
-	 * incoming packets and call the callbacks for intermediate messages (if applicable) */
-	rc = lgsm_blocking_wait_packet(lh, gmh->id, passthrough_rbuf, sizeof(passthrough_rbuf));
+	/* since we synchronously want to wait for a response, we need to
+	 * _internally_ loop over incoming packets and call the callbacks for
+	 * intermediate messages (if applicable) */
+	rc = lgsm_blocking_wait_packet(lh, rc, passthrough_rbuf, 
+					sizeof(passthrough_rbuf));
 	if (rc <= 0)
 		return rc;
 

Modified: trunk/src/target/gsm/src/libgsmd/libgsmd_voicecall.c
===================================================================
--- trunk/src/target/gsm/src/libgsmd/libgsmd_voicecall.c	2006-10-23 15:11:34 UTC (rev 113)
+++ trunk/src/target/gsm/src/libgsmd/libgsmd_voicecall.c	2006-10-23 20:28:37 UTC (rev 114)
@@ -1,24 +1,62 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
 
-
 #include <libgsmd/voicecall.h>
 
 #include "lgsm_internals.h"
 
+int lgsm_send_simple(struct lgsm_handle *lh, int type, int sub_type)
+{
+	struct gsmd_msg_hdr *gmh;
+	int rc;
 
+	gmh = lgsm_gmh_fill(type, sub_type, 0);
+	if (!gmh)
+		return -ENOMEM;
+	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_voice_out_init(struct lgsm_handle *lh,
 			const struct lgsm_addr *number)
 {
-	/* send ATD command */
-	return -EINVAL;
+	struct gsmd_msg_hdr *gmh;
+	struct gsmd_addr *ga;
+	int rc;
+
+	gmh = lgsm_gmh_fill(GSMD_MSG_VOICECALL,
+			    GSMD_VOICECALL_DIAL, sizeof(*ga));
+	if (!gmh)
+		return -ENOMEM;
+	ga = (struct gsmd_addr *) gmh->data;
+	ga->type = number->type;	/* FIXME: is this correct? */
+	memcpy(ga->number, number->addr, sizeof(ga->number));
+	ga->number[sizeof(ga->number)-1] = '\0';
+
+	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_voice_in_accept(struct lgsm_handle *lh)
 {
-	return -EINVAL;
+	return lgsm_send_simple(lh, GSMD_MSG_VOICECALL, GSMD_VOICECALL_ANSWER);
 }
 
 int lgsm_voice_hangup(struct lgsm_handle *lh)
 {
-	/* Send ATH0 */
-	return -EINVAL;
+	return lgsm_send_simple(lh, GSMD_MSG_VOICECALL, GSMD_VOICECALL_HANGUP);
 }

Modified: trunk/src/target/gsm/src/util/Makefile.am
===================================================================
--- trunk/src/target/gsm/src/util/Makefile.am	2006-10-23 15:11:34 UTC (rev 113)
+++ trunk/src/target/gsm/src/util/Makefile.am	2006-10-23 20:28:37 UTC (rev 114)
@@ -3,7 +3,7 @@
 
 bin_PROGRAMS = libgsmd-tool
 
-libgsmd_tool_SOURCES = libgsmd-tool.c shell.c
+libgsmd_tool_SOURCES = libgsmd-tool.c shell.c event.c pin.c
 libgsmd_tool_LDADD = ../libgsmd/libgsmd.la
 libgsmd_tool_LDFLAGS = -dynamic
 

Added: trunk/src/target/gsm/src/util/event.c
===================================================================
--- trunk/src/target/gsm/src/util/event.c	2006-10-23 15:11:34 UTC (rev 113)
+++ trunk/src/target/gsm/src/util/event.c	2006-10-23 20:28:37 UTC (rev 114)
@@ -0,0 +1,38 @@
+#include <stdio.h>
+#include <string.h>
+
+#include <libgsmd/libgsmd.h>
+#include <libgsmd/event.h>
+
+static int incall_handler(struct lgsm_handle *lh, int evt, struct gsmd_evt_auxdata *aux)
+{
+	printf("EVENT: Incoming call type=%u!\n", aux->u.call.type);
+
+	return 0;
+}
+
+static int clip_handler(struct lgsm_handle *lh, int evt, struct gsmd_evt_auxdata *aux)
+{
+	printf("EVENT: Incoming call clip=`%s'\n", aux->u.clip.addr.number);
+
+	return 0;
+}
+
+static int netreg_handler(struct lgsm_handle *lh, int evt, struct gsmd_evt_auxdata *aux)
+{
+	printf("EVENT: Netreg\n");
+
+	return 0;
+}
+
+int event_init(struct lgsm_handle *lh)
+{
+	int rc;
+
+	rc  = lgsm_evt_handler_register(lh, GSMD_EVT_IN_CALL, &incall_handler);
+	rc |= lgsm_evt_handler_register(lh, GSMD_EVT_IN_CLIP, &clip_handler);
+	rc |= lgsm_evt_handler_register(lh, GSMD_EVT_NETREG, &netreg_handler);
+
+	return rc;
+}
+

Added: trunk/src/target/gsm/src/util/event.h
===================================================================
--- trunk/src/target/gsm/src/util/event.h	2006-10-23 15:11:34 UTC (rev 113)
+++ trunk/src/target/gsm/src/util/event.h	2006-10-23 20:28:37 UTC (rev 114)
@@ -0,0 +1,2 @@
+
+extern int event_init(struct lgsm_handle *lh);

Modified: trunk/src/target/gsm/src/util/libgsmd-tool.c
===================================================================
--- trunk/src/target/gsm/src/util/libgsmd-tool.c	2006-10-23 15:11:34 UTC (rev 113)
+++ trunk/src/target/gsm/src/util/libgsmd-tool.c	2006-10-23 20:28:37 UTC (rev 114)
@@ -8,6 +8,9 @@
 
 #include <libgsmd/libgsmd.h>
 
+#include "pin.h"
+#include "event.h"
+
 #ifndef ARRAY_SIZE
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 #endif
@@ -44,6 +47,7 @@
 	{ "version", 0, 0, 'V' },
 	{ "verbose", 0, 0, 'v' },
 	{ "mode", 1, 0, 'm' },
+	{ "pin", 1, 0, 'p' },
 	{ 0, 0, 0, 0 }
 };
 
@@ -57,6 +61,7 @@
 
 int main(int argc, char **argv)
 {
+	char *pin = NULL;
 	int rc, i, mode;
 
 	printf("libgsm-tool - (C) 2006 by Harald Welte\n"
@@ -64,7 +69,7 @@
 
 	while (1) {
 		int c, option_index = 0;
-		c = getopt_long(argc, argv, "vVhm:", opts, &option_index);
+		c = getopt_long(argc, argv, "vVhm:p:", opts, &option_index);
 		if (c == -1)
 			break;
 
@@ -86,6 +91,9 @@
 				exit(2);
 			}
 			break;
+		case 'p':
+			pin = optarg;
+			break;
 		}
 	}
 
@@ -95,6 +103,9 @@
 		exit(1);
 	}
 
+	pin_init(lgsmh, pin);
+	event_init(lgsmh);
+
 	switch (mode) {
 	case MODE_SHELL:
 		shell_main(lgsmh);

Added: trunk/src/target/gsm/src/util/pin.c
===================================================================
--- trunk/src/target/gsm/src/util/pin.c	2006-10-23 15:11:34 UTC (rev 113)
+++ trunk/src/target/gsm/src/util/pin.c	2006-10-23 20:28:37 UTC (rev 114)
@@ -0,0 +1,39 @@
+#include <stdio.h>
+#include <string.h>
+
+#include <libgsmd/libgsmd.h>
+#include <libgsmd/event.h>
+
+#define PIN_SIZE 32
+
+static char *pin;
+static char pinbuf[PIN_SIZE+1];
+
+static int pin_handler(struct lgsm_handle *lh, int evt, struct gsmd_evt_auxdata *aux)
+{
+	int rc;
+
+	printf("EVENT: PIN request (type=%u) ", aux->u.pin.type);
+
+	/* FIXME: read pin from STDIN and send it back via lgsm_pin */
+	if (aux->u.pin.type == 1 && pin) {
+		printf("Auto-responding with pin `%s'\n", pin);
+		lgsm_pin(lh, pin);
+	} else {
+		do {
+			printf("Please enter PIN: ");
+			rc = fscanf(stdin, "%32s\n", &pinbuf);
+		} while (rc < 1);
+
+		return lgsm_pin(lh, pinbuf);
+	}
+
+	return 0;
+}
+
+int pin_init(struct lgsm_handle *lh, const char *pin_preset)
+{
+	pin = pin_preset;
+	return lgsm_evt_handler_register(lh, GSMD_EVT_PIN, &pin_handler);
+}
+

Added: trunk/src/target/gsm/src/util/pin.h
===================================================================
--- trunk/src/target/gsm/src/util/pin.h	2006-10-23 15:11:34 UTC (rev 113)
+++ trunk/src/target/gsm/src/util/pin.h	2006-10-23 20:28:37 UTC (rev 114)
@@ -0,0 +1,2 @@
+
+extern int pin_init(struct lgsm_handle *lh, const char *pin_preset);

Modified: trunk/src/target/gsm/src/util/shell.c
===================================================================
--- trunk/src/target/gsm/src/util/shell.c	2006-10-23 15:11:34 UTC (rev 113)
+++ trunk/src/target/gsm/src/util/shell.c	2006-10-23 20:28:37 UTC (rev 114)
@@ -1,30 +1,66 @@
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
 
 #include <libgsmd/libgsmd.h>
 
 #define STDIN_BUF_SIZE	1024
 
-int shell_main(struct lgsmd_handle *lgsmh)
+/* this is the handler for receiving passthrough responses */
+static int pt_msghandler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
 {
+	char *payload = (char *)gmh + sizeof(*gmh);
+	printf("RSTR=`%s'\n", payload);
+}
+
+int shell_main(struct lgsm_handle *lgsmh)
+{
 	int rc;
 	char buf[STDIN_BUF_SIZE+1];
 	char rbuf[STDIN_BUF_SIZE+1];
 	int rlen = sizeof(rbuf);
+	fd_set readset;
 
+	lgsm_register_handler(lgsmh, GSMD_MSG_PASSTHROUGH, &pt_msghandler);
+
+	FD_ZERO(&readset);
+
 	while (1) {
-		rc = fscanf(stdin, "%s", buf);
-		if (rc == EOF) {
-			printf("EOF\n");
-			return -1;
+		fd_set readset;
+		int gsm_fd = lgsm_fd(lgsmh);
+		FD_SET(0, &readset);
+		FD_SET(gsm_fd, &readset);
+
+		rc = select(gsm_fd+1, &readset, NULL, NULL, NULL);
+		if (rc <= 0)	
+			break;
+		if (FD_ISSET(gsm_fd, &readset)) {
+			/* we've received something on the gsmd socket, pass it
+			 * on to the library */
+			rc = read(gsm_fd, buf, sizeof(buf));
+			if (rc <= 0) {
+				printf("ERROR reding from gsm_fd\n");
+				break;
+			}
+			rc = lgsm_handle_packet(lgsmh, buf, rc);
 		}
-		if (rc <= 0) {
-			printf("NULL\n");
-			continue;
+		if (FD_ISSET(0, &readset)) {
+			/* we've received something on stdin.  send it as passthrough
+			 * to gsmd */
+			rc = fscanf(stdin, "%s", buf);
+			if (rc == EOF) {
+				printf("EOF\n");
+				return -1;
+			}
+			if (rc <= 0) {
+				printf("NULL\n");
+				continue;
+			}
+			printf("STR=`%s'\n", buf);
 		}
-		printf("STR=`%s'\n", buf);
+		/* this is a synchronous call for a passthrough command */
 		lgsm_passthrough(lgsmh, buf, rbuf, &rlen);
-
 		printf("RSTR=`%s'\n", rbuf);
 	}
 }





More information about the commitlog mailing list