summaryrefslogtreecommitdiff
path: root/src/libgsmd
diff options
context:
space:
mode:
authorlaforge <laforge@99fdad57-331a-0410-800a-d7fa5415bdb3>2006-10-22 14:05:53 +0000
committerlaforge <laforge@99fdad57-331a-0410-800a-d7fa5415bdb3>2006-10-22 14:05:53 +0000
commitbf9b037645a5943e3ba0220be55f7f875445bd5a (patch)
tree56083023e677d9ffaedbaac1d847c742db9dff39 /src/libgsmd
parent8045fdfb09c2e3b466f371b2ab64ff01f9f7aec1 (diff)
some further gsmd/libgsmd work
git-svn-id: http://svn.openmoko.org/trunk/src/target/gsm@96 99fdad57-331a-0410-800a-d7fa5415bdb3
Diffstat (limited to 'src/libgsmd')
-rw-r--r--src/libgsmd/lgsm_internals.h9
-rw-r--r--src/libgsmd/libgsmd.c45
-rw-r--r--src/libgsmd/libgsmd_passthrough.c65
3 files changed, 117 insertions, 2 deletions
diff --git a/src/libgsmd/lgsm_internals.h b/src/libgsmd/lgsm_internals.h
index 66fd5fe..0601959 100644
--- a/src/libgsmd/lgsm_internals.h
+++ b/src/libgsmd/lgsm_internals.h
@@ -1,4 +1,13 @@
+#ifndef _LGSM_INTERNALS_H
+#define _LGSM_INTERNALS_H
+
+#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];
};
+
+#endif /* _LGSM_INTERNALS_H */
diff --git a/src/libgsmd/libgsmd.c b/src/libgsmd/libgsmd.c
index 77b8499..104a8b3 100644
--- a/src/libgsmd/libgsmd.c
+++ b/src/libgsmd/libgsmd.c
@@ -36,7 +36,6 @@ static int lgsm_get_packet(struct lgsm_handle *lh)
return 0;
}
-
static int lgsm_open_backend(struct lgsm_handle *lh, const char *device)
{
int rc;
@@ -52,7 +51,6 @@ static int lgsm_open_backend(struct lgsm_handle *lh, const char *device)
memset(&sun, 0, sizeof(sun));
sun.sun_family = AF_UNIX;
memcpy(sun.sun_path, GSMD_UNIX_SOCKET, sizeof(GSMD_UNIX_SOCKET));
- printf("sizeof(GSMD_UNIX_SOCKET) = %u\n", sizeof(GSMD_UNIX_SOCKET));
rc = connect(lh->fd, (struct sockaddr *)&sun, sizeof(sun));
if (rc < 0) {
@@ -66,6 +64,49 @@ static int lgsm_open_backend(struct lgsm_handle *lh, const char *device)
return 0;
}
+/* handle a packet that was received on the gsmd socket */
+int lgsm_handle_packet(struct lgsm_handle *lh, char *buf, int len)
+{
+ struct gsmd_msg_hdr *gmh = (struct gsmd_msg_hdr *)buf;
+ if (len < sizeof(*gmh))
+ return -EINVAL;
+
+ if (len - sizeof(*gmh) < gmh->len)
+ return -EINVAL;
+
+ if (gmh->msg_type >= __NUM_GSMD_MSGS)
+ return -EINVAL;
+
+ return lh->handler[gmh->msg_type](lh, gmh);
+}
+
+/* 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)
+{
+ int rc;
+ fd_set readset;
+
+ FD_ZERO(&readset);
+
+ while (1) {
+ FD_SET(lh->fd, &readset);
+ rc = select(lh->fd+1, &readset, NULL, NULL, NULL);
+ if (rc <= 0)
+ return rc;
+
+ rc = read(lh->fd, (char *)gmh, rlen);
+ if (rc <= 0)
+ return rc;
+
+ if (gmh->id == id) {
+ /* we've found the matching packet, return to calling function */
+ return rc;
+ } else
+ rc = lgsm_handle_packet(lh, (char *)gmh, rc);
+ }
+}
+
int lgsm_fd(struct lgsm_handle *lh)
{
return lh->fd;
diff --git a/src/libgsmd/libgsmd_passthrough.c b/src/libgsmd/libgsmd_passthrough.c
new file mode 100644
index 0000000..45ce066
--- /dev/null
+++ b/src/libgsmd/libgsmd_passthrough.c
@@ -0,0 +1,65 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/types.h>
+
+#include <gsmd/usock.h>
+#include <libgsmd/libgsmd.h>
+
+#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);
+}
+
+#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)
+{
+ 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;
+
+ gmh->version = GSMD_PROTO_VERSION;
+ gmh->msg_type = GSMD_MSG_PASSTHROUGH;
+ gmh->msg_subtype = GSMD_PASSTHROUGH_REQUEST;
+ gmh->len = len;
+ strcpy(tx_buf, tx);
+
+ rc = lgsm_send(lh, gmh);
+ if (rc < len+sizeof(*gmh))
+ 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));
+ if (rc <= 0)
+ return rc;
+
+ if (rc < sizeof(*rgmh))
+ return -EINVAL;
+
+ if (rc < sizeof(*rgmh) + rgmh->len)
+ return -EINVAL;
+
+ /* FIXME: make sure rx_buf is zero-terminated */
+ strcpy(rx, rx_buf);
+ *rx_len = rgmh->len;
+
+ return rx_len;
+}
personal git repositories of Harald Welte. Your mileage may vary