/****************************************************************************** * Project Persistency * (c) copyright 2012 * Company XS Embedded GmbH *****************************************************************************/ /****************************************************************************** * This Source Code Form is subject to the terms of the * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed * with this file, You can obtain one at http://mozilla.org/MPL/2.0/. ******************************************************************************/ /** * @file persistence_client_library_dbus_cmd.c * @ingroup Persistence client library * @author Ingo Huerner * @brief Implementation of the persistence client library dbus commands. * @see */ #include "persistence_client_library_dbus_cmd.h" #include "persistence_client_library_handle.h" #include "persistence_client_library_custom_loader.h" #include "persistence_client_library_pas_interface.h" #include "persistence_client_library_db_access.h" #include "persistence_client_library_file.h" #if USE_FILECACHE #include /** * write back from cache to non volatile memory device * ATTENTION: * THIS FUNCTION IS NOT INTENDED TO BE USED BY A NORMAL APPLICATION. * ONLY SPECIAL APPLICATION ARE ALLOWED TO USING USE THIS FUNCTION **/ extern int pfcWriteBackAndSync(int handle); #endif #include #include #include DLT_IMPORT_CONTEXT(gPclDLTContext); /// change signal string static const char* gChangeSignal = "PersistenceResChange"; /// delete signal string static const char* gDeleteSignal = "PersistenceResDelete"; /// create signal string static const char* gCreateSignal = "PersistenceResCreate"; /// dbus timeout static int gTimeoutMs = 5000; // function prototype static void msg_pending_func(DBusPendingCall *call, void *data); void process_reg_notification_signal(DBusConnection* conn, unsigned int notifyLdbid, unsigned int notifyUserNo, unsigned int notifySeatNo, unsigned int notifyPolicy, const char* notifyKey) { char ruleChanged[DbusMatchRuleSize] = {[0 ... DbusMatchRuleSize-1] = 0}; char ruleDeleted[DbusMatchRuleSize] = {[0 ... DbusMatchRuleSize-1] = 0}; char ruleCreated[DbusMatchRuleSize] = {[0 ... DbusMatchRuleSize-1] = 0}; DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("process notification - User:"), DLT_UINT(notifyUserNo), DLT_STRING("- Seat:"), DLT_UINT(notifySeatNo)); // add match for c h a n g e snprintf(ruleChanged, DbusMatchRuleSize, "type='signal',interface='org.genivi.persistence.adminconsumer',member='PersistenceResChange',path='/org/genivi/persistence/adminconsumer',arg0='%s',arg1='%u',arg2='%u',arg3='%u'", notifyKey, notifyLdbid, notifyUserNo, notifySeatNo); // add match for d e l e t e snprintf(ruleDeleted, DbusMatchRuleSize, "type='signal',interface='org.genivi.persistence.adminconsumer',member='PersistenceResDelete',path='/org/genivi/persistence/adminconsumer',arg0='%s',arg1='%u',arg2='%u',arg3='%u'", notifyKey, notifyLdbid, notifyUserNo, notifySeatNo); // add match for c r e a t e snprintf(ruleCreated, DbusMatchRuleSize, "type='signal',interface='org.genivi.persistence.adminconsumer',member='PersistenceResCreate',path='/org/genivi/persistence/adminconsumer',arg0='%s',arg1='%u',arg2='%u',arg3='%u'", notifyKey, notifyLdbid, notifyUserNo, notifySeatNo); if(notifyPolicy == Notify_register) { dbus_bus_add_match(conn, ruleChanged, NULL); dbus_bus_add_match(conn, ruleDeleted, NULL); dbus_bus_add_match(conn, ruleCreated, NULL); DLT_LOG(gPclDLTContext, DLT_LOG_VERBOSE, DLT_STRING("Reg for change notify:"), DLT_STRING(ruleChanged)); } else if(notifyPolicy == Notify_unregister) { dbus_bus_remove_match(conn, ruleChanged, NULL); dbus_bus_remove_match(conn, ruleDeleted, NULL); dbus_bus_remove_match(conn, ruleCreated, NULL); DLT_LOG(gPclDLTContext, DLT_LOG_VERBOSE, DLT_STRING("unREg for change notify:"), DLT_STRING(ruleChanged)); } dbus_connection_flush(conn); // flush the connection to add the match } void process_send_notification_signal(DBusConnection* conn, unsigned int notifyLdbid, unsigned int notifyUserNo, unsigned int notifySeatNo, unsigned int notifyReason, const char* notifyKey) { dbus_bool_t ret; DBusMessage* message; const char* notifyReasonString = NULL; DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("send notification - User:"), DLT_UINT(notifyUserNo), DLT_STRING("- Seat:"), DLT_UINT(notifySeatNo)); char ldbidArray[DbusSubMatchSize] = {[0 ... DbusSubMatchSize-1] = 0}; char userArray[DbusSubMatchSize] = {[0 ... DbusSubMatchSize-1] = 0}; char seatArray[DbusSubMatchSize] = {[0 ... DbusSubMatchSize-1] = 0}; char* pldbidArra = ldbidArray; char* puserArray = userArray; char* pseatArray = seatArray; char* pnotifyKey = (char*)notifyKey; switch(notifyReason) { case pclNotifyStatus_deleted: notifyReasonString = gDeleteSignal; break; case pclNotifyStatus_created: notifyReasonString = gCreateSignal; break; case pclNotifyStatus_changed: notifyReasonString = gChangeSignal; break; default: notifyReasonString = NULL; break; } if(notifyReasonString != NULL) { // dbus_bus_add_match is used for the notification mechanism, // and this works only for type DBUS_TYPE_STRING as message arguments // this is the reason to use string instead of integer types directly snprintf(ldbidArray, DbusSubMatchSize, "%u", notifyLdbid); snprintf(userArray, DbusSubMatchSize, "%u", notifyUserNo); snprintf(seatArray, DbusSubMatchSize, "%u", notifySeatNo); //printf("process_send_Notification_Signal => key: %s | lbid: %d | gUserNo: %d | gSeatNo: %d | gReason: %d \n", notifyKey, notifyLdbid, notifyUserNo, notifySeatNo, notifyReason); message = dbus_message_new_signal(gPersAdminConsumerPath, gDbusPersAdminConsInterface, notifyReasonString); ret = dbus_message_append_args(message, DBUS_TYPE_STRING, &pnotifyKey, DBUS_TYPE_STRING, &pldbidArra, DBUS_TYPE_STRING, &puserArray, DBUS_TYPE_STRING, &pseatArray, DBUS_TYPE_INVALID); if(ret == TRUE) { if(conn != NULL) // Send the signal { if(dbus_connection_send(conn, message, 0) == TRUE) { dbus_message_unref(message); // Free the signal now we have finished with it } else { DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("sendNotifySig - failed to send msg!!")); } } else { DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("sendNotifySig - Con NULL")); } } else { DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("sendNotifySig - _append_args")); } } else { DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("sendNotifySig - Inval noty reason")); } } void process_block_and_write_data_back(unsigned int requestID, unsigned int status) { (void)requestID; (void)status; // lock persistence data access pers_lock_access(); // sync data back to memory device } void process_prepare_shutdown(unsigned int complete) { int i = 0; DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("prepShtdwn - writing all changed data / closing all handles")); // block write pers_lock_access(); // flush open files to disk #if USE_FILECACHE if(complete == Shutdown_Full) { rval = pfcCloseFile(i); } else if(complete == Shutdown_Partial) { pfcWriteBackAndSync(i); } #else if(complete == Shutdown_Full) { list_iterate(&gOpenFdList, &pclFileClose); } else if(complete == Shutdown_Partial) { list_iterate(&gOpenFdList, &fsync); } #endif pers_rct_close_all(); // close all opened resource configuration table database_close_all(); // close opened database if(complete > 0) { close_all_persistence_handle(); for(i=0; i UNlock mutex") ); dbus_message_get_args(message, &err, DBUS_TYPE_INT32, &replyArg, DBUS_TYPE_INVALID); } gDbusPendingRvalue = replyArg; // set the return value gDbusPendingCondValue = 1; pthread_cond_signal(&gDbusPendingCond); // unlock the mutex because we have received the reply to the dbus message pthread_mutex_unlock(&gDbusPendingRegMtx); dbus_message_unref(message); }