12343b45e9ec6a1cb61f9f0c6c75aafd70fced95
[platform/core/multimedia/audio-session-manager.git] / src / audio-session-mgr.c
1 /*
2  * audio-session-manager
3  *
4  * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Seungbae Shin <seungbae.shin at samsung.com>, Sangchul Lee <sc11.lee at samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #define CONFIG_ENABLE_MULTI_INSTANCE
23 #define CONFIG_ENABLE_ASM_SERVER_USING_GLIB
24 #define CONFIG_ENABLE_SIGNAL_HANDLER
25 #define CONFIG_ENABLE_RETCB
26 #define MAKE_HANDLE_FROM_SERVER
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <glib.h>
31 #include <sys/poll.h>
32 #include <sys/syscall.h>
33 #include <sys/time.h>
34 #include <sys/types.h>
35 #include <sys/ipc.h>
36 #include <sys/msg.h>
37 #include <sys/stat.h>
38 #include <unistd.h>
39 #include <fcntl.h>
40 #include <signal.h>
41 #include <poll.h>
42 #include <string.h>
43 #include <mm_debug.h>
44
45 #include <gio/gio.h>
46 #include <unistd.h>
47
48 #ifdef USE_SECURITY
49 #include <security-server.h>
50 #define COOKIE_SIZE 20
51 #endif
52
53 #if defined(USE_VCONF)
54 #include <vconf.h>
55 #include <errno.h>
56 #else
57 #include <gconf/gconf.h>
58 #include <gconf/gconf-client.h>
59 #include <phonestatus.h>
60
61 #endif
62 #include "../include/audio-session-manager.h"
63
64 #define asmgettid() (long int)getpid()
65 #define ASM_HANDLE_MAX 256
66
67 #define NO_EINTR(stmt) while ((stmt) == -1 && errno == EINTR);  /* sample code by THE LINUX PROGRAMMING INTERFACE */
68
69 static int asm_snd_msgid;
70 static int asm_rcv_msgid;
71 static int asm_cb_msgid;
72
73 static ASM_msg_lib_to_asm_t asm_snd_msg;
74 static ASM_msg_asm_to_lib_t asm_rcv_msg;
75
76 static unsigned char            str_pass[] = "< OK >";
77 static unsigned char            str_fail[] = "<FAIL>";
78
79 typedef gboolean (*gLoopPollHandler_t)(gpointer d);
80
81 static GThread *g_asm_thread;
82 static GMainLoop *g_asm_loop;
83
84 typedef struct
85 {
86         int                asm_tid;
87         int                handle;
88         ASM_sound_events_t sound_event;
89         ASM_sound_states_t sound_state;
90         ASM_sound_cb_t     asm_callback;
91         ASM_watch_cb_t     watch_callback;
92         void               *user_data;
93         int                option_flags;
94         int                asm_fd;
95         GSourceFuncs*      g_src_funcs;
96         GPollFD*           g_poll_fd;
97         GSource*           asm_src;
98         bool               is_used;
99         bool               is_for_watching;
100         GMutex*            asm_lock;
101 } ASM_sound_info_t;
102
103 static ASM_sound_info_t ASM_sound_handle[ASM_HANDLE_MAX];
104
105 static const char* ASM_sound_events_str[] =
106 {
107         "MEDIA_MMPLAYER",
108         "MEDIA_MMCAMCORDER",
109         "MEDIA_MMSOUND",
110         "MEDIA_OPENAL",
111         "MEDIA_FMRADIO",
112         "MEDIA_WEBKIT",
113         "NOTIFY",
114         "ALARM",
115         "EARJACK_UNPLUG",
116         "CALL",
117         "VIDEOCALL",
118         "VOIP",
119         "MONITOR",
120         "EMERGENCY",
121         "EXCLUSIVE_RESOURCE",
122         "VOICE_RECOGNITION",
123         "MMCAMCORDER_AUDIO",
124         "MMCAMCORDER_VIDEO"
125 };
126
127 static const char* ASM_sound_state_str[] =
128 {
129         "STATE_NONE",
130         "STATE_PLAYING",
131         "STATE_WAITING",
132         "STATE_STOP",
133         "STATE_PAUSE"
134 };
135
136 static unsigned int ASM_all_sound_status;
137
138 static int __ASM_find_index_by_handle(int handle);
139
140 static gpointer thread_func(gpointer data)
141 {
142         debug_log(">>> thread func..ID of this thread(%u)\n", (unsigned int)pthread_self());
143         g_main_loop_run(g_asm_loop);
144         debug_log("<<< quit thread func..\n");
145         return NULL;
146 }
147
148 static bool __ASM_get_sound_state(unsigned int *all_sound_status, int *error_code)
149 {
150         int value = 0;
151
152         if(vconf_get_int(SOUND_STATUS_KEY, &value)) {
153                 debug_error("failed to vconf_get_int(SOUND_STATUS_KEY)");
154                 *error_code = ERR_ASM_VCONF_ERROR;
155                 return false;
156         }
157         debug_log("All status(%#X)", value);
158         *all_sound_status = value;
159         ASM_all_sound_status = value;
160
161         return true;
162 }
163
164 static gboolean __asm_fd_check(GSource * source)
165 {
166         GSList *fd_list;
167         GPollFD *temp;
168
169         if (!source) {
170                 debug_error("GSource is null");
171                 return FALSE;
172         }
173         fd_list = source->poll_fds;
174         if (!fd_list) {
175                 debug_error("fd_list is null");
176                 return FALSE;
177         }
178         do {
179                 temp = (GPollFD*)fd_list->data;
180                 if (!temp) {
181                         debug_error("fd_list->data is null");
182                         return FALSE;
183                 }
184                 if (temp->revents & (POLLIN | POLLPRI)) {
185                         return TRUE;
186                 }
187                 fd_list = fd_list->next;
188         } while (fd_list);
189
190         return FALSE; /* there is no change in any fd state */
191 }
192
193 static gboolean __asm_fd_prepare(GSource *source, gint *timeout)
194 {
195         return FALSE;
196 }
197
198 static gboolean __asm_fd_dispatch(GSource *source,      GSourceFunc callback, gpointer user_data)
199 {
200         callback(user_data);
201         return TRUE;
202 }
203
204 static gboolean asm_callback_handler( gpointer d)
205 {
206         GPollFD *data = (GPollFD*)d;
207         unsigned int buf;
208         int count;
209         int tid = 0;
210         int asm_index = 0;
211         //debug_fenter();
212         debug_log(">>> asm_callback_handler()..ID of this thread(%u)\n", (unsigned int)pthread_self());
213
214         if (!data) {
215                 debug_error("GPollFd is null");
216                 return FALSE;
217         }
218         if (data->revents & (POLLIN | POLLPRI)) {
219                 int handle;
220                 int error_code = 0;
221                 int event_src;
222                 unsigned int sound_status_value;
223                 ASM_sound_commands_t rcv_command;
224                 ASM_cb_result_t cb_res = ASM_CB_RES_NONE;
225
226
227                 count = read(data->fd, &buf, sizeof(int));
228                 if (count != sizeof(int)) {
229                         debug_log("read %d/%d", count, sizeof(int));
230                 }
231
232                 handle = (int)( buf & 0x0000ffff);
233                 rcv_command = (ASM_sound_commands_t)((buf >> 16) & 0xff);
234                 event_src = (ASM_event_sources_t)((buf >> 24) & 0xff);
235
236                 asm_index = __ASM_find_index_by_handle(handle);
237                 if (asm_index == -1) {
238                         debug_error("Can not find index");
239                         return FALSE;
240                 }
241
242                 if (ASM_sound_handle[asm_index].asm_lock) {
243                         g_mutex_lock(ASM_sound_handle[asm_index].asm_lock);
244                 }
245
246                 tid = ASM_sound_handle[asm_index].asm_tid;
247
248                 if (rcv_command) {
249                         debug_msg("Got and start CB : TID(%d), handle(%d), command(%d,(PLAY(2)/STOP(3)/PAUSE(4)/RESUME(5)), event_src(%d)",
250                                         tid, handle, rcv_command, event_src );
251                         if (!__ASM_get_sound_state(&sound_status_value, &error_code)) {
252                                 debug_error("failed to __ASM_get_sound_state(), error(%d)", error_code);
253                         }
254                         switch (rcv_command) {
255                         case ASM_COMMAND_PLAY:
256                         case ASM_COMMAND_RESUME:
257                         case ASM_COMMAND_PAUSE:
258                         case ASM_COMMAND_STOP:
259                                 if (ASM_sound_handle[asm_index].asm_callback == NULL) {
260                                         debug_msg("callback is null..");
261                                         break;
262                                 }
263                                 debug_msg("[CALLBACK(%p) START]",ASM_sound_handle[asm_index].asm_callback);
264                                 cb_res = (ASM_sound_handle[asm_index].asm_callback)(handle, event_src, rcv_command, sound_status_value, ASM_sound_handle[asm_index].user_data);
265                                 debug_msg("[CALLBACK END]");
266                                 break;
267                         default:
268                                 break;
269                         }
270 #ifdef CONFIG_ENABLE_RETCB
271
272                         /* If the command is not RESUME, send return */
273                         if (rcv_command != ASM_COMMAND_RESUME) {
274                                 int rett = 0;
275                                 int buf = cb_res;
276                                 int tmpfd = -1;
277                                 char *filename2 = g_strdup_printf("/tmp/ASM.%d.%dr", ASM_sound_handle[asm_index].asm_tid, handle);
278                                 tmpfd = open(filename2, O_WRONLY | O_NONBLOCK);
279                                 if (tmpfd < 0) {
280                                         char str_error[256];
281                                         strerror_r(errno, str_error, sizeof(str_error));
282                                         debug_error("[RETCB][Failed(May Server Close First)]tid(%d) fd(%d) %s errno=%d(%s)\n", tid, tmpfd, filename2, errno, str_error);
283                                         g_free(filename2);
284                                         if (ASM_sound_handle[asm_index].asm_lock) {
285                                                 g_mutex_unlock(ASM_sound_handle[asm_index].asm_lock);
286                                         }
287                                         return FALSE;
288                                 }
289                                 rett = write(tmpfd, &buf, sizeof(buf));
290                                 close(tmpfd);
291                                 g_free(filename2);
292                                 debug_msg("[RETCB] tid(%d) finishing CB (write=%d)\n", tid, rett);
293                         } else {
294                                 debug_msg("[RETCB] No need to send return for RESUME command\n");
295                         }
296 #endif
297                 }
298         }
299         //debug_fleave();
300
301         if (ASM_sound_handle[asm_index].asm_lock) {
302                 g_mutex_unlock(ASM_sound_handle[asm_index].asm_lock);
303         }
304
305         return TRUE;
306 }
307
308 static gboolean watch_callback_handler( gpointer d)
309 {
310         GPollFD *data = (GPollFD*)d;
311         unsigned int buf;
312         int count;
313         int tid = 0;
314         int asm_index = 0;
315
316         debug_fenter();
317
318         if (!data) {
319                 debug_error("GPollFd is null");
320                 return FALSE;
321         }
322         if (data->revents & (POLLIN | POLLPRI)) {
323                 int handle;
324                 ASM_sound_events_t rcv_sound_event = ASM_EVENT_NONE;
325                 ASM_sound_states_t rcv_sound_state = ASM_STATE_NONE;
326                 int error_code = 0;
327
328                 unsigned int sound_status_value;
329
330                 ASM_cb_result_t cb_res = ASM_CB_RES_NONE;
331
332
333                 count = read(data->fd, &buf, sizeof(int));
334                 if (count != sizeof(int)) {
335                         debug_log("read %d/%d", count, sizeof(int));
336                 }
337
338                 handle = (int)( buf & 0x0000ffff);
339                 rcv_sound_event = (ASM_sound_events_t)((buf >> 16) & 0xff);
340                 rcv_sound_state = (ASM_sound_states_t)((buf >> 24) & 0xff);
341
342                 asm_index = __ASM_find_index_by_handle(handle);
343                 if (asm_index == -1) {
344                         debug_error("Can not find index");
345                         return FALSE;
346                 }
347
348                 if (ASM_sound_handle[asm_index].asm_lock) {
349                         g_mutex_lock(ASM_sound_handle[asm_index].asm_lock);
350                 }
351
352                 tid = ASM_sound_handle[asm_index].asm_tid;
353
354                 debug_msg("Got and start CB : handle(%d) sound_event(%d) sound_state(%d)", handle, rcv_sound_event, rcv_sound_state );
355
356                 if (!__ASM_get_sound_state(&sound_status_value, &error_code)) {
357                         debug_error("failed to __ASM_get_sound_state(), error(%d)", error_code);
358                 }
359
360                 if (ASM_sound_handle[asm_index].watch_callback == NULL) {
361                         debug_msg("callback is null..");
362                         if (ASM_sound_handle[asm_index].asm_lock) {
363                                 g_mutex_unlock(ASM_sound_handle[asm_index].asm_lock);
364                         }
365                         return FALSE;
366                 }
367                 debug_msg("[CALLBACK(%p) START]",ASM_sound_handle[asm_index].watch_callback);
368                 cb_res = (ASM_sound_handle[asm_index].watch_callback)(handle, rcv_sound_event, rcv_sound_state, ASM_sound_handle[asm_index].user_data);
369                 debug_msg("[CALLBACK END]");
370
371 #ifdef CONFIG_ENABLE_RETCB
372                 {
373                         int rett = 0;
374                         int buf = cb_res;
375                         int tmpfd = -1;
376                         char *filename2 = g_strdup_printf("/tmp/ASM.%d.%dr", ASM_sound_handle[asm_index].asm_tid, handle);
377                         tmpfd = open(filename2, O_WRONLY | O_NONBLOCK);
378                         if (tmpfd < 0) {
379                                 char str_error[256];
380                                 strerror_r(errno, str_error, sizeof(str_error));
381                                 debug_error("[RETCB][Failed(May Server Close First)]tid(%d) fd(%d) %s errno=%d(%s)\n", tid, tmpfd, filename2, errno, str_error);
382                                 g_free(filename2);
383                                 if (ASM_sound_handle[asm_index].asm_lock) {
384                                         g_mutex_unlock(ASM_sound_handle[asm_index].asm_lock);
385                                 }
386                                 return FALSE;
387                         }
388                         rett = write(tmpfd, &buf, sizeof(buf));
389                         close(tmpfd);
390                         g_free(filename2);
391                         debug_msg("[RETCB] tid(%d) finishing CB (write=%d)\n", tid, rett);
392                 }
393 #endif
394
395         }
396         debug_fleave();
397
398         if (ASM_sound_handle[asm_index].asm_lock) {
399                 g_mutex_unlock(ASM_sound_handle[asm_index].asm_lock);
400         }
401
402         return TRUE;
403 }
404
405
406 static bool __ASM_add_sound_callback(int index, int fd, gushort events, gLoopPollHandler_t p_gloop_poll_handler )
407 {
408         GSource* g_src = NULL;
409         GSourceFuncs *g_src_funcs = NULL;               /* handler function */
410         guint gsource_handle;
411         GPollFD *g_poll_fd = NULL;                      /* file descriptor */
412
413         ASM_sound_handle[index].asm_lock = g_new(GMutex, 1);
414         if (!ASM_sound_handle[index].asm_lock) {
415                 debug_error("failed to alloc GMutex for index(%d)", index);
416                 return false;
417         }
418         g_mutex_init(ASM_sound_handle[index].asm_lock);
419
420         /* 1. make GSource Object */
421         g_src_funcs = (GSourceFuncs *)g_malloc(sizeof(GSourceFuncs));
422         if (!g_src_funcs) {
423                 debug_error("g_malloc failed on g_src_funcs");
424                 return false;
425         }
426         g_src_funcs->prepare = __asm_fd_prepare;
427         g_src_funcs->check = __asm_fd_check;
428         g_src_funcs->dispatch = __asm_fd_dispatch;
429         g_src_funcs->finalize = NULL;
430         g_src = g_source_new(g_src_funcs, sizeof(GSource));
431         if (!g_src) {
432                 debug_error("g_malloc failed on m_readfd");
433                 return false;
434         }
435         ASM_sound_handle[index].asm_src = g_src;
436         ASM_sound_handle[index].g_src_funcs = g_src_funcs;
437
438         /* 2. add file description which used in g_loop() */
439         g_poll_fd = (GPollFD *)g_malloc(sizeof(GPollFD));
440         if (!g_poll_fd) {
441                 debug_error("g_malloc failed on g_poll_fd");
442                 return false;
443         }
444         g_poll_fd->fd = fd;
445         g_poll_fd->events = events;
446         ASM_sound_handle[index].g_poll_fd = g_poll_fd;
447
448         /* 3. combine g_source object and file descriptor */
449         g_source_add_poll(g_src, g_poll_fd);
450         gsource_handle = g_source_attach(g_src, g_main_loop_get_context(g_asm_loop));
451         if (!gsource_handle) {
452                 debug_error(" Failed to attach the source to context");
453                 return false;
454         }
455         g_source_unref(g_src);
456
457         /* 4. set callback */
458         g_source_set_callback(g_src, p_gloop_poll_handler,(gpointer)g_poll_fd, NULL);
459
460         debug_log(" g_malloc:g_src_funcs(%#X),g_poll_fd(%#X)  g_source_add_poll:g_src_id(%d)  g_source_set_callback:errno(%d)",
461                                 g_src_funcs, g_poll_fd, gsource_handle, errno);
462         return true;
463 }
464
465
466 static bool __ASM_remove_sound_callback(int index, gushort events)
467 {
468         bool ret = true;
469
470         if (ASM_sound_handle[index].asm_lock) {
471                 g_mutex_clear(ASM_sound_handle[index].asm_lock);
472                 g_free(ASM_sound_handle[index].asm_lock);
473                 ASM_sound_handle[index].asm_lock = NULL;
474         }
475
476         GSourceFuncs *g_src_funcs = ASM_sound_handle[index].g_src_funcs;
477         GPollFD *g_poll_fd = ASM_sound_handle[index].g_poll_fd; /* store file descriptor */
478         if (!g_poll_fd) {
479                 debug_error("g_poll_fd is null..");
480                 ret = false;
481                 goto init_handle;
482         }
483         g_poll_fd->fd = ASM_sound_handle[index].asm_fd;
484         g_poll_fd->events = events;
485
486         if (!ASM_sound_handle[index].asm_src) {
487                 debug_error("ASM_sound_handle[%d].asm_src is null..", index);
488                 goto init_handle;
489         }
490         debug_log(" g_source_remove_poll : fd(%d), event(%x), errno(%d)", g_poll_fd->fd, g_poll_fd->events, errno);
491         g_source_remove_poll(ASM_sound_handle[index].asm_src, g_poll_fd);
492
493 init_handle:
494
495         if (ASM_sound_handle[index].asm_src) {
496                 g_source_destroy(ASM_sound_handle[index].asm_src);
497                 if (!g_source_is_destroyed (ASM_sound_handle[index].asm_src)) {
498                         debug_warning(" failed to g_source_destroy(), asm_src(0x%p)", ASM_sound_handle[index].asm_src);
499                 }
500         }
501         debug_log(" g_free : g_src_funcs(%#X), g_poll_fd(%#X)", g_src_funcs, g_poll_fd);
502
503         if (g_src_funcs) {
504                 g_free(g_src_funcs);
505                 g_src_funcs = NULL;
506         }
507         if (g_poll_fd) {
508                 g_free(g_poll_fd);
509                 g_poll_fd = NULL;
510         }
511
512         ASM_sound_handle[index].g_src_funcs = NULL;
513         ASM_sound_handle[index].g_poll_fd = NULL;
514         ASM_sound_handle[index].asm_src = NULL;
515         ASM_sound_handle[index].asm_callback = NULL;
516         ASM_sound_handle[index].watch_callback = NULL;
517
518         return ret;
519 }
520
521
522 static bool __ASM_is_existed_request_for_watching(ASM_sound_events_t interest_event, ASM_sound_states_t interest_state, int *index)
523 {
524         int i = 0;
525         for(i = 0; i< ASM_HANDLE_MAX; i++) {
526                 if (ASM_sound_handle[i].is_for_watching && ASM_sound_handle[i].sound_event == interest_event) {
527                         if (ASM_sound_handle[i].sound_state == interest_state) {
528                                 debug_warning("already requested interest-session(%s, %s)",
529                                                 ASM_sound_events_str[interest_event], ASM_sound_state_str[interest_state]);
530                                 *index = i;
531                                 return true;
532                         }
533                 }
534         }
535         *index = 0;
536         return false;
537 }
538
539
540 static bool __ASM_is_supported_session_for_watching(ASM_sound_events_t interest_event, ASM_sound_states_t interest_state)
541 {
542         bool ret = false;
543
544         /* check sound_event */
545         switch (interest_event) {
546         case ASM_EVENT_MEDIA_MMPLAYER:
547         case ASM_EVENT_MEDIA_MMCAMCORDER:
548         case ASM_EVENT_MEDIA_MMSOUND:
549         case ASM_EVENT_MEDIA_OPENAL:
550         case ASM_EVENT_MEDIA_FMRADIO:
551         case ASM_EVENT_MEDIA_WEBKIT:
552         case ASM_EVENT_NOTIFY:
553         case ASM_EVENT_ALARM:
554         case ASM_EVENT_EARJACK_UNPLUG:
555         case ASM_EVENT_CALL:
556         case ASM_EVENT_VIDEOCALL:
557         case ASM_EVENT_VOIP:
558         case ASM_EVENT_MONITOR:
559         case ASM_EVENT_EMERGENCY:
560         case ASM_EVENT_EXCLUSIVE_RESOURCE:
561         case ASM_EVENT_VOICE_RECOGNITION:
562         case ASM_EVENT_MMCAMCORDER_AUDIO:
563         case ASM_EVENT_MMCAMCORDER_VIDEO:
564                 ret = true;
565                 break;
566         default:
567                 debug_error("not supported sound_event(%d)", interest_event);
568                 ret = false;
569                 return ret;
570         }
571
572         /* check sound_state */
573         switch (interest_state) {
574         case ASM_STATE_PLAYING:
575         case ASM_STATE_STOP:
576                 ret = true;
577                 break;
578         default:
579                 debug_error("not supported sound_state(%d)", interest_state);
580                 ret = false;
581                 return ret;
582         }
583
584         return ret;
585 }
586
587
588 static int __ASM_find_index_by_handle(int handle)
589 {
590         int i = 0;
591         for(i = 0; i< ASM_HANDLE_MAX; i++) {
592                 if (handle == ASM_sound_handle[i].handle) {
593                         //debug_msg("found index(%d) for handle(%d)", i, handle);
594                         if (handle == ASM_HANDLE_INIT_VAL) {
595                                 return -1;
596                         }
597                         return i;
598                 }
599         }
600         return -1;
601 }
602
603 static int __ASM_find_index_by_event(ASM_sound_events_t sound_event, int pid)
604 {
605         int i = 0;
606
607         for(i = 0; i< ASM_HANDLE_MAX; i++) {
608                 if (sound_event == ASM_sound_handle[i].sound_event && pid == ASM_sound_handle[i].asm_tid) {
609                         debug_msg("found index(%d) for sound_event(%d)", i, sound_event);
610                         return i;
611                 }
612         }
613         return -1;
614 }
615
616
617 static void __ASM_add_callback(int index, bool is_for_watching)
618 {
619         if (!is_for_watching) {
620                 if (!__ASM_add_sound_callback(index, ASM_sound_handle[index].asm_fd, (gushort)POLLIN | POLLPRI, asm_callback_handler)) {
621                         debug_error("failed to __ASM_add_sound_callback(asm_callback_handler)");
622                         //return false;
623                 }
624         } else {
625                 if (!__ASM_add_sound_callback(index, ASM_sound_handle[index].asm_fd, (gushort)POLLIN | POLLPRI, watch_callback_handler)) {
626                         debug_error("failed to __ASM_add_sound_callback(watch_callback_handler)");
627                         //return false;
628                 }
629         }
630 }
631
632
633 static void __ASM_remove_callback(int index)
634 {
635         if (!__ASM_remove_sound_callback(index, (gushort)POLLIN | POLLPRI)) {
636                 debug_error("failed to __ASM_remove_sound_callback()");
637                 //return false;
638         }
639 }
640
641
642 static void __ASM_open_callback(int index)
643 {
644         mode_t pre_mask;
645
646         char *filename = g_strdup_printf("/tmp/ASM.%d.%d", ASM_sound_handle[index].asm_tid, ASM_sound_handle[index].handle);
647         pre_mask = umask(0);
648         if (mknod(filename, S_IFIFO|0666, 0)) {
649                 debug_error("mknod() failure, errno(%d)", errno);
650         }
651         umask(pre_mask);
652         ASM_sound_handle[index].asm_fd = open( filename, O_RDWR|O_NONBLOCK);
653         if (ASM_sound_handle[index].asm_fd == -1) {
654                 debug_error("%s : index(%d), file open error(%d)", str_fail, index, errno);
655         } else {
656                 debug_log("%s : index(%d), filename(%s), fd(%d)", str_pass, index, filename, ASM_sound_handle[index].asm_fd);
657         }
658         g_free(filename);
659         filename = NULL;
660
661 #ifdef CONFIG_ENABLE_RETCB
662         char *filename2 = g_strdup_printf("/tmp/ASM.%d.%dr", ASM_sound_handle[index].asm_tid,  ASM_sound_handle[index].handle);
663         pre_mask = umask(0);
664         if (mknod(filename2, S_IFIFO | 0666, 0)) {
665                 debug_error("mknod() failure, errno(%d)", errno);
666         }
667         umask(pre_mask);
668         g_free(filename2);
669         filename2 = NULL;
670 #endif
671
672 }
673
674
675 void __ASM_close_callback(int index)
676 {
677         if (ASM_sound_handle[index].asm_fd < 0) {
678                 debug_error("%s : fd error.", str_fail);
679         } else {
680                 char *filename = g_strdup_printf("/tmp/ASM.%d.%d", ASM_sound_handle[index].asm_tid, ASM_sound_handle[index].handle);
681                 close(ASM_sound_handle[index].asm_fd);
682                 if (remove(filename)) {
683                         debug_error("remove() failure, filename(%s), errno(%d)", filename, errno);
684                 }
685                 debug_log("%s : index(%d), filename(%s), fd(%d)", str_pass, index, filename, ASM_sound_handle[index].asm_fd);
686                 g_free(filename);
687                 filename = NULL;
688         }
689
690 #ifdef CONFIG_ENABLE_RETCB
691         char *filename2 = g_strdup_printf("/tmp/ASM.%d.%dr", ASM_sound_handle[index].asm_tid, ASM_sound_handle[index].handle);
692
693         /* Defensive code - wait until callback timeout although callback is removed */
694         int buf = ASM_CB_RES_STOP;
695         int tmpfd = -1;
696         int ret;
697         tmpfd = open(filename2, O_WRONLY | O_NONBLOCK);
698         if (tmpfd < 0) {
699                 char str_error[256];
700                 strerror_r(errno, str_error, sizeof(str_error));
701                 debug_warning("could not open file(%s) (may server close it first), tid(%d) fd(%d) %s errno=%d(%s)",
702                         filename2, ASM_sound_handle[index].asm_tid, tmpfd, filename2, errno, str_error);
703         } else {
704                 ret = write(tmpfd, &buf, sizeof(buf));
705                 close(tmpfd);
706                 debug_msg("write ASM_CB_RES_STOP(tid:%d) for waiting server , error code(%d)", ASM_sound_handle[index].asm_tid, ret);
707         }
708
709         if (remove(filename2)) {
710                 debug_error("remove() failure, filename(%s), errno(%d)", filename2, errno);
711         }
712         g_free(filename2);
713         filename2 = NULL;
714 #endif
715
716 }
717
718 static bool __asm_construct_snd_msg(int asm_pid, int handle, ASM_sound_events_t sound_event,
719                                         ASM_requests_t request_id, ASM_sound_states_t sound_state, ASM_resource_t resource, int *error_code)
720 {
721         asm_snd_msg.instance_id = asm_pid;
722
723         asm_snd_msg.data.handle = handle;
724         asm_snd_msg.data.request_id = request_id;
725         asm_snd_msg.data.sound_event = sound_event;
726         asm_snd_msg.data.sound_state = sound_state;
727         asm_snd_msg.data.system_resource = resource;
728
729         debug_msg("tid=%ld,handle=%d,req=%d,evt=%d,state=%d,resource=%d,instance_id=%ld", asm_snd_msg.instance_id,
730                                 asm_snd_msg.data.handle, asm_snd_msg.data.request_id, asm_snd_msg.data.sound_event,
731                                 asm_snd_msg.data.sound_state, asm_snd_msg.data.system_resource, asm_snd_msg.instance_id);
732
733         return true;
734 }
735
736 static void __ASM_init_callback(int index, bool is_for_watching)
737 {
738         debug_fenter();
739         __ASM_open_callback(index);
740         __ASM_add_callback(index, is_for_watching);
741         debug_fleave();
742 }
743
744
745 static void __ASM_destroy_callback(int index)
746 {
747         debug_fenter();
748         __ASM_remove_callback(index);
749         __ASM_close_callback(index);
750         debug_fleave();
751 }
752
753 #ifdef SUPPORT_CONTAINER
754 #ifdef USE_SECURITY
755 char* _get_cookie(int cookie_size)
756 {
757         int retval = -1;
758         char* cookie = NULL;
759
760         if (security_server_get_cookie_size() != cookie_size) {
761                 debug_error ("[Security] security_server_get_cookie_size() != COOKIE_SIZE(%d)\n", cookie_size);
762                 return false;
763         }
764
765         cookie = (char*)malloc (cookie_size);
766
767         retval = security_server_request_cookie (cookie, cookie_size);
768         if (retval == SECURITY_SERVER_API_SUCCESS) {
769                 debug_msg ("[Security] security_server_request_cookie() returns [%d]\n", retval);
770         } else {
771                 debug_error ("[Security] security_server_request_cookie() returns [%d]\n", retval);
772         }
773
774         return cookie;
775 }
776
777 static GVariant* _get_cookie_variant ()
778 {
779         int i;
780         GVariantBuilder builder;
781         char* cookie = NULL;
782
783         cookie = _get_cookie(COOKIE_SIZE);
784
785         if (cookie == NULL)
786                 return NULL;
787
788         g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
789         for (i = 0; i < COOKIE_SIZE; i++)
790                 g_variant_builder_add(&builder, "y", cookie[i]);
791
792         free (cookie);
793         return g_variant_builder_end(&builder);
794 }
795
796 #endif /* USE_SECURITY */
797 #endif /* SUPPORT_CONTAINER */
798
799 EXPORT_API
800 bool ASM_register_sound_ex (const int application_pid, int *asm_handle, ASM_sound_events_t sound_event, ASM_sound_states_t sound_state,
801                                                 ASM_sound_cb_t callback, void *user_data, ASM_resource_t mm_resource, int *error_code, int (*func)(void*,void*))
802 {
803         unsigned int sound_status_value;
804         int handle = 0;
805         int asm_pid = 0;
806         int index = 0;
807         GError *err = NULL;
808         GDBusConnection *conn = NULL;
809         GVariant *res_variant = NULL;
810         GVariant *client_variant = NULL;
811 #ifdef SUPPORT_CONTAINER
812         char container[128];
813 #endif
814
815         debug_fenter();
816
817         if (error_code==NULL) {
818                 debug_error ("invalid parameter. error code is null");
819                 return false;
820         }
821         *error_code = ERR_ASM_ERROR_NONE;
822
823         if (sound_event < ASM_EVENT_MEDIA_MMPLAYER || sound_event >= ASM_EVENT_MAX) {
824                 *error_code = ERR_ASM_EVENT_IS_INVALID;
825                 debug_error ("invalid sound event(%d)",sound_event);
826                 return false;
827         }
828
829         for (index = 0; index < ASM_HANDLE_MAX; index++) {
830                 if (ASM_sound_handle[index].is_used == false) {
831                         break;
832                 }
833         }
834
835         if (index == ASM_HANDLE_MAX) {
836                 *error_code = ERR_ASM_LOCAL_HANDLE_IS_FULL;
837                 debug_error ("local sound event is full(MAX)");
838                 return false;
839         }
840
841         if (!g_asm_thread) {
842                 GMainContext* asm_context = g_main_context_new ();
843                 g_asm_loop = g_main_loop_new (asm_context, FALSE);
844                 g_main_context_unref(asm_context);
845                 g_asm_thread = g_thread_new("ASM Thread", thread_func, NULL);
846                 if (g_asm_thread == NULL) {
847                         debug_error ("could not create thread..");
848                         g_main_loop_unref(g_asm_loop);
849                         return false;
850                 }
851         }
852
853         if (application_pid == -1) {
854                 asm_pid = asmgettid();
855         } else if (application_pid > 2) {
856                 asm_pid = application_pid;
857         } else {
858                 *error_code = ERR_ASM_INVALID_PARAMETER;
859                 debug_error ("invalid pid %d", application_pid);
860                 return false;
861         }
862
863         ASM_sound_handle[index].sound_event = sound_event;
864         ASM_sound_handle[index].asm_tid = asm_pid;
865
866         if (!__ASM_get_sound_state(&sound_status_value, error_code)) {
867                 debug_error("failed to __ASM_get_sound_state(), error(%d)", *error_code);
868                 return false;
869         }
870
871         debug_error(" <<<< Event(%s), Tid(%d), Index(%d), State(%s)",
872                                 ASM_sound_events_str[sound_event], ASM_sound_handle[index].asm_tid, index, ASM_sound_state_str[sound_state]);
873
874         handle = -1; /* for register & get handle from server */
875
876         if (func) {
877                 /* Construct msg to send -> send msg -> recv msg */
878                 if (!__asm_construct_snd_msg(asm_pid, handle, sound_event, ASM_REQUEST_REGISTER, sound_state, mm_resource, error_code)) {
879                         debug_error("failed to __asm_construct_snd_msg(), error(%d)", *error_code);
880                         return false;
881                 }
882                 func ((void*)&asm_snd_msg, (void*)&asm_rcv_msg);
883         } else  {
884                 conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
885                 if (!conn && err) {
886                         debug_error ("g_bus_get_sync() error (%s) ", err->message);
887                         g_error_free (err);
888                         return false;
889                 }
890                 debug_error ("conn = %p", conn);
891
892 #ifdef SUPPORT_CONTAINER
893 #ifdef USE_SECURITY
894                 client_variant = g_variant_new("(@ayiiiiii)", _get_cookie_variant(), asm_pid, handle, sound_event,
895                                                                                 ASM_REQUEST_REGISTER, sound_state, mm_resource);
896 #else /* USE_SECURITY */
897                 gethostname(container, sizeof(container));
898                 debug_error ("container = %s", container);
899                 client_variant = g_variant_new("(siiiiii)", container, asm_pid, handle, sound_event,
900                                                                                 ASM_REQUEST_REGISTER, sound_state, mm_resource);
901 #endif /* USE_SECURITY */
902
903 #else /* SUPPORT_CONTAINER */
904                 client_variant = g_variant_new("(iiiiii)", asm_pid, handle, sound_event,
905                                                                                 ASM_REQUEST_REGISTER, sound_state, mm_resource);
906 #endif /* SUPPORT_CONTAINER */
907
908                 res_variant = g_dbus_connection_call_sync(conn, ASM_BUS_NAME_SOUND_SERVER, ASM_OBJECT_SOUND_SERVER, ASM_INTERFACE_SOUND_SERVER,
909                                                                                 "ASMRegisterSound", client_variant, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,  &err);
910                 if (!res_variant && err) {
911                         debug_error("g_dbus_connection_call_sync fail(%s)", err->message);
912                         *error_code = ERR_ASM_GDBUS_CONNECTION_ERROR;
913                         g_error_free (err);
914                         return false;
915                 } else {
916                         g_variant_get(res_variant ,"(iiiiii)",
917                                         &(asm_rcv_msg.instance_id), &(asm_rcv_msg.data.alloc_handle), &(asm_rcv_msg.data.cmd_handle),
918                                         &(asm_rcv_msg.data.source_request_id), &(asm_rcv_msg.data.result_sound_command),
919                                         &(asm_rcv_msg.data.result_sound_state));
920                 }
921         }
922
923         handle = asm_rcv_msg.data.alloc_handle; /* get handle from server */
924         if (handle == -1) {
925                 debug_error("failed to create handle from server");
926                 *error_code = ERR_ASM_SERVER_HANDLE_IS_FULL;
927                 return false;
928         }
929
930         ASM_sound_handle[index].handle = handle;
931
932         __ASM_init_callback(index, ASM_sound_handle[index].is_for_watching);
933
934 /********************************************************************************************************/
935         switch (asm_rcv_msg.data.result_sound_command) {
936         case ASM_COMMAND_PAUSE:
937         case ASM_COMMAND_STOP:
938                 debug_msg( " <<<<<<<<<<<<<<<< Received command : %d (STOP(3)/PAUSE(4)) >>>>>>>>>>>>>>>>>>>>\n", asm_rcv_msg.data.result_sound_command);
939                 if (handle == asm_rcv_msg.data.cmd_handle) {
940
941                         __ASM_destroy_callback(index);
942
943                         ASM_sound_handle[index].asm_fd = 0;
944                         ASM_sound_handle[index].asm_tid = 0;
945                         ASM_sound_handle[index].sound_event = ASM_EVENT_NONE;
946                         ASM_sound_handle[index].is_used = false;
947                         if (asm_rcv_msg.data.result_sound_command == ASM_COMMAND_PAUSE) {
948                                 ASM_sound_handle[index].sound_state = ASM_STATE_PAUSE;
949                         } else if (asm_rcv_msg.data.result_sound_command == ASM_COMMAND_STOP) {
950                                 ASM_sound_handle[index].sound_state = ASM_STATE_STOP;
951                         }
952
953                         if (asm_rcv_msg.data.error_code){
954                                 *error_code = asm_rcv_msg.data.error_code;
955                                 debug_warning("error code: %x",*error_code);
956                         }
957                         return false;
958
959                 } else {
960                         int action_index = 0;
961                         unsigned int rcv_sound_status_value = 0;
962
963                         if (!__ASM_get_sound_state(&rcv_sound_status_value, error_code)) {
964                                 debug_error("failed to __ASM_get_sound_state(), error(%d)", *error_code);
965                         }
966
967                         debug_msg("Callback : TID(%ld), handle(%d), command(%d)",
968                                         asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle, asm_rcv_msg.data.result_sound_command);
969                         action_index = __ASM_find_index_by_handle(asm_rcv_msg.data.cmd_handle);
970                         if (action_index == -1) {
971                                 debug_error("Can not find index of instance %ld, handle %d", asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle);
972                         } else {
973                                 if (ASM_sound_handle[action_index].asm_callback != NULL) {
974                                         ASM_sound_handle[action_index].asm_callback(asm_rcv_msg.data.cmd_handle, ASM_sound_handle[action_index].sound_event,
975                                                                                                                                 asm_rcv_msg.data.result_sound_command, rcv_sound_status_value,
976                                                                                                                                 ASM_sound_handle[action_index].user_data);
977                                 } else {
978                                         debug_msg("null callback");
979                                 }
980                         }
981                 }
982                 break;
983
984         case ASM_COMMAND_PLAY:
985         case ASM_COMMAND_NONE:
986         case ASM_COMMAND_RESUME:
987                 ASM_sound_handle[index].sound_state = sound_state;
988                 break;
989         default:
990                 break;
991         }
992 /********************************************************************************************************/
993
994
995         ASM_sound_handle[index].asm_callback = callback;
996         ASM_sound_handle[index].user_data = user_data;
997         ASM_sound_handle[index].is_used = true;
998
999         debug_error(" >>>> Event(%s), Handle(%d), CBFuncPtr(%p)", ASM_sound_events_str[sound_event], handle, callback);
1000         /* Add [out] param, asm_handle */
1001         *asm_handle = handle;
1002
1003         debug_fleave();
1004
1005         return true;
1006
1007 }
1008
1009 EXPORT_API
1010 bool ASM_register_sound (const int application_pid, int *asm_handle, ASM_sound_events_t sound_event, ASM_sound_states_t sound_state,
1011                                                 ASM_sound_cb_t callback, void *user_data, ASM_resource_t mm_resource, int *error_code)
1012 {
1013         return ASM_register_sound_ex (application_pid, asm_handle, sound_event, sound_state, callback, user_data, mm_resource, error_code, NULL);
1014 }
1015
1016
1017 EXPORT_API
1018 bool ASM_change_callback(const int asm_handle, ASM_sound_events_t sound_event, ASM_sound_cb_t callback, void *user_data, int *error_code)
1019 {
1020         int handle=0;
1021
1022         if (error_code==NULL) {
1023                 debug_error ("invalid parameter. error code is null");
1024                 return false;
1025         }
1026         *error_code = ERR_ASM_ERROR_NONE;
1027
1028         if (sound_event < ASM_EVENT_MEDIA_MMPLAYER || sound_event >= ASM_EVENT_MAX) {
1029                 *error_code = ERR_ASM_EVENT_IS_INVALID;
1030                 debug_error ("invalid sound event(%d)",sound_event);
1031                 return false;
1032         }
1033
1034         int asm_index = -1;
1035
1036         if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
1037                 *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
1038                 debug_error("invalid handle(%d). callback is not registered", asm_handle);
1039                 return false;
1040         }
1041
1042         handle = asm_handle;
1043
1044         asm_index = __ASM_find_index_by_handle(handle);
1045         if (asm_index == -1) {
1046                 *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
1047                 debug_error("Can not find index for handle %d", handle);
1048                 return false;
1049         }
1050
1051         debug_msg("callback function has changed to %p", callback);
1052         ASM_sound_handle[asm_index].asm_callback = callback;
1053         ASM_sound_handle[asm_index].user_data = user_data;
1054
1055         return true;
1056 }
1057
1058 EXPORT_API
1059 bool ASM_unregister_sound_ex(const int asm_handle, ASM_sound_events_t sound_event, int *error_code, int (*func)(void*,void*))
1060 {
1061         int handle=0;
1062         int asm_index = -1;
1063         GError *err = NULL;
1064         GDBusConnection *conn = NULL;
1065         GVariant *client_variant = NULL;
1066
1067         debug_fenter();
1068
1069         if (error_code == NULL) {
1070                 debug_error ("invalid parameter. error code is null");
1071                 return false;
1072         }
1073         *error_code = ERR_ASM_ERROR_NONE;
1074
1075         if (sound_event < ASM_EVENT_MEDIA_MMPLAYER || sound_event >= ASM_EVENT_MAX) {
1076                 *error_code = ERR_ASM_EVENT_IS_INVALID;
1077                 debug_error ("invalid sound event(%d)",sound_event);
1078                 return false;
1079         }
1080
1081         if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
1082                 *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
1083                 debug_error("invalid handle(%d). callback is not registered", asm_handle);
1084                 return false;
1085         }
1086
1087         handle = asm_handle;
1088         asm_index = __ASM_find_index_by_handle(handle);
1089         if (asm_index == -1) {
1090                 *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
1091                 debug_error("Can not find index for handle(%d)", handle);
1092                 return false;
1093         }
1094         debug_msg("<<<< Event(%s), Tid(%d), Handle(%d) Index(%d)",
1095                                 ASM_sound_events_str[sound_event],
1096                                 ASM_sound_handle[asm_index].asm_tid,
1097                                 ASM_sound_handle[asm_index].handle,
1098                                 asm_index);
1099
1100         if (ASM_sound_handle[asm_index].asm_lock) {
1101                 if (!g_mutex_trylock(ASM_sound_handle[asm_index].asm_lock)) {
1102                         debug_warning("maybe asm_callback is being called, try one more time..");
1103                         usleep(2500000); // 2.5 sec
1104                         if (g_mutex_trylock(ASM_sound_handle[asm_index].asm_lock)) {
1105                                 debug_msg("finally got asm_lock");
1106                         }
1107                 }
1108         }
1109
1110         if (func) {
1111                 /* Construct msg to send -> send msg -> recv msg */
1112                 if (!__asm_construct_snd_msg(ASM_sound_handle[asm_index].asm_tid, handle, sound_event,
1113                                                                         ASM_REQUEST_UNREGISTER, ASM_STATE_NONE, ASM_RESOURCE_NONE, error_code)) {
1114                         debug_error("failed to __asm_construct_snd_msg(), error(%d)", *error_code);
1115                         return false;
1116                 }
1117                 func(&asm_snd_msg, &asm_rcv_msg);
1118         } else  {
1119                 conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
1120                 if (!conn && err) {
1121                         debug_error ("g_bus_get_sync() error (%s) ", err->message);
1122                         g_error_free (err);
1123                         return false;
1124                 }
1125
1126                 client_variant = g_variant_new("(iiiiii)",ASM_sound_handle[asm_index].asm_tid, handle, sound_event,
1127                                                                 ASM_REQUEST_UNREGISTER, ASM_STATE_NONE, ASM_RESOURCE_NONE);
1128                 g_dbus_connection_call_sync(conn, ASM_BUS_NAME_SOUND_SERVER, ASM_OBJECT_SOUND_SERVER, ASM_INTERFACE_SOUND_SERVER,
1129                                                                 "ASMUnregisterSound", client_variant, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,  &err);
1130
1131                 if(err) {
1132                         debug_error("g_dbus_connection_call_sync fail(%s)", err->message);
1133                         *error_code = ERR_ASM_GDBUS_CONNECTION_ERROR;
1134                         g_error_free (err);
1135                         return false;
1136                 }
1137         }
1138
1139         if (ASM_sound_handle[asm_index].asm_lock) {
1140                 g_mutex_unlock(ASM_sound_handle[asm_index].asm_lock);
1141         }
1142
1143         __ASM_destroy_callback(asm_index);
1144
1145         ASM_sound_handle[asm_index].asm_fd = 0;
1146         ASM_sound_handle[asm_index].asm_tid = 0;
1147         ASM_sound_handle[asm_index].handle = 0;
1148         ASM_sound_handle[asm_index].sound_event = ASM_EVENT_NONE;
1149         ASM_sound_handle[asm_index].sound_state = ASM_STATE_NONE;
1150         ASM_sound_handle[asm_index].is_used = false;
1151
1152         debug_fleave();
1153
1154         return true;
1155 }
1156
1157 EXPORT_API
1158 bool ASM_unregister_sound(const int asm_handle, ASM_sound_events_t sound_event, int *error_code)
1159 {
1160         return ASM_unregister_sound_ex (asm_handle, sound_event, error_code, NULL);
1161 }
1162
1163 EXPORT_API
1164 bool ASM_set_watch_session (const int application_pid,  ASM_sound_events_t interest_sound_event,
1165                             ASM_sound_states_t interest_sound_state, ASM_watch_cb_t callback, void *user_data, int *error_code)
1166 {
1167         unsigned int sound_status_value;
1168         int handle = 0;
1169         int asm_pid = 0;
1170         int index = 0;
1171         GError *err = NULL;
1172         GDBusConnection *conn = NULL;
1173         GVariant *res_variant = NULL;
1174         GVariant *client_variant = NULL;
1175 #ifdef SUPPORT_CONTAINER
1176         char container[128];
1177 #endif
1178
1179         debug_fenter();
1180
1181         if (error_code==NULL) {
1182                 debug_error ("invalid parameter. error code is null");
1183                 return false;
1184         }
1185         *error_code = ERR_ASM_ERROR_NONE;
1186
1187         if (interest_sound_event < ASM_EVENT_MEDIA_MMPLAYER || interest_sound_event >= ASM_EVENT_MAX) {
1188                 *error_code = ERR_ASM_EVENT_IS_INVALID;
1189                 debug_error ("invalid sound event(%d)", interest_sound_event);
1190                 return false;
1191         }
1192
1193         if (!__ASM_is_supported_session_for_watching(interest_sound_event, interest_sound_state)) {
1194                 debug_error("not supported sound_event(%d) or sound_state(%d)", interest_sound_event, interest_sound_state);
1195                 *error_code = ERR_ASM_WATCH_NOT_SUPPORTED;
1196                 return false;
1197         }
1198
1199         if (__ASM_is_existed_request_for_watching(interest_sound_event, interest_sound_state, &index))
1200         {
1201                 debug_warning("already requested interest-session, do not send request message");
1202                 *error_code = ERR_ASM_WATCH_ALREADY_REQUESTED;
1203                 return false;
1204         }
1205
1206         for (index = 0; index < ASM_HANDLE_MAX; index++) {
1207                 if (ASM_sound_handle[index].is_used == false) {
1208                         break;
1209                 }
1210         }
1211
1212         if (index == ASM_HANDLE_MAX) {
1213                 *error_code = ERR_ASM_LOCAL_HANDLE_IS_FULL;
1214                 debug_error ("local sound event is full(MAX)");
1215                 return false;
1216         }
1217
1218         if (application_pid == -1) {
1219                 asm_pid = asmgettid();
1220         } else if (application_pid > 2) {
1221                 asm_pid = application_pid;
1222         } else {
1223                 *error_code = ERR_ASM_INVALID_PARAMETER;
1224                 debug_error ("invalid pid %d", application_pid);
1225                 return false;
1226         }
1227
1228         ASM_sound_handle[index].asm_tid = asm_pid;
1229         ASM_sound_handle[index].sound_event = interest_sound_event;
1230         ASM_sound_handle[index].sound_state = interest_sound_state;
1231
1232         debug_msg(" <<<< Interest event(%s), state(%s), Tid(%d), Index(%d)",
1233                                 ASM_sound_events_str[interest_sound_event],
1234                                 ASM_sound_state_str[interest_sound_state],
1235                                 ASM_sound_handle[index].asm_tid, index);
1236
1237         if (!__ASM_get_sound_state(&sound_status_value, error_code)) {
1238                 debug_error("failed to __ASM_get_sound_state(), error(%d)", *error_code);
1239                 return false;
1240         }
1241
1242         handle = -1; /* for register & get handle from server */
1243         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
1244         if (!conn && err) {
1245                 debug_error ("g_bus_get_sync() error (%s) ", err->message);
1246                 g_error_free (err);
1247                 return false;
1248         }
1249
1250 #ifdef SUPPORT_CONTAINER
1251 #ifdef USE_SECURITY
1252         client_variant = g_variant_new("(@ayiiiiii)", _get_cookie_variant(), asm_pid, handle, interest_sound_event,
1253                                                                         ASM_REQUEST_REGISTER_WATCHER, interest_sound_state, ASM_RESOURCE_NONE);
1254 #else /* USE_SECURITY */
1255         gethostname(container, sizeof(container));
1256         debug_error ("container = %s", container);
1257         client_variant = g_variant_new("(siiiiii)", container, asm_pid, handle, interest_sound_event,
1258                                                                         ASM_REQUEST_REGISTER_WATCHER, interest_sound_state, ASM_RESOURCE_NONE);
1259 #endif /* USE_SECURITY */
1260
1261 #else /* SUPPORT_CONTAINER */
1262         client_variant = g_variant_new("(iiiiii)", asm_pid, handle, interest_sound_event,
1263                                                                         ASM_REQUEST_REGISTER_WATCHER, interest_sound_state, ASM_RESOURCE_NONE);
1264 #endif /* SUPPORT_CONTAINER */
1265
1266         res_variant = g_dbus_connection_call_sync(conn, ASM_BUS_NAME_SOUND_SERVER, ASM_OBJECT_SOUND_SERVER, ASM_INTERFACE_SOUND_SERVER,
1267                                                                         "ASMRegisterWatcher", client_variant, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,  &err);
1268
1269         if(!res_variant && err) {
1270                 debug_error("g_dbus_connection_call_sync fail(%s)", err->message);
1271                 *error_code = ERR_ASM_GDBUS_CONNECTION_ERROR;
1272                 g_error_free (err);
1273                 return false;
1274         } else {        
1275                 g_variant_get(res_variant ,"(iiiiii)", &(asm_rcv_msg.instance_id), &(asm_rcv_msg.data.alloc_handle), &(asm_rcv_msg.data.cmd_handle),
1276                                         &(asm_rcv_msg.data.source_request_id), &(asm_rcv_msg.data.result_sound_command), &(asm_rcv_msg.data.result_sound_state));
1277         }
1278
1279         handle = asm_rcv_msg.data.alloc_handle; /* get handle from server */
1280         if (handle == -1) {
1281                 debug_error("failed to create handle from server");
1282                 *error_code = ERR_ASM_SERVER_HANDLE_IS_FULL;
1283                 return false;
1284         }
1285
1286         ASM_sound_handle[index].handle = handle;
1287         ASM_sound_handle[index].watch_callback = callback;
1288         ASM_sound_handle[index].user_data = user_data;
1289         ASM_sound_handle[index].is_used = true;
1290         ASM_sound_handle[index].is_for_watching = true;
1291
1292         __ASM_init_callback(index, ASM_sound_handle[index].is_for_watching);
1293
1294         /********************************************************************************************************/
1295         switch (asm_rcv_msg.data.result_sound_command) {
1296         case ASM_COMMAND_PLAY:
1297                 debug_msg(" >>>> added to watch list successfully");
1298                 break;
1299
1300         default:
1301                 debug_error("received message is abnormal..result_sound_command(%d) from ASM server", asm_rcv_msg.data.result_sound_command);
1302                 *error_code = ERR_ASM_GDBUS_CONNECTION_ERROR;
1303                 return false;
1304         }
1305         /********************************************************************************************************/
1306
1307         debug_fleave();
1308
1309         return true;
1310 }
1311
1312 EXPORT_API
1313 bool ASM_unset_watch_session (ASM_sound_events_t interest_sound_event, ASM_sound_states_t interest_sound_state, int *error_code)
1314 {
1315         unsigned int sound_status_value;
1316         int handle = 0;
1317         int asm_pid = 0;
1318         int index = 0;
1319         GError *err = NULL;
1320         GDBusConnection *conn = NULL;
1321         GVariant *client_variant = NULL;
1322
1323         debug_fenter();
1324
1325         if (error_code==NULL) {
1326                 debug_error ("invalid parameter. error code is null");
1327                 return false;
1328         }
1329         *error_code = ERR_ASM_ERROR_NONE;
1330
1331         if (interest_sound_event < ASM_EVENT_MEDIA_MMPLAYER || interest_sound_event >= ASM_EVENT_MAX) {
1332                 *error_code = ERR_ASM_EVENT_IS_INVALID;
1333                 debug_error ("invalid sound event(%d)",interest_sound_event);
1334                 return false;
1335         }
1336
1337         if (!__ASM_is_supported_session_for_watching(interest_sound_event, interest_sound_state)) {
1338                 debug_error("not supported sound_event(%d) or sound_state(%d)", interest_sound_event, interest_sound_state);
1339                 *error_code = ERR_ASM_WATCH_NOT_SUPPORTED;
1340                 return false;
1341         }
1342
1343         if (!__ASM_is_existed_request_for_watching(interest_sound_event, interest_sound_state, &index))
1344         {
1345                 debug_warning("already unrequested interest-session or have not been requested it before, do not send request message");
1346                 *error_code = ERR_ASM_WATCH_ALREADY_UNREQUESTED;
1347                 return false;
1348         }
1349
1350         debug_msg(" <<<< Unregister interest event(%s), state(%s), Tid(%d), Index(%d)",
1351                                 ASM_sound_events_str[ASM_sound_handle[index].sound_event],
1352                                 ASM_sound_state_str[ASM_sound_handle[index].sound_state],
1353                                 ASM_sound_handle[index].asm_tid, index);
1354
1355         if (!__ASM_get_sound_state(&sound_status_value, error_code)) {
1356                 debug_error("failed to __ASM_get_sound_state(), error(%d)", *error_code);
1357                 return false;
1358         }
1359
1360         handle = ASM_sound_handle[index].handle;
1361         asm_pid = ASM_sound_handle[index].asm_tid;
1362
1363         if (ASM_sound_handle[index].asm_lock) {
1364                 g_mutex_lock(ASM_sound_handle[index].asm_lock);
1365         }
1366
1367         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
1368         if (!conn && err) {
1369                 debug_error ("g_bus_get_sync() error (%s) ", err->message);
1370                 g_error_free (err);
1371                 return false;
1372         }
1373
1374         client_variant = g_variant_new("(iiiiii)", asm_pid, handle, interest_sound_event,
1375                                                                 ASM_REQUEST_UNREGISTER_WATCHER, interest_sound_state, ASM_RESOURCE_NONE);
1376         g_dbus_connection_call_sync(conn, ASM_BUS_NAME_SOUND_SERVER, ASM_OBJECT_SOUND_SERVER, ASM_INTERFACE_SOUND_SERVER,
1377                                                                 "ASMUnregisterWatcher", client_variant, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,  &err);
1378
1379         if(err) {
1380                 debug_error("g_dbus_connection_call_sync fail(%s)", err->message);
1381                 *error_code = ERR_ASM_GDBUS_CONNECTION_ERROR;
1382                 g_error_free (err);
1383                 return false;
1384         }
1385
1386         if (ASM_sound_handle[index].asm_lock) {
1387                 g_mutex_unlock(ASM_sound_handle[index].asm_lock);
1388         }
1389
1390         __ASM_destroy_callback(index);
1391
1392         ASM_sound_handle[index].asm_tid = 0;
1393         ASM_sound_handle[index].handle = 0;
1394         ASM_sound_handle[index].sound_event = ASM_EVENT_NONE;
1395         ASM_sound_handle[index].sound_state = ASM_STATE_NONE;
1396         ASM_sound_handle[index].is_used = false;
1397         ASM_sound_handle[index].is_for_watching = false;
1398
1399         debug_msg(" >>>> send requesting message successfully");
1400
1401         debug_fleave();
1402
1403         return true;
1404 }
1405
1406 EXPORT_API
1407 bool ASM_get_sound_status(unsigned int *all_sound_status, int *error_code)
1408 {
1409         if (all_sound_status == NULL || error_code == NULL) {
1410                 if (error_code)
1411                         *error_code = ERR_ASM_INVALID_PARAMETER;
1412                 debug_error("invalid parameter");
1413                 return false;
1414         }
1415
1416         debug_msg("Tid(%ld)", asmgettid());
1417
1418         if (!__ASM_get_sound_state(all_sound_status, error_code)) {
1419                 debug_error("failed to __ASM_get_sound_state(), error(%d)", *error_code);
1420                 return false;
1421         }
1422
1423         return true;
1424 }
1425
1426 EXPORT_API
1427 bool ASM_get_process_session_state(const int asm_handle, ASM_sound_states_t *sound_state, int *error_code)
1428 {
1429         int handle = 0;
1430         int asm_index = 0;
1431         GError *err = NULL;
1432         GDBusConnection *conn = NULL;
1433         GVariant *res_variant = NULL;
1434         GVariant *client_variant = NULL;
1435
1436         if (sound_state == NULL || error_code == NULL) {
1437                 if (error_code)
1438                         *error_code = ERR_ASM_INVALID_PARAMETER;
1439                 debug_error("invalid parameter");
1440                 return false;
1441         }
1442
1443         handle = asm_handle;
1444         asm_index = __ASM_find_index_by_handle(handle);
1445         if (asm_index == -1) {
1446                 debug_error("Can not find index of %d", handle);
1447                 return false;
1448         }
1449
1450
1451         debug_msg("Pid(%d)", ASM_sound_handle[asm_index].asm_tid);
1452
1453         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
1454         if (!conn && err) {
1455                 debug_error ("g_bus_get_sync() error (%s) ", err->message);
1456                 g_error_free (err);
1457                 return false;
1458         }
1459
1460         client_variant = g_variant_new("(iiiiii)", ASM_sound_handle[asm_index].asm_tid, handle, ASM_EVENT_MONITOR,
1461                                                                         ASM_REQUEST_GETMYSTATE, ASM_STATE_NONE, ASM_RESOURCE_NONE);
1462         res_variant = g_dbus_connection_call_sync(conn, ASM_BUS_NAME_SOUND_SERVER, ASM_OBJECT_SOUND_SERVER, ASM_INTERFACE_SOUND_SERVER,
1463                                                                         "ASMGetMyState", client_variant, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
1464
1465         if(!res_variant && err) {
1466                 debug_error("g_dbus_connection_call_sync fail(%s)", err->message);
1467                 *error_code = ERR_ASM_GDBUS_CONNECTION_ERROR;
1468                 g_error_free (err);
1469                 return false;
1470         } else {
1471                 g_variant_get(res_variant ,"(iiiii)", &(asm_rcv_msg.instance_id), &(asm_rcv_msg.data.alloc_handle),
1472                                 &(asm_rcv_msg.data.cmd_handle), &(asm_rcv_msg.data.source_request_id), &(asm_rcv_msg.data.result_sound_state));
1473         }
1474
1475         *sound_state = asm_rcv_msg.data.result_sound_state;
1476
1477         debug_msg(">>>> Pid(%d), State(%s)", ASM_sound_handle[asm_index].asm_tid, ASM_sound_state_str[*sound_state]);
1478
1479         return true;
1480 }
1481
1482 EXPORT_API
1483 bool ASM_attach_callback(ASM_sound_events_t sound_event, ASM_sound_cb_t callback, void *user_data, int *error_code)
1484 {
1485         int asm_index = 0;
1486
1487         if (callback == NULL || error_code == NULL) {
1488                 if (error_code)
1489                         *error_code = ERR_ASM_INVALID_PARAMETER;
1490                 debug_error("invalid parameter");
1491                 return false;
1492         }
1493
1494         asm_index = __ASM_find_index_by_event(sound_event, asmgettid());
1495         if (asm_index == -1) {
1496                 debug_error("Could not find index of the event(%d)", sound_event);
1497                 return false;
1498         }
1499
1500         if (!ASM_sound_handle[asm_index].asm_callback) {
1501                 ASM_sound_handle[asm_index].asm_callback = callback;
1502                 ASM_sound_handle[asm_index].user_data = user_data;
1503         } else {
1504                 if (error_code)
1505                         *error_code = ERR_ASM_ALREADY_REGISTERED;
1506                 debug_error("asm_callback was already registered(0x%x)", ASM_sound_handle[asm_index].asm_callback);
1507                 return false;
1508         }
1509
1510         debug_msg(">>>> Pid(%d), Handle(%d), Event(%s), Callback(0x%x)", ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle,
1511                 ASM_sound_events_str[ASM_sound_handle[asm_index].sound_event], ASM_sound_handle[asm_index].asm_callback);
1512
1513         return true;
1514 }
1515
1516 EXPORT_API
1517 bool ASM_get_sound_state(const int asm_handle, ASM_sound_events_t sound_event, ASM_sound_states_t *sound_state, int *error_code)
1518 {
1519         int handle = 0;
1520         int asm_index = 0;
1521         GError *err = NULL;
1522         GDBusConnection *conn = NULL;
1523         GVariant *res_variant = NULL;
1524         GVariant *client_variant = NULL;
1525
1526         if (sound_state == NULL || error_code == NULL) {
1527                 if (error_code)
1528                         *error_code = ERR_ASM_UNKNOWN_ERROR;
1529                 debug_error("invalid parameter");
1530                 return false;
1531         }
1532         if (sound_event < ASM_EVENT_MEDIA_MMPLAYER || sound_event >= ASM_EVENT_MAX) {
1533                 *error_code = ERR_ASM_EVENT_IS_INVALID;
1534                 debug_error("invalid sound event(%d)",sound_event);
1535                 return false;
1536         }
1537         handle = asm_handle;
1538
1539         asm_index = __ASM_find_index_by_handle(handle);
1540         if (asm_index == -1) {
1541                 debug_error("Can not find index of %d", handle);
1542                 return false;
1543         }
1544         debug_msg("<<<< Event(%s), Tid(%d), handle(%d)",
1545                         ASM_sound_events_str[sound_event], ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle);
1546
1547         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
1548         if (!conn && err) {
1549                 debug_error ("g_bus_get_sync() error (%s) ", err->message);
1550                 g_error_free (err);
1551                 return false;
1552         }
1553
1554         client_variant = g_variant_new("(iiiiii)", ASM_sound_handle[asm_index].asm_tid, handle, sound_event,
1555                                                                 ASM_REQUEST_GETSTATE, ASM_STATE_NONE, ASM_RESOURCE_NONE);
1556         res_variant = g_dbus_connection_call_sync(conn, ASM_BUS_NAME_SOUND_SERVER, ASM_OBJECT_SOUND_SERVER, ASM_INTERFACE_SOUND_SERVER,
1557                                                                 "ASMGetState", client_variant, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
1558
1559         if(!res_variant && err) {
1560                 debug_error("g_dbus_connection_call_sync fail(%s)", err->message);
1561                 *error_code = ERR_ASM_GDBUS_CONNECTION_ERROR;
1562                 g_error_free (err);
1563                 return false;
1564         } else {        
1565                 g_variant_get(res_variant ,"(iiiii)", &(asm_rcv_msg.instance_id), &(asm_rcv_msg.data.alloc_handle), &(asm_rcv_msg.data.cmd_handle), &(asm_rcv_msg.data.source_request_id), &(asm_rcv_msg.data.result_sound_state));
1566         }
1567
1568         *sound_state = asm_rcv_msg.data.result_sound_state;
1569
1570         debug_msg(">>>> Event(%s), State(%s)", ASM_sound_events_str[sound_event], ASM_sound_state_str[*sound_state]);
1571
1572         return true;
1573 }
1574
1575 EXPORT_API
1576 bool ASM_set_sound_state_ex (const int asm_handle, ASM_sound_events_t sound_event, ASM_sound_states_t sound_state, ASM_resource_t mm_resource, int *error_code, int (*func)(void*,void*))
1577 {
1578         int handle = 0;
1579         int asm_index = 0;
1580         GError *err = NULL;
1581         GDBusConnection *conn = NULL;
1582         GVariant *res_variant = NULL;
1583         GVariant *client_variant = NULL;
1584
1585         debug_fenter();
1586
1587         if (error_code == NULL) {
1588                 debug_error("error_code is null");
1589                 return false;
1590         }
1591
1592         if (sound_event < 0 || sound_event > ASM_PRIORITY_MATRIX_MIN) {
1593                 debug_error("invalid sound event(%d)",sound_event);
1594                 *error_code = ERR_ASM_EVENT_IS_INVALID;
1595                 return false;
1596         }
1597
1598         if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
1599                 *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
1600                 debug_error("Invalid handle %d", asm_handle);
1601                 return false;
1602         }
1603
1604         handle = asm_handle;
1605
1606         asm_index = __ASM_find_index_by_handle(handle);
1607         if (asm_index == -1) {
1608                 debug_error("Can not find index of %d", handle);
1609                 return false;
1610         }
1611
1612         debug_msg("<<<< Event(%s), State(%s), Tid(%d), handle(%d)",
1613                                 ASM_sound_events_str[sound_event], ASM_sound_state_str[sound_state], ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle);
1614
1615         if (func) {
1616                 /* Construct msg to send -> send msg -> recv msg */
1617                 if (!__asm_construct_snd_msg(ASM_sound_handle[asm_index].asm_tid, handle, sound_event, ASM_REQUEST_SETSTATE, sound_state, mm_resource, error_code)) {
1618                         debug_error("failed to __asm_construct_snd_msg(), error(%d)", *error_code);
1619                         return false;
1620                 }
1621                 debug_msg( "[func(%p) START]", func);
1622                 func (&asm_snd_msg, &asm_rcv_msg);
1623                 debug_msg( "[func END]");
1624         } else {
1625                 conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
1626                 if (!conn && err) {
1627                         debug_error ("g_bus_get_sync() error (%s) ", err->message);
1628                         g_error_free (err);
1629                         return false;
1630                 }
1631
1632                 client_variant = g_variant_new("(iiiiii)", ASM_sound_handle[asm_index].asm_tid, handle, sound_event,
1633                                                                                 ASM_REQUEST_SETSTATE, sound_state, mm_resource);
1634                 res_variant = g_dbus_connection_call_sync(conn, ASM_BUS_NAME_SOUND_SERVER, ASM_OBJECT_SOUND_SERVER, ASM_INTERFACE_SOUND_SERVER,
1635                                                                                 "ASMSetState", client_variant, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
1636
1637                 if(!res_variant && err) {
1638                         debug_error("g_dbus_connection_call_sync fail(%s)", err->message);
1639                         *error_code = ERR_ASM_GDBUS_CONNECTION_ERROR;
1640                         g_error_free (err);
1641                         return false;
1642                 } else {
1643                         g_variant_get(res_variant ,"(iiiiiii)", &(asm_rcv_msg.instance_id), &(asm_rcv_msg.data.alloc_handle),
1644                                                                                                 &(asm_rcv_msg.data.cmd_handle), &(asm_rcv_msg.data.source_request_id),
1645                                                                                                 &(asm_rcv_msg.data.result_sound_command), &(asm_rcv_msg.data.result_sound_state),
1646                                                                                                 &(asm_rcv_msg.data.error_code));
1647                 }
1648         }
1649
1650         if (sound_state == ASM_STATE_PLAYING ) {
1651                 debug_log( "sound_state is PLAYING, func(0x%x)", func);
1652
1653                 switch (asm_rcv_msg.data.result_sound_command) {
1654                 case ASM_COMMAND_PAUSE:
1655                 case ASM_COMMAND_STOP:
1656                         debug_msg( " <<<<<<<<<<<<<<<< Received command : %d (STOP(3)/PAUSE(4)) >>>>>>>>>>>>>>>>>>>>\n", asm_rcv_msg.data.result_sound_command);
1657                         if (handle == asm_rcv_msg.data.cmd_handle) {
1658
1659                                 debug_msg("handle(%d) is same as asm_rcv_msg.data.cmd_handle", handle);
1660
1661                                 asm_index = __ASM_find_index_by_handle(asm_rcv_msg.data.cmd_handle);
1662                                 if (asm_index == -1) {
1663                                         *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
1664                                         debug_error( "Can not find index from instance_id %ld, handle %d", asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle);
1665                                         return false;
1666                                 }
1667
1668                                 if (asm_rcv_msg.data.result_sound_command == ASM_COMMAND_PAUSE) {
1669                                         ASM_sound_handle[asm_index].sound_state = ASM_STATE_PAUSE;
1670                                 } else if (asm_rcv_msg.data.result_sound_command == ASM_COMMAND_STOP) {
1671                                         ASM_sound_handle[asm_index].sound_state = ASM_STATE_STOP;
1672                                 }
1673
1674                                 if (asm_rcv_msg.data.error_code){
1675                                         *error_code = asm_rcv_msg.data.error_code;
1676                                         debug_warning("error code: %x",*error_code);
1677                                 }
1678                                 return false;
1679
1680                         } else {
1681                                 unsigned int rcv_sound_status_value = 0;
1682                                 if (!__ASM_get_sound_state(&rcv_sound_status_value, error_code)) {
1683                                         debug_error("failed to __ASM_get_sound_state(), error(%d)", *error_code);
1684                                 }
1685
1686                                 debug_msg("[ASM_CB] Callback : TID(%ld), handle(%d)", asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle);
1687
1688                                 asm_index = __ASM_find_index_by_handle(asm_rcv_msg.data.cmd_handle);
1689                                 if (asm_index == -1) {
1690                                         *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
1691                                         debug_error("Can not find index from instance_id %ld, handle %d", asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle);
1692                                         return false;
1693                                 }
1694
1695                                 if (ASM_sound_handle[asm_index].asm_callback!=NULL) {
1696                                         debug_msg( "[ASM_CB(%p) START]", ASM_sound_handle[asm_index].asm_callback);
1697                                         ASM_sound_handle[asm_index].asm_callback(asm_rcv_msg.data.cmd_handle, ASM_sound_handle[asm_index].sound_event,
1698                                                         asm_rcv_msg.data.result_sound_command, rcv_sound_status_value, ASM_sound_handle[asm_index].user_data);
1699                                         debug_msg( "[ASM_CB END]");
1700                                 } else {
1701                                         debug_msg("asm callback is null");
1702                                 }
1703                         }
1704                         break;
1705                 case ASM_COMMAND_PLAY:
1706                 case ASM_COMMAND_NONE:
1707                 case ASM_COMMAND_RESUME:
1708                         ASM_sound_handle[asm_index].sound_state = sound_state;
1709                         break;
1710                 default:
1711                         break;
1712                 }
1713
1714         }
1715
1716         debug_fleave();
1717
1718         return true;
1719 }
1720
1721 EXPORT_API
1722 bool ASM_set_sound_state (const int asm_handle, ASM_sound_events_t sound_event, ASM_sound_states_t sound_state, ASM_resource_t mm_resource, int *error_code)
1723 {
1724         return ASM_set_sound_state_ex (asm_handle, sound_event, sound_state, mm_resource, error_code, NULL);
1725 }
1726
1727 EXPORT_API
1728 bool ASM_set_subsession (const int asm_handle, ASM_sound_sub_sessions_t subsession, int resource, int *error_code)
1729 {
1730         int handle = 0;
1731         int asm_index = 0;
1732         GError *err = NULL;
1733         GDBusConnection *conn = NULL;
1734         GVariant *res_variant = NULL;
1735         GVariant *client_variant = NULL;
1736
1737         debug_fenter();
1738
1739         if (error_code == NULL) {
1740                 debug_error("error_code is null");
1741                 return false;
1742         }
1743
1744         if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
1745                 *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
1746                 debug_error("Invalid handle(%d)", asm_handle);
1747                 return false;
1748         }
1749
1750         if (subsession < ASM_SUB_SESSION_TYPE_VOICE || subsession >= ASM_SUB_SESSION_TYPE_MAX) {
1751                 *error_code = ERR_ASM_INVALID_PARAMETER;
1752                 debug_error("Invalid sub session type(%d)", subsession);
1753                 return false;
1754         }
1755
1756         handle = asm_handle;
1757
1758         asm_index = __ASM_find_index_by_handle(handle);
1759         if (asm_index == -1) {
1760                 debug_error("Can not find index of %d", handle);
1761                 return false;
1762         }
1763
1764         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
1765         if (!conn && err) {
1766                 debug_error ("g_bus_get_sync() error (%s) ", err->message);
1767                 g_error_free (err);
1768                 return false;
1769         }
1770
1771         client_variant = g_variant_new("(iiiiii)", ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle, subsession,
1772                                                                 ASM_REQUEST_SET_SUBSESSION,  ASM_sound_handle[asm_index].sound_state, resource);
1773         res_variant = g_dbus_connection_call_sync(conn, ASM_BUS_NAME_SOUND_SERVER, ASM_OBJECT_SOUND_SERVER, ASM_INTERFACE_SOUND_SERVER,
1774                                                                 "ASMSetSubsession", client_variant, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
1775
1776         if(!res_variant && err) {
1777                 debug_error("g_dbus_connection_call_sync fail(%s)", err->message);
1778                 *error_code = ERR_ASM_GDBUS_CONNECTION_ERROR;
1779                 g_error_free (err);
1780                 return false;
1781         } else {
1782                 g_variant_get(res_variant ,"(iiii)", &(asm_rcv_msg.instance_id), &(asm_rcv_msg.data.alloc_handle), &(asm_rcv_msg.data.cmd_handle), &(asm_rcv_msg.data.source_request_id));
1783         }
1784
1785
1786
1787         /* TODO: Should check msg returned.....*/
1788 #if 0
1789         {
1790                 debug_msg( " <<<<<<<<<<<<<<<< [BEFORE] Callback : Main Context >>>>>>>>>>>>>>>>>>>> \n");
1791                 /********************************************************************************************************/
1792                 switch (asm_rcv_msg.data.result_sound_command) {
1793                 case ASM_COMMAND_PAUSE:
1794                 case ASM_COMMAND_STOP:
1795                 case ASM_COMMAND_PLAY:
1796                 case ASM_COMMAND_NONE:
1797                 case ASM_COMMAND_RESUME:
1798                 default:
1799                         break;
1800                 }
1801                 /********************************************************************************************************/
1802                 debug_msg(" <<<<<<<<<<<<<<<< [AFTER]  Callback : Main Context >>>>>>>>>>>>>>>>>>>> \n");
1803
1804         }
1805 #endif
1806
1807         debug_fleave();
1808
1809         return true;
1810 }
1811
1812 EXPORT_API
1813 bool ASM_get_subsession (const int asm_handle, ASM_sound_sub_sessions_t *subsession, int *error_code)
1814 {
1815         int handle = 0;
1816         int asm_index = 0;
1817         GError *err = NULL;
1818         GDBusConnection *conn = NULL;
1819         GVariant *res_variant = NULL;
1820         GVariant *client_variant = NULL;
1821
1822         debug_fenter();
1823
1824         if (error_code == NULL) {
1825                 debug_error("error_code is null");
1826                 return false;
1827         }
1828
1829         if (subsession == NULL) {
1830                 debug_error("subsession is null");
1831                 *error_code = ERR_ASM_INVALID_PARAMETER;
1832                 return false;
1833         }
1834
1835         if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
1836                 *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
1837                 debug_error("Invalid handle %d \n", asm_handle);
1838                 return false;
1839         }
1840
1841         handle = asm_handle;
1842
1843         asm_index = __ASM_find_index_by_handle(handle);
1844         if (asm_index == -1) {
1845                 debug_error("Can not find index of %d", handle);
1846                 return false;
1847         }
1848
1849         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
1850         if (!conn && err) {
1851                 debug_error ("g_bus_get_sync() error (%s) ", err->message);
1852                 g_error_free (err);
1853                 return false;
1854         }
1855
1856         client_variant = g_variant_new("(iiiiii)", ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle, 0,
1857                                                                 ASM_REQUEST_GET_SUBSESSION, 0, 0);
1858         res_variant = g_dbus_connection_call_sync(conn, ASM_BUS_NAME_SOUND_SERVER, ASM_OBJECT_SOUND_SERVER, ASM_INTERFACE_SOUND_SERVER,
1859                                                         "ASMGetSubsession", client_variant, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
1860
1861         if(!res_variant && err) {
1862                 debug_error("g_dbus_connection_call_sync fail(%s)", err->message);
1863                 *error_code = ERR_ASM_GDBUS_CONNECTION_ERROR;
1864                 g_error_free (err);
1865                 return false;
1866         } else {
1867                 g_variant_get(res_variant ,"(iiiii)", &(asm_rcv_msg.instance_id), &(asm_rcv_msg.data.alloc_handle), &(asm_rcv_msg.data.cmd_handle), &(asm_rcv_msg.data.source_request_id), &(asm_rcv_msg.data.result_sound_command));
1868         }
1869
1870         *subsession = asm_rcv_msg.data.result_sound_command;
1871
1872         debug_msg(">>>> ASM_get_subsession with subsession value [%d]\n", *subsession);
1873         debug_fleave();
1874
1875         return true;
1876 }
1877
1878 EXPORT_API
1879 bool ASM_set_subevent (const int asm_handle, ASM_sound_sub_events_t subevent, int *error_code)
1880 {
1881         int handle = 0;
1882         int asm_index = 0;
1883         ASM_sound_states_t sound_state = ASM_STATE_NONE;
1884         GError *err = NULL;
1885         GDBusConnection *conn = NULL;
1886         GVariant *res_variant = NULL;
1887         GVariant *client_variant = NULL;
1888
1889         debug_fenter();
1890
1891         if (error_code == NULL) {
1892                 debug_error("error_code is null");
1893                 return false;
1894         }
1895
1896         if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
1897                 *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
1898                 debug_error("Invalid handle(%d)", asm_handle);
1899                 return false;
1900         }
1901
1902         if (subevent < ASM_SUB_EVENT_NONE || subevent >= ASM_SUB_EVENT_MAX) {
1903                 *error_code = ERR_ASM_INVALID_PARAMETER;
1904                 debug_error("Invalid sub event(%d)", subevent);
1905                 return false;
1906         }
1907
1908         handle = asm_handle;
1909
1910         asm_index = __ASM_find_index_by_handle(handle);
1911         if (asm_index == -1) {
1912                 debug_error("Can not find index of %d", handle);
1913                 return false;
1914         }
1915
1916         if (subevent == ASM_SUB_EVENT_NONE) {
1917                 sound_state = ASM_STATE_STOP;
1918         } else if (subevent < ASM_SUB_EVENT_MAX) {
1919                 sound_state = ASM_STATE_PLAYING;
1920         }
1921
1922
1923         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
1924         if (!conn && err) {
1925                 debug_error ("g_bus_get_sync() error (%s) ", err->message);
1926                 g_error_free (err);
1927                 return false;
1928         }
1929
1930         client_variant = g_variant_new("(iiiiii)", ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle, subevent,
1931                                                                 ASM_REQUEST_SET_SUBEVENT, sound_state, 0);
1932         res_variant = g_dbus_connection_call_sync(conn, ASM_BUS_NAME_SOUND_SERVER, ASM_OBJECT_SOUND_SERVER, ASM_INTERFACE_SOUND_SERVER,
1933                                                                 "ASMSetSubevent", client_variant, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
1934
1935         if (!res_variant && err) {
1936                 debug_error("g_dbus_connection_call_sync fail(%s)", err->message);
1937                 *error_code = ERR_ASM_GDBUS_CONNECTION_ERROR;
1938                 g_error_free (err);
1939                 return false;
1940         } else {
1941                 g_variant_get(res_variant, "(iiiiii)", &(asm_rcv_msg.instance_id), &(asm_rcv_msg.data.alloc_handle), &(asm_rcv_msg.data.cmd_handle),
1942                                         &(asm_rcv_msg.data.source_request_id), &(asm_rcv_msg.data.result_sound_command), &(asm_rcv_msg.data.result_sound_state));
1943         }
1944
1945         switch (asm_rcv_msg.data.result_sound_command) {
1946         case ASM_COMMAND_PAUSE:
1947         case ASM_COMMAND_STOP:
1948                 debug_msg( " <<<<<<<<<<<<<<<< Received command : %d (STOP(3)/PAUSE(4)) >>>>>>>>>>>>>>>>>>>>\n", asm_rcv_msg.data.result_sound_command);
1949                 if (handle == asm_rcv_msg.data.cmd_handle) {
1950
1951                         debug_msg("handle(%d) is same as asm_rcv_msg.data.cmd_handle", handle);
1952
1953                         asm_index = __ASM_find_index_by_handle(asm_rcv_msg.data.cmd_handle);
1954                         if (asm_index == -1) {
1955                                 *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
1956                                 debug_error( "Can not find index from instance_id %ld, handle %d", asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle);
1957                                 return false;
1958                         }
1959
1960                         if (asm_rcv_msg.data.result_sound_command == ASM_COMMAND_PAUSE) {
1961                                 ASM_sound_handle[asm_index].sound_state = ASM_STATE_PAUSE;
1962                         } else if (asm_rcv_msg.data.result_sound_command == ASM_COMMAND_STOP) {
1963                                 ASM_sound_handle[asm_index].sound_state = ASM_STATE_STOP;
1964                         }
1965
1966                         if (asm_rcv_msg.data.error_code){
1967                                 *error_code = asm_rcv_msg.data.error_code;
1968                                 debug_warning("error code: %x",*error_code);
1969                         }
1970                         return false;
1971
1972                 } else {
1973                         unsigned int rcv_sound_status_value = 0;
1974                         if (!__ASM_get_sound_state(&rcv_sound_status_value, error_code)) {
1975                                 debug_error("failed to __ASM_get_sound_state(), error(%d)", *error_code);
1976                         }
1977                         asm_index = __ASM_find_index_by_handle(asm_rcv_msg.data.cmd_handle);
1978                         if (asm_index == -1) {
1979                                 *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
1980                                 debug_error("Can not find index from instance_id %ld, handle %d", asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle);
1981                                 return false;
1982                         }
1983
1984                         if (ASM_sound_handle[asm_index].asm_callback!=NULL) {
1985                                 debug_msg( "[ASM_CB(%p) START]", ASM_sound_handle[asm_index].asm_callback);
1986                                 ASM_sound_handle[asm_index].asm_callback(asm_rcv_msg.data.cmd_handle, ASM_sound_handle[asm_index].sound_event,
1987                                                         asm_rcv_msg.data.result_sound_command, rcv_sound_status_value, ASM_sound_handle[asm_index].user_data);
1988                                 debug_msg( "[ASM_CB END]");
1989                         } else {
1990                                 debug_msg("asm callback is null");
1991                         }
1992                 }
1993                 break;
1994         case ASM_COMMAND_PLAY:
1995         case ASM_COMMAND_NONE:
1996         case ASM_COMMAND_RESUME:
1997                 ASM_sound_handle[asm_index].sound_state = sound_state;
1998                 break;
1999         default:
2000                 break;
2001         }
2002
2003         debug_fleave();
2004
2005         return true;
2006 }
2007
2008 EXPORT_API
2009 bool ASM_get_subevent (const int asm_handle, ASM_sound_sub_events_t *subevent, int *error_code)
2010 {
2011         int handle = 0;
2012         int asm_index = 0;
2013         GError *err = NULL;
2014         GDBusConnection *conn = NULL;
2015         GVariant *res_variant = NULL;
2016         GVariant *client_variant = NULL;
2017
2018         debug_fenter();
2019
2020         if (error_code == NULL) {
2021                 debug_error("error_code is null");
2022                 return false;
2023         }
2024
2025         if (subevent == NULL) {
2026                 debug_error("subevent is null");
2027                 *error_code = ERR_ASM_INVALID_PARAMETER;
2028                 return false;
2029         }
2030
2031         if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
2032                 *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
2033                 debug_error("Invalid handle %d \n", asm_handle);
2034                 return false;
2035         }
2036
2037         handle = asm_handle;
2038
2039         asm_index = __ASM_find_index_by_handle(handle);
2040         if (asm_index == -1) {
2041                 debug_error("Can not find index of %d", handle);
2042                 return false;
2043         }
2044
2045         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
2046         if (!conn && err) {
2047                 debug_error ("g_bus_get_sync() error (%s) ", err->message);
2048                 g_error_free (err);
2049                 return false;
2050         }
2051
2052         client_variant = g_variant_new("(iiiiii)", ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle, 0,
2053                                                                 ASM_REQUEST_GET_SUBEVENT, 0, 0);
2054         res_variant = g_dbus_connection_call_sync(conn, ASM_BUS_NAME_SOUND_SERVER, ASM_OBJECT_SOUND_SERVER, ASM_INTERFACE_SOUND_SERVER,
2055                                                                 "ASMGetSubevent", client_variant, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,  &err);
2056
2057         if(!res_variant && err) {
2058                 debug_error("g_dbus_connection_call_sync fail(%s)", err->message);
2059                 *error_code = ERR_ASM_GDBUS_CONNECTION_ERROR;
2060                 g_error_free (err);
2061                 return false;
2062         } else {
2063                 g_variant_get(res_variant, "(iiiii)", &(asm_rcv_msg.instance_id), &(asm_rcv_msg.data.alloc_handle), &(asm_rcv_msg.data.cmd_handle),
2064                                                 &(asm_rcv_msg.data.source_request_id), &(asm_rcv_msg.data.result_sound_command));
2065         }
2066
2067         *subevent = asm_rcv_msg.data.result_sound_command;
2068
2069         debug_msg(">>>> ASM_get_subevent with subevent value [%d]\n", *subevent);
2070         debug_fleave();
2071
2072         return true;
2073 }
2074
2075
2076 EXPORT_API
2077 bool ASM_set_session_option (const int asm_handle, int option_flags, int *error_code)
2078 {
2079         int handle = 0;
2080         int asm_index = 0;
2081         ASM_sound_states_t sound_state = ASM_STATE_NONE;
2082         GError *err = NULL;
2083         GDBusConnection *conn = NULL;
2084         GVariant *res_variant = NULL;
2085         GVariant *client_variant = NULL;
2086
2087         debug_fenter();
2088
2089         if (error_code == NULL) {
2090                 debug_error("error_code is null");
2091                 return false;
2092         }
2093
2094         if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
2095                 *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
2096                 debug_error("Invalid handle(%d)", asm_handle);
2097                 return false;
2098         }
2099
2100         if (option_flags < 0) {
2101                 *error_code = ERR_ASM_INVALID_PARAMETER;
2102                 debug_error("Invalid option_flags(%x)", option_flags);
2103                 return false;
2104         }
2105
2106         handle = asm_handle;
2107
2108         asm_index = __ASM_find_index_by_handle(handle);
2109         if (asm_index == -1) {
2110                 debug_error("Can not find index of %d", handle);
2111                 return false;
2112         }
2113
2114         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
2115         if (!conn && err) {
2116                 debug_error ("g_bus_get_sync() error (%s) ", err->message);
2117                 g_error_free (err);
2118                 return false;
2119         }
2120
2121     client_variant = g_variant_new("(iiiiii)",ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle, option_flags,
2122                                                                         ASM_REQUEST_SET_SESSION_OPTIONS, sound_state, 0);
2123         res_variant = g_dbus_connection_call_sync(conn, ASM_BUS_NAME_SOUND_SERVER, ASM_OBJECT_SOUND_SERVER, ASM_INTERFACE_SOUND_SERVER,
2124                                                                 "ASMSetSessionOption", client_variant, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,  &err);
2125         if(!res_variant && err) {
2126                 debug_error("g_dbus_connection_call_sync fail(%s)", err->message);
2127                 *error_code = ERR_ASM_GDBUS_CONNECTION_ERROR;
2128                 g_error_free (err);
2129                 return false;
2130         } else {
2131                 g_variant_get(res_variant ,"(iiiiii)", &(asm_rcv_msg.instance_id), &(asm_rcv_msg.data.alloc_handle), &(asm_rcv_msg.data.cmd_handle),
2132                                                 &(asm_rcv_msg.data.source_request_id), &(asm_rcv_msg.data.result_sound_command), &(asm_rcv_msg.data.error_code));
2133         }
2134
2135
2136         switch (asm_rcv_msg.data.result_sound_command) {
2137         case ASM_COMMAND_PAUSE:
2138         case ASM_COMMAND_STOP:
2139                 debug_msg( " <<<<<<<<<<<<<<<< Received command : %d (STOP(3)/PAUSE(4)) >>>>>>>>>>>>>>>>>>>>\n", asm_rcv_msg.data.result_sound_command);
2140                 if (handle == asm_rcv_msg.data.cmd_handle) {
2141
2142                         debug_msg("handle(%d) is same as asm_rcv_msg.data.cmd_handle", handle);
2143
2144                         asm_index = __ASM_find_index_by_handle(asm_rcv_msg.data.cmd_handle);
2145                         if (asm_index == -1) {
2146                                 *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
2147                                 debug_error( "Can not find index from instance_id %ld, handle %d", asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle);
2148                                 return false;
2149                         }
2150
2151                         if (asm_rcv_msg.data.result_sound_command == ASM_COMMAND_PAUSE) {
2152                                 ASM_sound_handle[asm_index].sound_state = ASM_STATE_PAUSE;
2153                         } else if (asm_rcv_msg.data.result_sound_command == ASM_COMMAND_STOP) {
2154                                 ASM_sound_handle[asm_index].sound_state = ASM_STATE_STOP;
2155                         }
2156
2157                         if (asm_rcv_msg.data.error_code){
2158                                 *error_code = asm_rcv_msg.data.error_code;
2159                                 debug_warning("error code: %x",*error_code);
2160                         }
2161                         return false;
2162
2163                 }
2164                 break;
2165         case ASM_COMMAND_PLAY:
2166                 ASM_sound_handle[asm_index].option_flags = option_flags;
2167                 break;
2168         default:
2169                 break;
2170         }
2171
2172         debug_fleave();
2173
2174         return true;
2175 }
2176
2177 EXPORT_API
2178 bool ASM_get_session_option (const int asm_handle, int *option_flags, int *error_code)
2179 {
2180         int handle = 0;
2181         int asm_index = 0;
2182         GError *err = NULL;
2183         GDBusConnection *conn = NULL;
2184         GVariant *res_variant = NULL;
2185         GVariant *client_variant = NULL;
2186
2187         debug_fenter();
2188
2189         if (error_code == NULL) {
2190                 debug_error("error_code is null");
2191                 return false;
2192         }
2193
2194         if (option_flags == NULL) {
2195                 debug_error("option_flags is null");
2196                 *error_code = ERR_ASM_INVALID_PARAMETER;
2197                 return false;
2198         }
2199
2200         if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
2201                 *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
2202                 debug_error("Invalid handle %d \n", asm_handle);
2203                 return false;
2204         }
2205
2206         handle = asm_handle;
2207
2208         asm_index = __ASM_find_index_by_handle(handle);
2209         if (asm_index == -1) {
2210                 debug_error("Can not find index of %d", handle);
2211                 return false;
2212         }
2213
2214         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
2215         if (!conn && err) {
2216                 debug_error ("g_bus_get_sync() error (%s) ", err->message);
2217                 g_error_free (err);
2218                 return false;
2219         }
2220
2221         client_variant = g_variant_new("(iiiiii)",ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle, 0,
2222                                                                         ASM_REQUEST_GET_SESSION_OPTIONS, 0, 0);
2223         res_variant = g_dbus_connection_call_sync(conn, ASM_BUS_NAME_SOUND_SERVER, ASM_OBJECT_SOUND_SERVER, ASM_INTERFACE_SOUND_SERVER,
2224                                                                                 "ASMGetSessionOption", client_variant, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,  &err);
2225
2226         if(!res_variant && err) {
2227                 debug_error("g_dbus_connection_call_sync fail(%s)", err->message);
2228                 *error_code = ERR_ASM_GDBUS_CONNECTION_ERROR;
2229                 g_error_free (err);
2230                 return false;
2231         } else {
2232                 g_variant_get(res_variant ,"(iiiiii)", &(asm_rcv_msg.instance_id), &(asm_rcv_msg.data.alloc_handle), &(asm_rcv_msg.data.cmd_handle),
2233                                                 &(asm_rcv_msg.data.source_request_id), &(asm_rcv_msg.data.result_sound_command), &(asm_rcv_msg.data.option_flags));
2234         }
2235
2236         if (asm_rcv_msg.data.result_sound_command == ASM_COMMAND_STOP) {
2237                 *error_code = asm_rcv_msg.data.error_code;
2238                 debug_error("received handle is not valid");
2239                 return false;
2240         }
2241
2242         *option_flags = asm_rcv_msg.data.option_flags;
2243         if (ASM_sound_handle[asm_index].option_flags != *option_flags) {
2244                 debug_error("received flag(%x) from server is not same as local's(%x)", *option_flags, ASM_sound_handle[asm_index].option_flags);
2245                 return false;
2246         }
2247
2248         debug_msg(">>>> option flags [%x]\n", *option_flags);
2249
2250         debug_fleave();
2251
2252         return true;
2253 }
2254
2255 EXPORT_API
2256 bool ASM_reset_resumption_info(const int asm_handle, int *error_code)
2257 {
2258         int handle = 0;
2259         int asm_index = 0;
2260         GError *err = NULL;
2261         GDBusConnection *conn = NULL;
2262         GVariant *res_variant = NULL;
2263         GVariant *client_variant = NULL;
2264
2265         debug_fenter();
2266
2267         if (error_code == NULL) {
2268                 debug_error("error_code is null");
2269                 return false;
2270         }
2271
2272         if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
2273                 *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
2274                 debug_error("Invalid handle %d \n", asm_handle);
2275                 return false;
2276         }
2277
2278         handle = asm_handle;
2279
2280         asm_index = __ASM_find_index_by_handle(handle);
2281         if (asm_index == -1) {
2282                 debug_error("Can not find index of %d", handle);
2283                 return false;
2284         }
2285
2286         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
2287         if (!conn && err) {
2288                 debug_error ("g_bus_get_sync() error (%s) ", err->message);
2289                 g_error_free (err);
2290                 return false;
2291         }
2292
2293         client_variant = g_variant_new("(iiiiii)",ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle, 0,
2294                                                                         ASM_REQUEST_RESET_RESUME_TAG, 0, 0);
2295         res_variant = g_dbus_connection_call_sync(conn, ASM_BUS_NAME_SOUND_SERVER, ASM_OBJECT_SOUND_SERVER, ASM_INTERFACE_SOUND_SERVER,
2296                                                                                         "ASMResetResumeTag", client_variant, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,  &err);
2297
2298         if(!res_variant && err) {
2299                 debug_error("g_dbus_connection_call_sync fail(%s)", err->message);
2300                 *error_code = ERR_ASM_GDBUS_CONNECTION_ERROR;
2301                 g_error_free (err);
2302                 return false;
2303         } else {
2304                 g_variant_get(res_variant ,"(iiiiii)", &(asm_rcv_msg.instance_id), &(asm_rcv_msg.data.alloc_handle), &(asm_rcv_msg.data.cmd_handle),
2305                                         &(asm_rcv_msg.data.source_request_id), &(asm_rcv_msg.data.result_sound_command), &(asm_rcv_msg.data.result_sound_state));
2306         }
2307
2308         switch (asm_rcv_msg.data.result_sound_command) {
2309         case ASM_COMMAND_PLAY:
2310                 debug_msg(" >>>> reset information of resumption successfully");
2311                 break;
2312         default:
2313                 debug_error("received message is abnormal..result_sound_command(%d) from ASM server", asm_rcv_msg.data.result_sound_command);
2314                 *error_code = ERR_ASM_GDBUS_CONNECTION_ERROR;
2315                 return false;
2316         }
2317
2318         debug_leave();
2319
2320         return true;
2321 }
2322
2323 EXPORT_API
2324 void ASM_dump_sound_state()
2325 {
2326         GError *err = NULL;
2327         GDBusConnection *conn = NULL;
2328         GVariant *client_variant = NULL;
2329
2330         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
2331         if (!conn && err) {
2332                 debug_error ("g_bus_get_sync() error (%s) ", err->message);
2333                 g_error_free (err);
2334                 return;
2335         }
2336
2337         client_variant = g_variant_new("(iiiiii)", getpid(), 0, 0, ASM_REQUEST_DUMP, ASM_STATE_NONE, ASM_RESOURCE_NONE);
2338         g_dbus_connection_call_sync(conn, ASM_BUS_NAME_SOUND_SERVER, ASM_OBJECT_SOUND_SERVER, ASM_INTERFACE_SOUND_SERVER,
2339                                                                 "ASMDump", client_variant, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
2340
2341         if(err) {
2342                 debug_error("g_dbus_connection_call_sync fail(%s)", err->message);
2343                 g_error_free (err);
2344                 return;
2345         }
2346
2347 }
2348
2349
2350 #if defined(CONFIG_ENABLE_SIGNAL_HANDLER)
2351 struct sigaction ASM_int_old_action;
2352 struct sigaction ASM_abrt_old_action;
2353 struct sigaction ASM_segv_old_action;
2354 struct sigaction ASM_term_old_action;
2355 struct sigaction ASM_sys_old_action;
2356 struct sigaction ASM_xcpu_old_action;
2357
2358 static void __asm_notify_emergent_exit(GDBusConnection *conn, int exit_pid, int handle, int sound_event, int request_id, int sound_state)
2359 {
2360         GVariant *client_variant = NULL;
2361         GError *err = NULL;
2362
2363         debug_log("Send Signal EmergentExit");
2364
2365         client_variant = g_variant_new("(iiiii)", exit_pid, handle, sound_event, ASM_REQUEST_EMERGENT_EXIT, sound_state);
2366         g_dbus_connection_emit_signal(conn, NULL, OBJECT_ASM, INTERFACE_ASM, "EmergentExit", client_variant, &err);
2367         if(err) {
2368                 debug_error("g_dbus_connection_emit_signal fail(%s)", err->message);
2369                 g_error_free (err);
2370         } else {
2371                 g_dbus_connection_flush_sync(conn, NULL, &err);
2372                 if(err) {
2373                         debug_error("g_dbus_connection_flush_sync fail(%s)", err->message);
2374                         g_error_free (err);
2375                 }
2376         }
2377 }
2378
2379 void __ASM_signal_handler(int signo)
2380 {
2381         int exit_pid = 0;
2382         int asm_index = 0;
2383         GError *err = NULL;
2384         GDBusConnection *conn = NULL;
2385
2386         debug_warning("ENTER, sig.num(%d)",signo);
2387
2388         /* signal block -------------- */
2389         sigset_t old_mask, all_mask;
2390         sigfillset(&all_mask);
2391         sigprocmask(SIG_BLOCK, &all_mask, &old_mask);
2392
2393         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
2394         if (!conn && err) {
2395                 debug_error ("g_bus_get_sync() error (%s) ", err->message);
2396                 g_error_free (err);
2397                 return;
2398         }
2399         for (asm_index=0 ;asm_index < ASM_HANDLE_MAX; asm_index++) {
2400                 if (ASM_sound_handle[asm_index].is_used == true &&
2401                                 ASM_sound_handle[asm_index].is_for_watching == false) {
2402                         exit_pid = ASM_sound_handle[asm_index].asm_tid;
2403                         if (exit_pid == asmgettid()) {
2404                                 __asm_notify_emergent_exit(conn, exit_pid, ASM_sound_handle[asm_index].handle, ASM_sound_handle[asm_index].sound_event,
2405                                                            ASM_REQUEST_EMERGENT_EXIT, ASM_sound_handle[asm_index].sound_state);
2406                         }
2407                 }
2408         }
2409
2410         sigprocmask(SIG_SETMASK, &old_mask, NULL);
2411         /* signal unblock ------------ */
2412
2413         switch (signo) {
2414         case SIGINT:
2415                 sigaction(SIGINT, &ASM_int_old_action, NULL);
2416                 raise( signo);
2417                 break;
2418         case SIGABRT:
2419                 sigaction(SIGABRT, &ASM_abrt_old_action, NULL);
2420                 raise( signo);
2421                 break;
2422         case SIGSEGV:
2423                 sigaction(SIGSEGV, &ASM_segv_old_action, NULL);
2424                 raise( signo);
2425                 break;
2426         case SIGTERM:
2427                 sigaction(SIGTERM, &ASM_term_old_action, NULL);
2428                 raise( signo);
2429                 break;
2430         case SIGSYS:
2431                 sigaction(SIGSYS, &ASM_sys_old_action, NULL);
2432                 raise( signo);
2433                 break;
2434         case SIGXCPU:
2435                 sigaction(SIGXCPU, &ASM_xcpu_old_action, NULL);
2436                 raise( signo);
2437                 break;
2438         default:
2439                 break;
2440         }
2441
2442         debug_warning("LEAVE");
2443 }
2444
2445 #endif
2446 static void __attribute__((constructor)) __ASM_init_module(void)
2447 {
2448 #if defined(CONFIG_ENABLE_SIGNAL_HANDLER)
2449         struct sigaction ASM_action;
2450         ASM_action.sa_handler = __ASM_signal_handler;
2451         ASM_action.sa_flags = SA_NOCLDSTOP;
2452         int asm_index = 0;
2453
2454         debug_fenter();
2455         g_type_init();
2456
2457         for (asm_index = 0; asm_index < ASM_HANDLE_MAX; asm_index++) {
2458                 ASM_sound_handle[asm_index].handle = ASM_HANDLE_INIT_VAL;
2459         }
2460
2461         sigemptyset(&ASM_action.sa_mask);
2462
2463         sigaction(SIGINT, &ASM_action, &ASM_int_old_action);
2464         sigaction(SIGABRT, &ASM_action, &ASM_abrt_old_action);
2465         sigaction(SIGSEGV, &ASM_action, &ASM_segv_old_action);
2466         sigaction(SIGTERM, &ASM_action, &ASM_term_old_action);
2467         sigaction(SIGSYS, &ASM_action, &ASM_sys_old_action);
2468         sigaction(SIGXCPU, &ASM_action, &ASM_xcpu_old_action);
2469
2470         debug_fleave();
2471 #endif
2472 }
2473
2474
2475 static void __attribute__((destructor)) __ASM_fini_module(void)
2476 {
2477         debug_fenter();
2478
2479 #if defined(CONFIG_ENABLE_SIGNAL_HANDLER)
2480
2481         int exit_pid = 0;
2482         int asm_index = 0;
2483         GError *err = NULL;
2484         GDBusConnection *conn = NULL;
2485         GVariant *client_variant = NULL;
2486
2487         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
2488         if (!conn && err) {
2489                 debug_error ("g_bus_get_sync() error (%s) ", err->message);
2490                 g_error_free (err);
2491                 return;
2492         }
2493         for (asm_index=0 ;asm_index < ASM_HANDLE_MAX; asm_index++) {
2494                 if (ASM_sound_handle[asm_index].is_used == true &&
2495                                 ASM_sound_handle[asm_index].is_for_watching == false) {
2496                         exit_pid = ASM_sound_handle[asm_index].asm_tid;
2497                         if (exit_pid == asmgettid()) {
2498                                 __asm_notify_emergent_exit(conn, exit_pid, ASM_sound_handle[asm_index].handle, ASM_sound_handle[asm_index].sound_event,
2499                                                        ASM_REQUEST_EMERGENT_EXIT, ASM_sound_handle[asm_index].sound_state);
2500                         }
2501                 }
2502         }
2503
2504 #endif
2505
2506         if (g_asm_thread) {
2507                 g_main_loop_quit(g_asm_loop);
2508                 g_thread_join(g_asm_thread);
2509                 debug_log("after thread join");
2510                 g_main_loop_unref(g_asm_loop);
2511                 g_asm_thread = NULL;
2512         }
2513         sigaction(SIGINT, &ASM_int_old_action, NULL);
2514         sigaction(SIGABRT, &ASM_abrt_old_action, NULL);
2515         sigaction(SIGSEGV, &ASM_segv_old_action, NULL);
2516         sigaction(SIGTERM, &ASM_term_old_action, NULL);
2517         sigaction(SIGSYS, &ASM_sys_old_action, NULL);
2518         sigaction(SIGXCPU, &ASM_xcpu_old_action, NULL);
2519
2520         debug_fleave();
2521 }
2522