summaryrefslogtreecommitdiff
path: root/gisi
diff options
context:
space:
mode:
authorRĂ©mi Denis-Courmont <remi.denis-courmont@nokia.com>2009-12-17 09:15:57 +0200
committerAki Niemi <aki.niemi@nokia.com>2009-12-18 15:59:17 +0200
commit2b2a410deb7953f095999e4ade3eb154f0f9f58c (patch)
tree5703a770d3599a64cc5466f535491e782f5c6522 /gisi
parentbc6c4adcac319ce22508b4e7f5ea272162ea4b2e (diff)
downloadofono-2b2a410deb7953f095999e4ade3eb154f0f9f58c.tar.gz
gisi: support sending ISI request as a scatter-gather array
Diffstat (limited to 'gisi')
-rw-r--r--gisi/client.c50
-rw-r--r--gisi/client.h4
2 files changed, 43 insertions, 11 deletions
diff --git a/gisi/client.c b/gisi/client.c
index f0db24ea..02294ff0 100644
--- a/gisi/client.c
+++ b/gisi/client.c
@@ -232,7 +232,33 @@ GIsiRequest *g_isi_request_make(GIsiClient *cl, const void *__restrict buf,
size_t len, unsigned timeout,
GIsiResponseFunc cb, void *opaque)
{
- struct iovec iov[2];
+ const struct iovec iov = {
+ .iov_base = (void *)buf,
+ .iov_len = len,
+ };
+ GIsiRequest *req;
+
+ req = g_isi_request_vmake(cl, &iov, 1, timeout, cb, opaque);
+ if (cl->debug_func)
+ cl->debug_func(buf, len, cl->debug_data);
+ return req;
+}
+
+/**
+ * Make an ISI request and register a callback to process the response(s) to
+ * the resulting transaction.
+ * @param cl ISI client (from g_isi_client_create())
+ * @param iov scatter-gather array to the request payload
+ * @param iovlen number of vectors in the scatter-gather array
+ * @param cb callback to process response(s)
+ * @param opaque data for the callback
+ */
+GIsiRequest *g_isi_request_vmake(GIsiClient *cl,
+ const struct iovec *__restrict iov,
+ size_t iovlen, unsigned timeout,
+ GIsiResponseFunc cb, void *opaque)
+{
+ struct iovec _iov[1 + iovlen];
const struct sockaddr_pn dst = {
.spn_family = AF_PHONET,
.spn_resource = cl->resource,
@@ -240,13 +266,14 @@ GIsiRequest *g_isi_request_make(GIsiClient *cl, const void *__restrict buf,
const struct msghdr msg = {
.msg_name = (struct sockaddr *)&dst,
.msg_namelen = sizeof(dst),
- .msg_iov = (struct iovec *)iov,
- .msg_iovlen = 2,
+ .msg_iov = (struct iovec *)_iov,
+ .msg_iovlen = 1 + iovlen,
.msg_control = NULL,
.msg_controllen = 0,
.msg_flags = 0,
};
ssize_t ret;
+ size_t i, len;
uint8_t id = cl->next[0];
if (id == 0) {
@@ -257,21 +284,22 @@ GIsiRequest *g_isi_request_make(GIsiClient *cl, const void *__restrict buf,
errno = EINVAL;
return NULL;
}
- iov[0].iov_base = &id;
- iov[0].iov_len = 1;
- iov[1].iov_base = (void *)buf;
- iov[1].iov_len = len;
+
+ _iov[0].iov_base = &id;
+ _iov[0].iov_len = 1;
+ for (i = 0, len = 1; i < iovlen; i++) {
+ _iov[1 + i] = iov[i];
+ len += iov[i].iov_len;
+ }
+
ret = sendmsg(cl->fd, &msg, MSG_NOSIGNAL);
if (ret == -1)
return NULL;
- if (ret != (ssize_t)(len + 1)) {
+ if (ret != (ssize_t)len) {
errno = EMSGSIZE;
return NULL;
}
- if (cl->debug_func)
- cl->debug_func(buf, len, cl->debug_data);
-
cl->func[id] = cb;
cl->data[id] = opaque;
diff --git a/gisi/client.h b/gisi/client.h
index 683d284a..4d7b19a5 100644
--- a/gisi/client.h
+++ b/gisi/client.h
@@ -73,6 +73,10 @@ int g_isi_client_error(const GIsiClient *client);
GIsiRequest *g_isi_request_make(GIsiClient *client, const void *data,
size_t len, unsigned timeout,
GIsiResponseFunc func, void *opaque);
+struct iovec;
+GIsiRequest *g_isi_request_vmake(GIsiClient *client, const struct iovec *iov,
+ size_t iovlen, unsigned timeout,
+ GIsiResponseFunc func, void *opaque);
void g_isi_request_cancel(GIsiRequest *req);