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