2 * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Bumjin Im <bj.im@samsung.com>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License
19 * @file dbus_access.cpp
20 * @author Zbigniew Jasinski (z.jasinski@samsung.com)
22 * @brief Functios used in security-tests package for restarting Security Server through
23 * SystemD DBuS interface.
26 #include <dpl/log/log.h>
27 #include <tests_common.h>
31 #include "dbus_access.h"
33 DBusAccess::DBusAccess()
39 dbus_error_init(&m_err);
41 m_signal_type = "signal";
42 m_signal_interface = "org.freedesktop.systemd1.Manager";
43 m_signal_member = "JobRemoved";
44 m_signal_path = "/org/freedesktop/systemd1";
46 m_signal_match = "type='" + m_signal_type + "',interface='" + m_signal_interface +
47 "',member='" + m_signal_member + "',path='" + m_signal_path + "'";
49 m_dbus_client_name = "tests.dbus.client";
52 void DBusAccess::connect() {
53 m_conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, &m_err);
54 RUNNER_ASSERT_MSG_BT(dbus_error_is_set(&m_err) != 1, m_tracker.str() <<
55 "Error in dbus_bus_get: " << m_err.message);
56 dbus_connection_set_exit_on_disconnect(m_conn, FALSE);
59 void DBusAccess::requestName() {
60 dbus_bus_request_name(m_conn, m_dbus_client_name.c_str(),
61 DBUS_NAME_FLAG_REPLACE_EXISTING , &m_err);
62 RUNNER_ASSERT_MSG_BT(dbus_error_is_set(&m_err) != 1, m_tracker.str() <<
63 "Error in dbus_bus_request_name: " << m_err.message);
66 void DBusAccess::newMethodCall(const std::string& method) {
67 const std::string dbus_systemd_name = "org.freedesktop.systemd1";
68 const std::string dbus_systemd_object =
69 "/org/freedesktop/systemd1/unit/security_2dserver_2eservice";
70 const std::string dbus_systemd_interface = "org.freedesktop.systemd1.Unit";
72 m_msg = dbus_message_new_method_call(dbus_systemd_name.c_str(),
73 dbus_systemd_object.c_str(),
74 dbus_systemd_interface.c_str(),
76 RUNNER_ASSERT_MSG_BT(NULL != m_msg, m_tracker.str() <<
77 "Error in dbus_message_new_method_call");
80 void DBusAccess::appendToMsg() {
82 const char *dbus_systemd_srv_unit_mode = "fail";
84 dbus_message_iter_init_append(m_msg, &iter);
85 int ret = dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
86 &dbus_systemd_srv_unit_mode);
87 RUNNER_ASSERT_MSG_BT(ret != 0, m_tracker.str() <<
88 "Error in dbus_message_iter_append_basic");
91 void DBusAccess::sendMsgWithReply() {
92 int ret = dbus_connection_send_with_reply(m_conn, m_msg, &m_pending, -1);
93 RUNNER_ASSERT_MSG_BT(ret == 1, m_tracker.str() <<
94 "Error in dbus_connection_send_with_reply");
96 RUNNER_ASSERT_MSG_BT(NULL != m_pending, m_tracker.str() << "Pending call null");
98 dbus_connection_flush(m_conn);
99 dbus_pending_call_block(m_pending);
100 dbus_message_unref(m_msg);
104 void DBusAccess::getMsgReply() {
105 m_msg = dbus_pending_call_steal_reply(m_pending);
106 RUNNER_ASSERT_MSG_BT(NULL != m_msg, m_tracker.str() <<
107 "Error in dbus_pending_call_steal_reply");
110 void DBusAccess::handleMsgRestartReply() {
111 char *object_path = NULL;
112 DBusMessageIter iter;
114 RUNNER_ASSERT_MSG_BT(dbus_message_iter_init(m_msg, &iter) != 0,
115 m_tracker.str() << "Message has no arguments");
116 if (DBUS_TYPE_OBJECT_PATH == dbus_message_iter_get_arg_type(&iter)) {
117 dbus_message_iter_get_basic(&iter, &object_path);
118 m_jobID = std::strrchr(object_path, '/') + 1;
120 RUNNER_ASSERT_MSG_BT(false, m_tracker.str() << "No job path in msg");
122 dbus_message_unref(m_msg);
123 dbus_pending_call_unref(m_pending);
128 DBusHandlerResult DBusAccess::signalFilter(DBusConnection *, DBusMessage *message, void *This) {
129 DBusMessageIter iter;
131 DBusAccess *a = reinterpret_cast<DBusAccess *>(This);
133 if (dbus_message_is_signal(message, a->m_signal_interface.c_str(), a->m_signal_member.c_str()))
135 RUNNER_ASSERT_MSG_BT(dbus_message_iter_init(message, &iter) != 0, a->m_tracker.str() <<
136 "No messages in reply");
138 RUNNER_ASSERT_MSG_BT(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_UINT32,
139 a->m_tracker.str() << "Argument is not integer");
141 dbus_message_iter_get_basic(&iter, &id);
143 if (id == (unsigned int)std::stoi(a->m_jobID)) {
144 while (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INVALID) {
145 if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) {
147 dbus_message_iter_get_basic(&iter, &str);
148 if (!strncmp(str, "done", strlen("done")))
151 dbus_message_iter_next(&iter);
155 return (a->m_handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
158 void DBusAccess::handleMsgRestartSignal() {
159 dbus_bus_add_match(m_conn, m_signal_match.c_str(), &m_err);
160 RUNNER_ASSERT_MSG_BT(dbus_error_is_set(&m_err) != 1, m_tracker.str() <<
161 "Error in dbus_bus_add_match: " << m_err.message);
163 dbus_connection_add_filter(m_conn, signalFilter, reinterpret_cast<void *>(this), NULL);
165 while(dbus_connection_read_write_dispatch(m_conn, 1000)) {
171 void DBusAccess::connectToDBus() {
176 void DBusAccess::sendRestartToSS() {
177 const std::string method = "Restart";
179 newMethodCall(method);
183 handleMsgRestartReply();
184 handleMsgRestartSignal();
187 void DBusAccess::sendResetFailedToSS() {
188 const std::string method = "ResetFailed";
190 newMethodCall(method);
195 void DBusAccess::restartSS(const Tracker &tracker) {
200 sendResetFailedToSS();
203 DBusAccess::~DBusAccess() {
204 dbus_connection_close(m_conn);
206 dbus_connection_unref(m_conn);
207 dbus_error_free(&m_err);
209 dbus_message_unref(m_msg);
211 dbus_pending_call_unref(m_pending);