blob: 811e0d4250fbca57abbe11976341856489cffea7 [file] [log] [blame]
Alexander Afanasyevfe3b1502013-12-18 16:45:03 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2013 Regents of the University of California.
4 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
5 * See COPYING for copyright and distribution information.
6 */
7
8#include <stdexcept>
9#include <stdlib.h>
10
11#include <ndn-cpp/face.hpp>
12#include <ndn-cpp/transport/unix-transport.hpp>
13
14#include <boost/asio.hpp>
15#include <boost/bind.hpp>
16
17using namespace std;
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -080018typedef boost::asio::local::stream_protocol protocol;
Alexander Afanasyevfe3b1502013-12-18 16:45:03 -080019
20namespace ndn {
21
22const size_t MAX_LENGTH = 9000;
23
24class UnixTransport::Impl
25{
26public:
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -080027 Impl(UnixTransport &transport)
28 : transport_(transport),
29 socket_(*transport_.ioService_)
Alexander Afanasyevfe3b1502013-12-18 16:45:03 -080030 {
31 }
32
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -080033 void
34 connect()
Alexander Afanasyevfe3b1502013-12-18 16:45:03 -080035 {
36 socket_.open();
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -080037 socket_.connect(protocol::endpoint(transport_.unixSocket_));
Alexander Afanasyevfe3b1502013-12-18 16:45:03 -080038 // socket_.async_connect(protocol::endpoint(unixSocket));
39
40 socket_.async_receive(boost::asio::buffer(inputBuffer_, MAX_LENGTH), 0,
41 boost::bind(&Impl::handle_async_receive, this, _1, _2));
Alexander Afanasyevfe3b1502013-12-18 16:45:03 -080042 }
43
44 void
Alexander Afanasyevfe3b1502013-12-18 16:45:03 -080045 close()
46 {
47 socket_.close();
48 }
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -080049
50 void
51 send(const Block &wire)
52 {
53 socket_.async_send(boost::asio::buffer(wire.wire(), wire.size()),
54 boost::bind(&Impl::handle_async_send, this, _1, wire));
55 }
56
57 void
58 handle_async_receive(const boost::system::error_code& error, std::size_t bytes_recvd)
59 {
60 /// @todo The socket is not datagram, so need to have internal buffer to handle partial data reception
61
62 if (!error && bytes_recvd > 0)
63 {
64 // inputBuffer_ has bytes_recvd received bytes of data
65 try {
66 Block element(inputBuffer_, bytes_recvd);
67 transport_.receive(element);
68 }
69 catch(Tlv::Error &error)
70 {
71 // pass
72 }
73 catch(Block::Error &error)
74 {
75 // pass
76 }
77 }
78
79 socket_.async_receive(boost::asio::buffer(inputBuffer_, MAX_LENGTH), 0,
80 boost::bind(&Impl::handle_async_receive, this, _1, _2));
81 }
82
83 void
84 handle_async_send(const boost::system::error_code& error, const Block &wire)
85 {
86 // pass
87 }
Alexander Afanasyevfe3b1502013-12-18 16:45:03 -080088
89private:
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -080090 UnixTransport &transport_;
91
Alexander Afanasyevfe3b1502013-12-18 16:45:03 -080092 protocol::socket socket_;
Alexander Afanasyevfe3b1502013-12-18 16:45:03 -080093 uint8_t inputBuffer_[MAX_LENGTH];
94};
95
96UnixTransport::UnixTransport(const std::string &unixSocket/* = "/tmp/.ndnd.sock"*/)
97 : unixSocket_(unixSocket)
Alexander Afanasyevfe3b1502013-12-18 16:45:03 -080098{
99}
100
101UnixTransport::~UnixTransport()
102{
103}
104
105void
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800106UnixTransport::connect(boost::asio::io_service &ioService, const ReceiveCallback &receiveCallback)
Alexander Afanasyevfe3b1502013-12-18 16:45:03 -0800107{
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800108 Transport::connect(ioService, receiveCallback);
109
110 impl_ = std::auto_ptr<UnixTransport::Impl> (new UnixTransport::Impl(*this));
111 impl_->connect();
112
113 isConnected_ = true;
Alexander Afanasyevfe3b1502013-12-18 16:45:03 -0800114}
115
116void
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800117UnixTransport::send(const Block &wire)
Alexander Afanasyevfe3b1502013-12-18 16:45:03 -0800118{
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800119 impl_->send(wire);
Alexander Afanasyevfe3b1502013-12-18 16:45:03 -0800120}
121
122void
123UnixTransport::close()
124{
125 impl_->close();
126}
127
128}