blob: 4c781c336f280617d64b30ce3ca6ec9183e6b6f7 [file] [log] [blame]
Wentao Shang53df1632014-04-21 12:01:32 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shi1e46be32015-01-08 20:18:05 -07003 * Copyright (c) 2014-2015, Regents of the University of California,
4 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
Wentao Shang53df1632014-04-21 12:01:32 -070010 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Junxiao Shi39cd6332014-11-06 21:53:18 -070024 */
Wentao Shang53df1632014-04-21 12:01:32 -070025
26#include "websocket-face.hpp"
27
28namespace nfd {
29
30NFD_LOG_INIT("WebSocketFace");
31
32WebSocketFace::WebSocketFace(const FaceUri& remoteUri, const FaceUri& localUri,
33 websocketpp::connection_hdl hdl,
34 websocket::Server& server)
35 : Face(remoteUri, localUri)
36 , m_handle(hdl)
37 , m_server(server)
38 , m_closed(false)
39{
Davide Pesaventobe40fb12015-02-23 21:09:34 +010040 NFD_LOG_FACE_INFO("Creating face");
Wentao Shang98733142014-09-17 12:13:57 -070041 this->setOnDemand(true);
Wentao Shang53df1632014-04-21 12:01:32 -070042}
43
Wentao Shang53df1632014-04-21 12:01:32 -070044void
45WebSocketFace::sendInterest(const Interest& interest)
46{
Wentao Shang3d36c2b2014-07-04 10:09:58 -040047 if (m_closed)
48 return;
49
Davide Pesaventobe40fb12015-02-23 21:09:34 +010050 NFD_LOG_FACE_TRACE(__func__);
51
Junxiao Shic099ddb2014-12-25 20:53:20 -070052 this->emitSignal(onSendInterest, interest);
Davide Pesavento66ff0982015-01-29 22:39:00 +010053
Wentao Shang53df1632014-04-21 12:01:32 -070054 const Block& payload = interest.wireEncode();
Wentao Shange612e2f2014-08-04 10:24:59 -040055 this->getMutableCounters().getNOutBytes() += payload.size();
Wentao Shang3d36c2b2014-07-04 10:09:58 -040056
Wentao Shangd397d772015-04-29 12:09:31 -070057 websocketpp::lib::error_code ec;
58 m_server.send(m_handle, payload.wire(), payload.size(),
59 websocketpp::frame::opcode::binary, ec);
60 if (ec)
61 NFD_LOG_FACE_WARN("Failed to send Interest: " << ec.message());
Wentao Shang53df1632014-04-21 12:01:32 -070062}
63
64void
65WebSocketFace::sendData(const Data& data)
66{
Wentao Shang3d36c2b2014-07-04 10:09:58 -040067 if (m_closed)
68 return;
69
Davide Pesaventobe40fb12015-02-23 21:09:34 +010070 NFD_LOG_FACE_TRACE(__func__);
71
Junxiao Shic099ddb2014-12-25 20:53:20 -070072 this->emitSignal(onSendData, data);
Davide Pesavento66ff0982015-01-29 22:39:00 +010073
Wentao Shang53df1632014-04-21 12:01:32 -070074 const Block& payload = data.wireEncode();
Wentao Shange612e2f2014-08-04 10:24:59 -040075 this->getMutableCounters().getNOutBytes() += payload.size();
Wentao Shang3d36c2b2014-07-04 10:09:58 -040076
Wentao Shangd397d772015-04-29 12:09:31 -070077 websocketpp::lib::error_code ec;
78 m_server.send(m_handle, payload.wire(), payload.size(),
79 websocketpp::frame::opcode::binary, ec);
80 if (ec)
81 NFD_LOG_FACE_WARN("Failed to send Data: " << ec.message());
Wentao Shang53df1632014-04-21 12:01:32 -070082}
83
84void
85WebSocketFace::close()
86{
Davide Pesaventobe40fb12015-02-23 21:09:34 +010087 if (m_closed)
88 return;
Alexander Afanasyev251f3c12014-06-02 18:39:58 +030089
Davide Pesaventobe40fb12015-02-23 21:09:34 +010090 NFD_LOG_FACE_INFO("Closing face");
91
92 m_closed = true;
93 scheduler::cancel(m_pingEventId);
Wentao Shangd397d772015-04-29 12:09:31 -070094 websocketpp::lib::error_code ec;
95 m_server.close(m_handle, websocketpp::close::status::normal, "closed by nfd", ec);
96 // ignore error on close
Davide Pesaventobe40fb12015-02-23 21:09:34 +010097 fail("Face closed");
Wentao Shang53df1632014-04-21 12:01:32 -070098}
99
100void
101WebSocketFace::handleReceive(const std::string& msg)
102{
103 // Copy message into Face internal buffer
Junxiao Shi39cd6332014-11-06 21:53:18 -0700104 if (msg.size() > ndn::MAX_NDN_PACKET_SIZE)
Wentao Shang6990e4c2014-11-05 11:17:35 -0800105 {
Davide Pesaventobe40fb12015-02-23 21:09:34 +0100106 NFD_LOG_FACE_WARN("Received WebSocket message is too big (" << msg.size() << " bytes)");
Wentao Shang6990e4c2014-11-05 11:17:35 -0800107 return;
108 }
Wentao Shang53df1632014-04-21 12:01:32 -0700109
Davide Pesaventobe40fb12015-02-23 21:09:34 +0100110 NFD_LOG_FACE_TRACE("Received: " << msg.size() << " bytes");
Wentao Shange612e2f2014-08-04 10:24:59 -0400111 this->getMutableCounters().getNInBytes() += msg.size();
112
Wentao Shang53df1632014-04-21 12:01:32 -0700113 // Try to parse message data
Junxiao Shi78926c92015-02-28 22:56:06 -0700114 bool isOk = false;
Wentao Shang53df1632014-04-21 12:01:32 -0700115 Block element;
Junxiao Shi78926c92015-02-28 22:56:06 -0700116 std::tie(isOk, element) = Block::fromBuffer(reinterpret_cast<const uint8_t*>(msg.c_str()),
117 msg.size());
Wentao Shang53df1632014-04-21 12:01:32 -0700118 if (!isOk)
119 {
Davide Pesaventobe40fb12015-02-23 21:09:34 +0100120 NFD_LOG_FACE_WARN("Received block is invalid or too large to process");
Wentao Shang53df1632014-04-21 12:01:32 -0700121 return;
122 }
123
124 if (!this->decodeAndDispatchInput(element))
125 {
Davide Pesaventobe40fb12015-02-23 21:09:34 +0100126 NFD_LOG_FACE_WARN("Received unrecognized TLV block of type " << element.type());
Wentao Shang53df1632014-04-21 12:01:32 -0700127 // ignore unknown packet and proceed
128 }
129}
130
131} // namespace nfd