Removed compiler warnings
[profile/ivi/persistence-client-library.git] / src / persistence_client_library_dbus_cmd.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_dbus_cmd.c
13  * @ingroup        Persistence client library
14  * @author         Ingo Huerner
15  * @brief          Implementation of the persistence client library dbus commands.
16  * @see
17  */
18
19 #include "persistence_client_library_dbus_cmd.h"
20
21 #include "persistence_client_library_handle.h"
22 #include "persistence_client_library_itzam_errors.h"
23 #include "persistence_client_library_custom_loader.h"
24 #include "persistence_client_library_prct_access.h"
25 #include "persistence_client_library_pas_interface.h"
26
27 #include "../include_protected/persistence_client_library_data_organization.h"
28 #include "../include_protected/persistence_client_library_db_access.h"
29
30 #include <itzam.h>
31 #include <dlfcn.h>
32
33
34 // function prototype
35 void msg_pending_func(DBusPendingCall *call, void *data);
36
37
38
39 void process_reg_notification_signal(DBusConnection* conn)
40 {
41    char ruleChanged[DbusMatchRuleSize] = {0};
42    char ruleDeleted[DbusMatchRuleSize] = {0};
43    char ruleCreated[DbusMatchRuleSize] = {0};
44
45    // add match for  c h a n g e
46    snprintf(ruleChanged, DbusMatchRuleSize,
47             "type='signal',interface='org.genivi.persistence.adminconsumer',member='PersistenceResChange',path='/org/genivi/persistence/adminconsumer',arg0='%s',arg1='%u',arg2='%u',arg3='%u'",
48             gNotifykey, gNotifyLdbid, gNotifyUserNo, gNotifySeatNo);
49
50    // add match for  d e l e t e
51    snprintf(ruleDeleted, DbusMatchRuleSize,
52             "type='signal',interface='org.genivi.persistence.adminconsumer',member='PersistenceResDelete',path='/org/genivi/persistence/adminconsumer',arg0='%s',arg1='%u',arg2='%u',arg3='%u'",
53             gNotifykey, gNotifyLdbid, gNotifyUserNo, gNotifySeatNo);
54
55    // add match for  c r e a t e
56    snprintf(ruleCreated, DbusMatchRuleSize,
57             "type='signal',interface='org.genivi.persistence.adminconsumer',member='PersistenceResCreate',path='/org/genivi/persistence/adminconsumer',arg0='%s',arg1='%u',arg2='%u',arg3='%u'",
58             gNotifykey, gNotifyLdbid, gNotifyUserNo, gNotifySeatNo);
59
60    if(gNotifyPolicy == Notify_register)
61    {
62       dbus_bus_add_match(conn, ruleChanged, NULL);
63       dbus_bus_add_match(conn, ruleDeleted, NULL);
64       dbus_bus_add_match(conn, ruleCreated, NULL);
65    }
66    else if(gNotifyPolicy == Notify_unregister)
67    {
68       dbus_bus_remove_match(conn, ruleChanged, NULL);
69       dbus_bus_remove_match(conn, ruleDeleted, NULL);
70       dbus_bus_remove_match(conn, ruleCreated, NULL);
71    }
72
73    dbus_connection_flush(conn);  // flush the connection to add the match
74 }
75
76
77
78 void process_send_notification_signal(DBusConnection* conn)
79 {
80    dbus_bool_t ret;
81    DBusMessage* message;
82    const char* notifyReason = NULL;
83
84    char ldbidArray[DbusSubMatchSize] = {0};
85    char userArray[DbusSubMatchSize]  = {0};
86    char seatArray[DbusSubMatchSize]  = {0};
87    char* pldbidArra = ldbidArray;
88    char* puserArray = userArray;
89    char* pseatArray = seatArray;
90    char* pnotifyKey = gNotifykey;
91
92    switch(gNotifyReason)
93    {
94       case pclNotifyStatus_deleted:
95          notifyReason = gDeleteSignal;
96          break;
97       case  pclNotifyStatus_created:
98          notifyReason = gCreateSignal;
99          break;
100       case pclNotifyStatus_changed:
101          notifyReason = gChangeSignal;
102          break;
103       default:
104          notifyReason = NULL;
105          break;
106    }
107
108    if(notifyReason != NULL)
109    {
110       // dbus_bus_add_match is used for the notification mechanism,
111       // and this works only for type DBUS_TYPE_STRING as message arguments
112       // this is the reason to use string instead of integer types directly
113       snprintf(ldbidArray, DbusSubMatchSize, "%u", gNotifyLdbid);
114       snprintf(userArray,  DbusSubMatchSize, "%u", gNotifyUserNo);
115       snprintf(seatArray,  DbusSubMatchSize, "%u", gNotifySeatNo);
116
117       //printf("process_send_Notification_Signal => key: %s | lbid: %d | gUserNo: %d | gSeatNo: %d | gReason: %d \n", gNotifykey, gLdbid, gUserNo, gSeatNo, gReason);
118       message = dbus_message_new_signal("/org/genivi/persistence/adminconsumer",    // const char *path,
119                                         "org.genivi.persistence.adminconsumer",     // const char *interface,
120                                         notifyReason);                                 // const char *name
121
122       ret = dbus_message_append_args(message, DBUS_TYPE_STRING, &pnotifyKey,
123                                               DBUS_TYPE_STRING, &pldbidArra,
124                                               DBUS_TYPE_STRING, &puserArray,
125                                               DBUS_TYPE_STRING, &pseatArray,
126                                               DBUS_TYPE_INVALID);
127       if(ret == TRUE)
128       {
129          // Send the signal
130          if(conn != NULL)
131          {
132             if(dbus_connection_send(conn, message, 0) == TRUE)
133             {
134                // Free the signal now we have finished with it
135                dbus_message_unref(message);
136             }
137             else
138             {
139                DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("process_send_Notification_Signal ==> failed to send dbus message!!"));
140             }
141          }
142          else
143          {
144             DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("process_send_Notification_Signal ==> E R R O R  C O N E C T I O N  NULL!!"));
145          }
146       }
147       else
148       {
149          DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("process_send_Notification_Signal ==> ERROR dbus_message_append_args"));
150       }
151    }
152    else
153    {
154       DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("process_send_Notification_Signal ==> ERROR invalid notification reason"));
155    }
156 }
157
158
159
160 void process_block_and_write_data_back(unsigned int requestID, unsigned int status)
161 {
162    // lock persistence data access
163    pers_lock_access();
164    // sync data back to memory device
165    pers_data_sync();
166    // send complete notification
167    //pers_admin_service_data_sync_complete(requestID, status);
168 }
169
170
171
172 void process_prepare_shutdown(unsigned char requestId, unsigned int status)
173 {
174    int i = 0;
175
176    // block write
177    pers_lock_access();
178
179    // flush open files to disk
180    for(i=0; i<MaxPersHandle; i++)
181    {
182       int tmp = i;
183       if(gOpenFdArray[tmp] == FileOpen)
184       {
185          fsync(tmp);
186          close(tmp);
187       }
188    }
189
190    // close all opend rct
191    pers_rct_close_all();
192
193    // close opend database
194    pers_db_close_all();
195
196
197    // unload custom client libraries
198    for(i=0; i<PersCustomLib_LastEntry; i++)
199    {
200       if(gPersCustomFuncs[i].custom_plugin_deinit != NULL)
201       {
202          // deinitialize plugin
203          gPersCustomFuncs[i].custom_plugin_deinit();
204          // close library handle
205          dlclose(gPersCustomFuncs[i].handle);
206
207          invalidate_custom_plugin(i);
208       }
209    }
210 }
211
212
213
214 void process_send_pas_request(DBusConnection* conn, unsigned int requestID, int status)
215 {
216    DBusError error;
217    dbus_error_init (&error);
218
219    DBusMessage* message = dbus_message_new_method_call("org.genivi.persistence.admin",       // destination
220                                                       "/org/genivi/persistence/admin",       // path
221                                                        "org.genivi.persistence.admin",       // interface
222                                                        "PersistenceAdminRequestCompleted");  // method
223    if(conn != NULL)
224    {
225       if(message != NULL)
226       {
227          dbus_message_append_args(message, DBUS_TYPE_UINT32, &requestID,
228                                            DBUS_TYPE_INT32,  &status,
229                                            DBUS_TYPE_INVALID);
230
231          if(!dbus_connection_send(conn, message, 0))
232          {
233             DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_lifecycle_register => Access denied"), DLT_STRING(error.message) );
234          }
235
236          dbus_connection_flush(conn);
237          dbus_message_unref(message);
238       }
239       else
240       {
241          DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_pas_request => ERROR: Invalid message") );
242       }
243    }
244    else
245    {
246       DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_pas_request => ERROR: Invalid connection") );
247    }
248 }
249
250
251 void process_send_pas_register(DBusConnection* conn, int regType, int notificationFlag)
252 {
253    DBusError error;
254    dbus_error_init (&error);
255    DBusPendingCall* pending = NULL;
256
257    char* method = NULL;
258
259    if(regType == 0)
260       method = "UnRegisterPersAdminNotification";
261    else if(regType == 1)
262       method = "RegisterPersAdminNotification";
263
264    if(conn != NULL)
265    {
266       const char* objName = "/org/genivi/persistence/adminconsumer";
267       const char* busName = dbus_bus_get_unique_name(conn);
268
269       if(busName != NULL)
270       {
271          DBusMessage* message = dbus_message_new_method_call("org.genivi.persistence.admin",    // destination
272                                                             "/org/genivi/persistence/admin",    // path
273                                                              "org.genivi.persistence.admin",    // interface
274                                                              method);                           // method
275
276          if(message != NULL)
277          {
278             dbus_message_append_args(message, DBUS_TYPE_STRING, &busName,  // bus name
279                                               DBUS_TYPE_STRING, &objName,
280                                               DBUS_TYPE_INT32,  &notificationFlag,
281                                               DBUS_TYPE_UINT32, &gTimeoutMs,
282                                               DBUS_TYPE_INVALID);
283
284             dbus_connection_send_with_reply(conn,           //    the connection
285                                             message,        // the message to write
286                                             &pending,       // pending
287                                             gTimeoutMs);    // timeout in milliseconds or -1 for default
288
289             dbus_connection_flush(conn);
290
291             if(!dbus_pending_call_set_notify(pending, msg_pending_func, method, NULL))
292             {
293                DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("process_send_pas_register => dbus_pending_call_set_notify: FAILED\n") );
294             }
295             dbus_pending_call_unref(pending);
296          }
297          else
298          {
299             DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_pas_register =>  ERROR: Invalid message") );
300          }
301          dbus_message_unref(message);
302       }
303       else
304       {
305          DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_pas_register =>  ERROR: Invalid busname") );
306       }
307    }
308    else
309    {
310       DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_pas_register =>  ERROR: Invalid connection") );
311    }
312 }
313
314
315 void process_send_lifecycle_register(DBusConnection* conn, int regType, int shutdownMode)
316 {
317    DBusError error;
318    dbus_error_init (&error);
319
320    char* method = NULL;
321
322    if(regType == 1)
323       method = "RegisterShutdownClient";
324    else if(regType == 0)
325       method = "UnRegisterShutdownClient";
326
327    if(conn != NULL)
328    {
329       const char* objName = "/org/genivi/NodeStateManager/LifeCycleConsumer";
330       const char* busName = dbus_bus_get_unique_name(conn);
331
332       DBusMessage* message = dbus_message_new_method_call("org.genivi.NodeStateManager",           // destination
333                                                           "/org/genivi/NodeStateManager/Consumer", // path
334                                                           "org.genivi.NodeStateManager.Consumer",  // interface
335                                                           method);                                 // method
336       if(message != NULL)
337       {
338          if(regType == 1)   // register
339          {
340             dbus_message_append_args(message, DBUS_TYPE_STRING, &busName,
341                                               DBUS_TYPE_STRING, &objName,
342                                               DBUS_TYPE_UINT32, &shutdownMode,
343                                               DBUS_TYPE_UINT32, &gTimeoutMs, DBUS_TYPE_INVALID);
344          }
345          else           // unregister
346          {
347             dbus_message_append_args(message, DBUS_TYPE_STRING, &busName,
348                                               DBUS_TYPE_STRING, &objName,
349                                               DBUS_TYPE_UINT32, &shutdownMode, DBUS_TYPE_INVALID);
350          }
351
352                    if(!dbus_connection_send(conn, message, 0))
353                    {
354                       DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_lifecycle_register => Access denied"), DLT_STRING(error.message) );
355                    }
356                    dbus_connection_flush(conn);
357          dbus_message_unref(message);
358       }
359       else
360       {
361          DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_lifecycle_register => ERROR: Invalid message"));
362       }
363    }
364    else
365    {
366       DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_lifecycle_register => ERROR: connection isn NULL"));
367    }
368 }
369
370
371
372 void process_send_lifecycle_request(DBusConnection* conn, int requestId, int status)
373 {
374    DBusError error;
375    dbus_error_init (&error);
376
377    if(conn != NULL)
378    {
379       DBusMessage* message = dbus_message_new_method_call("org.genivi.NodeStateManager",           // destination
380                                                          "/org/genivi/NodeStateManager/Consumer",  // path
381                                                           "org.genivi.NodeStateManager.Consumer",  // interface
382                                                           "LifecycleRequestComplete");             // method
383       if(message != NULL)
384       {
385          dbus_message_append_args(message, DBUS_TYPE_INT32, &requestId,
386                                            DBUS_TYPE_INT32, &status,
387                                            DBUS_TYPE_INVALID);
388
389
390          if(!dbus_connection_send(conn, message, 0))
391          {
392             DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_lifecycle_request => Access denied"), DLT_STRING(error.message) );
393           }
394
395           dbus_connection_flush(conn);
396           dbus_message_unref(message);
397       }
398       else
399       {
400          DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_lifecycle_request => ERROR: Invalid message"));
401       }
402    }
403    else
404    {
405       DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_lifecycle_request => ERROR: connection isn NULL"));
406    }
407 }
408
409
410
411 void msg_pending_func(DBusPendingCall *call, void *data)
412 {
413    int replyArg = -1;
414    DBusError err;
415    dbus_error_init(&err);
416
417    DBusMessage *message = dbus_pending_call_steal_reply(call);
418
419    if (dbus_set_error_from_message(&err, message))
420    {
421       DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("msg_pending_func ==> Access denied") );
422    }
423    else
424    {
425       //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("msg_pending_func ==> UNlock mutex") );
426       dbus_message_get_args(message, &err, DBUS_TYPE_INT32, &replyArg, DBUS_TYPE_INVALID);
427    }
428
429    gDbusPendingRvalue = replyArg;   // set the return value
430    dbus_message_unref(message);
431
432    // unlock the mutex because we have received the reply to the dbus message
433    pthread_mutex_unlock(&gDbusPendingRegMtx);
434 }
435
436
437
438