diff options
author | Ingo Huerner <ingo.huerner@xse.de> | 2013-03-27 14:17:43 +0100 |
---|---|---|
committer | Ingo Huerner <ingo.huerner@xse.de> | 2013-03-27 14:17:43 +0100 |
commit | 9b1db7aadd4e326a24c35a7b2408b8e1d3958026 (patch) | |
tree | eede6ccecbcc07cbe9aad180c450b55ae6fad9e1 | |
parent | 1e9bbac24b54622b43c3ed04a639506cdb905252 (diff) | |
download | persistence-client-library-9b1db7aadd4e326a24c35a7b2408b8e1d3958026.tar.gz |
Implemented changed notification for shared data; persistence_client_library_dbus_test.c has beend used for receiving notifications
-rw-r--r-- | README | 11 | ||||
-rw-r--r-- | include/persistence_client_library_key.h | 33 | ||||
-rw-r--r-- | include_protected/persistence_client_library_data_organization.h | 6 | ||||
-rw-r--r-- | include_protected/persistence_client_library_db_access.h | 4 | ||||
-rw-r--r-- | src/persistence_client_library_data_organization.c | 2 | ||||
-rw-r--r-- | src/persistence_client_library_db_access.c | 74 | ||||
-rw-r--r-- | src/persistence_client_library_dbus_service.c | 61 | ||||
-rw-r--r-- | src/persistence_client_library_key.c | 14 | ||||
-rw-r--r-- | src/persistence_client_library_pas_interface.c | 34 | ||||
-rw-r--r-- | test/data/Data.tar.gz | bin | 98914 -> 131411 bytes | |||
-rw-r--r-- | test/persistence_client_library_dbus_test.c | 24 | ||||
-rw-r--r-- | test/persistence_client_library_test.c | 31 | ||||
-rw-r--r-- | test/persistence_lifeCycle_mockup.c | 7 |
13 files changed, 257 insertions, 44 deletions
@@ -1,6 +1,7 @@ Environment The Persistence Client Library has been developed using Ubuntu 11.10 + Required packages * automotive-dlt: available via GENIVI projects ==> http://git.projects.genivi.org/?p=dlt-daemon.git;a=summary * Itzam/C: download from here ==> http://www.coyotegulch.com/products/itzam/c/index.html @@ -8,6 +9,7 @@ Required packages * autotools: install via Synaptic Package Manger or use apt-get * GNU c compiler: install via Synaptic Package Manger or use apt-get + Known issues: * Patch Itzam/C configure.ac file: - replace in the Itzam/C configure.ac GENERIC_LIBRARY_NAME=libitzam with GENERIC_LIBRARY_NAME=itzam @@ -20,3 +22,12 @@ To build the client library perform the following steps: * "autoreconf -vi" * "./configure --enable-tests" * "make" + + +How to run: +After building the client library and the test code the test data needs to be copied to the appropriate place. +The test data is located in the test subdirectory test/data/Data.tar.gz and needs be extracted to the root/Data folder. + + + + diff --git a/include/persistence_client_library_key.h b/include/persistence_client_library_key.h index 72acf65..876d951 100644 --- a/include/persistence_client_library_key.h +++ b/include/persistence_client_library_key.h @@ -34,7 +34,34 @@ extern "C" { #define PERSIST_KEYVALUEAPI_INTERFACE_VERSION (0x03000000U) +/** +* status returned in notification structure +*/ +typedef enum _PersistenceNotifyStatus_e +{ + pclNotifyStatus_no_changed = 0, + pclNotifyStatus_created, + pclNotifyStatus_changed, + pclNotifyStatus_deleted, + /* insert new_ entries here .. */ + pclNotifyStatus_lastEntry +} PersistenceNotifyStatus_e; + + +/** +* structure to return in case of notification +*/ +typedef struct _PersistenceNotification_s +{ + PersistenceNotifyStatus_e pclKeyNotify_Status; + unsigned int ldbid; + const char * resource_id; + unsigned int user_no; + unsigned int seat_no; +} PersistenceNotification_s; + +typedef int(* changeNotifyCallback_t)(PersistenceNotification_s * notifyStruct); /** * @brief delete persistent data @@ -120,10 +147,11 @@ int pclKeyHandleReadData(int key_handle, unsigned char* buffer, int buffer_size) * @brief register a change notification for persistent data * * @param key_handle key value handle return by key_handle_open() + * @param callback notification callback * * @return positive value: registration OK; On error a negative value will be returned with th follwoing error codes: */ -int pclKeyHandleRegisterNotifyOnChange(int key_handle); +int pclKeyHandleRegisterNotifyOnChange(int key_handle, changeNotifyCallback_t callback); @@ -164,10 +192,11 @@ int pclKeyReadData(unsigned int ldbid, const char* resource_id, unsigned int use * @param resource_id the resource ID * @param user_no the user ID; user_no=0 can not be used as user-ID beacause ‘0’ is defined as System/node * @param seat_no the seat number + * @param callback notification callback * * @return positive value: registration OK; On error a negative value will be returned with th follwoing error codes: */ -int pclKeyRegisterNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no); +int pclKeyRegisterNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no, changeNotifyCallback_t callback); diff --git a/include_protected/persistence_client_library_data_organization.h b/include_protected/persistence_client_library_data_organization.h index ca28be8..6151aa4 100644 --- a/include_protected/persistence_client_library_data_organization.h +++ b/include_protected/persistence_client_library_data_organization.h @@ -27,6 +27,8 @@ extern "C" { #define PERSIST_CLIENT_LIBRARY_DATA_ORGANIZATION_INTERFACE_VERSION (0x01000000U) #include "../include/persistence_client_library_error_def.h" +#include "../include/persistence_client_library_key.h" + #include <string.h> #include <stdio.h> @@ -127,6 +129,10 @@ extern char gAppId[MaxAppNameLen]; /// max key value data size extern int gMaxKeyValDataSize; + +extern int(* gChangeNotifyCallback)(PersistenceNotification_s * notifyStruct); + + #ifdef __cplusplus } #endif diff --git a/include_protected/persistence_client_library_db_access.h b/include_protected/persistence_client_library_db_access.h index 7e7c0aa..1958b0a 100644 --- a/include_protected/persistence_client_library_db_access.h +++ b/include_protected/persistence_client_library_db_access.h @@ -29,6 +29,7 @@ extern "C" { #include "persistence_client_library_data_organization.h" #include "persistence_client_library_rc_table.h" +#include "persistence_client_library_key.h" @@ -116,7 +117,8 @@ void pers_db_close_all(); * * @return 0 of registration was successfull; -1 if registration failes */ -int persistence_reg_notify_on_change(char* dbPath, char* key); +int persistence_reg_notify_on_change(char* dbPath, char* key, unsigned int ldbid, unsigned int user_no, unsigned int seat_no, + changeNotifyCallback_t callback); diff --git a/src/persistence_client_library_data_organization.c b/src/persistence_client_library_data_organization.c index b53d15f..f88becb 100644 --- a/src/persistence_client_library_data_organization.c +++ b/src/persistence_client_library_data_organization.c @@ -77,6 +77,6 @@ char gAppId[MaxAppNameLen]; int gMaxKeyValDataSize = defaultMaxKeyValDataSize; - +int(* gChangeNotifyCallback)(PersistenceNotification_s * notifyStruct); diff --git a/src/persistence_client_library_db_access.c b/src/persistence_client_library_db_access.c index 778cd03..5fdb09b 100644 --- a/src/persistence_client_library_db_access.c +++ b/src/persistence_client_library_db_access.c @@ -22,6 +22,9 @@ #include "persistence_client_library_custom_loader.h" #include "persistence_client_library_itzam_errors.h" +#include "persistence_client_library_dbus_service.h" + +#include <dbus/dbus.h> #include <string.h> #include <stdio.h> #include <stdlib.h> @@ -219,8 +222,8 @@ int pers_db_write_key(char* dbPath, char* key, PersistenceInfo_s* info, unsigned { int write_size = -1; - if( PersistenceStorage_shared == info->configKey.storage - || PersistenceStorage_local == info->configKey.storage) + if( PersistenceStorage_local == info->configKey.storage + || PersistenceStorage_shared == info->configKey.storage ) { write_size = buffer_size; itzam_btree* btree = NULL; @@ -260,6 +263,46 @@ int pers_db_write_key(char* dbPath, char* key, PersistenceInfo_s* info, unsigned fprintf(stderr, "\npersistence_set_data ==> Insert Itzam problem: %s\n", STATE_MESSAGES[state]); write_size = EPERS_DB_ERROR_INTERNAL; } + + if(PersistenceStorage_shared == info->configKey.storage) + { + // send changed notification + DBusMessage* message; + char ldbid_array[12]; + char user_array[12]; + char seat_array[12]; + const char* ldbid_ptr = ldbid_array; + const char* user_ptr = user_array; + const char* seat_ptr = seat_array; + + memset(ldbid_array, 0, 12); + memset(user_array, 0, 12); + memset(seat_array, 0, 12); + + // 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(ldbid_array, 12, "%d", info->context.ldbid); + snprintf(user_array, 12, "%d", info->context.user_no); + snprintf(seat_array, 12, "%d", info->context.seat_no); + + message = dbus_message_new_signal("/org/genivi/persistence/adminconsumer", // const char *path, + "org.genivi.persistence.adminconsumer", // const char *interface, + "PersistenceValueChanged" ); // const char *name + + dbus_message_append_args(message, + DBUS_TYPE_STRING, &key, + DBUS_TYPE_STRING, &ldbid_ptr, + DBUS_TYPE_STRING, &user_ptr, + DBUS_TYPE_STRING, &seat_ptr, + DBUS_TYPE_INVALID); + + // Send the signal + dbus_connection_send(get_dbus_connection(), message, NULL); + + // Free the signal now we have finished with it + dbus_message_unref(message); + } } else { @@ -422,9 +465,34 @@ int pers_db_delete_key(char* dbPath, char* dbKey, PersistenceInfo_s* info) } -int persistence_reg_notify_on_change(char* dbPath, char* key) +int persistence_reg_notify_on_change(char* dbPath, char* key, unsigned int ldbid, unsigned int user_no, unsigned int seat_no, + changeNotifyCallback_t callback) { int rval = -1; + DBusError error; + dbus_error_init (&error); + char rule[300]; + char ldbid_array[12]; + char user_array[12]; + char seat_array[12]; + + memset(ldbid_array, 0, 12); + memset(user_array, 0, 12); + memset(seat_array, 0, 12); + + // assign callback + gChangeNotifyCallback = callback; + + // dbus_bus_add_match works only for type DBUS_TYPE_STRING as message arguments + // this is the reason to use string instead of integer types directly + snprintf(ldbid_array, 12, "%d", ldbid); + snprintf(user_array, 12, "%d", user_no); + snprintf(seat_array, 12, "%d", seat_no); + + snprintf(rule, 256, "type='signal',interface='org.genivi.persistence.adminconsumer',member='PersistenceValueChanged',path='/org/genivi/persistence/adminconsumer',arg0='%s',arg1='%s',arg2='%s',arg3='%s'", + key, ldbid_array, user_array, seat_array); + + dbus_bus_add_match(get_dbus_connection(), rule, &error); return rval; } diff --git a/src/persistence_client_library_dbus_service.c b/src/persistence_client_library_dbus_service.c index fd24232..d82d2e7 100644 --- a/src/persistence_client_library_dbus_service.c +++ b/src/persistence_client_library_dbus_service.c @@ -20,6 +20,7 @@ #include "persistence_client_library_dbus_service.h" #include "persistence_client_library_lc_interface.h" #include "persistence_client_library_pas_interface.h" +#include "../include_protected/persistence_client_library_data_organization.h" #include <stdio.h> #include <errno.h> @@ -63,7 +64,6 @@ typedef struct SPollInfo /// polling information static tPollInfo gPollInfo; - /// dbus connection DBusConnection* gDbusConn = NULL; @@ -107,7 +107,7 @@ static DBusHandlerResult handleObjectPathMessageFallback(DBusConnection * connec // org.genivi.persistence.admin S I G N A L if((0==strcmp("org.genivi.persistence.admin", dbus_message_get_interface(message)))) { - // printf("checkPersAdminSignalInterface '%s' -> '%s'\n", dbus_message_get_interface(message), dbus_message_get_member(message)); + printf("checkPersAdminSignalInterface '%s' -> '%s'\n", dbus_message_get_interface(message), dbus_message_get_member(message)); if(dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL) { printf(" checkPersAdminSignal signal\n"); @@ -123,7 +123,64 @@ static DBusHandlerResult handleObjectPathMessageFallback(DBusConnection * connec } } } + // org.genivi.persistence.admin S I G N A L + else if((0==strcmp("org.genivi.persistence.adminconsumer", dbus_message_get_interface(message)))) + { + printf("checkPersAdminconsumerSignalInterface '%s' -> '%s'\n", dbus_message_get_interface(message), dbus_message_get_member(message)); + if(dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL) + { + if((0==strcmp("PersistenceValueChanged", dbus_message_get_member(message)))) + { + DBusError error; + DBusMessage *reply; + dbus_error_init (&error); + char* ldbid; + char* user_no; + char* seat_no; + + printf("PersistenceValueChanged signal\n"); + // to do handle signal + PersistenceNotification_s notifyStruct; + notifyStruct.pclKeyNotify_Status = pclNotifyStatus_changed; + + if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING, ¬ifyStruct.resource_id, + DBUS_TYPE_STRING, &ldbid, + DBUS_TYPE_STRING, &user_no, + DBUS_TYPE_STRING, &seat_no, + DBUS_TYPE_INVALID)) + { + reply = dbus_message_new_error(message, error.name, error.message); + + if (reply == 0) + { + //DLT_LOG(mgrContext, DLT_LOG_ERROR, DLT_STRING("DBus No memory")); + printf("DBus No memory\n"); + } + if (!dbus_connection_send(connection, reply, 0)) + { + //DLT_LOG(mgrContext, DLT_LOG_ERROR, DLT_STRING("DBus No memory")); + printf("DBus No memory\n"); + } + + result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;; + dbus_message_unref(reply); + } + else + { + notifyStruct.ldbid = atoi(ldbid); + notifyStruct.user_no = atoi(user_no); + notifyStruct.seat_no = atoi(seat_no); + + // call the registered callback function + gChangeNotifyCallback(¬ifyStruct); + + result = DBUS_HANDLER_RESULT_HANDLED; + } + dbus_connection_flush(connection); + } + } + } // org.genivi.persistence.admin P R O P E R T Y else if((0==strcmp("org.freedesktop.DBus.Properties", dbus_message_get_interface(message)))) { diff --git a/src/persistence_client_library_key.c b/src/persistence_client_library_key.c index 7a3df3f..291c6c8 100644 --- a/src/persistence_client_library_key.c +++ b/src/persistence_client_library_key.c @@ -204,7 +204,7 @@ int pclKeyHandleReadData(int key_handle, unsigned char* buffer, int buffer_size) -int pclKeyHandleRegisterNotifyOnChange(int key_handle) +int pclKeyHandleRegisterNotifyOnChange(int key_handle, changeNotifyCallback_t callback) { int rval = -1; @@ -470,7 +470,7 @@ int pclKeyWriteData(unsigned int ldbid, const char* resource_id, unsigned int us // status: TODO implement register on change -int pclKeyRegisterNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no) +int pclKeyRegisterNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no, changeNotifyCallback_t callback) { int rval = 0; PersistenceInfo_s dbContext; @@ -490,10 +490,14 @@ int pclKeyRegisterNotifyOnChange(unsigned int ldbid, const char* resource_id, un rval = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath); // registration is only on shared key possible - if( (PersistenceStorage_shared == rval) - && (dbContext.configKey.type == PersistenceResourceType_key) ) + if( (dbContext.configKey.storage == PersistenceStorage_shared) + && (dbContext.configKey.type == PersistenceResourceType_key) ) { - rval = persistence_reg_notify_on_change(dbPath, dbKey); + rval = persistence_reg_notify_on_change(dbPath, dbKey, ldbid, user_no, seat_no, callback); + } + else + { + printf("pclKeyRegisterNotifyOnChange: error - resource is not a shared resource or resource is not a key\n"); } return rval; diff --git a/src/persistence_client_library_pas_interface.c b/src/persistence_client_library_pas_interface.c index 7d5292d..e2db17e 100644 --- a/src/persistence_client_library_pas_interface.c +++ b/src/persistence_client_library_pas_interface.c @@ -156,6 +156,7 @@ DBusHandlerResult msg_persAdminRequest(DBusConnection *connection, DBusMessage * return DBUS_HANDLER_RESULT_HANDLED; } + int signal_persModeChange(DBusConnection *connection, DBusMessage *message) { int persistenceMode = 0; @@ -213,35 +214,6 @@ int signal_persModeChange(DBusConnection *connection, DBusMessage *message) return DBUS_HANDLER_RESULT_HANDLED; } -/* -DBusHandlerResult checkPersAdminSignal(DBusConnection *connection, DBusMessage *message, void *user_data) -{ - DBusHandlerResult result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - printf("checkPersAdminSignalInterface '%s' -> '%s'\n", dbus_message_get_interface(message), dbus_message_get_member(message)); - - if((0==strcmp("org.genivi.persistence.admin", dbus_message_get_interface(message)))) - { - if(dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL) - { - printf("checkPersAdminSignal signal\n"); - if((0==strcmp("PersistenceModeChanged", dbus_message_get_member(message)))) - { - printf("checkPersAdminSignal signal\n"); - // to do handle signal - result = signal_persModeChange(connection, message); - } - else - { - printf("checkPersAdminMsg -> unknown signal '%s'\n", dbus_message_get_interface(message)); - } - } - } - - return result; -} -*/ - DBusHandlerResult checkPersAdminMsg(DBusConnection * connection, DBusMessage * message, void * user_data) { @@ -259,6 +231,10 @@ DBusHandlerResult checkPersAdminMsg(DBusConnection * connection, DBusMessage * m printf("checkPersAdminMsg -> unknown message '%s'\n", dbus_message_get_interface(message)); } } + else + { + printf("checkPersAdminMsg ELSE -> unknown message '%s'\n", dbus_message_get_interface(message)); + } return result; } diff --git a/test/data/Data.tar.gz b/test/data/Data.tar.gz Binary files differindex dab24c2..64f0d92 100644 --- a/test/data/Data.tar.gz +++ b/test/data/Data.tar.gz diff --git a/test/persistence_client_library_dbus_test.c b/test/persistence_client_library_dbus_test.c index f30d5c5..f276caf 100644 --- a/test/persistence_client_library_dbus_test.c +++ b/test/persistence_client_library_dbus_test.c @@ -23,15 +23,37 @@ #include <stdio.h> + + +int myChangeCallback(PersistenceNotification_s * notifyStruct) +{ + printf(" ==> * - * myChangeCallback * - *\n"); + printf("Notification received ==> lbid: %d | resource_id: %s | seat: %d | user: %d \n", notifyStruct->ldbid, + notifyStruct->resource_id, + notifyStruct->seat_no, + notifyStruct->user_no ); + printf(" <== * - * myChangeCallback * - *\n"); + + return 1; +} + + int main(int argc, char *argv[]) { int ret = 0; + PersistenceNotification_s notifyValue; + printf("Dbus interface test application\n"); printf("Press a key to end application\n"); ret = pclKeyHandleOpen(0xFF, "posHandle/last_position", 0, 0); - getchar(); + printf("Register for change notification\n"); + ret = pclKeyRegisterNotifyOnChange(0x84, "links/last_link2", 2/*user_no*/, 1/*seat_no*/, &myChangeCallback); + //ret = pclKeyRegisterNotifyOnChange(0x84, "links/last_link3", 3/*user_no*/, 2/*seat_no*/, &myChangeCallback); + ret = pclKeyRegisterNotifyOnChange(0x84, "links/last_link4", 4/*user_no*/, 1/*seat_no*/, &myChangeCallback); + + getchar(); printf("By\n"); return ret; diff --git a/test/persistence_client_library_test.c b/test/persistence_client_library_test.c index d7d1375..96b7ef5 100644 --- a/test/persistence_client_library_test.c +++ b/test/persistence_client_library_test.c @@ -282,6 +282,37 @@ START_TEST(test_SetData) fail_unless(ret == strlen(write2), "Wrong write size"); + /*******************************************************************************************************************************************/ + /* used for changed notification testing */ + /*******************************************************************************************************************************************/ + /** + * Logical DB ID: 0x84 with user 2 and seat 1 + * ==> shared user value accessible by A GROUP (user 2 and seat 1) + * + * ==> used for shared testing + */ + printf("Write data to trigger change notification\n"); + ret = pclKeyWriteData(0x84, "links/last_link2", 2, 1, (unsigned char*)"Test notify shared data", strlen("Test notify shared data")); + + /** + * Logical DB ID: 0x84 with user 2 and seat 1 + * ==> shared user value accessible by A GROUP (user 2 and seat 1) + * + * ==> used for shared testing + */ + printf("Write data to trigger change notification\n"); + ret = pclKeyWriteData(0x84, "links/last_link3", 3, 2, (unsigned char*)"Test notify shared data", strlen("Test notify shared data")); + + /** + * Logical DB ID: 0x84 with user 2 and seat 1 + * ==> shared user value accessible by A GROUP (user 2 and seat 1) + * + * ==> used for shared testing + */ + printf("Write data to trigger change notification\n"); + ret = pclKeyWriteData(0x84, "links/last_link4", 4, 1, (unsigned char*)"Test notify shared data", strlen("Test notify shared data")); + /*******************************************************************************************************************************************/ + /*******************************************************************************************************************************************/ /* * now read the data written in the previous steps to the keys diff --git a/test/persistence_lifeCycle_mockup.c b/test/persistence_lifeCycle_mockup.c index 14a6ca3..f6a1458 100644 --- a/test/persistence_lifeCycle_mockup.c +++ b/test/persistence_lifeCycle_mockup.c @@ -176,6 +176,13 @@ DBusHandlerResult checkPersAdminMsg(DBusConnection * connection, DBusMessage * m result = checkAdminMsg(connection, message); } + else if((0==strcmp("LifecycleRequestComplete", dbus_message_get_member(message)))) + { + printf(" ==> org.genivi.NodeStateManager.Consumer - received - ==> LifecycleRequestComplete \n"); + + result = checkAdminMsg(connection, message); + } + else { printf(" ==> org.genivi.NodeStateManager.Consumer - received U N KN O W N-'%s'\n", dbus_message_get_interface(message)); |