blob: 4875f6ce6770ed9a1c83a43a1f0fbef43efeb56b [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{
Wentao Shang98733142014-09-17 12:13:57 -070040 this->setOnDemand(true);
Wentao Shang53df1632014-04-21 12:01:32 -070041}
42
Wentao Shang53df1632014-04-21 12:01:32 -070043void
44WebSocketFace::sendInterest(const Interest& interest)
45{
Wentao Shang3d36c2b2014-07-04 10:09:58 -040046 if (m_closed)
47 return;
48
Junxiao Shic099ddb2014-12-25 20:53:20 -070049 this->emitSignal(onSendInterest, interest);
Davide Pesavento66ff0982015-01-29 22:39:00 +010050
Wentao Shang53df1632014-04-21 12:01:32 -070051 const Block& payload = interest.wireEncode();
Wentao Shange612e2f2014-08-04 10:24:59 -040052 this->getMutableCounters().getNOutBytes() += payload.size();
Wentao Shang3d36c2b2014-07-04 10:09:58 -040053
54 try {
55 m_server.send(m_handle, payload.wire(), payload.size(),
56 websocketpp::frame::opcode::binary);
57 }
58 catch (const websocketpp::lib::error_code& e) {
Davide Pesavento66ff0982015-01-29 22:39:00 +010059 NFD_LOG_WARN("Failed to send Interest: " << e << " (" << e.message() << ")");
Wentao Shang3d36c2b2014-07-04 10:09:58 -040060 }
Wentao Shang53df1632014-04-21 12:01:32 -070061}
62
63void
64WebSocketFace::sendData(const Data& data)
65{
Wentao Shang3d36c2b2014-07-04 10:09:58 -040066 if (m_closed)
67 return;
68
Junxiao Shic099ddb2014-12-25 20:53:20 -070069 this->emitSignal(onSendData, data);
Davide Pesavento66ff0982015-01-29 22:39:00 +010070
Wentao Shang53df1632014-04-21 12:01:32 -070071 const Block& payload = data.wireEncode();
Wentao Shange612e2f2014-08-04 10:24:59 -040072 this->getMutableCounters().getNOutBytes() += payload.size();
Wentao Shang3d36c2b2014-07-04 10:09:58 -040073
74 try {
75 m_server.send(m_handle, payload.wire(), payload.size(),
76 websocketpp::frame::opcode::binary);
77 }
78 catch (const websocketpp::lib::error_code& e) {
Davide Pesavento66ff0982015-01-29 22:39:00 +010079 NFD_LOG_WARN("Failed to send Data: " << e << " (" << e.message() << ")");
Wentao Shang3d36c2b2014-07-04 10:09:58 -040080 }
Wentao Shang53df1632014-04-21 12:01:32 -070081}
82
83void
84WebSocketFace::close()
85{
86 if (m_closed == false)
87 {
88 m_closed = true;
Wentao Shang98733142014-09-17 12:13:57 -070089 scheduler::cancel(m_pingEventId);
Wentao Shang53df1632014-04-21 12:01:32 -070090 websocketpp::lib::error_code ecode;
91 m_server.close(m_handle, websocketpp::close::status::normal, "closed by nfd", ecode);
Alexander Afanasyev251f3c12014-06-02 18:39:58 +030092
Junxiao Shi08d07a72014-06-09 23:17:57 -070093 fail("Face closed");
Wentao Shang53df1632014-04-21 12:01:32 -070094 }
95}
96
97void
98WebSocketFace::handleReceive(const std::string& msg)
99{
100 // Copy message into Face internal buffer
Junxiao Shi39cd6332014-11-06 21:53:18 -0700101 if (msg.size() > ndn::MAX_NDN_PACKET_SIZE)
Wentao Shang6990e4c2014-11-05 11:17:35 -0800102 {
103 NFD_LOG_WARN("[id:" << this->getId()
Davide Pesavento66ff0982015-01-29 22:39:00 +0100104 << "] Received WebSocket message is too big (" << msg.size() << " bytes)");
Wentao Shang6990e4c2014-11-05 11:17:35 -0800105 return;
106 }
Wentao Shang53df1632014-04-21 12:01:32 -0700107
Davide Pesavento66ff0982015-01-29 22:39:00 +0100108 NFD_LOG_TRACE("[id:" << this->getId()
109 << "] Received: " << msg.size() << " bytes");
Wentao Shange612e2f2014-08-04 10:24:59 -0400110 this->getMutableCounters().getNInBytes() += msg.size();
111
Wentao Shang53df1632014-04-21 12:01:32 -0700112 // Try to parse message data
Wentao Shang53df1632014-04-21 12:01:32 -0700113 Block element;
Davide Pesavento66ff0982015-01-29 22:39:00 +0100114 bool isOk = Block::fromBuffer(reinterpret_cast<const uint8_t*>(msg.c_str()),
115 msg.size(), element);
Wentao Shang53df1632014-04-21 12:01:32 -0700116 if (!isOk)
117 {
Wentao Shang6990e4c2014-11-05 11:17:35 -0800118 NFD_LOG_WARN("[id:" << this->getId()
Davide Pesavento66ff0982015-01-29 22:39:00 +0100119 << "] Received block is invalid or too large to process");
Wentao Shang53df1632014-04-21 12:01:32 -0700120 return;
121 }
122
123 if (!this->decodeAndDispatchInput(element))
124 {
125 NFD_LOG_WARN("[id:" << this->getId()
Davide Pesavento66ff0982015-01-29 22:39:00 +0100126 << "] 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