Updated Lifecycle interface names; added information about user_no=0 in header files
[profile/ivi/persistence-client-library.git] / src / persistence_client_library_lc_interface.c
1 /******************************************************************************
2  * Project         Persistency
3  * (c) copyright   2012
4  * Company         XS Embedded GmbH
5  *****************************************************************************/
6 /******************************************************************************
7  * This Source Code Form is subject to the terms of the
8  * Mozilla Public License, v. 2.0. If a  copy of the MPL was not distributed
9  * with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 ******************************************************************************/
11  /**
12  * @file           persistence_client_library_lc_interface.c
13  * @ingroup        Persistence client library
14  * @author         Ingo Huerner
15  * @brief          Implementation of the persistence client library lifecycle interface.
16  * @see
17  */
18
19
20 #include "persistence_client_library_lc_interface.h"
21
22 #include "../include_protected/persistence_client_library_data_organization.h"
23 #include "../include_protected/persistence_client_library_db_access.h"
24
25 #include "persistence_client_library_handle.h"
26 #include "persistence_client_library_pas_interface.h"
27 #include "persistence_client_library_dbus_service.h"
28 #include "persistence_client_library_custom_loader.h"
29 #include "persistence_client_library_prct_access.h"
30 #include "persistence_client_library_itzam_errors.h"
31
32 #include <errno.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <unistd.h>
36 #include <dlfcn.h>
37
38 static int gTimeoutMs = 500;
39
40 int check_lc_request(int request, int requestID)
41 {
42    int rval = 0;
43
44    switch(request)
45    {
46       case NsmShutdownNormal:
47       {
48          uint64_t cmd;
49          // add command and data to queue
50          cmd = ( ((uint64_t)requestID << 32) | ((uint64_t)request << 16) | CMD_LC_PREPARE_SHUTDOWN);
51
52          if(-1 == write(gEfds, &cmd, (sizeof(uint64_t))))
53          {
54             printf("write failed w/ errno %d\n", errno);
55             rval = NsmErrorStatus_Fail;
56          }
57          else
58          {
59             rval = NsmErrorStatus_OK;
60          }
61          break;
62       }
63       default:
64       {
65          printf("Unknown lifecycle message!\n");
66          break;
67       }
68    }
69
70    return rval;
71 }
72
73
74 int msg_lifecycleRequest(DBusConnection *connection, DBusMessage *message)
75 {
76    int request   = 0,
77        requestID = 0,
78        msgReturn = 0;
79
80    DBusMessage *reply;
81    DBusError error;
82    dbus_error_init (&error);
83
84    if (!dbus_message_get_args (message, &error, DBUS_TYPE_UINT32, &request,
85                                                 DBUS_TYPE_UINT32, &requestID,
86                                                 DBUS_TYPE_INVALID))
87    {
88       reply = dbus_message_new_error(message, error.name, error.message);
89
90       if (reply == 0)
91       {
92          //DLT_LOG(mgrContext, DLT_LOG_ERROR, DLT_STRING("DBus No memory"));
93          printf("DBus No memory\n");
94       }
95
96       if (!dbus_connection_send(connection, reply, 0))
97       {
98          //DLT_LOG(mgrContext, DLT_LOG_ERROR, DLT_STRING("DBus No memory"));
99          printf("DBus No memory\n");
100       }
101
102       dbus_message_unref (reply);
103
104       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
105    }
106
107    msgReturn = check_lc_request(request, requestID);
108
109    reply = dbus_message_new_method_return(message);
110
111    if (reply == 0)
112    {
113      //DLT_LOG(mgrContext, DLT_LOG_ERROR, DLT_STRING("DBus No memory"));
114       printf("DBus No memory\n");
115    }
116
117    if (!dbus_message_append_args(reply, DBUS_TYPE_INT32, &msgReturn, DBUS_TYPE_INVALID))
118    {
119      //DLT_LOG(mgrContext, DLT_LOG_ERROR, DLT_STRING("DBus No memory"));
120       printf("DBus No memory\n");
121    }
122
123    if (!dbus_connection_send(connection, reply, 0))
124    {
125      //DLT_LOG(mgrContext, DLT_LOG_ERROR, DLT_STRING("DBus No memory"));
126       printf("DBus No memory\n");
127    }
128
129    dbus_connection_flush(connection);
130    dbus_message_unref(reply);
131
132    return DBUS_HANDLER_RESULT_HANDLED;
133 }
134
135
136
137
138 DBusHandlerResult checkLifecycleMsg(DBusConnection * connection, DBusMessage * message, void * user_data)
139 {
140    DBusHandlerResult result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
141
142    //printf("handleObjectPathMessage '%s' -> '%s'\n", dbus_message_get_interface(message), dbus_message_get_member(message));
143    if((0==strncmp("org.genivi.NodeStateManager.LifeCycleConsumer", dbus_message_get_interface(message), 20)))
144    {
145       if((0==strncmp("LifecycleRequest", dbus_message_get_member(message), 18)))
146       {
147          result = msg_lifecycleRequest(connection, message);
148       }
149       else
150       {
151           printf("checkLifecycleMsg -> unknown message '%s'\n", dbus_message_get_interface(message));
152       }
153    }
154    return result;
155 }
156
157
158
159 int send_lifecycle_register(const char* method, int shutdownMode)
160 {
161    int rval = 0;
162
163    DBusError error;
164    dbus_error_init (&error);
165    DBusConnection* conn = get_dbus_connection();
166
167    const char* objName = "/org/genivi/NodeStateManager/LifeCycleConsumer";
168    const char* busName = dbus_bus_get_unique_name(conn);
169
170    DBusMessage* message = dbus_message_new_method_call("org.genivi.NodeStateManager.Consumer",  // destination
171                                                        "/org/genivi/NodeStateManager/Consumer",  // path
172                                                        "org.genivi.NodeStateManager.Consumer",  // interface
173                                                        method);                  // method
174    if(message != NULL)
175    {
176       dbus_message_append_args(message, DBUS_TYPE_STRING, &busName,
177                                         DBUS_TYPE_STRING, &objName,
178                                         DBUS_TYPE_INT32, &shutdownMode,
179                                         DBUS_TYPE_INT32, &gTimeoutMs,
180                                         DBUS_TYPE_INVALID);
181
182       if(conn != NULL)
183       {
184          if(!dbus_connection_send(conn, message, 0))
185          {
186             fprintf(stderr, "send_lifecycle ==> Access denied: %s \n", error.message);
187          }
188
189          dbus_connection_flush(conn);
190       }
191       else
192       {
193          fprintf(stderr, "send_lifecycle ==> ERROR: Invalid connection!! \n");
194       }
195       dbus_message_unref(message);
196    }
197    else
198    {
199       fprintf(stderr, "send_lifecycle ==> ERROR: Invalid message!! \n");
200    }
201
202    return rval;
203 }
204
205
206
207 int send_lifecycle_request(const char* method, int requestId, int status)
208 {
209    int rval = 0;
210
211    DBusError error;
212    dbus_error_init (&error);
213
214    DBusConnection* conn = get_dbus_connection();
215
216    DBusMessage* message = dbus_message_new_method_call("org.genivi.NodeStateManager.Consumer",  // destination
217                                                       "/org/genivi/NodeStateManager/Consumer",  // path
218                                                        "org.genivi.NodeStateManager.Consumer",  // interface
219                                                        method);                  // method
220    if(message != NULL)
221    {
222       dbus_message_append_args(message, DBUS_TYPE_INT32, &requestId,
223                                         DBUS_TYPE_INT32, &status,
224                                         DBUS_TYPE_INVALID);
225
226       if(conn != NULL)
227       {
228          if(!dbus_connection_send(conn, message, 0))
229          {
230             fprintf(stderr, "send_lifecycle ==> Access denied: %s \n", error.message);
231          }
232
233          dbus_connection_flush(conn);
234       }
235       else
236       {
237          fprintf(stderr, "send_lifecycle ==> ERROR: Invalid connection!! \n");
238       }
239       dbus_message_unref(message);
240    }
241    else
242    {
243       fprintf(stderr, "send_lifecycle ==> ERROR: Invalid message!! \n");
244    }
245
246    return rval;
247 }
248
249
250
251 int register_lifecycle()
252 {
253    int shutdownMode = 1;  // TODO send correct mode
254
255    return send_lifecycle_register("RegisterShutdownClient", shutdownMode);
256 }
257
258
259
260 int unregister_lifecycle()
261 {
262    int shutdownMode = 1;     // TODO send correct mode
263
264    return send_lifecycle_register("UnRegisterShutdownClient", shutdownMode);
265 }
266
267
268 int send_prepare_shutdown_complete(int requestId, int status)
269 {
270    return send_lifecycle_request("LifecycleRequestComplete", requestId, status);
271 }
272
273
274
275
276 void process_prepare_shutdown(unsigned char requestId, unsigned int status)
277 {
278    int i = 0;
279    //GvdbTable* resourceTable = NULL;
280    itzam_btree* resourceTable = NULL;
281    itzam_state  state = ITZAM_FAILED;
282
283    // block write
284    pers_lock_access();
285
286    // flush open files to disk
287    for(i=0; i<MaxPersHandle; i++)
288    {
289       int tmp = i;
290       if(gOpenFdArray[tmp] == FileOpen)
291       {
292          fsync(tmp);
293          close(tmp);
294       }
295    }
296
297    // close open gvdb persistence resource configuration table
298    for(i=0; i< PrctDbTableSize; i++)
299    {
300      resourceTable = get_resource_cfg_table_by_idx(i);
301      // dereference opend database
302      if(resourceTable != NULL)
303      {
304         state = itzam_btree_close(resourceTable);
305         if (state != ITZAM_OKAY)
306         {
307            fprintf(stderr, "\nOpen Itzam problem: %s\n", STATE_MESSAGES[state]);
308         }
309      }
310    }
311
312    //close opend database
313    pers_db_close_all();
314
315
316    // unload custom client libraries
317    for(i=0; i<get_num_custom_client_libs(); i++)
318    {
319       // deinitialize plugin
320       gPersCustomFuncs[i].custom_plugin_deinit();
321       // close library handle
322       dlclose(gPersCustomFuncs[i].handle);
323    }
324
325    // notify lifecycle shutdown OK
326    send_prepare_shutdown_complete((int)requestId, (int)status);
327 }
328