1 /******************************************************************************
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 ******************************************************************************/
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.
19 #include "persistence_client_library_dbus_cmd.h"
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"
27 #include "../include_protected/persistence_client_library_data_organization.h"
28 #include "../include_protected/persistence_client_library_db_access.h"
35 void msg_pending_func(DBusPendingCall *call, void *data);
39 void process_reg_notification_signal(DBusConnection* conn)
41 char ruleChanged[DbusMatchRuleSize] = {0};
42 char ruleDeleted[DbusMatchRuleSize] = {0};
43 char ruleCreated[DbusMatchRuleSize] = {0};
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);
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);
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);
60 if(gNotifyPolicy == Notify_register)
62 dbus_bus_add_match(conn, ruleChanged, NULL);
63 dbus_bus_add_match(conn, ruleDeleted, NULL);
64 dbus_bus_add_match(conn, ruleCreated, NULL);
66 else if(gNotifyPolicy == Notify_unregister)
68 dbus_bus_remove_match(conn, ruleChanged, NULL);
69 dbus_bus_remove_match(conn, ruleDeleted, NULL);
70 dbus_bus_remove_match(conn, ruleCreated, NULL);
73 dbus_connection_flush(conn); // flush the connection to add the match
78 void process_send_notification_signal(DBusConnection* conn)
82 const char* notifyReason = NULL;
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;
94 case pclNotifyStatus_deleted:
95 notifyReason = gDeleteSignal;
97 case pclNotifyStatus_created:
98 notifyReason = gCreateSignal;
100 case pclNotifyStatus_changed:
101 notifyReason = gChangeSignal;
108 if(notifyReason != NULL)
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);
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
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,
132 if(dbus_connection_send(conn, message, 0) == TRUE)
134 // Free the signal now we have finished with it
135 dbus_message_unref(message);
139 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("process_send_Notification_Signal ==> failed to send dbus message!!"));
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!!"));
149 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("process_send_Notification_Signal ==> ERROR dbus_message_append_args"));
154 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("process_send_Notification_Signal ==> ERROR invalid notification reason"));
160 void process_block_and_write_data_back(unsigned int requestID, unsigned int status)
162 // lock persistence data access
164 // sync data back to memory device
166 // send complete notification
167 //pers_admin_service_data_sync_complete(requestID, status);
172 void process_prepare_shutdown(unsigned char requestId, unsigned int status)
179 // flush open files to disk
180 for(i=0; i<MaxPersHandle; i++)
183 if(gOpenFdArray[tmp] == FileOpen)
190 // close all opend rct
191 pers_rct_close_all();
193 // close opend database
197 // unload custom client libraries
198 for(i=0; i<PersCustomLib_LastEntry; i++)
200 if(gPersCustomFuncs[i].custom_plugin_deinit != NULL)
202 // deinitialize plugin
203 gPersCustomFuncs[i].custom_plugin_deinit();
204 // close library handle
205 dlclose(gPersCustomFuncs[i].handle);
207 invalidate_custom_plugin(i);
214 void process_send_pas_request(DBusConnection* conn, unsigned int requestID, int status)
217 dbus_error_init (&error);
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
227 dbus_message_append_args(message, DBUS_TYPE_UINT32, &requestID,
228 DBUS_TYPE_INT32, &status,
231 if(!dbus_connection_send(conn, message, 0))
233 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_lifecycle_register => Access denied"), DLT_STRING(error.message) );
236 dbus_connection_flush(conn);
237 dbus_message_unref(message);
241 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_pas_request => ERROR: Invalid message") );
246 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_pas_request => ERROR: Invalid connection") );
251 void process_send_pas_register(DBusConnection* conn, int regType, int notificationFlag)
254 dbus_error_init (&error);
255 DBusPendingCall* pending = NULL;
260 method = "UnRegisterPersAdminNotification";
261 else if(regType == 1)
262 method = "RegisterPersAdminNotification";
266 const char* objName = "/org/genivi/persistence/adminconsumer";
267 const char* busName = dbus_bus_get_unique_name(conn);
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
278 dbus_message_append_args(message, DBUS_TYPE_STRING, &busName, // bus name
279 DBUS_TYPE_STRING, &objName,
280 DBUS_TYPE_INT32, ¬ificationFlag,
281 DBUS_TYPE_UINT32, &gTimeoutMs,
284 dbus_connection_send_with_reply(conn, // the connection
285 message, // the message to write
287 gTimeoutMs); // timeout in milliseconds or -1 for default
289 dbus_connection_flush(conn);
291 if(!dbus_pending_call_set_notify(pending, msg_pending_func, method, NULL))
293 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("process_send_pas_register => dbus_pending_call_set_notify: FAILED\n") );
295 dbus_pending_call_unref(pending);
299 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_pas_register => ERROR: Invalid message") );
301 dbus_message_unref(message);
305 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_pas_register => ERROR: Invalid busname") );
310 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_pas_register => ERROR: Invalid connection") );
315 void process_send_lifecycle_register(DBusConnection* conn, int regType, int shutdownMode)
318 dbus_error_init (&error);
323 method = "RegisterShutdownClient";
324 else if(regType == 0)
325 method = "UnRegisterShutdownClient";
329 const char* objName = "/org/genivi/NodeStateManager/LifeCycleConsumer";
330 const char* busName = dbus_bus_get_unique_name(conn);
332 DBusMessage* message = dbus_message_new_method_call("org.genivi.NodeStateManager", // destination
333 "/org/genivi/NodeStateManager/Consumer", // path
334 "org.genivi.NodeStateManager.Consumer", // interface
338 if(regType == 1) // register
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);
347 dbus_message_append_args(message, DBUS_TYPE_STRING, &busName,
348 DBUS_TYPE_STRING, &objName,
349 DBUS_TYPE_UINT32, &shutdownMode, DBUS_TYPE_INVALID);
352 if(!dbus_connection_send(conn, message, 0))
354 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_lifecycle_register => Access denied"), DLT_STRING(error.message) );
356 dbus_connection_flush(conn);
357 dbus_message_unref(message);
361 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_lifecycle_register => ERROR: Invalid message"));
366 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_lifecycle_register => ERROR: connection isn NULL"));
372 void process_send_lifecycle_request(DBusConnection* conn, int requestId, int status)
375 dbus_error_init (&error);
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
385 dbus_message_append_args(message, DBUS_TYPE_INT32, &requestId,
386 DBUS_TYPE_INT32, &status,
390 if(!dbus_connection_send(conn, message, 0))
392 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_lifecycle_request => Access denied"), DLT_STRING(error.message) );
395 dbus_connection_flush(conn);
396 dbus_message_unref(message);
400 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_lifecycle_request => ERROR: Invalid message"));
405 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("send_lifecycle_request => ERROR: connection isn NULL"));
411 void msg_pending_func(DBusPendingCall *call, void *data)
415 dbus_error_init(&err);
417 DBusMessage *message = dbus_pending_call_steal_reply(call);
419 if (dbus_set_error_from_message(&err, message))
421 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("msg_pending_func ==> Access denied") );
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);
429 gDbusPendingRvalue = replyArg; // set the return value
430 dbus_message_unref(message);
432 // unlock the mutex because we have received the reply to the dbus message
433 pthread_mutex_unlock(&gDbusPendingRegMtx);