f8304ff7ffba0d8b891ffb1006d62b47bf8f292a
[framework/multimedia/audio-session-manager.git] / src / audio-session-mgr.c
1 /*
2  * audio-session-manager
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Seungbae Shin <seungbae.shin@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 typedef struct
83 {
84         ASM_sound_events_t      sound_event;
85         GSourceFuncs*           g_src_funcs;
86         GPollFD*                g_poll_fd;
87         int                     asm_fd;
88         ASM_sound_cb_t          asm_callback;
89         void                    *cb_data;
90         int                     asm_tid;
91         int                     handle;
92         bool                    is_used;
93         GSource*                asm_src;
94         guint                   ASM_g_id;
95 } ASM_sound_ino_t;
96
97 ASM_sound_ino_t ASM_sound_handle[ASM_HANDLE_MAX];
98
99 static const char* ASM_sound_events_str[] =
100 {
101         "SHARE_MMPLAYER",
102         "SHARE_MMCAMCORDER",
103         "SHARE_MMSOUND",
104         "SHARE_OPENAL",
105         "SHARE_AVSYSTEM",
106         "EXCLUSIVE_MMPLAYER",
107         "EXCLUSIVE_MMCAMCORDER",
108         "EXCLUSIVE_MMSOUND",
109         "EXCLUSIVE_OPENAL",
110         "EXCLUSIVE_AVSYSTEM",
111         "NOTIFY",
112         "CALL",
113         "SHARE_FMRADIO",
114         "EXCLUSIVE_FMRADIO",
115         "EARJACK_UNPLUG",
116         "ALARM",
117         "VIDEOCALL",
118         "MONITOR",
119         "RICH_CALL",
120         "EMERGENCY",
121         "EXCLUSIVE_RESOURCE"
122 };
123
124 static const char* ASM_sound_cases_str[] =
125 {
126         "CASE_NONE",
127         "CASE_1PLAY_2STOP",
128         "CASE_1PLAY_2ALTER_PLAY",
129         "CASE_1PLAY_2WAIT",
130         "CASE_1ALTER_PLAY_2PLAY",
131         "CASE_1STOP_2PLAY",
132         "CASE_1PAUSE_2PLAY",
133         "CASE_1VIRTUAL_2PLAY",
134         "CASE_1PLAY_2PLAY_MIX",
135         "CASE_RESOURCE_CHECK"
136 };
137
138 static const char* ASM_sound_state_str[] =
139 {
140         "STATE_NONE",
141         "STATE_PLAYING",
142         "STATE_WAITING",
143         "STATE_STOP",
144         "STATE_PAUSE",
145         "STATE_PAUSE_BY_APP",
146         "STATE_ALTER_PLAYING"
147 };
148
149 /*
150  * function prototypes
151  */
152
153
154 unsigned int ASM_all_sound_status;
155
156 void __asm_init_module(void);
157 void __asm_fini_module(void);
158 int __ASM_find_index(int handle);
159
160 bool __ASM_get_sound_state(unsigned int *all_sound_status, int *error_code)
161 {
162         int value = 0;
163
164         if(vconf_get_int(SOUND_STATUS_KEY, &value)) {
165                 debug_error("failed to vconf_get_int(SOUND_STATUS_KEY)");
166                 *error_code = ERR_ASM_VCONF_ERROR;
167                 return false;
168         }
169         debug_msg("All status(%#X)", value);
170         *all_sound_status = value;
171         ASM_all_sound_status = value;
172
173         return true;
174 }
175
176 bool __ASM_set_sound_state(ASM_sound_events_t sound_event, ASM_sound_states_t sound_state, int *error_code)
177 {
178         /* this function will deprecated */
179         debug_msg("Event(%s), State(%s)", ASM_sound_events_str[sound_event], ASM_sound_state_str[sound_state]);
180
181         return true;
182 }
183
184 gboolean __asm_fd_check(GSource * source)
185 {
186         GSList *fd_list;
187         if (!source) {
188                 debug_error("GSource is null");
189                 return FALSE;
190         }
191         fd_list = source->poll_fds;
192         GPollFD *temp;
193
194         do {
195                 temp = (GPollFD*)fd_list->data;
196                 if (temp->revents & (POLLIN | POLLPRI))
197                         return TRUE;
198                 fd_list = fd_list->next;
199         } while (fd_list);
200
201         return FALSE; /* there is no change in any fd state */
202 }
203
204
205 gboolean __asm_fd_prepare(GSource *source, gint *timeout)
206 {
207         return FALSE;
208 }
209
210 gboolean __asm_fd_dispatch(GSource *source,     GSourceFunc callback, gpointer user_data)
211 {
212         callback(user_data);
213         return TRUE;
214 }
215
216 gboolean asm_callback_handler( gpointer d)
217 {
218         GPollFD *data = (GPollFD*)d;
219         unsigned int buf;
220         int count;
221         int tid = 0;
222         int asm_index = 0;
223         debug_fenter();
224
225         if (!data) {
226                 debug_error("GPollFd is null");
227                 return FALSE;
228         }
229         if (data->revents & (POLLIN | POLLPRI)) {
230                 int handle;
231                 int error_code = 0;
232                 int event_src;
233                 unsigned int sound_status_value;
234                 ASM_sound_commands_t rcv_command;
235                 ASM_cb_result_t cb_res = ASM_CB_RES_NONE;
236
237
238                 count = read(data->fd, &buf, sizeof(int));
239
240                 handle = (int)( buf & 0x0000ffff);
241                 rcv_command = (ASM_sound_commands_t)((buf >> 16) & 0x0f);
242                 event_src = (ASM_event_sources_t)((buf >> 24) & 0x0f);
243
244                 asm_index = __ASM_find_index(handle);
245                 if (asm_index == -1) {
246                         debug_error("Can not find index");
247                         return FALSE;
248                 }
249
250                 tid = ASM_sound_handle[asm_index].asm_tid;
251                 
252                 if (rcv_command) {
253                         debug_msg("got and start CB : TID(%d), handle(%d) cmd(%d) event_src(%d)", tid, handle, rcv_command, event_src );
254                         if (!__ASM_get_sound_state(&sound_status_value, &error_code)) {
255                                 debug_error("failed to __ASM_get_sound_state(), error(%d)", error_code);
256                         }
257                         switch (rcv_command) {
258                         case ASM_COMMAND_PLAY:
259                         case ASM_COMMAND_RESUME:
260                         case ASM_COMMAND_PAUSE:
261                         case ASM_COMMAND_STOP:
262                                 if (ASM_sound_handle[asm_index].asm_callback == NULL) {
263                                         debug_msg("callback is null..");
264                                         return FALSE;
265                                 }
266                                 debug_msg("[CALLBACK(%p) START]",ASM_sound_handle[asm_index].asm_callback);
267                                 cb_res = (ASM_sound_handle[asm_index].asm_callback)(handle, event_src, rcv_command, sound_status_value, ASM_sound_handle[asm_index].cb_data);
268                                 debug_msg("[CALLBACK END]");
269                                 break;
270                         default:
271                                 break;
272                         }
273 #ifdef CONFIG_ENABLE_RETCB
274
275                         /* If command is other than RESUME, send return */
276                         if (rcv_command != ASM_COMMAND_RESUME) {
277                                 int rett = 0;
278                                 int buf = cb_res;
279                                 int tmpfd = -1;
280                                 char *filename2 = g_strdup_printf("/tmp/ASM.%d.%dr", ASM_sound_handle[asm_index].asm_tid, handle);
281                                 tmpfd = open(filename2, O_WRONLY | O_NONBLOCK);
282                                 if (tmpfd < 0) {
283                                         char str_error[256];
284                                         strerror_r(errno, str_error, sizeof(str_error));
285                                         debug_error("[RETCB][Failed(May Server Close First)]tid(%d) fd(%d) %s errno=%d(%s)\n", tid, tmpfd, filename2, errno, str_error);
286                                         g_free(filename2);
287                                         return FALSE;
288                                 }
289                                 rett = write(tmpfd, &buf, sizeof(buf));
290                                 close(tmpfd);
291                                 g_free(filename2);
292                                 debug_msg("[RETCB] tid(%d) finishing CB (write=%d)\n", tid, rett);
293                         } else {
294                                 debug_msg("[RETCB] No need to send return for RESUME command\n");
295                         }
296 #endif
297                 }
298         }
299         debug_fleave();
300         return TRUE;
301 }
302
303 bool __ASM_add_sound_callback(int index, int fd, gushort events, gLoopPollHandler_t p_gloop_poll_handler )
304 {
305         GSource* g_src = NULL;
306         GSourceFuncs *g_src_funcs = NULL;               /* handler function */
307         guint gsource_handle;
308         GPollFD *g_poll_fd = NULL;                      /* file descriptor */
309
310         /* 1. make GSource Object */
311         g_src_funcs = (GSourceFuncs *)g_malloc(sizeof(GSourceFuncs));
312         if (!g_src_funcs) {
313                 debug_error("g_malloc failed on g_src_funcs");
314                 return false;
315         }
316         g_src_funcs->prepare = __asm_fd_prepare;
317         g_src_funcs->check = __asm_fd_check;
318         g_src_funcs->dispatch = __asm_fd_dispatch;
319         g_src_funcs->finalize = NULL;
320         g_src = g_source_new(g_src_funcs, sizeof(GSource));
321         if (!g_src) {
322                 debug_error("g_malloc failed on m_readfd");
323                 return false;
324         }
325         ASM_sound_handle[index].asm_src = g_src;
326         ASM_sound_handle[index].g_src_funcs = g_src_funcs;
327         debug_msg(" g_malloc : g_src_funcs(%#X)", g_src_funcs);
328
329         /* 2. add file description which used in g_loop() */
330         g_poll_fd = (GPollFD *)g_malloc(sizeof(GPollFD));
331         if (!g_poll_fd) {
332                 debug_error("g_malloc failed on g_poll_fd");
333                 return false;
334         }
335         g_poll_fd->fd = fd;
336         g_poll_fd->events = events;
337         ASM_sound_handle[index].g_poll_fd = g_poll_fd;
338         debug_msg(" g_malloc : g_poll_fd(%#X)", g_poll_fd);
339
340         /* 3. combine g_source object and file descriptor */
341         g_source_add_poll(g_src, g_poll_fd);
342         gsource_handle = g_source_attach(g_src, NULL);
343         if (!gsource_handle) {
344                 debug_error(" Failed to attach the source to context");
345                 return false;
346         }
347
348         debug_msg(" g_source_add_poll : g_src_id(%d)", gsource_handle);
349         ASM_sound_handle[index].ASM_g_id = gsource_handle;
350
351         /* 4. set callback */
352         g_source_set_callback(g_src, p_gloop_poll_handler,(gpointer)g_poll_fd, NULL);
353
354         debug_msg(" g_source_set_callback : %d", errno);
355         return true;
356 }
357
358
359 bool __ASM_remove_sound_callback(int index, gushort events)
360 {
361         bool ret = true;
362         gboolean gret = TRUE;
363
364         GSourceFunc *g_src_funcs = ASM_sound_handle[index].g_src_funcs;
365         GPollFD *g_poll_fd = ASM_sound_handle[index].g_poll_fd; /* store file descriptor */
366         if (!g_poll_fd) {
367                 debug_error("g_poll_fd is null..");
368                 ret = false;
369                 goto init_handle;
370         }
371         g_poll_fd->fd = ASM_sound_handle[index].asm_fd;
372         g_poll_fd->events = events;
373
374         debug_msg(" g_source_remove_poll : fd(%d), event(%x)", g_poll_fd->fd, g_poll_fd->events);
375         g_source_remove_poll(ASM_sound_handle[index].asm_src, g_poll_fd);
376         debug_msg(" g_source_remove_poll : %d", errno);
377
378         gret = g_source_remove(ASM_sound_handle[index].ASM_g_id);
379         debug_msg(" g_source_remove : gret(%d)", gret);
380         if (!gret) {
381                 debug_error("failed to g_source_remove(). ASM_g_id(%d)", ASM_sound_handle[index].ASM_g_id);
382                 ret = false;
383                 goto init_handle;
384         }
385
386 init_handle:
387
388         if (g_src_funcs) {
389                 debug_msg(" g_free : g_src_funcs(%#X)", g_src_funcs);
390                 g_free(g_src_funcs);
391
392         }
393         if (g_poll_fd) {
394                 debug_msg(" g_free : g_poll_fd(%#X)", g_poll_fd);
395                 g_free(g_poll_fd);
396         }
397
398         ASM_sound_handle[index].g_src_funcs = NULL;
399         ASM_sound_handle[index].g_poll_fd = NULL;
400         ASM_sound_handle[index].ASM_g_id = 0;
401         ASM_sound_handle[index].asm_src = NULL;
402         ASM_sound_handle[index].asm_callback = NULL;
403
404         return ret;
405 }
406
407 int __ASM_find_index(int handle)
408 {
409         int i = 0;
410         for(i = 0; i< ASM_HANDLE_MAX; i++) {
411                 if (handle == ASM_sound_handle[i].handle) {
412                         debug_msg("found index(%d) for handle(%d)", i, handle);
413                         return i;
414                 }
415         }
416         return -1;
417 }
418
419 void __ASM_add_callback(int index)
420 {
421         if (!__ASM_add_sound_callback(index, ASM_sound_handle[index].asm_fd, (gushort)POLLIN | POLLPRI, asm_callback_handler)) {
422                 debug_error("failed to __ASM_add_sound_callback()");
423                 //return false;
424         }
425 }
426
427
428 void __ASM_remove_callback(int index)
429 {
430         if (!__ASM_remove_sound_callback(index, (gushort)POLLIN | POLLPRI)) {
431                 debug_error("failed to __ASM_remove_sound_callback()");
432                 //return false;
433         }
434 }
435
436
437 void __ASM_open_callback(int index)
438 {
439         mode_t pre_mask;
440
441         debug_msg("index (%d)", index);
442         char *filename = g_strdup_printf("/tmp/ASM.%d.%d", ASM_sound_handle[index].asm_tid, ASM_sound_handle[index].handle);
443         pre_mask = umask(0);
444         if (mknod(filename, S_IFIFO|0666, 0)) {
445                 debug_error("mknod() failure, errno(%d)", errno);
446         }
447         umask(pre_mask);
448         ASM_sound_handle[index].asm_fd = open( filename, O_RDWR|O_NONBLOCK);
449         if (ASM_sound_handle[index].asm_fd == -1) {
450                 debug_error("%s : file open error(%d)", str_fail, errno);
451         } else {
452                 debug_msg("%s : filename(%s), fd(%d)", str_pass, filename, ASM_sound_handle[index].asm_fd);
453         }
454         g_free(filename);
455
456 #ifdef CONFIG_ENABLE_RETCB
457         char *filename2 = g_strdup_printf("/tmp/ASM.%d.%dr", ASM_sound_handle[index].asm_tid,  ASM_sound_handle[index].handle);
458         pre_mask = umask(0);
459         if (mknod(filename2, S_IFIFO | 0666, 0)) {
460                 debug_error("mknod() failure, errno(%d)", errno);
461         }
462         umask(pre_mask);
463         g_free(filename2);
464 #endif
465
466 }
467
468
469 void __ASM_close_callback(int index)
470 {
471         debug_msg("index (%d)", index);
472         if (ASM_sound_handle[index].asm_fd < 0) {
473                 debug_error("%s : fd error.", str_fail);
474         } else {
475                 char *filename = g_strdup_printf("/tmp/ASM.%d.%d", ASM_sound_handle[index].asm_tid, ASM_sound_handle[index].handle);
476                 close(ASM_sound_handle[index].asm_fd);
477                 if (remove(filename)) {
478                         debug_error("remove() failure, filename(%s), errno(%d)", filename, errno);
479                 }
480                 debug_msg("%s : filename(%s), fd(%d)", str_pass, filename, ASM_sound_handle[index].asm_fd);
481                 g_free(filename);
482         }
483
484 #ifdef CONFIG_ENABLE_RETCB
485         char *filename2 = g_strdup_printf("/tmp/ASM.%d.%dr", ASM_sound_handle[index].asm_tid, ASM_sound_handle[index].handle);
486
487         /* Defensive code - wait until callback timeout although callback is removed */
488         int buf = ASM_CB_RES_STOP;
489         int tmpfd = -1;
490
491         tmpfd = open(filename2, O_WRONLY | O_NONBLOCK);
492         if (tmpfd < 0) {
493                 char str_error[256];
494                 strerror_r(errno, str_error, sizeof(str_error));
495                 debug_error("failed to open file(%s) (may server close first), tid(%d) fd(%d) %s errno=%d(%s)",
496                         filename2, ASM_sound_handle[index].asm_tid, tmpfd, filename2, errno, str_error);
497         } else {
498                 debug_msg("write ASM_CB_RES_STOP(tid:%d) for waiting server", ASM_sound_handle[index].asm_tid);
499                 write(tmpfd, &buf, sizeof(buf));
500                 close(tmpfd);
501         }
502
503         if (remove(filename2)) {
504                 debug_error("remove() failure, filename(%s), errno(%d)", filename2, errno);
505         }
506         g_free(filename2);
507 #endif
508
509 }
510
511 bool __asm_construct_snd_msg(int asm_pid, int handle, ASM_sound_events_t sound_event,
512                                         ASM_requests_t request_id, ASM_sound_states_t sound_state, ASM_resource_t resource, int *error_code)
513 {
514         asm_snd_msg.instance_id = asm_pid;
515
516         asm_snd_msg.data.handle = handle;
517         asm_snd_msg.data.request_id = request_id;
518         asm_snd_msg.data.sound_event = sound_event;
519         asm_snd_msg.data.sound_state = sound_state;
520         asm_snd_msg.data.system_resource = resource;
521
522         debug_msg("tid=%ld,handle=%d,req=%d,evt=%d,state=%d,resource=%d", asm_snd_msg.instance_id, asm_snd_msg.data.handle,
523                                 asm_snd_msg.data.request_id, asm_snd_msg.data.sound_event, asm_snd_msg.data.sound_state, asm_snd_msg.data.system_resource);
524         debug_msg("     instance_id : %ld\n", asm_snd_msg.instance_id);
525         debug_msg("     handle : %d\n", asm_snd_msg.data.handle);
526
527         return true;
528 }
529
530
531 bool __ASM_init_msg(int *error_code)
532 {
533         asm_snd_msgid = msgget((key_t)2014, 0666);
534         asm_rcv_msgid = msgget((key_t)4102, 0666);
535         asm_cb_msgid = msgget((key_t)4103, 0666);
536
537         debug_msg("snd_msqid(%#X), rcv_msqid(%#X), cb_msqid(%#X)\n", asm_snd_msgid, asm_rcv_msgid, asm_cb_msgid);
538
539         if (asm_snd_msgid == -1 || asm_rcv_msgid == -1 || asm_cb_msgid == -1 ) {
540                 *error_code = ERR_ASM_MSG_QUEUE_MSGID_GET_FAILED;
541                 debug_error("failed to msgget with error(%d)",error_code);
542                 return false;
543         }
544
545         return true;
546 }
547
548 void __ASM_init_callback(int index)
549 {
550         debug_fenter();
551         __ASM_open_callback(index);
552         __ASM_add_callback(index);
553         debug_fleave();
554 }
555
556
557 void __ASM_destroy_callback(int index)
558 {
559         debug_fenter();
560         __ASM_remove_callback(index);
561         __ASM_close_callback(index);
562         debug_fleave();
563 }
564
565 #ifdef USE_SECURITY
566 bool __ASM_set_cookie (unsigned char* cookie)
567 {
568         int retval = -1;
569         int cookie_size = 0;
570
571         cookie_size = security_server_get_cookie_size();
572         if (cookie_size != COOKIE_SIZE) {
573                 debug_error ("[Security] security_server_get_cookie_size(%d)  != COOKIE_SIZE(%d)\n", cookie_size, COOKIE_SIZE);
574                 return false;
575         }
576
577         retval = security_server_request_cookie (cookie, COOKIE_SIZE);
578         if (retval == SECURITY_SERVER_API_SUCCESS) {
579                 debug_msg ("[Security] security_server_request_cookie() returns [%d]\n", retval);
580                 return true;
581         } else {
582                 debug_error ("[Security] security_server_request_cookie() returns [%d]\n", retval);
583                 return false;
584         }
585 }
586 #endif
587
588 EXPORT_API
589 bool ASM_register_sound_ex (const int application_pid, int *asm_handle, ASM_sound_events_t sound_event, ASM_sound_states_t sound_state,
590                                                 ASM_sound_cb_t callback, void *cb_data, ASM_resource_t mm_resource, int *error_code, int (*func)(void*,void*))
591 {
592         int error = 0;
593         unsigned int sound_status_value;
594         int handle = 0;
595         int asm_pid = 0;
596         int index = 0;
597         int ret = 0;
598         unsigned int rcv_sound_status_value;
599
600         debug_fenter();
601
602         if (error_code==NULL) {
603                 debug_error ("invalid parameter. error code is null");
604                 return false;
605         }
606
607         if (sound_event< ASM_EVENT_SHARE_MMPLAYER || sound_event >= ASM_EVENT_MAX) {
608                 *error_code = ERR_ASM_EVENT_IS_INVALID;
609                 debug_error ("invalid sound event(%d)",sound_event);
610                 return false;
611         }
612
613         for (index = 0; index < ASM_HANDLE_MAX; index++) {
614                 if (ASM_sound_handle[index].is_used == false) {
615                         break;
616                 }
617         }
618
619         if (index == ASM_HANDLE_MAX) {
620                 *error_code = ERR_ASM_EVENT_IS_FULL;
621                 debug_error ("local sound event is full(MAX)");
622                 return false;
623         }
624
625         if (application_pid == -1) {
626                 asm_pid = asmgettid();
627         } else if (application_pid > 2) {
628                 asm_pid = application_pid;
629         } else {
630                 *error_code = ERR_ASM_INVALID_PARAMETER;
631                 debug_error ("invalid pid %d", application_pid);
632                 return false;
633         }
634
635         ASM_sound_handle[index].sound_event = sound_event;
636         ASM_sound_handle[index].asm_tid = asm_pid;
637
638         debug_msg(" <<<< Event(%s), Tid(%d), Index(%d)", ASM_sound_events_str[sound_event], ASM_sound_handle[index].asm_tid, index);
639
640         if (!__ASM_init_msg(&error)) {
641                 debug_error("failed to __ASM_init_msg(), error(%d)", error);
642         }
643
644         if (!__ASM_get_sound_state(&sound_status_value, error_code)) {
645                 debug_error("failed to __ASM_get_sound_state(), error(%d)", *error_code);
646         }
647
648         /* If state is PLAYING, do set state immediately */
649         if (sound_state == ASM_STATE_PLAYING) {
650                 debug_msg(" <<<< Event(%s), Tid(%d), State(PLAYING)", ASM_sound_events_str[sound_event], ASM_sound_handle[index].asm_tid);
651                 if (!__ASM_set_sound_state(sound_event, ASM_STATE_PLAYING, error_code)) {
652                         debug_error("failed to __ASM_set_sound_state(PLAYING), error(%d)", *error_code);
653                         return false;
654                 }
655         } else {
656                 debug_msg(" <<<< Event(%s), Tid(%ld), State(WAITING)", ASM_sound_events_str[sound_event], asmgettid());
657         }
658
659
660         handle = -1; /* for register & get handle from server */
661
662 #ifdef USE_SECURITY
663         /* get cookie from security server */
664         if (__ASM_set_cookie (asm_snd_msg.data.cookie) == false) {
665                 debug_error("failed to ASM_set_cookie()");
666                 return false;
667         }
668 #endif
669
670         /* Construct msg to send -> send msg -> recv msg */
671         if (!__asm_construct_snd_msg(asm_pid, handle, sound_event, ASM_REQUEST_REGISTER, sound_state, mm_resource, error_code)) {
672                 debug_error("failed to __asm_construct_snd_msg(), error(%d)", *error_code);
673                 return false;
674         }
675
676         if (func) {
677                 func ((void*)&asm_snd_msg, (void*)&asm_rcv_msg);
678         } else  {
679                 NO_EINTR(ret = msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0));
680                 if (ret == -1) {
681                         *error_code = ERR_ASM_MSG_QUEUE_SND_ERROR;
682                         debug_error("failed to msgsnd(%d,%s)", errno, strerror(errno));
683                         return false;
684                 }
685                 NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), asm_pid, 0));
686                 if (ret == -1) {
687                         *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
688                         debug_error("failed to msgrcv(%d,%s)", errno, strerror(errno));
689                         return false;
690                 }
691         }
692         /* Construct msg to send -> send msg -> recv msg : end */
693
694 #ifdef USE_SECURITY
695         /* Check privilege first */
696         if (asm_rcv_msg.data.check_privilege == 0) {
697                 debug_error("[Security] Check privilege from server Failed!!!");
698                 *error_code = ERR_ASM_CHECK_PRIVILEGE_FAILED;
699                 return false;
700         } else {
701                 debug_msg ("[Security] Check privilege from server Success");
702         }
703 #endif
704
705         handle = asm_rcv_msg.data.alloc_handle; /* get handle from server */
706         if (handle == -1) {
707                 debug_error("failed to create handle from server");
708                 *error_code = ERR_ASM_HANDLE_IS_FULL;
709                 return false;
710         }
711
712         ASM_sound_handle[index].handle = handle;
713
714         __ASM_init_callback(index);
715
716 /********************************************************************************************************/
717         switch (asm_rcv_msg.data.result_sound_command) {
718         case ASM_COMMAND_PAUSE:
719         case ASM_COMMAND_STOP:
720                 if (handle == asm_rcv_msg.data.cmd_handle) {
721
722                         __ASM_destroy_callback(index);
723
724                         ASM_sound_handle[index].asm_fd = 0;
725                         ASM_sound_handle[index].asm_tid = 0;
726                         ASM_sound_handle[index].sound_event = ASM_EVENT_NONE;
727                         ASM_sound_handle[index].is_used = false;
728
729                         *error_code = ERR_ASM_POLICY_CANNOT_PLAY;
730                         return false;
731                 } else {
732                         int action_index = 0;
733
734                         if (!__ASM_get_sound_state(&rcv_sound_status_value, error_code)) {
735                                 debug_error("failed to __ASM_get_sound_state(), error(%d)", *error_code);
736                         }
737
738                         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);
739                         action_index = __ASM_find_index(asm_rcv_msg.data.cmd_handle);
740                         if (action_index == -1) {
741                                 debug_error("Can not find index of instance %ld, handle %d", asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle);
742                         } else {
743                                 if (ASM_sound_handle[action_index].asm_callback!=NULL) {
744                                         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].cb_data);
745                                 } else {
746                                         debug_msg("null callback");
747                                 }
748                         }
749                 }
750                 break;
751
752         case ASM_COMMAND_PLAY:
753         case ASM_COMMAND_NONE:
754         case ASM_COMMAND_RESUME:
755         default:
756                 break;
757         }
758 /********************************************************************************************************/
759
760
761         ASM_sound_handle[index].asm_callback = callback;
762         ASM_sound_handle[index].cb_data = cb_data;
763         ASM_sound_handle[index].is_used = true;
764
765         debug_msg(" >>>> Event(%s), Handle(%d), CBFuncPtr(%p)", ASM_sound_events_str[sound_event], handle, callback);
766         /* Add [out] param, asm_handle */
767         *asm_handle = handle;
768
769         debug_fleave();
770
771         return true;
772
773 }
774
775 EXPORT_API
776 bool ASM_register_sound (const int application_pid, int *asm_handle, ASM_sound_events_t sound_event, ASM_sound_states_t sound_state,
777                                                 ASM_sound_cb_t callback, void *cb_data, ASM_resource_t mm_resource, int *error_code)
778 {
779         return ASM_register_sound_ex (application_pid, asm_handle, sound_event, sound_state, callback, cb_data, mm_resource, error_code, NULL);
780 }
781
782
783 EXPORT_API
784 bool ASM_change_callback(const int asm_handle, ASM_sound_events_t sound_event, ASM_sound_cb_t callback, void *cb_data, int *error_code)
785 {
786         int handle=0;
787
788         if (error_code==NULL) {
789                 debug_error ("invalid parameter. error code is null");
790                 return false;
791         }
792
793         if (sound_event < ASM_EVENT_SHARE_MMPLAYER || sound_event >= ASM_EVENT_MAX) {
794                 *error_code = ERR_ASM_EVENT_IS_INVALID;
795                 debug_error ("invalid sound event(%d)",sound_event);
796                 return false;
797         }
798
799         int asm_index = -1;
800
801         if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
802                 *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
803                 debug_error("invalid handle(%d). callback is not registered", asm_handle);
804                 return false;
805         }
806
807         handle = asm_handle;
808
809         asm_index = __ASM_find_index(handle);
810         if (asm_index == -1) {
811                 *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
812                 debug_error("Can not find index for handle %d", handle);
813                 return false;
814         }
815
816         debug_msg("callback function has changed to %p", callback);
817         ASM_sound_handle[asm_index].asm_callback = callback;
818         ASM_sound_handle[asm_index].cb_data = cb_data;
819
820         return true;
821 }
822
823 EXPORT_API
824 bool ASM_unregister_sound_ex(const int asm_handle, ASM_sound_events_t sound_event, int *error_code, int (*func)(void*,void*))
825 {
826         int handle=0;
827         int asm_index = -1;
828         int ret = 0;
829
830         debug_fenter();
831
832         if (error_code==NULL) {
833                 debug_error ("invalid parameter. error code is null");
834                 return false;
835         }
836
837         if (sound_event<ASM_EVENT_SHARE_MMPLAYER || sound_event >= ASM_EVENT_MAX) {
838                 *error_code = ERR_ASM_EVENT_IS_INVALID;
839                 debug_error ("invalid sound event(%d)",sound_event);
840                 return false;
841         }
842
843         if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
844                 *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
845                 debug_error("invalid handle(%d). callback is not registered", asm_handle);
846                 return false;
847         }
848
849         handle = asm_handle;
850         asm_index = __ASM_find_index(handle);
851         if (asm_index == -1) {
852                 *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
853                 debug_error("Can not find index for handle(%d)", handle);
854                 return false;
855         }
856         debug_msg("<<<< Event(%s), Tid(%d), Handle(%d) Index(%d)",
857                                 ASM_sound_events_str[sound_event], ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle, asm_index);
858
859         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)) {
860                 debug_error("failed to __asm_construct_snd_msg(), error(%d)", *error_code);
861                 return false;
862         }
863
864         if (func) {
865                 func(&asm_snd_msg, &asm_rcv_msg);
866         } else  {
867                 NO_EINTR(ret = msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0));
868                 if (ret == -1) {
869                         *error_code = ERR_ASM_MSG_QUEUE_SND_ERROR;
870                         debug_error("failed to msgsnd(%d,%s)", errno, strerror(errno));
871                         return false;
872                 }
873         }
874
875         __ASM_destroy_callback(asm_index);
876
877         ASM_sound_handle[asm_index].asm_fd = 0;
878         ASM_sound_handle[asm_index].asm_tid = 0;
879         ASM_sound_handle[asm_index].sound_event = ASM_EVENT_NONE;
880         ASM_sound_handle[asm_index].is_used = false;
881
882         debug_msg(">>>> Event(%s)", ASM_sound_events_str[sound_event]);
883
884         debug_fleave();
885
886         return true;
887 }
888
889 EXPORT_API
890 bool ASM_unregister_sound(const int asm_handle, ASM_sound_events_t sound_event, int *error_code)
891 {
892         return ASM_unregister_sound_ex (asm_handle, sound_event, error_code, NULL);
893 }
894
895 EXPORT_API
896 bool ASM_get_sound_status(unsigned int *all_sound_status, int *error_code)
897 {
898         if (all_sound_status == NULL || error_code == NULL) {
899                 if (error_code)
900                         *error_code = ERR_ASM_UNKNOWN_ERROR;
901                 debug_error("invalid parameter");
902                 return false;
903         }
904
905         debug_msg("Tid(%ld)", asmgettid());
906
907         if (!__ASM_get_sound_state(all_sound_status, error_code)) {
908                 debug_error("failed to __ASM_get_sound_state(), error(%d)", *error_code);
909                 return false;
910         }
911
912         return true;
913 }
914
915 EXPORT_API
916 bool ASM_get_process_session_state(const int asm_handle, ASM_sound_states_t *sound_state, int *error_code)
917 {
918         int handle = 0;
919         int asm_index = 0;
920         int ret = 0;
921
922         if (sound_state == NULL || error_code == NULL) {
923                 if (error_code)
924                         *error_code = ERR_ASM_UNKNOWN_ERROR;
925                 debug_error("invalid parameter");
926                 return false;
927         }
928
929         handle = asm_handle;
930         asm_index = __ASM_find_index(handle);
931         if (asm_index == -1) {
932                 debug_error("Can not find index of %d", handle);
933                 return false;
934         }
935
936
937         debug_msg("Pid(%d)", ASM_sound_handle[asm_index].asm_tid);
938
939         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)) {
940                 debug_error("failed to __asm_construct_snd_msg(), error(%d)", *error_code);
941                 return false;
942         }
943
944
945         NO_EINTR(ret = msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0));
946         if (ret == -1) {
947                 *error_code = ERR_ASM_MSG_QUEUE_SND_ERROR;
948                 debug_error("failed to msgsnd(%d,%s)", errno, strerror(errno));
949                 return false;
950         }
951
952         NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), asm_snd_msg.instance_id, 0));
953         if (ret == -1) {
954                 *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
955                 debug_error("failed to msgrcv(%d,%s)", errno, strerror(errno));
956                 return false;
957         }
958
959         *sound_state = asm_rcv_msg.data.result_sound_state;
960
961         debug_msg(">>>> Pid(%d), State(%s)", ASM_sound_handle[asm_index].asm_tid, ASM_sound_state_str[*sound_state]);
962
963
964         return true;
965 }
966
967 EXPORT_API
968 bool ASM_get_sound_state(const int asm_handle, ASM_sound_events_t sound_event, ASM_sound_states_t *sound_state, int *error_code)
969 {
970         int handle = 0;
971         int asm_index = 0;
972         int ret = 0;
973
974         if (sound_state == NULL || error_code == NULL) {
975                 if (error_code)
976                         *error_code = ERR_ASM_UNKNOWN_ERROR;
977                 debug_error("invalid parameter");
978                 return false;
979         }
980         if (sound_event < ASM_EVENT_SHARE_MMPLAYER || sound_event >= ASM_EVENT_MAX) {
981                 *error_code = ERR_ASM_EVENT_IS_INVALID;
982                 debug_error("invalid sound event(%d)",sound_event);
983                 return false;
984         }
985         handle = asm_handle;
986
987         asm_index = __ASM_find_index(handle);
988         if (asm_index == -1) {
989                 debug_error("Can not find index of %d", handle);
990                 return false;
991         }
992         debug_msg("<<<< Event(%s), Tid(%d), handle(%d)",
993                         ASM_sound_events_str[sound_event], ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle);
994
995         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)) {
996                 debug_error("failed to __asm_construct_snd_msg(), error(%d)", *error_code);
997                 return false;
998         }
999
1000
1001         NO_EINTR(ret = msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0));
1002         if (ret == -1) {
1003                 *error_code = ERR_ASM_MSG_QUEUE_SND_ERROR;
1004                 debug_error("failed to msgsnd(%d,%s)", errno, strerror(errno));
1005                 return false;
1006         }
1007
1008         NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), asm_snd_msg.instance_id, 0));
1009         if (ret == -1) {
1010                 *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
1011                 debug_error("failed to msgrcv(%d,%s)", errno, strerror(errno));
1012                 return false;
1013         }
1014
1015         *sound_state = asm_rcv_msg.data.result_sound_state;
1016
1017         debug_msg(">>>> Event(%s), State(%s)", ASM_sound_events_str[sound_event], ASM_sound_state_str[*sound_state]);
1018
1019
1020         return true;
1021 }
1022
1023 EXPORT_API
1024 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*))
1025 {
1026         int handle = 0;
1027         int asm_index = 0;
1028         int ret = 0;
1029         unsigned int rcv_sound_status_value;
1030
1031         debug_fenter();
1032
1033         if (error_code == NULL) {
1034                 debug_error("error_code is null");
1035                 return false;
1036         }
1037
1038         if (sound_event < 0 || sound_event > ASM_PRIORITY_MATRIX_MIN) {
1039                 debug_error("invalid sound event(%d)",sound_event);
1040                 *error_code = ERR_ASM_EVENT_IS_INVALID;
1041                 return false;
1042         }
1043
1044         if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
1045                 *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
1046                 debug_error("Invalid handle %d", asm_handle);
1047                 return false;
1048         }
1049
1050         handle = asm_handle;
1051
1052         asm_index = __ASM_find_index(handle);
1053         if (asm_index == -1) {
1054                 debug_error("Can not find index of %d", handle);
1055                 return false;
1056         }
1057
1058         debug_msg("<<<< Event(%s), State(%s), Tid(%d), handle(%d)",
1059                                 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);
1060
1061         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)) {
1062                 debug_error("failed to __asm_construct_snd_msg(), error(%d)", *error_code);
1063                 return false;
1064         }
1065
1066         if (func) {
1067                 debug_msg( "[func(%p) START]", func);
1068                 func (&asm_snd_msg, &asm_rcv_msg);
1069                 debug_msg( "[func END]");
1070         } else {
1071                 NO_EINTR(ret = msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0));
1072                 if (ret == -1) {
1073                         *error_code = ERR_ASM_MSG_QUEUE_SND_ERROR;
1074                         debug_error("failed to msgsnd(%d,%s)", errno, strerror(errno));
1075                         return false;
1076                 }
1077         }
1078
1079         if (sound_state == ASM_STATE_PLAYING ) {
1080                 debug_msg( "sound_state is PLAYING");
1081                 if (func == NULL) {
1082                         NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), ASM_sound_handle[handle].asm_tid, 0));
1083                         if (ret == -1) {
1084                                 *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
1085                                 debug_error("failed to msgrcv(%d,%s)", errno, strerror(errno));
1086                                 return false;
1087                         } else {
1088
1089                         }
1090                 }
1091
1092                 debug_msg( " <<<<<<<<<<<<<<<< [BEFORE] Callback : Main Context >>>>>>>>>>>>>>>>>>>> \n");
1093         /********************************************************************************************************/
1094                 switch (asm_rcv_msg.data.result_sound_command) {
1095                 case ASM_COMMAND_PAUSE:
1096                 case ASM_COMMAND_STOP:
1097                         if (handle == asm_rcv_msg.data.cmd_handle) {
1098
1099                                 debug_msg("handle(%d) is same as asm_rcv_msg.data.cmd_handle", handle);
1100
1101                                 asm_index = __ASM_find_index(asm_rcv_msg.data.cmd_handle);
1102                                 if (asm_index == -1) {
1103                                         *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
1104                                         debug_error( "Can not find index from instance_id %ld, handle %d",      asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle);
1105                                         return false;
1106                                 }
1107
1108                                 /* check former sound event */
1109                                 switch (asm_rcv_msg.data.former_sound_event) {
1110                                 case ASM_EVENT_ALARM:
1111                                         debug_msg("blocked by ALARM");
1112                                         *error_code = ERR_ASM_POLICY_CANNOT_PLAY_BY_ALARM;
1113                                         break;
1114                                 case ASM_EVENT_CALL:
1115                                 case ASM_EVENT_VIDEOCALL:
1116                                 case ASM_EVENT_RICH_CALL:
1117                                         debug_msg("blocked by CALL/VIDEOCALL/RICH_CALL");
1118                                         *error_code = ERR_ASM_POLICY_CANNOT_PLAY_BY_CALL;
1119                                         break;
1120                                 default:
1121                                         debug_msg("blocked by Other(sound_event num:%d)", asm_rcv_msg.data.former_sound_event);
1122                                         *error_code = ERR_ASM_POLICY_CANNOT_PLAY;
1123                                         break;
1124                                 }
1125                                 return false;
1126                         } else {
1127
1128                                 if (!__ASM_get_sound_state(&rcv_sound_status_value, error_code)) {
1129                                         debug_error("failed to __ASM_get_sound_state(), error(%d)", *error_code);
1130                                 }
1131
1132                                 debug_msg("[ASM_CB] Callback : TID(%ld), handle(%d)", asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle);
1133
1134                                 asm_index = __ASM_find_index(asm_rcv_msg.data.cmd_handle);
1135                                 if (asm_index == -1) {
1136                                         *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
1137                                         debug_error("Can not find index from instance_id %ld, handle %d", asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle);
1138                                         return false;
1139                                 }
1140
1141                                 if (ASM_sound_handle[asm_index].asm_callback!=NULL) {
1142                                         debug_msg( "[ASM_CB(%p) START]", ASM_sound_handle[asm_index].asm_callback);
1143                                         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].cb_data);
1144                                         debug_msg( "[ASM_CB END]");
1145                                 } else {
1146                                         debug_msg("asm callback is null");
1147                                 }
1148                         }
1149                         break;
1150
1151                 case ASM_COMMAND_PLAY:
1152                 case ASM_COMMAND_NONE:
1153                 case ASM_COMMAND_RESUME:
1154                 default:
1155                         break;
1156                 }
1157         /********************************************************************************************************/
1158                 debug_msg(" <<<<<<<<<<<<<<<< [AFTER]  Callback : Main Context >>>>>>>>>>>>>>>>>>>> \n");
1159
1160         }
1161
1162
1163         debug_msg(">>>> Event(%s), State(%s)", ASM_sound_events_str[sound_event],ASM_sound_state_str[sound_state]);
1164
1165         debug_fleave();
1166
1167         return true;
1168 }
1169
1170 EXPORT_API
1171 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)
1172 {
1173         return ASM_set_sound_state_ex (asm_handle, sound_event, sound_state, mm_resource, error_code, NULL);
1174 }
1175
1176 EXPORT_API
1177 bool ASM_set_subsession (const int asm_handle, int subsession, int *error_code, int (*func)(void*,void*))
1178 {
1179         int handle = 0;
1180         int asm_index = 0;
1181         int ret = 0;
1182         unsigned int rcv_sound_status_value;
1183
1184         debug_fenter();
1185
1186         if (error_code == NULL) {
1187                 debug_error("error_code is null");
1188                 return false;
1189         }
1190
1191         if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
1192                 *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
1193                 debug_error("Invalid handle(%d)", asm_handle);
1194                 return false;
1195         }
1196
1197         handle = asm_handle;
1198
1199         asm_index = __ASM_find_index(handle);
1200         if (asm_index == -1) {
1201                 debug_error("Can not find index of %d", handle);
1202                 return false;
1203         }
1204
1205         if (!__asm_construct_snd_msg(ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle, subsession, ASM_REQUEST_SET_SUBSESSION, 0, 0, error_code)) {
1206                 debug_error("failed to __asm_construct_snd_msg(), error(%d)", *error_code);
1207                 return false;
1208         }
1209
1210
1211         if (func) {
1212                 func (&asm_snd_msg, &asm_rcv_msg);
1213         } else {
1214                 NO_EINTR(ret = msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0));
1215                 if (ret == -1) {
1216                         *error_code = ERR_ASM_MSG_QUEUE_SND_ERROR;
1217                         debug_error("failed to msgsnd(%d,%s)", errno, strerror(errno));
1218                         return false;
1219                 }
1220
1221                 NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), ASM_sound_handle[handle].asm_tid, 0));
1222                 if (ret == -1) {
1223                         *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
1224                         debug_error("failed to msgrcv(%d,%s)", errno, strerror(errno));
1225                         return false;
1226                 }
1227         }
1228
1229         /* TODO: Should check msg returned.....*/
1230 #if 0
1231         {
1232                 debug_msg( " <<<<<<<<<<<<<<<< [BEFORE] Callback : Main Context >>>>>>>>>>>>>>>>>>>> \n");
1233                 /********************************************************************************************************/
1234                 switch (asm_rcv_msg.data.result_sound_command) {
1235                 case ASM_COMMAND_PAUSE:
1236                 case ASM_COMMAND_STOP:
1237                 case ASM_COMMAND_PLAY:
1238                 case ASM_COMMAND_NONE:
1239                 case ASM_COMMAND_RESUME:
1240                 default:
1241                         break;
1242                 }
1243                 /********************************************************************************************************/
1244                 debug_msg(" <<<<<<<<<<<<<<<< [AFTER]  Callback : Main Context >>>>>>>>>>>>>>>>>>>> \n");
1245
1246         }
1247 #endif
1248
1249         debug_fleave();
1250
1251         return true;
1252 }
1253
1254 EXPORT_API
1255 bool ASM_get_subsession (const int asm_handle, int *subsession_value, int *error_code, int (*func)(void*,void*))
1256 {
1257         int handle = 0;
1258         int asm_index = 0;
1259         int ret = 0;
1260         unsigned int rcv_sound_status_value;
1261
1262         debug_fenter();
1263
1264         if (error_code == NULL) {
1265                 debug_error("error_code is null");
1266                 return false;
1267         }
1268
1269         /* TODO : Error Handling */
1270 #if 0
1271         if (sound_event < 0 || sound_event > ASM_PRIORITY_MATRIX_MIN) {
1272                 debug_error("invalid sound event(%d)",sound_event);
1273                 *error_code = ERR_ASM_EVENT_IS_INVALID;
1274                 return false;
1275         }
1276 #endif
1277
1278         if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
1279                 *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
1280                 debug_error("Invalid handle %d \n", asm_handle);
1281                 return false;
1282         }
1283
1284         handle = asm_handle;
1285
1286         asm_index = __ASM_find_index(handle);
1287         if (asm_index == -1) {
1288                 debug_error("Can not find index of %d", handle);
1289                 return false;
1290         }
1291
1292         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)) {
1293                 debug_error("failed to __asm_construct_snd_msg(), error(%d)", *error_code);
1294                 return false;
1295         }
1296
1297
1298         if (func) {
1299                 func (&asm_snd_msg, &asm_rcv_msg);
1300         } else {
1301                 NO_EINTR(ret = msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0));
1302                 if (ret == -1) {
1303                         *error_code = ERR_ASM_MSG_QUEUE_SND_ERROR;
1304                         debug_error("failed to msgsnd(%d,%s)", errno, strerror(errno));
1305                         return false;
1306                 }
1307
1308                 NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), ASM_sound_handle[handle].asm_tid, 0));
1309                 if (ret == -1) {
1310                         *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
1311                         debug_error("failed to msgrcv(%d,%s)", errno, strerror(errno));
1312                         return false;
1313                 }
1314         }
1315
1316         *subsession_value = asm_rcv_msg.data.result_sound_command;
1317
1318         debug_msg(">>>> ASM_get_subsession with subsession value [%d]\n", *subsession_value);
1319         debug_fleave();
1320
1321         return true;
1322 }
1323
1324 EXPORT_API
1325 void ASM_dump_sound_state()
1326 {
1327         int error = 0;
1328         int ret = 0;
1329
1330         if (!__ASM_init_msg(&error) ) {
1331                 debug_error("failed to __ASM_init_msg(), error(%d)", error);
1332         }
1333         if (!__asm_construct_snd_msg(getpid(), 0, 0, ASM_REQUEST_DUMP, ASM_STATE_NONE, ASM_RESOURCE_NONE, &error)) {
1334                 debug_error("failed to __asm_construct_snd_msg(), error(%d)", error);
1335                 return;
1336         }
1337         NO_EINTR(ret = msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0));
1338         if (ret == -1) {
1339                 debug_error("failed to msgsnd(%d,%s)", errno, strerror(errno));
1340                 return;
1341         }
1342 }
1343
1344
1345 void ASM_ask_sound_policy(ASM_sound_events_t playing_sound, ASM_sound_events_t request_sound,
1346                                 ASM_sound_cases_t *sound_policy)
1347 {
1348 }
1349
1350
1351 #if defined(CONFIG_ENABLE_SIGNAL_HANDLER)
1352 struct sigaction ASM_int_old_action;
1353 struct sigaction ASM_abrt_old_action;
1354 struct sigaction ASM_segv_old_action;
1355 struct sigaction ASM_term_old_action;
1356 struct sigaction ASM_sys_old_action;
1357 struct sigaction ASM_xcpu_old_action;
1358
1359 void __ASM_unregister_sound(int index)
1360 {
1361         int error_code = 0;
1362         int ret = 0;
1363         unsigned int sound_status_value;
1364
1365         debug_fenter();
1366
1367         debug_msg(" <<<< Event(%s), Index(%d)", ASM_sound_events_str[ASM_sound_handle[index].sound_event], index);
1368
1369         if (!__ASM_get_sound_state(&sound_status_value, &error_code)) {
1370                 debug_error("failed to __ASM_get_sound_state()", error_code);
1371         }
1372         if (!__ASM_set_sound_state(ASM_sound_handle[index].sound_event, ASM_STATE_NONE, &error_code)) {
1373                 debug_error("failed to __ASM_set_sound_state(NONE)", error_code);
1374         }
1375
1376         if (!__asm_construct_snd_msg(ASM_sound_handle[index].asm_tid, ASM_sound_handle[index].handle, ASM_sound_handle[index].sound_event, ASM_REQUEST_UNREGISTER, ASM_STATE_NONE, ASM_RESOURCE_NONE, &error_code)) {
1377                 debug_error("failed to __asm_construct_snd_msg(), error(%d)", error_code);
1378         }
1379
1380         NO_EINTR(ret = msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0));
1381         if (ret == -1) {
1382                 debug_error("failed to msgsnd(%d,%s)", errno, strerror(errno));
1383         }
1384
1385         __ASM_destroy_callback(index);
1386
1387         debug_msg(" >>>> Event(%s)", ASM_sound_events_str[ASM_sound_handle[index].sound_event]);
1388
1389         ASM_sound_handle[index].asm_fd = 0;
1390         ASM_sound_handle[index].asm_tid = 0;
1391         ASM_sound_handle[index].sound_event = ASM_EVENT_NONE;
1392         ASM_sound_handle[index].is_used = false;
1393
1394         debug_fleave();
1395 }
1396
1397
1398 void __ASM_signal_handler(int signo)
1399 {
1400         int exit_pid = 0;
1401         int asm_index = 0;
1402         int run_emergency_exit = 0;
1403
1404         for (asm_index=0 ;asm_index < ASM_HANDLE_MAX; asm_index++) {
1405                 if (ASM_sound_handle[asm_index].is_used == true) {
1406                         exit_pid = ASM_sound_handle[asm_index].asm_tid;
1407                         if (exit_pid == asmgettid()) {
1408                                 run_emergency_exit = 1;
1409                                 break;
1410                         }
1411                 }
1412         }
1413
1414         if (run_emergency_exit) {
1415                 asm_snd_msg.instance_id = exit_pid;
1416                 asm_snd_msg.data.handle = 0;
1417                 asm_snd_msg.data.request_id = ASM_REQUEST_EMERGENT_EXIT;
1418                 asm_snd_msg.data.sound_event = 0;
1419                 asm_snd_msg.data.sound_state = 0;
1420                 /* signal block -------------- */
1421                 sigset_t old_mask, all_mask;
1422                 sigfillset(&all_mask);
1423                 sigprocmask(SIG_BLOCK, &all_mask, &old_mask);
1424
1425                 if (msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0) < 0) {
1426                         debug_error("msgsnd() failed, tid=%ld, reqid=%d, handle=0x%x, state=0x%x event=%d size=%d",asm_snd_msg.instance_id,
1427                                         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) );
1428                         int tmpid = msgget((key_t)2014, 0666);
1429                         if (msgsnd(tmpid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0) > 0) {
1430                                 debug_msg("msgsnd() succeed");
1431                         } else {
1432                                 debug_error("msgsnd() retry also failed");
1433                         }
1434                 }
1435
1436                 sigprocmask(SIG_SETMASK, &old_mask, NULL);
1437                 /* signal unblock ------------ */
1438         }
1439
1440         switch (signo) {
1441         case SIGINT:
1442                 sigaction(SIGINT, &ASM_int_old_action, NULL);
1443                 raise( signo);
1444                 break;
1445         case SIGABRT:
1446                 sigaction(SIGABRT, &ASM_abrt_old_action, NULL);
1447                 raise( signo);
1448                 break;
1449         case SIGSEGV:
1450                 sigaction(SIGSEGV, &ASM_segv_old_action, NULL);
1451                 raise( signo);
1452                 break;
1453         case SIGTERM:
1454                 sigaction(SIGTERM, &ASM_term_old_action, NULL);
1455                 raise( signo);
1456                 break;
1457         case SIGSYS:
1458                 sigaction(SIGSYS, &ASM_sys_old_action, NULL);
1459                 raise( signo);
1460                 break;
1461         case SIGXCPU:
1462                 sigaction(SIGXCPU, &ASM_xcpu_old_action, NULL);
1463                 raise( signo);
1464                 break;
1465         default:
1466                 break;
1467         }
1468 }
1469
1470 #endif
1471 void __attribute__((constructor)) __ASM_init_module(void)
1472 {
1473 #if defined(CONFIG_ENABLE_SIGNAL_HANDLER)
1474         struct sigaction ASM_action;
1475         ASM_action.sa_handler = __ASM_signal_handler;
1476         ASM_action.sa_flags = SA_NOCLDSTOP;
1477
1478         debug_fenter();
1479
1480         sigemptyset(&ASM_action.sa_mask);
1481
1482         sigaction(SIGINT, &ASM_action, &ASM_int_old_action);
1483         sigaction(SIGABRT, &ASM_action, &ASM_abrt_old_action);
1484         sigaction(SIGSEGV, &ASM_action, &ASM_segv_old_action);
1485         sigaction(SIGTERM, &ASM_action, &ASM_term_old_action);
1486         sigaction(SIGSYS, &ASM_action, &ASM_sys_old_action);
1487         sigaction(SIGXCPU, &ASM_action, &ASM_xcpu_old_action);
1488
1489         debug_fleave();
1490 #endif
1491 }
1492
1493
1494 void __attribute__((destructor)) __ASM_fini_module(void)
1495 {
1496         debug_fenter();
1497
1498 #if defined(CONFIG_ENABLE_SIGNAL_HANDLER)
1499
1500         int exit_pid = 0;
1501         int asm_index = 0;
1502         int run_emergency_exit = 0;
1503
1504         for (asm_index = 0; asm_index < ASM_HANDLE_MAX; asm_index++) {
1505                 if (ASM_sound_handle[asm_index].is_used == true) {
1506                         exit_pid = ASM_sound_handle[asm_index].asm_tid;
1507                         if (exit_pid == asmgettid()) {
1508                                 run_emergency_exit = 1;
1509                                 break;
1510                         }
1511                 }
1512         }
1513
1514         if (run_emergency_exit) {
1515                 asm_snd_msg.instance_id = exit_pid;
1516                 asm_snd_msg.data.handle = 0; /* dummy */
1517                 asm_snd_msg.data.request_id = ASM_REQUEST_EMERGENT_EXIT;
1518                 asm_snd_msg.data.sound_event = 0;
1519                 asm_snd_msg.data.sound_state = 0;
1520
1521                 if (msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0) < 0 ) {
1522                         debug_msg( "msgsnd() failed, tid=%ld, reqid=%d, handle=0x%x, state=0x%x event=%d size=%d",asm_snd_msg.instance_id,
1523                                         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) );
1524                         int tmpid = msgget((key_t)2014, 0666);
1525                         if (msgsnd(tmpid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0) > 0) {
1526                                 debug_msg("msgsnd() succeed");
1527                         } else {
1528                                 debug_error("msgsnd() retry also failed");
1529                         }
1530                 }
1531         }
1532 #endif
1533         sigaction(SIGINT, &ASM_int_old_action, NULL);
1534         sigaction(SIGABRT, &ASM_abrt_old_action, NULL);
1535         sigaction(SIGSEGV, &ASM_segv_old_action, NULL);
1536         sigaction(SIGTERM, &ASM_term_old_action, NULL);
1537         sigaction(SIGSYS, &ASM_sys_old_action, NULL);
1538         sigaction(SIGXCPU, &ASM_xcpu_old_action, NULL);
1539
1540         debug_fleave();
1541 }
1542