transport: Implementation of semi-async UNIX transport (for TLV format only)
This implementation uses boost::asio to simplify all the implementation.
- connect and send operations are sync
- receive operation is async
Change-Id: If21147fbb579dc073c385a0f3a2aeef2d83fab04
diff --git a/src/transport/unix-transport.cpp b/src/transport/unix-transport.cpp
new file mode 100644
index 0000000..603f5e3
--- /dev/null
+++ b/src/transport/unix-transport.cpp
@@ -0,0 +1,128 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#include <stdexcept>
+#include <stdlib.h>
+
+#include <ndn-cpp/face.hpp>
+#include <ndn-cpp/transport/unix-transport.hpp>
+
+#include <boost/asio.hpp>
+#include <boost/bind.hpp>
+
+using namespace std;
+typedef boost::asio::local::datagram_protocol protocol;
+
+namespace ndn {
+
+const size_t MAX_LENGTH = 9000;
+
+class UnixTransport::Impl
+{
+public:
+ Impl() : socket_(io_)
+ {
+ }
+
+ bool
+ connect(const std::string &unixSocket, ElementListener& elementListener)
+ {
+ socket_.open();
+ socket_.connect(protocol::endpoint(unixSocket));
+ // socket_.async_connect(protocol::endpoint(unixSocket));
+
+ socket_.async_receive(boost::asio::buffer(inputBuffer_, MAX_LENGTH), 0,
+ boost::bind(&Impl::handle_async_receive, this, _1, _2));
+
+ return true;
+ }
+
+ void
+ send(const uint8_t *data, size_t dataLength)
+ {
+ socket_.send(boost::asio::buffer(data, dataLength));
+ }
+
+ void
+ processEvents()
+ {
+ io_.poll();
+ // from boost docs:
+ // The poll() function runs handlers that are ready to run, without blocking, until the io_service has been stopped or there are no more ready handlers.
+ }
+
+ void
+ handle_async_receive(const boost::system::error_code& error, std::size_t bytes_recvd)
+ {
+ if (!error && bytes_recvd > 0)
+ {
+ // inputBuffer_ has bytes_recvd received bytes of data
+ }
+
+ socket_.async_receive(boost::asio::buffer(inputBuffer_, MAX_LENGTH), 0,
+ boost::bind(&Impl::handle_async_receive, this, _1, _2));
+ }
+
+ void
+ close()
+ {
+ socket_.close();
+ }
+
+private:
+ boost::asio::io_service io_;
+
+ protocol::socket socket_;
+
+ uint8_t inputBuffer_[MAX_LENGTH];
+};
+
+UnixTransport::UnixTransport(const std::string &unixSocket/* = "/tmp/.ndnd.sock"*/)
+ : unixSocket_(unixSocket)
+ , isConnected_(false)
+ , impl_(new UnixTransport::Impl())
+{
+}
+
+UnixTransport::~UnixTransport()
+{
+}
+
+void
+UnixTransport::connect(ElementListener& elementListener)
+{
+ if (impl_->connect(unixSocket_, elementListener))
+ {
+ isConnected_ = true;
+ }
+}
+
+void
+UnixTransport::send(const uint8_t *data, size_t dataLength)
+{
+ impl_->send(data, dataLength);
+}
+
+void
+UnixTransport::processEvents()
+{
+ impl_->processEvents();
+}
+
+bool
+UnixTransport::getIsConnected()
+{
+ return isConnected_;
+}
+
+void
+UnixTransport::close()
+{
+ impl_->close();
+}
+
+}