1 /**
2 * Copyright 2017 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "lpcsnoop/snoop.hpp"
18
19 #include <sdbusplus/bus.hpp>
20 #include <sdbusplus/bus/match.hpp>
21 #include <sdbusplus/message.hpp>
22
23 namespace lpcsnoop
24 {
25 using std::get;
26
27 /* Returns matching string for what signal to listen on Dbus */
GetMatchRule()28 static const std::string GetMatchRule()
29 {
30 using namespace sdbusplus::bus::match::rules;
31
32 return type::signal() + interface("org.freedesktop.DBus.Properties") +
33 member("PropertiesChanged") + path(snoopObject);
34 }
35
36 class SnoopListen
37 {
38 using message_handler_t = std::function<void(sdbusplus::message_t&)>;
39 using postcode_handler_t = std::function<void(FILE*, postcode_t)>;
40
41 public:
SnoopListen(sdbusplus::bus_t & busIn,sd_bus_message_handler_t handler)42 SnoopListen(sdbusplus::bus_t& busIn, sd_bus_message_handler_t handler) :
43 signal(busIn, GetMatchRule().c_str(), handler, this)
44 {}
45
SnoopListen(sdbusplus::bus_t & busIn,message_handler_t handler)46 SnoopListen(sdbusplus::bus_t& busIn, message_handler_t handler) :
47 signal(busIn, GetMatchRule(), handler)
48 {}
49
SnoopListen(sdbusplus::bus_t & busIn,postcode_handler_t handler,FILE * f=NULL)50 SnoopListen(sdbusplus::bus_t& busIn, postcode_handler_t handler,
51 FILE* f = NULL) :
52 SnoopListen(busIn, std::bind(defaultMessageHandler, handler, f,
53 std::placeholders::_1))
54 {}
55
56 SnoopListen() = delete; // no default constructor
57 ~SnoopListen() = default;
58 SnoopListen(const SnoopListen&) = delete;
59 SnoopListen& operator=(const SnoopListen&) = delete;
60 SnoopListen(SnoopListen&&) = default;
61 SnoopListen& operator=(SnoopListen&&) = default;
62
63 private:
64 sdbusplus::bus::match_t signal;
65
66 /*
67 * Default message handler which listens to published messages on snoop
68 * DBus path, and calls the given postcode_handler on each value received.
69 */
defaultMessageHandler(postcode_handler_t & handler,FILE * f,sdbusplus::message_t & m)70 static void defaultMessageHandler(postcode_handler_t& handler, FILE* f,
71 sdbusplus::message_t& m)
72 {
73 std::string messageBusName;
74 std::map<std::string, std::variant<postcode_t>> messageData;
75 constexpr char propertyKey[] = "Value";
76
77 m.read(messageBusName, messageData);
78
79 if (messageBusName == snoopDbus &&
80 messageData.find(propertyKey) != messageData.end())
81 {
82 handler(f, get<postcode_t>(messageData[propertyKey]));
83 }
84 }
85 };
86
87 } // namespace lpcsnoop
88