blob: 797467a1568a0dffa90053f935a433b871dedc5a [file] [log] [blame]
Zhiyi Zhangcea58d52015-08-26 10:19:56 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Zhiyi Zhang19a11d22018-04-12 22:58:20 -07003 * Copyright (c) 2014-2018, Regents of the University of California
Zhiyi Zhangcea58d52015-08-26 10:19:56 -07004 *
5 * This file is part of ndn-group-encrypt (Group-based Encryption Protocol for NDN).
6 * See AUTHORS.md for complete list of ndn-group-encrypt authors and contributors.
7 *
8 * ndn-group-encrypt is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * ndn-group-encrypt is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * ndn-group-encrypt, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 *
Zhiyi Zhang19a11d22018-04-12 22:58:20 -070019 * @author Zhiyi Zhang <zhiyi@cs.ucla.edu>
Zhiyi Zhangcea58d52015-08-26 10:19:56 -070020 */
21
22#include "schedule.hpp"
23#include "tlv.hpp"
24
25#include <ndn-cxx/encoding/block-helpers.hpp>
26#include <ndn-cxx/util/concepts.hpp>
27
28namespace ndn {
29namespace gep {
30
Zhiyi Zhang2f9efa62015-11-23 19:02:28 +080031/**
32 * @brief Helper functon to calculate black interval results or white interval results
33 * @p list The RepetitiveInterval list, which can be white list or the black list
34 * @p tp The timestamp
35 * @p positiveR The positive result
36 * @p negativeR The negative result
37 */
38static void
Zhiyi Zhang19a11d22018-04-12 22:58:20 -070039calIntervalResult(const std::set<RepetitiveInterval>& list,
40 const TimeStamp& ts,
41 Interval& positiveR,
42 Interval& negativeR)
Zhiyi Zhang2f9efa62015-11-23 19:02:28 +080043{
44 Interval tempInterval;
45 bool isPositive;
46
47 for (const RepetitiveInterval& element : list) {
48 std::tie(isPositive, tempInterval) = element.getInterval(ts);
49 if (isPositive == true) {
50 positiveR || tempInterval;
51 }
52 else {
53 if (!negativeR.isValid())
54 negativeR = tempInterval;
55 else
Zhiyi Zhang19a11d22018-04-12 22:58:20 -070056 negativeR&& tempInterval;
Zhiyi Zhang2f9efa62015-11-23 19:02:28 +080057 }
58 }
59}
60
Zhiyi Zhangcea58d52015-08-26 10:19:56 -070061BOOST_CONCEPT_ASSERT((WireEncodable<Schedule>));
62BOOST_CONCEPT_ASSERT((WireDecodable<Schedule>));
63
64Schedule::Schedule() = default;
65
66Schedule::Schedule(const Block& block)
67{
68 wireDecode(block);
69}
70
71template<encoding::Tag TAG>
72size_t
73Schedule::wireEncode(EncodingImpl<TAG>& encoder) const
74{
75 size_t totalLength = 0;
76 size_t blackLength = 0;
77 size_t whiteLength = 0;
78
79 // encode the blackIntervalList as an embed TLV structure
Yingdi Yud263c8a2016-03-09 16:53:19 -080080 for (auto it = m_blackIntervalList.rbegin(); it != m_blackIntervalList.rend(); it++) {
81 blackLength += encoder.prependBlock(it->wireEncode());
Zhiyi Zhangcea58d52015-08-26 10:19:56 -070082 }
83 blackLength += encoder.prependVarNumber(blackLength);
84 blackLength += encoder.prependVarNumber(tlv::BlackIntervalList);
85
86 // encode the whiteIntervalList as an embed TLV structure
Yingdi Yud263c8a2016-03-09 16:53:19 -080087 for (auto it = m_whiteIntervalList.rbegin(); it != m_whiteIntervalList.rend(); it++) {
88 whiteLength += encoder.prependBlock(it->wireEncode());
Zhiyi Zhangcea58d52015-08-26 10:19:56 -070089 }
90 whiteLength += encoder.prependVarNumber(whiteLength);
91 whiteLength += encoder.prependVarNumber(tlv::WhiteIntervalList);
92
93 totalLength = whiteLength + blackLength;
94 totalLength += encoder.prependVarNumber(totalLength);
95 totalLength += encoder.prependVarNumber(tlv::Schedule);
96
97 return totalLength;
98}
99
100const Block&
101Schedule::wireEncode() const
102{
103 if (m_wire.hasWire())
104 return m_wire;
105
106 EncodingEstimator estimator;
107 size_t estimatedSize = wireEncode(estimator);
108
109 EncodingBuffer buffer(estimatedSize, 0);
110 wireEncode(buffer);
111
112 this->m_wire = buffer.block();
113 return m_wire;
114}
115
116void
117Schedule::wireDecode(const Block& wire)
118{
119 if (wire.type() != tlv::Schedule)
120 BOOST_THROW_EXCEPTION(tlv::Error("Unexpected TLV type when decoding RepetitiveInterval"));
121
122 m_wire = wire;
123 m_wire.parse();
124
125 if (m_wire.elements_size() != 2)
126 BOOST_THROW_EXCEPTION(tlv::Error("RepetitiveInterval tlv does not have two sub-TLVs"));
127
128 Block::element_const_iterator it = m_wire.elements_begin();
129
130 if (it != m_wire.elements_end() && it->type() == tlv::WhiteIntervalList) {
131 it->parse();
132 Block::element_const_iterator tempIt = it->elements_begin();
133 while (tempIt != it->elements_end() && tempIt->type() == tlv::RepetitiveInterval) {
134 m_whiteIntervalList.insert(RepetitiveInterval(*tempIt));
135 tempIt++;
136 }
137 it++;
138 }
139 else
140 BOOST_THROW_EXCEPTION(tlv::Error("The first element must be WhiteIntervalList"));
141
142 if (it != m_wire.elements_end() && it->type() == tlv::BlackIntervalList) {
143 it->parse();
144 Block::element_const_iterator tempIt = it->elements_begin();
145 while (tempIt != it->elements_end() && tempIt->type() == tlv::RepetitiveInterval) {
146 m_blackIntervalList.insert(RepetitiveInterval(*tempIt));
147 tempIt++;
148 }
149 it++;
150 }
151 else
152 BOOST_THROW_EXCEPTION(tlv::Error("The second element must be BlackIntervalList"));
153}
154
155Schedule&
156Schedule::addWhiteInterval(const RepetitiveInterval& repetitiveInterval)
157{
Zhiyi Zhang7cc09fc2015-09-01 13:40:32 -0700158 m_wire.reset();
Zhiyi Zhangcea58d52015-08-26 10:19:56 -0700159 m_whiteIntervalList.insert(repetitiveInterval);
160 return *this;
161}
162
163Schedule&
164Schedule::addBlackInterval(const RepetitiveInterval& repetitiveInterval)
165{
Zhiyi Zhang7cc09fc2015-09-01 13:40:32 -0700166 m_wire.reset();
Zhiyi Zhangcea58d52015-08-26 10:19:56 -0700167 m_blackIntervalList.insert(repetitiveInterval);
168 return *this;
169}
170
Zhiyi Zhang7cc09fc2015-09-01 13:40:32 -0700171std::tuple<bool, Interval>
Zhiyi Zhang2f9efa62015-11-23 19:02:28 +0800172Schedule::getCoveringInterval(const TimeStamp& ts) const
Zhiyi Zhangcea58d52015-08-26 10:19:56 -0700173{
Zhiyi Zhang7cc09fc2015-09-01 13:40:32 -0700174 Interval blackPositiveResult(true);
175 Interval whitePositiveResult(true);
176
177 Interval blackNegativeResult;
178 Interval whiteNegativeResult;
179
Zhiyi Zhangcea58d52015-08-26 10:19:56 -0700180 // get the blackResult
Zhiyi Zhang19a11d22018-04-12 22:58:20 -0700181 calIntervalResult(m_blackIntervalList, ts, blackPositiveResult, blackNegativeResult);
Zhiyi Zhangcea58d52015-08-26 10:19:56 -0700182
Zhiyi Zhang2f9efa62015-11-23 19:02:28 +0800183 // if black positive result is not empty, the result must be false
Zhiyi Zhang7cc09fc2015-09-01 13:40:32 -0700184 if (!blackPositiveResult.isEmpty())
185 return std::make_tuple(false, blackPositiveResult);
186
Zhiyi Zhangcea58d52015-08-26 10:19:56 -0700187 // get the whiteResult
Zhiyi Zhang19a11d22018-04-12 22:58:20 -0700188 calIntervalResult(m_whiteIntervalList, ts, whitePositiveResult, whiteNegativeResult);
Zhiyi Zhang2f9efa62015-11-23 19:02:28 +0800189
190 if (whitePositiveResult.isEmpty() && !whiteNegativeResult.isValid()) {
191 // there is no white interval covering the timestamp
192 // return false and a 24-hour interval
Zhiyi Zhang19a11d22018-04-12 22:58:20 -0700193 return std::make_tuple(false,
194 Interval(TimeStamp(ts.date(), boost::posix_time::hours(0)),
195 TimeStamp(ts.date(), boost::posix_time::hours(24))));
Zhiyi Zhangcea58d52015-08-26 10:19:56 -0700196 }
197
Zhiyi Zhang2f9efa62015-11-23 19:02:28 +0800198 if (!whitePositiveResult.isEmpty()) {
199 // there is white interval covering the timestamp
200 // return ture and calculate the intersection
201 if (blackNegativeResult.isValid())
202 return std::make_tuple(true, whitePositiveResult && blackNegativeResult);
203 else
204 return std::make_tuple(true, whitePositiveResult);
205 }
206 else {
207 // there is no white interval covering the timestamp
208 // return false
Zhiyi Zhang7cc09fc2015-09-01 13:40:32 -0700209 return std::make_tuple(false, whiteNegativeResult);
Zhiyi Zhang2f9efa62015-11-23 19:02:28 +0800210 }
Zhiyi Zhangcea58d52015-08-26 10:19:56 -0700211}
212
213} // namespace gep
214} // namespace ndn