TIVI-1924: Initial commit of IVI settings daemon.
[profile/ivi/settings-daemon.git] / lib / response_callback.cpp
1 /**
2  * @file response_callback.cpp
3  *
4  * @brief Settings plugin response_callback implementation.
5  *
6  * @author Ossama Othman @<ossama.othman@@intel.com@>
7  *
8  * @copyright @par
9  * Copyright 2012, 2013 Intel Corporation All Rights Reserved.
10  * @par
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation;
14  * version 2.1 of the License.
15  * @par
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  * @par
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
24  * Boston, MA  02110-1301  USA
25  */
26
27 #include <settingsd/response_callback.hpp>
28 #include <settingsd/glib_traits.hpp>
29 #include <settingsd/json_glib_traits.hpp>
30 #include <settingsd/smart_ptr.hpp>
31
32 #include <cstring>
33 #include <algorithm>
34 #include <iostream>
35
36
37 ivi::settings::response_callback::response_callback(
38   struct libwebsocket * wsi,
39   std::string type,
40   std::string transaction_id)
41   : wsi_(wsi)
42   , type_(type)
43   , transaction_id_(transaction_id)
44 {
45 }
46
47 ivi::settings::response_callback::~response_callback()
48 {
49 }
50
51 bool
52 ivi::settings::response_callback::send_response(
53   std::function<void(JsonBuilder *)> response_builder)
54 {
55   smart_ptr<JsonBuilder> const builder = begin_response("succeeded");
56
57   // Append successful Settings app results to the JSON formatted
58   // response.
59   response_builder(builder.get());
60
61   end_response(builder);
62
63   return send_payload(builder);
64 }
65
66 bool
67 ivi::settings::response_callback::send_error(std::string error_message)
68 {
69   smart_ptr<JsonBuilder> builder = begin_response("failed");
70
71   json_builder_set_member_name(builder.get(), "reason");;
72   json_builder_add_string_value(builder.get(), error_message.c_str());
73
74   end_response(builder);
75
76   return send_payload(builder);
77 }
78
79 void
80 ivi::settings::response_callback::add_string_value(
81   JsonBuilder * builder,
82   std::string const & name,
83   std::string const & value)
84 {
85   json_builder_set_member_name(builder, name.c_str());
86   if (value.empty())
87     json_builder_add_null_value(builder);
88   else
89     json_builder_add_string_value(builder, value.c_str());
90 }
91
92 ivi::settings::smart_ptr<JsonBuilder>
93 ivi::settings::response_callback::begin_response(char const * result)
94 {
95   // Construct JSON response.
96   smart_ptr<JsonBuilder> safe_builder(json_builder_new());
97   JsonBuilder * const builder = safe_builder.get();
98
99   json_builder_begin_object(builder);
100
101   add_string_value(builder, "type",          type_);
102   add_string_value(builder, "transactionid", transaction_id_);
103
104   json_builder_set_member_name(builder, "result");
105   json_builder_add_string_value(builder, result);
106
107   return safe_builder;
108 }
109
110 void
111 ivi::settings::response_callback::end_response(
112   ivi::settings::smart_ptr<JsonBuilder> const & builder)
113 {
114   json_builder_end_object(builder.get());
115 }
116
117 bool
118 ivi::settings::response_callback::send_payload(
119   ivi::settings::smart_ptr<JsonBuilder> const & builder)
120 {
121   smart_ptr<JsonGenerator> const generator(json_generator_new());
122   smart_ptr<JsonNode> const root(json_builder_get_root(builder.get()));
123   json_generator_set_root(generator.get(), root.get());
124
125   gchar * const response =
126     json_generator_to_data(generator.get(), nullptr);
127
128   smart_ptr<gchar> safe_response(response);
129
130   if (response == nullptr) {
131     g_critical("Unable to generate JSON response for:\n"
132                "    type:          %s\n"
133                "    transactionid: %s\n",
134                type_.c_str(),
135                transaction_id_.c_str());
136
137     return false;
138   }
139
140   g_debug("Sending response: %s\n", response);
141
142   size_t const payload_len = strlen(response);
143
144   // libwebsockets wants a sequence of octets (unsigned char *) rather
145   // than characters.
146   typedef std::vector<unsigned char> vector_type;
147
148   vector_type::size_type const buf_len =
149     LWS_SEND_BUFFER_PRE_PADDING
150     + payload_len
151     + LWS_SEND_BUFFER_POST_PADDING;
152
153   vector_type buf(buf_len);
154   unsigned char * const payload =
155     buf.data() + LWS_SEND_BUFFER_PRE_PADDING;
156
157   // Copy the string into the buffer after libwebsockets pre-padding.
158   std::copy(response,
159             response + payload_len,
160             payload);
161
162   int const count = libwebsocket_write(wsi_,
163                                        payload,
164                                        payload_len,
165                                        LWS_WRITE_TEXT);
166
167   return count >= 0;
168 }
169
170
171
172 // Local Variables:
173 // mode:c++
174 // c-basic-offset:2
175 // indent-tabs-mode: nil
176 // End: