summaryrefslogtreecommitdiff
path: root/src/libgsmd/libgsmd_passthrough.c
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/libgsmd_passthrough.c
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/libgsmd_passthrough.c')
-rw-r--r--src/libgsmd/libgsmd_passthrough.c65
1 files changed, 65 insertions, 0 deletions
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