diff options
author | laforge <laforge@99fdad57-331a-0410-800a-d7fa5415bdb3> | 2006-10-22 14:05:53 +0000 |
---|---|---|
committer | laforge <laforge@99fdad57-331a-0410-800a-d7fa5415bdb3> | 2006-10-22 14:05:53 +0000 |
commit | bf9b037645a5943e3ba0220be55f7f875445bd5a (patch) | |
tree | 56083023e677d9ffaedbaac1d847c742db9dff39 /src/libgsmd/libgsmd_passthrough.c | |
parent | 8045fdfb09c2e3b466f371b2ab64ff01f9f7aec1 (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.c | 65 |
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; +} |