aboutsummaryrefslogtreecommitdiffstats
path: root/src/ipa.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@gnumonks.org>2011-10-17 19:49:33 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2011-10-17 22:12:42 +0200
commit20c660caecc95b03489f870945ae9fe91c839bd3 (patch)
tree77a64e776b56212768574aa8e3bd2a48136969eb /src/ipa.c
parent1434e40951a4eda107e2e81425f99a2d5de23975 (diff)
ipa: initial addition of helper functions and examples
This patch adds IPA helper function that can be use on top of stream sockets. The current API is just a copy and paste from libosmo-abis, it will change in follow up patches to improve it.
Diffstat (limited to 'src/ipa.c')
-rw-r--r--src/ipa.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/ipa.c b/src/ipa.c
new file mode 100644
index 0000000..335c830
--- /dev/null
+++ b/src/ipa.c
@@ -0,0 +1,73 @@
+#include <stdlib.h>
+#include <arpa/inet.h>
+#include <errno.h>
+
+#include <osmocom/core/logging.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/netif/ipa.h>
+
+#define IPA_ALLOC_SIZE 1200
+
+struct msgb *osmo_ipa_msg_alloc(int headroom)
+{
+ struct msgb *msg;
+
+ headroom += sizeof(struct ipa_head);
+
+ msg = msgb_alloc_headroom(IPA_ALLOC_SIZE + headroom, headroom, "IPA");
+ if (msg == NULL) {
+ LOGP(DLINP, LOGL_ERROR, "cannot allocate message\n");
+ return NULL;
+ }
+ return msg;
+}
+
+void osmo_ipa_msg_push_header(struct msgb *msg, uint8_t proto)
+{
+ struct ipa_head *hh;
+
+ msg->l2h = msg->data;
+ hh = (struct ipa_head *) msgb_push(msg, sizeof(*hh));
+ hh->proto = proto;
+ hh->len = htons(msgb_l2len(msg));
+}
+
+int osmo_ipa_msg_recv(int fd, struct msgb *msg)
+{
+ struct ipa_head *hh;
+ int len, ret;
+
+ /* first read our 3-byte header */
+ hh = (struct ipa_head *) msg->data;
+ ret = recv(fd, msg->data, sizeof(*hh), 0);
+ if (ret <= 0) {
+ return ret;
+ } else if (ret != sizeof(*hh)) {
+ LOGP(DLINP, LOGL_ERROR, "too small message received\n");
+ return -EIO;
+ }
+ msgb_put(msg, ret);
+
+ /* then read the length as specified in header */
+ msg->l2h = msg->data + sizeof(*hh);
+ len = ntohs(hh->len);
+
+ if (len < 0 || IPA_ALLOC_SIZE < len + sizeof(*hh)) {
+ LOGP(DLINP, LOGL_ERROR, "bad message length of %d bytes, "
+ "received %d bytes\n", len, ret);
+ msgb_free(msg);
+ return -EIO;
+ }
+
+ ret = recv(fd, msg->l2h, len, 0);
+ if (ret <= 0) {
+ msgb_free(msg);
+ return ret;
+ } else if (ret < len) {
+ LOGP(DLINP, LOGL_ERROR, "trunked message received\n");
+ msgb_free(msg);
+ return -EIO;
+ }
+ msgb_put(msg, ret);
+ return ret;
+}