1 /* Copyright 2016, Ableton AG, Berlin. All rights reserved.
2  *
3  *  This program is free software: you can redistribute it and/or modify
4  *  it under the terms of the GNU General Public License as published by
5  *  the Free Software Foundation, either version 2 of the License, or
6  *  (at your option) any later version.
7  *
8  *  This program is distributed in the hope that it will be useful,
9  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  *  GNU General Public License for more details.
12  *
13  *  You should have received a copy of the GNU General Public License
14  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  *
16  *  If you would like to incorporate Link into a proprietary software application,
17  *  please contact <link-devs@ableton.com>.
18  */
19 
20 #pragma once
21 
22 #include <ableton/discovery/Payload.hpp>
23 #include <ableton/link/MeasurementEndpointV4.hpp>
24 #include <ableton/link/NodeState.hpp>
25 
26 namespace ableton
27 {
28 namespace link
29 {
30 
31 // A state type for peers. PeerState stores the normal NodeState plus
32 // additional information (the remote endpoint at which to find its
33 // ping/pong measurement server).
34 
35 struct PeerState
36 {
37   using IdType = NodeId;
38 
identableton::link::PeerState39   IdType ident() const
40   {
41     return nodeState.ident();
42   }
43 
sessionIdableton::link::PeerState44   SessionId sessionId() const
45   {
46     return nodeState.sessionId;
47   }
48 
timelineableton::link::PeerState49   Timeline timeline() const
50   {
51     return nodeState.timeline;
52   }
53 
startStopStateableton::link::PeerState54   StartStopState startStopState() const
55   {
56     return nodeState.startStopState;
57   }
58 
operator ==(const PeerState & lhs,const PeerState & rhs)59   friend bool operator==(const PeerState& lhs, const PeerState& rhs)
60   {
61     return lhs.nodeState == rhs.nodeState && lhs.endpoint == rhs.endpoint;
62   }
63 
toPayload(const PeerState & state)64   friend auto toPayload(const PeerState& state)
65     -> decltype(std::declval<NodeState::Payload>()
66                 + discovery::makePayload(MeasurementEndpointV4{{}}))
67   {
68     return toPayload(state.nodeState)
69            + discovery::makePayload(MeasurementEndpointV4{state.endpoint});
70   }
71 
72   template <typename It>
fromPayloadableton::link::PeerState73   static PeerState fromPayload(NodeId id, It begin, It end)
74   {
75     using namespace std;
76     auto peerState = PeerState{NodeState::fromPayload(move(id), begin, end), {}};
77 
78     discovery::parsePayload<MeasurementEndpointV4>(move(begin), move(end),
79       [&peerState](MeasurementEndpointV4 me4) { peerState.endpoint = move(me4.ep); });
80     return peerState;
81   }
82 
83   NodeState nodeState;
84   asio::ip::udp::endpoint endpoint;
85 };
86 
87 } // namespace link
88 } // namespace ableton
89