[Internal: merge sync-agent]
[platform/core/system/sync-agent.git] / src / fw-plugins / common-public / slp-sysnoti-wap-push / src / plugin_interface.c
1 /*
2  * sync-agent
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <glib.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <glib-object.h>
22 #include <glib/gprintf.h>
23 #include <time.h>
24 #include <vconf-keys.h>
25 #include <vconf.h>
26
27 #include <msg.h>
28 #include <msg_storage.h>
29 #include <msg_transport.h>
30
31 #include "plugin_slp_sysnoti_wap_push.h"
32 #include "plugin/platform_monitor_interface.h"
33
34 /* for data logging */
35 #include "fsapi/operation.h"
36
37 /* for log */
38 #include "utility/sync_util.h"
39
40 #ifndef EXPORT_API
41 #define EXPORT_API __attribute__ ((visibility("default")))
42 #endif
43
44 #ifndef SYNC_AGENT_LOG
45 #undef LOG_TAG
46 #define LOG_TAG "PLUGIN_PM_SYSNOTI_WAP_PUSH"
47 #endif
48
49 #define CP_HEADER_DATA_PATH "/opt/data/header_log.wbxml"
50 #define CP_BODY_DATA_PATH "/opt/data/body_log.wbxml"
51
52 static msg_handle_t msg_handle = NULL;
53
54 static int (*registered_wap_push_incoming_cb) (int data_id, void *user_data);
55 static int (*registered_wap_push_operation_cb) (int data_id, void *user_data);
56
57 static int _start_wap_push();
58 static int _end_wap_push();
59 static int _add_message(void *add_data, int *added_data_id);
60 static int _remove_message(int remove_data_id);
61
62 static int __register_msg_callback();
63 static void __check_msg_server_cb(keynode_t * node, void *data);
64 static void ___incomming_syncml_msg_cb(msg_handle_t msg_handle, msg_syncml_message_type_t msg_type, const char *push_body, int push_body_len, const char *wsp_header, int wsp_header_len, void *user_param);
65 void ___operation_syncml_msg_cb(msg_handle_t handle, int msg_id, int ext_id, void *user_param);
66
67 EXPORT_API void sync_agent_plugin_init_service_noti(void *data)
68 {
69         _EXTERN_FUNC_ENTER;
70
71         int res = 0;
72
73         res = _start_wap_push();
74
75         if (res != 1) {
76                 _DEBUG_ERROR("_start_wap_push() failed !!");
77         } else {
78                 _DEBUG_INFO("_start_wap_push() success !!");
79         }
80
81         if (data != NULL) {
82                 if (((sync_agent_pm_register_data_s *) data)->pkg_name != NULL)
83                         free(((sync_agent_pm_register_data_s *) data)->pkg_name);
84
85                 if (((sync_agent_pm_register_data_s *) data)->additional_data != NULL)
86                         free(((sync_agent_pm_register_data_s *) data)->additional_data);
87
88                 free(data);
89
90                 _DEBUG_INFO("free sync_agent_pm_register_data_s !!");
91         }
92
93         _EXTERN_FUNC_EXIT;
94 }
95
96 EXPORT_API sync_agent_pm_return_e sync_agent_plugin_unregister_service_noti(void)
97 {
98         _EXTERN_FUNC_ENTER;
99
100         sync_agent_pm_return_e ret = SYNC_AGENT_PM_SUCCESS;
101
102         int res = 0;
103
104         res = _end_wap_push();
105
106         if (res != 1) {
107                 _DEBUG_ERROR("_end_wap_push() failed !!");
108                 return res;
109         } else {
110                 _DEBUG_INFO("_end_wap_push() success !!");
111         }
112
113         _EXTERN_FUNC_EXIT;
114
115         return ret;
116 }
117
118 EXPORT_API sync_agent_pm_return_e sync_agent_plugin_add_service_data(void *add_data, int *added_data_id)
119 {
120         _EXTERN_FUNC_ENTER;
121
122         retvm_if(add_data == NULL, SYNC_AGENT_PM_FAIL, "add_data is NULL. FAIL !!!");
123
124         sync_agent_pm_return_e ret = SYNC_AGENT_PM_SUCCESS;
125
126         int res = 0;
127
128         res = _add_message(add_data, added_data_id);
129
130         if (res != 1) {
131                 _DEBUG_ERROR("_add_message() failed !!");
132                 return SYNC_AGENT_PM_FAIL;
133         } else {
134                 _DEBUG_INFO("_add_message() success !!");
135         }
136
137         _EXTERN_FUNC_EXIT;
138
139         return ret;
140 }
141
142 EXPORT_API sync_agent_pm_return_e sync_agent_plugin_remove_service_data(int remove_data_id)
143 {
144         _EXTERN_FUNC_ENTER;
145
146         sync_agent_pm_return_e ret = SYNC_AGENT_PM_SUCCESS;
147
148         int res = 0;
149
150         res = _remove_message(remove_data_id);
151
152         if (res != 1) {
153                 _DEBUG_ERROR("_remove_message() failed !!");
154                 return res;
155         } else {
156                 _DEBUG_INFO("_remove_message() success !!");
157         }
158
159         _EXTERN_FUNC_EXIT;
160
161         return ret;
162 }
163
164 EXPORT_API sync_agent_pm_return_e sync_agent_plugin_get_service_data(int get_data_id, void **service_data)
165 {
166         _EXTERN_FUNC_ENTER;
167
168         sync_agent_pm_return_e ret = SYNC_AGENT_PM_SUCCESS;
169
170         _DEBUG_INFO("not support this feature !!");
171
172         _EXTERN_FUNC_EXIT;
173
174         return ret;
175 }
176
177 EXPORT_API void sync_agent_plugin_set_user_callback(int callback_counts, va_list list)
178 {
179         _EXTERN_FUNC_ENTER;
180
181         int i = 0;
182
183         _DEBUG_INFO("callback_counts : %d", callback_counts);
184         for (; i < callback_counts; i++) {
185                 switch (i) {
186                 case 0:
187                         registered_wap_push_incoming_cb = va_arg(list, sync_agent_user_callback_cb_plugin);
188                         _DEBUG_INFO("set user callback ( for WAP Push Incoming ) !!");
189                         break;
190                 case 1:
191                         registered_wap_push_operation_cb = va_arg(list, sync_agent_user_callback_cb_plugin);
192                         _DEBUG_INFO("set user callback ( for WAP Push Operation End ) !!");
193                         break;
194                 default:
195                         break;
196                 }
197         }
198
199         _EXTERN_FUNC_EXIT;
200 }
201
202 static int _start_wap_push()
203 {
204         _INNER_FUNC_ENTER;
205
206         int res = 1;
207         int msg_key = 0;
208
209         msg_error_t err = MSG_SUCCESS;
210
211         if (vconf_get_bool(VCONFKEY_MSG_SERVER_READY, &msg_key) == 0) {
212                 if (msg_key == 1) {
213                         _DEBUG_TRACE("msg server is ready !!");
214
215                         err = msg_open_msg_handle(&msg_handle);
216                         if (err != MSG_SUCCESS) {
217                                 _DEBUG_ERROR("msg_open_msg_handle() failed ( err_code : %d ) !!", err);
218                                 res = -1;
219                                 goto return_part;
220                         } else {
221                                 _DEBUG_TRACE("msg_open_msg_handle() success !!");
222
223                                 res = __register_msg_callback();
224                                 if (res != 1) {
225                                         _DEBUG_ERROR("register_syncml_msg_callback() failed ( err_code : %d ) !!", res);
226
227                                         err = msg_close_msg_handle(&msg_handle);
228                                         if (err != MSG_SUCCESS) {
229                                                 _DEBUG_ERROR("msg_close_msg_handle() failed ( err_code : %d ) !!", err);
230                                                 res = -1;
231                                                 goto return_part;
232                                         } else {
233                                                 _DEBUG_TRACE("msg_close_msg_handle() success !!");
234                                                 msg_handle = NULL;
235                                                 res = -1;
236                                                 goto return_part;
237                                         }
238                                 } else {
239                                         _DEBUG_TRACE("register_syncml_msg_callback() success !!");
240                                 }
241                         }
242                 } else {
243                         _DEBUG_ERROR("msg server is not ready !!");
244
245                         if (vconf_notify_key_changed((char *)VCONFKEY_MSG_SERVER_READY, __check_msg_server_cb, NULL) != 0) {
246                                 _DEBUG_ERROR("vconf_notify_key_changed( VCONFKEY_MSG_SERVER_READY ) failed !!");
247                                 res = -1;
248                                 goto return_part;
249                         } else {
250                                 _DEBUG_TRACE("vconf_notify_key_changed() success !!");
251                         }
252                 }
253         } else {
254                 _DEBUG_ERROR("vconf_get_bool ( VCONFKEY_MSG_SERVER_READY ) failed !!");
255                 res = -1;
256                 goto return_part;
257         }
258
259  return_part:
260
261         _INNER_FUNC_EXIT;
262
263         return res;
264 }
265
266 static int _end_wap_push()
267 {
268         _INNER_FUNC_ENTER;
269
270         int res = 1;
271         msg_error_t err = MSG_SUCCESS;
272
273         err = msg_close_msg_handle(&msg_handle);
274         if (err != MSG_SUCCESS) {
275                 _DEBUG_ERROR("msg_close_msg_handle() failed ( err_code : %d ) !!", err);
276                 res = -1;
277                 goto return_part;
278         } else {
279                 _DEBUG_TRACE("msg_close_msg_handle() success !!");
280                 msg_handle = NULL;
281         }
282
283  return_part:
284
285         _INNER_FUNC_EXIT;
286
287         return res;
288 }
289
290 static int _add_message(void *add_data, int *added_data_id)
291 {
292         _INNER_FUNC_ENTER;
293
294         retvm_if(add_data == NULL, 0, "add_data is NULL. FAIL !!!");
295
296         int res = 1;
297         msg_error_t err = MSG_SUCCESS;
298
299         msg_struct_t syncml_msg = msg_create_struct(MSG_STRUCT_SYNCML_INFO);
300         pmci_san_message_s *add_msg = (pmci_san_message_s *) add_data;
301
302         *added_data_id = add_msg->ext_id;
303         msg_set_int_value(syncml_msg, MSG_SYNCML_INFO_EXTID_INT, add_msg->ext_id);
304         msg_set_int_value(syncml_msg, MSG_SYNCML_INFO_PINCODE_INT, add_msg->pin_code);
305
306         msg_struct_t msg = NULL;
307         msg_get_struct_handle(syncml_msg, MSG_SYNCML_INFO_MESSAGE_HND, &msg);
308         msg_set_int_value(msg, MSG_MESSAGE_FOLDER_ID_INT, MSG_INBOX_ID);
309         msg_set_int_value(msg, MSG_MESSAGE_TYPE_INT, MSG_TYPE_SMS_SYNCML);
310         msg_set_int_value(msg, MSG_MESSAGE_NETWORK_STATUS_INT, MSG_NETWORK_RECEIVED);
311         msg_set_int_value(msg, MSG_MESSAGE_DIRECTION_INT, MSG_DIRECTION_TYPE_MT);
312
313         msg_struct_list_s *addr_list = NULL;
314         msg_get_list_handle(msg, MSG_MESSAGE_ADDR_LIST_STRUCT, (void **)&addr_list);
315         addr_list->nCount = 1;
316
317         msg_struct_t addr_info = NULL;
318         addr_info = addr_list->msg_struct_info[0];
319         msg_set_int_value(addr_info, MSG_ADDRESS_INFO_RECIPIENT_TYPE_INT, MSG_RECIPIENTS_TYPE_TO);
320         char addr_value[MAX_ADDRESS_VAL_LEN] = "+1004";
321         msg_set_str_value(addr_info, MSG_ADDRESS_INFO_ADDRESS_VALUE_STR, addr_value, MAX_ADDRESS_VAL_LEN);
322
323         time_t t = time(NULL);
324         time_t utfTime = time(&t);
325         msg_set_int_value(msg, MSG_MESSAGE_DISPLAY_TIME_INT, utfTime);
326
327         msg_set_str_value(msg, MSG_MESSAGE_SMS_DATA_STR, add_msg->msg_data, strlen(add_msg->msg_data));
328
329         err = msg_add_syncml_message(msg_handle, syncml_msg);
330         if (err != MSG_SUCCESS) {
331                 _DEBUG_ERROR("msg_add_syncml_message() failed ( err_code : %d ) !!", err);
332                 res = -1;
333                 goto return_part;
334         } else {
335                 _DEBUG_TRACE("msg_add_syncml_message() success !!");
336         }
337
338  return_part:
339         msg_release_struct(&syncml_msg);
340
341         _INNER_FUNC_EXIT;
342
343         return res;
344 }
345
346 static int _remove_message(int remove_data_id)
347 {
348         _INNER_FUNC_ENTER;
349
350         int res = 1;
351         msg_error_t err = MSG_SUCCESS;
352
353         if (msg_handle == NULL) {
354                 _DEBUG_ERROR("msg_handle is NULL !!");
355                 res = -1;
356                 goto return_part;
357         }
358
359         err = msg_delete_message(msg_handle, remove_data_id);
360         if (err != MSG_SUCCESS) {
361                 _DEBUG_ERROR("msg_delete_message() fail !!");
362                 res = -1;
363         } else {
364                 _DEBUG_INFO("msg_delete_message() success !!");
365         }
366
367  return_part:
368
369         _INNER_FUNC_EXIT;
370
371         return res;
372 }
373
374 static int __register_msg_callback()
375 {
376         _INNER_FUNC_ENTER;
377
378         int res = 1;
379         msg_error_t err = MSG_SUCCESS;
380
381         if (msg_handle == NULL) {
382                 _DEBUG_ERROR("msg_handle is NULL !!");
383                 res = -1;
384                 goto return_part;
385         }
386 //    err = msg_reg_syncml_message_callback(msg_handle, &___incomming_syncml_msg_cb, NULL);
387         err = msg_reg_syncml_message_callback(msg_handle, ___incomming_syncml_msg_cb, NULL);
388         if (err != MSG_SUCCESS) {
389                 _DEBUG_ERROR("Register SyncML Incoming Callback fail [%d] !!", err);
390                 res = -1;
391                 goto return_part;
392         } else {
393                 _DEBUG_VERBOSE("Register SyncML Incoming Callback success !!");
394         }
395
396 //      err = msg_reg_syncml_message_operation_callback(msg_handle, &___operation_syncml_msg_cb, NULL);
397         err = msg_reg_syncml_message_operation_callback(msg_handle, ___operation_syncml_msg_cb, NULL);
398         if (err != MSG_SUCCESS) {
399                 _DEBUG_ERROR("Register SyncML Operation Callback fail [%d] !!", err);
400                 res = -1;
401                 goto return_part;
402         } else {
403                 _DEBUG_VERBOSE("Register SyncML Operation Callback success !!");
404         }
405
406  return_part:
407
408         _INNER_FUNC_EXIT;
409
410         return res;
411 }
412
413 static void __check_msg_server_cb(keynode_t * node, void *data)
414 {
415         _INNER_FUNC_ENTER;
416
417         int res = 1;
418         int msg_key = 0;
419         msg_error_t err = MSG_SUCCESS;
420
421         if (vconf_get_bool(VCONFKEY_MSG_SERVER_READY, &msg_key) == 0) {
422                 if (msg_key == 1) {
423                         _DEBUG_VERBOSE("msg server is ready !!");
424
425                         if (msg_handle == NULL) {
426                                 err = msg_open_msg_handle(&msg_handle);
427                                 if (err != MSG_SUCCESS) {
428                                         _DEBUG_ERROR("msg_open_msg_handle() fail [%d] !!", err);
429                                         goto return_part;
430                                 } else {
431                                         _DEBUG_VERBOSE("msg_open_msg_handle() success !!");
432
433                                         res = __register_msg_callback();
434                                         if (res != 1) {
435                                                 _DEBUG_ERROR("register_syncml_msg_callback() fail !!");
436                                                 goto return_part;
437                                         } else {
438                                                 _DEBUG_VERBOSE("register_syncml_msg_callback() success !!");
439                                         }
440                                 }
441                         } else {
442                                 _DEBUG_VERBOSE("callback is already registered !!");
443                         }
444                 } else {
445                         _DEBUG_VERBOSE("msg server is not ready !!");
446                 }
447         } else {
448                 _DEBUG_ERROR("vconf_get_bool ( VCONFKEY_MSG_SERVER_READY ) fail !!");
449                 goto return_part;
450         }
451
452  return_part:
453
454         _INNER_FUNC_EXIT;
455
456         return;
457 }
458
459 static void ___incomming_syncml_msg_cb(msg_handle_t msg_handle, msg_syncml_message_type_t msg_type, const char *push_body, int push_body_len, const char *wsp_header, int wsp_header_len, void *user_param)
460 {
461         _INNER_FUNC_ENTER;
462
463         pmci_san_incoming_s *san_incoming = (pmci_san_incoming_s *) calloc(1, sizeof(pmci_san_incoming_s));
464         if (san_incoming == NULL) {
465                 _DEBUG_ERROR("pmci_san_incomming_t calloc error !!");
466                 /* todo : exception handling */
467                 return;
468         }
469         _DEBUG_VERBOSE("push body : %s,   push body len : %d", push_body, push_body_len);
470         _DEBUG_VERBOSE("wsp header : %s,   wsp header len : %d", wsp_header, wsp_header_len);
471
472         /* FIXME : for recoding log data - Start */
473         _DEBUG_VERBOSE("logging wsp_header >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
474
475         int file_ret = sync_agent_write_whole_file(CP_HEADER_DATA_PATH, wsp_header, wsp_header_len, 1);
476         if (file_ret != 1) {
477                 _DEBUG_ERROR("sync_agent_write_whole_file() - CP header data failed !!");
478         } else {
479                 _DEBUG_VERBOSE("sync_agent_write_whole_file() - CP header data success !!");
480         }
481
482         _DEBUG_VERBOSE("logging PushBody >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
483         file_ret = sync_agent_write_whole_file(CP_BODY_DATA_PATH, push_body, push_body_len, 1);
484
485         if (file_ret != 1) {
486                 _DEBUG_ERROR("sync_agent_write_whole_file() - CP body data failed !!");
487         } else {
488                 _DEBUG_VERBOSE("sync_agent_write_whole_file() - CP body data success !!");
489         }
490
491         /* FIXME : for recoding log data - End */
492
493         if ((msg_type == CP_WBXML) || (msg_type == CP_XML)) {   /* CP case : merging header & body messages */
494                 if ((push_body_len > 0) && (wsp_header_len > 0)) {
495                         int msg_len = push_body_len + wsp_header_len + 1;
496
497                         san_incoming->msg_body = (char *)calloc(msg_len, sizeof(char));
498                         if (san_incoming->msg_body == NULL) {
499                                 _DEBUG_ERROR("san_incoming->msg_body calloc error !!");
500                                 goto free_part;
501                         } else {
502                                 if (wsp_header != NULL) {
503                                         _DEBUG_VERBOSE("CP : add wsp_header data !!");
504                                         memcpy((void *)(san_incoming->msg_body), wsp_header, wsp_header_len + 1);
505                                 } else {
506                                         _DEBUG_ERROR("wrong message - wapHeader is NULL !!");
507                                         goto free_part;
508                                 }
509
510                                 if (push_body != NULL) {
511                                         _DEBUG_VERBOSE("CP : add push_body data !!");
512                                         memcpy((void *)((san_incoming->msg_body) + wsp_header_len), push_body, push_body_len + 1);
513                                 } else {
514                                         _DEBUG_ERROR("wrong message - push_body is NULL !!");
515                                         goto free_part;
516                                 }
517
518                                 san_incoming->msg_size = msg_len - 1;
519                         }
520                 } else {
521                         _DEBUG_ERROR("wrong message format !!");
522                         goto free_part;
523                 }
524         } else {
525                 if ((push_body_len > 0) && (push_body != NULL)) {
526                         san_incoming->msg_body = (char *)calloc(push_body_len + 1, sizeof(char));
527                         if (san_incoming->msg_body == NULL) {
528                                 _DEBUG_ERROR("san_incoming->msg_body calloc error !!");
529                                 goto free_part;
530                         } else {
531                                 _DEBUG_VERBOSE("OTHERS : set push_body data !!");
532                                 memcpy((void *)(san_incoming->msg_body), push_body, push_body_len + 1);
533                                 san_incoming->msg_size = push_body_len;
534                         }
535                 } else {
536                         _DEBUG_VERBOSE("PushBody message is NULL !!");
537                         san_incoming->msg_body = NULL;
538                         san_incoming->msg_size = 0;
539                 }
540         }
541
542         switch (msg_type) {
543         case DM_WBXML:
544                 {
545                         _DEBUG_VERBOSE("MsgNoti ( msg_type = 0, DM_WBXML ) detected.\n");
546                         san_incoming->version = SAN_DM_WBXML;
547                 }
548                 break;
549         case DM_XML:
550                 {
551                         _DEBUG_VERBOSE("MsgNoti ( msg_type = 1, DM_XML ) detected.\n");
552                         san_incoming->version = SAN_DM_XML;
553                 }
554                 break;
555         case DM_NOTIFICATION:
556                 {
557                         _DEBUG_VERBOSE("MsgNoti ( msg_type = 2, DM_NOTIFICATION ) detected.\n");
558                         san_incoming->version = SAN_DM_NOTI;
559                 }
560                 break;
561         case DS_NOTIFICATION:
562                 {
563                         _DEBUG_VERBOSE("MsgNoti ( msg_type = 3, DS_NOTIFICATION ) detected.\n");
564                         san_incoming->version = SAN_VERSION_12;
565                 }
566                 break;
567         case DS_WBXML:
568                 {
569                         _DEBUG_VERBOSE("MsgNoti ( msg_type = 4, DS_WBXML ) detected.\n");
570                         san_incoming->version = SAN_VERSION_11;
571                 }
572                 break;
573         case CP_XML:
574                 {
575                         _DEBUG_VERBOSE("MsgNoti ( msg_type = 5, CP_XML ) detected.\n");
576                         san_incoming->version = SAN_CP_XML;
577                 }
578                 break;
579         case CP_WBXML:
580                 {
581                         _DEBUG_VERBOSE("MsgNoti ( msg_type = 6, CP_WBXML ) detected.\n");
582                         san_incoming->version = SAN_CP_WBXML;
583                 }
584                 break;
585         case OTHERS:
586         default:
587                 _DEBUG_VERBOSE("Unknown MsgNoti ( %d ) detected.\n", msg_type);
588                 break;
589         }
590
591         if (registered_wap_push_incoming_cb != NULL) {
592                 registered_wap_push_incoming_cb(0, (void *)san_incoming);
593         } else {
594                 _DEBUG_ERROR("not registered registered_wap_push_incoming_cb !!");
595         }
596
597  free_part:
598         if (san_incoming != NULL) {
599                 if (san_incoming->msg_body != NULL)
600                         free((void *)(san_incoming->msg_body));
601
602                 free(san_incoming);
603         }
604
605         _INNER_FUNC_EXIT;
606 }
607
608 void ___operation_syncml_msg_cb(msg_handle_t handle, int msg_id, int ext_id, void *user_param)
609 {
610         _INNER_FUNC_ENTER;
611
612         pmci_san_operation_s *san_operation = (pmci_san_operation_s *) calloc(1, sizeof(pmci_san_operation_s));
613         if (san_operation == NULL) {
614                 _DEBUG_ERROR("pmci_san_operation_s calloc error !!");
615                 /* todo : exception handling */
616                 return;
617         }
618
619         san_operation->msg_id = msg_id;
620         _DEBUG_VERBOSE("msg_id : %d", msg_id);
621
622         san_operation->ext_id = ext_id;
623         _DEBUG_VERBOSE("ext_id : %d", ext_id);
624
625         san_operation->user_param = user_param;
626         /*memcpy(san_operation->user_param, user_param, sizeof(user_param)); */
627
628         if (registered_wap_push_operation_cb != NULL) {
629                 registered_wap_push_operation_cb(0, (void *)san_operation);
630         } else {
631                 _DEBUG_ERROR("not registered registered_wap_push_operation_cb !!");
632                 if(san_operation != NULL) {
633                         free(san_operation);
634                         san_operation = NULL;
635                 }
636         }
637
638         _INNER_FUNC_EXIT;
639 }