Changed file and key-value API according GENIVI naming conventions
[profile/ivi/persistence-client-library.git] / src / persistence_client_library_pas_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_pas_interface.c
13  * @ingroup        Persistence client library
14  * @author         Ingo Huerner
15  * @brief          Implementation of the persistence client library persistence
16  *                 administration service interface.
17  * @see
18  */
19
20 #include "persistence_client_library_pas_interface.h"
21 #include "persistence_client_library_dbus_service.h"
22
23 #include "../include_protected/persistence_client_library_data_organization.h"
24
25 #include <errno.h>
26 #include <unistd.h>
27
28
29 static int gTimeoutMs = 500;
30
31 /// flag if access is locked
32 static int gLockAccess = 0;
33
34
35 int pers_data_sync(void)
36 {
37    return 1;   // TODO  implement sync data back
38 }
39
40 void pers_lock_access(void)
41 {
42    __sync_fetch_and_add(&gLockAccess,1);
43 }
44
45 void pers_unlock_access(void)
46 {
47    __sync_fetch_and_sub(&gLockAccess,1);
48 }
49
50 int isAccessLocked(void)
51 {
52    return gLockAccess;
53 }
54
55
56 int check_pas_request(unsigned int request, unsigned int requestID)
57 {
58    int rval = 0;
59
60    switch(request)
61    {
62       case (PasMsg_Block|PasMsg_WriteBack):
63       {
64          // add command and data to queue
65          unsigned long cmd = ( (requestID << 8) | CMD_PAS_BLOCK_AND_WRITE_BACK);
66
67          if(sizeof(int)!=write(gPipefds[1], &cmd, sizeof(unsigned long)))
68          {
69             printf("write failed w/ errno %d\n", errno);
70             rval = PasErrorStatus_FAIL;
71          }
72          else
73          {
74             rval = PasErrorStatus_RespPend;
75          }
76          break;
77       }
78       case PasMsg_Unblock:
79       {
80          pers_unlock_access();
81          rval = PasErrorStatus_OK;
82          break;
83       }
84       default:
85       {
86          rval = PasErrorStatus_FAIL;
87          break;
88       }
89    }
90    return rval;
91 }
92
93
94
95
96
97 DBusHandlerResult msg_persAdminRequest(DBusConnection *connection, DBusMessage *message)
98 {
99    int request = 0, requestID = 0;
100    int errorReturn = 0;
101
102    DBusMessage *reply;
103    DBusError error;
104    dbus_error_init (&error);
105
106
107    if (!dbus_message_get_args (message, &error, DBUS_TYPE_INT32 , &request,
108                                                 DBUS_TYPE_INT32 , &requestID,
109                                                 DBUS_TYPE_INVALID))
110    {
111       reply = dbus_message_new_error(message, error.name, error.message);
112
113       if(reply == 0)
114       {
115          //DLT_LOG(mgrContext, DLT_LOG_ERROR, DLT_STRING("DBus No memory"));
116          printf("DBus No memory\n");
117       }
118
119       if (!dbus_connection_send(connection, reply, 0))
120       {
121          //DLT_LOG(mgrContext, DLT_LOG_ERROR, DLT_STRING("DBus No memory"));
122          printf("DBus No memory\n");
123       }
124
125       dbus_message_unref (reply);
126
127       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
128    }
129    errorReturn = check_pas_request(request, requestID);
130
131    reply = dbus_message_new_method_return(message);
132
133    if (reply == 0)
134    {
135      //DLT_LOG(mgrContext, DLT_LOG_ERROR, DLT_STRING("DBus No memory"));
136       printf("DBus No memory\n");
137    }
138
139    if (!dbus_message_append_args(reply, DBUS_TYPE_INT32, &errorReturn, DBUS_TYPE_INVALID))
140    {
141      //DLT_LOG(mgrContext, DLT_LOG_ERROR, DLT_STRING("DBus No memory"));
142       printf("DBus No memory\n");
143    }
144
145    if (!dbus_connection_send(connection, reply, 0))
146    {
147      //DLT_LOG(mgrContext, DLT_LOG_ERROR, DLT_STRING("DBus No memory"));
148       printf("DBus No memory\n");
149    }
150
151    dbus_connection_flush(connection);
152    dbus_message_unref(reply);
153
154    return DBUS_HANDLER_RESULT_HANDLED;
155 }
156
157 int signal_persModeChange(DBusConnection *connection, DBusMessage *message)
158 {
159    int persistenceMode = 0;
160    int errorCode = 0;
161
162    DBusMessage *reply;
163    DBusError error;
164    dbus_error_init (&error);
165
166    if (!dbus_message_get_args (message, &error, DBUS_TYPE_INT32 , &persistenceMode,
167                                                 DBUS_TYPE_INVALID))
168    {
169       reply = dbus_message_new_error(message, error.name, error.message);
170
171       if(reply == 0)
172       {
173          //DLT_LOG(mgrContext, DLT_LOG_ERROR, DLT_STRING("DBus No memory"));
174          printf("DBus No memory\n");
175       }
176
177       if (!dbus_connection_send(connection, reply, 0))
178       {
179          //DLT_LOG(mgrContext, DLT_LOG_ERROR, DLT_STRING("DBus No memory"));
180          printf("DBus No memory\n");
181       }
182
183       dbus_message_unref (reply);
184
185       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
186    }
187
188    reply = dbus_message_new_method_return(message);
189
190    if (reply == 0)
191    {
192      //DLT_LOG(mgrContext, DLT_LOG_ERROR, DLT_STRING("DBus No memory"));
193       printf("DBus No memory\n");
194    }
195
196    if (!dbus_message_append_args(reply, DBUS_TYPE_INT32, &errorCode, DBUS_TYPE_INVALID))
197    {
198      //DLT_LOG(mgrContext, DLT_LOG_ERROR, DLT_STRING("DBus No memory"));
199       printf("DBus No memory\n");
200    }
201
202    if (!dbus_connection_send(connection, reply, 0))
203    {
204      //DLT_LOG(mgrContext, DLT_LOG_ERROR, DLT_STRING("DBus No memory"));
205       printf("DBus No memory\n");
206    }
207
208    dbus_connection_flush(connection);
209    dbus_message_unref(reply);
210
211    return DBUS_HANDLER_RESULT_HANDLED;
212 }
213
214 /*
215 DBusHandlerResult checkPersAdminSignal(DBusConnection *connection, DBusMessage *message, void *user_data)
216 {
217    DBusHandlerResult result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
218
219    printf("checkPersAdminSignalInterface '%s' -> '%s'\n", dbus_message_get_interface(message), dbus_message_get_member(message));
220
221    if((0==strcmp("org.genivi.persistence.admin", dbus_message_get_interface(message))))
222    {
223       if(dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL)
224       {
225          printf("checkPersAdminSignal signal\n");
226          if((0==strcmp("PersistenceModeChanged", dbus_message_get_member(message))))
227          {
228             printf("checkPersAdminSignal signal\n");
229             // to do handle signal
230             result = signal_persModeChange(connection, message);
231          }
232          else
233          {
234             printf("checkPersAdminMsg -> unknown signal '%s'\n", dbus_message_get_interface(message));
235          }
236       }
237    }
238
239    return result;
240 }
241 */
242
243
244 DBusHandlerResult checkPersAdminMsg(DBusConnection * connection, DBusMessage * message, void * user_data)
245 {
246    DBusHandlerResult result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
247
248    //printf("checkPersAdminMsg '%s' -> '%s'\n", dbus_message_get_interface(message), dbus_message_get_member(message));
249    if((0==strcmp("org.genivi.persistence.adminconsumer", dbus_message_get_interface(message))))
250    {
251       if((0==strcmp("PersistenceAdminRequest", dbus_message_get_member(message))))
252       {
253          result = msg_persAdminRequest(connection, message);
254       }
255       else
256       {
257          printf("checkPersAdminMsg -> unknown message '%s'\n", dbus_message_get_interface(message));
258       }
259    }
260    return result;
261 }
262
263
264
265 int send_pas_register(const char* method, int notificationFlag)
266 {
267    int rval = 0;
268
269    DBusError error;
270    dbus_error_init (&error);
271    DBusMessage *replyMsg = NULL;
272    DBusConnection* conn = get_dbus_connection();
273
274    const char* objName = "/org/genivi/persistence/adminconsumer";
275    const char* busName = dbus_bus_get_unique_name(conn);
276
277    DBusMessage* message = dbus_message_new_method_call("org.genivi.persistence.admin",    // destination
278                                                       "/org/genivi/persistence/admin",    // path
279                                                        "org.genivi.persistence.admin",    // interface
280                                                        method);                  // method
281
282    if(message != NULL)
283    {
284       dbus_message_append_args(message, DBUS_TYPE_STRING, &busName,  // bus name
285                                         DBUS_TYPE_STRING, &objName,
286                                         DBUS_TYPE_INT32,  &notificationFlag,
287                                         DBUS_TYPE_UINT32, &gTimeoutMs,
288                                         DBUS_TYPE_INVALID);
289
290       if(conn != NULL)
291       {
292          replyMsg = dbus_connection_send_with_reply_and_block(conn, message, gTimeoutMs, &error);
293          if(dbus_set_error_from_message(&error, replyMsg))
294          {
295             fprintf(stderr, "sendDBusMessage ==> Access denied: %s \n", error.message);
296          }
297          else
298          {
299             dbus_message_get_args(replyMsg, &error, DBUS_TYPE_INT32, &rval, DBUS_TYPE_INVALID);
300          }
301
302          dbus_message_unref(message);
303       }
304       else
305       {
306          fprintf(stderr, "send_pers_admin_service ==> ERROR: Invalid connection!! \n");
307          rval = -1;
308       }
309       dbus_message_unref(message);
310    }
311    else
312    {
313       fprintf(stderr, "send_pers_admin_service ==> ERROR: Invalid message!! \n");
314       rval = -1;
315    }
316
317    return rval;
318 }
319
320
321
322 int send_pas_request(const char* method, unsigned int requestID, int status)
323 {
324    int rval = 0, errorCode = 0;
325
326    DBusError error;
327    dbus_error_init (&error);
328    DBusMessage *replyMsg = NULL;
329    DBusConnection* conn = get_dbus_connection();
330
331    DBusMessage* message = dbus_message_new_method_call("org.genivi.persistence.admin",    // destination
332                                                       "/org/genivi/persistence/admin",    // path
333                                                        "org.genivi.persistence.admin",    // interface
334                                                        method);                  // method
335    if(message != NULL)
336    {
337       dbus_message_append_args(message, DBUS_TYPE_UINT32, &requestID,
338                                         DBUS_TYPE_INT32,  &status,
339                                         DBUS_TYPE_INT32,  &errorCode,
340                                         DBUS_TYPE_INVALID);
341
342       if(conn != NULL)
343       {
344          replyMsg = dbus_connection_send_with_reply_and_block(conn, message, gTimeoutMs, &error);
345          if(dbus_set_error_from_message(&error, replyMsg))
346          {
347             fprintf(stderr, "sendDBusMessage ==> Access denied: %s \n", error.message);
348          }
349          else
350          {
351             dbus_message_get_args(replyMsg, &error, DBUS_TYPE_INT32, &rval, DBUS_TYPE_INVALID);
352          }
353
354          dbus_message_unref(message);
355       }
356       else
357       {
358          fprintf(stderr, "send_pers_admin_service ==> ERROR: Invalid connection!! \n");
359          rval = -1;
360       }
361       dbus_message_unref(message);
362    }
363    else
364    {
365       fprintf(stderr, "send_pers_admin_service ==> ERROR: Invalid message!! \n");
366       rval = -1;
367    }
368
369    return rval;
370 }
371
372
373
374 int register_pers_admin_service(void)
375 {
376    // register for everything
377    int notificationFlag = PasMsg_Block | PasMsg_WriteBack | PasMsg_Unblock;
378
379    return send_pas_register("RegisterPersAdminNotification", notificationFlag);
380 }
381
382
383
384 int unregister_pers_admin_service(void)
385 {
386    // register for everything
387    int notificationFlag = PasMsg_Block | PasMsg_WriteBack | PasMsg_Unblock;
388
389    return send_pas_register("UnRegisterPersAdminNotification", notificationFlag);
390 }
391
392
393
394 int pers_admin_service_data_sync_complete(unsigned int requestID)
395 {
396    return send_pas_request("PersistenceAdminRequestCompleted", requestID, 1);
397 }
398
399
400
401 void process_block_and_write_data_back(unsigned int requestID)
402 {
403    // lock persistence data access
404    pers_lock_access();
405    // sync data back to memory device
406    pers_data_sync();
407    // send complete notification
408    pers_admin_service_data_sync_complete(requestID);
409 }
410
411