Merge "Removed unused result variable from sound_codec_asm_callback" into tizen
[platform/core/multimedia/libmm-sound.git] / server / mm_sound_mgr_ipc.c
1 /*
2  * libmm-sound
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 #include <stdlib.h>
23 #include <string.h>
24
25 #include <pthread.h>
26 #include <sys/shm.h>
27 #include <sys/msg.h>
28 #include <sys/mman.h>
29 #include <sys/stat.h>
30 #include <fcntl.h>
31
32 #include <errno.h>
33
34 #include "include/mm_sound_mgr_common.h"
35 #include "include/mm_sound_mgr_ipc.h"
36
37 #include "../include/mm_sound_msg.h"
38 #include "include/mm_sound_thread_pool.h"
39 #include "include/mm_sound_mgr_codec.h"
40 #include "include/mm_sound_mgr_device.h"
41 #include <mm_error.h>
42 #include <mm_debug.h>
43
44 #include <audio-session-manager.h>
45
46 #define SHM_OPEN
47
48 #ifdef PULSE_CLIENT
49 #include "include/mm_sound_mgr_pulse.h"
50 #endif
51
52 /* message id */
53 int g_rcvid;
54 int g_sndid;
55 int g_cbid;
56
57
58 /* Msg processing */
59 static void _MMSoundMgrRun(void *data);
60 static int _MMSoundMgrStopCB(int msgid, void* msgcallback, void *msgdata);      /* msg_type means instance for client */
61 static int _MMSoundMgrIpcPlayFile(int *codechandle, mm_ipc_msg_t *msg); /* codechandle means codec slotid */
62 static int _MMSoundMgrIpcPlayMemory(int *codechandle, mm_ipc_msg_t *msg);
63 static int _MMSoundMgrIpcStop(mm_ipc_msg_t *msg);
64 static int _MMSoundMgrIpcPlayDTMF(int *codechandle, mm_ipc_msg_t *msg);
65 static int __mm_sound_mgr_ipc_is_route_available(mm_ipc_msg_t *msg, bool *is_available);
66 static int __mm_sound_mgr_ipc_foreach_available_route_cb(mm_ipc_msg_t *msg);
67 static int __mm_sound_mgr_ipc_set_active_route(mm_ipc_msg_t *msg);
68 static int __mm_sound_mgr_ipc_get_active_device(mm_ipc_msg_t *msg, mm_sound_device_in *device_in, mm_sound_device_out *device_out);
69 static int __mm_sound_mgr_ipc_add_active_device_changed_cb(mm_ipc_msg_t *msg);
70 static int __mm_sound_mgr_ipc_remove_active_device_changed_cb(mm_ipc_msg_t *msg);
71 static int __mm_sound_mgr_ipc_add_available_device_changed_cb(mm_ipc_msg_t *msg);
72 static int __mm_sound_mgr_ipc_remove_available_device_changed_cb(mm_ipc_msg_t *msg);
73 static int _MMIpcRecvMsg(int msgtype, mm_ipc_msg_t *msg);
74 static int _MMIpcSndMsg(mm_ipc_msg_t *msg);
75
76 int MMSoundMgrIpcInit(void)
77 {
78         debug_fenter();
79
80         /* create msg queue rcv, snd, cb */
81         /* This func is called only once */
82         g_rcvid = msgget(ftok(KEY_BASE_PATH, RCV_MSG), IPC_CREAT |0666);
83         g_sndid = msgget(ftok(KEY_BASE_PATH, SND_MSG), IPC_CREAT |0666);
84         g_cbid = msgget(ftok(KEY_BASE_PATH, CB_MSG), IPC_CREAT |0666);
85
86         if ((g_rcvid == -1 || g_sndid == -1 || g_cbid == -1) != MM_ERROR_NONE) {
87                 if(errno == EACCES)
88                         printf("Require ROOT permission.\n");
89                 else if(errno == EEXIST)
90                         printf("System memory is empty.\n");
91                 else if(errno == ENOMEM)
92                         printf("System memory is empty.\n");
93                 else if(errno == ENOSPC)
94                         printf("Resource is empty.\n");
95
96                 debug_error("Fail to create msgid\n");
97                 exit(1);
98                 return MM_ERROR_SOUND_INTERNAL;
99         }                       
100
101         debug_msg("Created server msg queue id : [%d]\n", g_rcvid);
102         debug_msg("Created server msg queue id : [%d]\n", g_sndid);
103         debug_msg("Created server msg queue id : [%d]\n", g_cbid);
104         
105         debug_fleave();
106         return MM_ERROR_NONE;
107 }
108
109 int MMSoundMgrIpcFini(void)
110 {
111         return MM_ERROR_NONE;
112 }
113
114 int MMSoundMgrIpcReady(void)
115 {
116         int ret = MM_ERROR_NONE;
117         int err1, err2, err3;
118         mm_ipc_msg_t msg = {0,};
119         mm_ipc_msg_t resp  = {0,};
120
121         debug_fenter();
122
123         debug_msg("Created server msg queue id : [%d]\n", g_rcvid);
124         debug_msg("Created server msg queue id : [%d]\n", g_sndid);
125         debug_msg("Created server msg queue id : [%d]\n", g_cbid);      
126
127         /* Ready to recive message */
128         while(1) {
129                 ret = _MMIpcRecvMsg(0, &msg);           
130                 if (ret != MM_ERROR_NONE) {
131                         debug_critical("Fail recieve message. \n");
132                         exit(1);
133                 }
134                         
135                 debug_msg("msgtype : %d\n", msg.sound_msg.msgtype);
136                 debug_msg("instance msgid : %d\n", msg.sound_msg.msgid);
137                 debug_msg("handle : %d\n", msg.sound_msg.handle);
138                 debug_msg("volume : %d\n", msg.sound_msg.volume);
139                 debug_msg("keytone : %d\n", msg.sound_msg.keytone);
140                 debug_msg("tone : %d\n", msg.sound_msg.tone);
141                 debug_msg("callback : %p\n", msg.sound_msg.callback);
142                 debug_msg("volume_config : %x\n", msg.sound_msg.volume_config);
143                 debug_msg("priority : %d\n", msg.sound_msg.priority);
144                 debug_msg("data : %p\n", msg.sound_msg.cbdata);
145                 debug_msg("route : %d\n", msg.sound_msg.handle_route);
146                 
147                 switch (msg.sound_msg.msgtype)
148                 {
149                 case MM_SOUND_MSG_REQ_FILE:
150                 case MM_SOUND_MSG_REQ_MEMORY:
151                 case MM_SOUND_MSG_REQ_STOP:
152 #ifdef PULSE_CLIENT
153                 case MM_SOUND_MSG_REQ_GET_AUDIO_ROUTE:
154                 case MM_SOUND_MSG_REQ_SET_AUDIO_ROUTE:
155 #endif
156                 case MM_SOUND_MSG_REQ_IS_BT_A2DP_ON:
157                 case MM_SOUND_MSG_REQ_DTMF:
158                 case MM_SOUND_MSG_REQ_IS_ROUTE_AVAILABLE:
159                 case MM_SOUND_MSG_REQ_FOREACH_AVAILABLE_ROUTE_CB:
160                 case MM_SOUND_MSG_REQ_SET_ACTIVE_ROUTE:
161                 case MM_SOUND_MSG_REQ_GET_ACTIVE_DEVICE:
162                 case MM_SOUND_MSG_REQ_ADD_ACTIVE_DEVICE_CB:
163                 case MM_SOUND_MSG_REQ_REMOVE_ACTIVE_DEVICE_CB:
164                 case MM_SOUND_MSG_REQ_ADD_AVAILABLE_ROUTE_CB:
165                 case MM_SOUND_MSG_REQ_REMOVE_AVAILABLE_ROUTE_CB:
166                         {
167                                 /* Create msg to queue : this will be freed inside thread function after use */
168                                 mm_ipc_msg_t* msg_to_queue = malloc (sizeof(mm_ipc_msg_t));
169                                 if (msg_to_queue) {
170                                         memcpy (msg_to_queue, &msg, sizeof (mm_ipc_msg_t));
171                                         debug_msg ("func = %p, alloc param(msg_to_queue) = %p\n", _MMSoundMgrRun, msg_to_queue);
172                                         ret = MMSoundThreadPoolRun(msg_to_queue, _MMSoundMgrRun);
173                                         /* In case of error condition */
174                                         if (ret != MM_ERROR_NONE) {
175                                                 /* Do not send msg in Ready, Just print log */
176                                                 debug_critical("Fail to run thread [MgrRun]");
177         
178                                                 SOUND_MSG_SET(resp.sound_msg, MM_SOUND_MSG_RES_ERROR, ret, -1, msg.sound_msg.msgid);
179                                                 ret = _MMIpcSndMsg(&resp);
180                                                 if (ret != MM_ERROR_NONE)
181                                                         debug_error("Fail to send message in IPC ready\n");
182                                         }
183                                 } else {
184                                         debug_error ("failed to alloc msg\n");
185                                 }
186                         }
187                         break;
188
189                 default:
190                         /*response err unknown operation*/;
191                         debug_critical("Error condition\n");
192                         debug_msg("The message Msg [%d] client id [%d]\n", msg.sound_msg.msgtype, msg.sound_msg.msgid);
193                         SOUND_MSG_SET(resp.sound_msg, MM_SOUND_MSG_RES_ERROR, ret, -1, msg.sound_msg.msgid);
194                         ret = _MMIpcSndMsg(&resp);
195                         if (ret != MM_ERROR_NONE)
196                                         debug_error("Fail to send message in IPC ready\n");
197                         break;
198                 } /* end : switch (msg.sound_msg.msgtype) */
199         }
200
201         /* destroy msg queue */
202         err1 = msgctl(g_rcvid, IPC_RMID, NULL);
203         err2 = msgctl(g_sndid, IPC_RMID, NULL);
204         err3 = msgctl(g_cbid, IPC_RMID, NULL);
205         
206         if (err1 == -1 ||err2 == -1 ||err3 ==-1) {
207                 debug_error("Base message node destroy fail");
208                 return MM_ERROR_SOUND_INTERNAL;
209         }
210         
211         debug_fleave();
212         return MM_ERROR_NONE;
213 }
214
215 static void _MMSoundMgrRun(void *data)
216 {
217         mm_ipc_msg_t respmsg = {0,};
218         int ret = MM_ERROR_NONE;
219         int instance;
220         int handle = -1;
221         bool is_available = 0;
222         mm_sound_device_in device_in = MM_SOUND_DEVICE_IN_NONE;
223         mm_sound_device_out device_out = MM_SOUND_DEVICE_OUT_NONE;
224         mm_ipc_msg_t *msg = (mm_ipc_msg_t *)data;
225
226         debug_fenter();
227
228         instance = msg->sound_msg.msgid;
229
230         switch (msg->sound_msg.msgtype)
231         {
232         case MM_SOUND_MSG_REQ_FILE:
233                 debug_msg("Recv REQUEST FILE MSG\n");
234                 ret = _MMSoundMgrIpcPlayFile(&handle, msg);
235                 if ( ret != MM_ERROR_NONE)      {
236                         debug_error("Error to MM_SOUND_MSG_REQ_FILE\n");
237                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_ERROR, -1, ret, instance);
238                 } else {
239                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_FILE, handle, MM_ERROR_NONE, instance);
240                 }
241                 break;
242
243         case MM_SOUND_MSG_REQ_MEMORY:
244                 debug_msg("Recv REQUEST MEMORY MSG\n");
245                 ret =_MMSoundMgrIpcPlayMemory(&handle, msg);
246                 if (ret != MM_ERROR_NONE) {
247                         debug_error("Error to MM_SOUND_MSG_REQ_MEMORY.\n");
248                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_ERROR, -1, ret, instance);
249                 } else {
250                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_MEMORY, handle, MM_ERROR_NONE, instance);
251                 }
252                 break;
253                 
254         case MM_SOUND_MSG_REQ_STOP:
255                 debug_msg("Recv STOP msg\n");
256                 debug_msg("STOP Handle(codec slot ID) %d \n", msg->sound_msg.handle);
257                 ret = _MMSoundMgrIpcStop(msg);
258                 if ( ret != MM_ERROR_NONE) {
259                         debug_error("Error to MM_SOUND_MSG_REQ_STOP.\n");
260                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_ERROR, -1, ret, instance);
261                 } else {
262                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_STOP, msg->sound_msg.handle, MM_ERROR_NONE, instance);
263                 }
264                 break;
265                 
266 #ifdef PULSE_CLIENT
267         case MM_SOUND_MSG_REQ_IS_BT_A2DP_ON:
268                 debug_msg("Recv REQ_IS_BT_A2DP_ON msg\n");
269                 MMSoundMgrPulseHandleIsBtA2DPOnReq (msg,_MMIpcSndMsg);
270                 return;
271 #endif // PULSE_CLIENT
272
273         case MM_SOUND_MSG_REQ_DTMF:
274                 debug_msg("Recv DTMF msg\n");
275                 debug_msg(" Handle(codec slot ID) %d \n", msg->sound_msg.handle);
276                 ret = _MMSoundMgrIpcPlayDTMF(&handle, msg);
277                 if ( ret != MM_ERROR_NONE) {
278                         debug_error("Error to MM_SOUND_MSG_REQ_STOP.\n");
279                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_ERROR, -1, ret, instance);
280                 } else {
281                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_DTMF, handle, MM_ERROR_NONE, instance);
282                 }
283                 break;
284
285         case MM_SOUND_MSG_REQ_IS_ROUTE_AVAILABLE:
286                 debug_msg("Recv REQ_SET_ACTIVE_ROUTE msg\n");
287                 ret = __mm_sound_mgr_ipc_is_route_available(msg, &is_available);
288                 if (ret != MM_ERROR_NONE) {
289                         debug_error("Error to MM_SOUND_MSG_REQ_IS_ROUTE_AVAILABLE.\n");
290                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_ERROR, -1, ret, instance);
291                 } else {
292                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_IS_ROUTE_AVAILABLE, 0, MM_ERROR_NONE, instance);
293                         respmsg.sound_msg.is_available = is_available;
294                 }
295                 break;
296
297         case MM_SOUND_MSG_REQ_FOREACH_AVAILABLE_ROUTE_CB:
298                 debug_msg("Recv REQ_FOREACH_AVAILABLE_ROUTE_CB msg\n");
299                 ret = __mm_sound_mgr_ipc_foreach_available_route_cb(&respmsg);
300                 if (ret != MM_ERROR_NONE) {
301                         debug_error("Error to MM_SOUND_MSG_REQ_FOREACH_AVAILABLE_ROUTE_CB.\n");
302                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_ERROR, -1, ret, instance);
303                 } else {
304                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_FOREACH_AVAILABLE_ROUTE_CB, 0, MM_ERROR_NONE, instance);
305                 }
306                 break;
307
308         case MM_SOUND_MSG_REQ_SET_ACTIVE_ROUTE:
309                 debug_msg("Recv REQ_SET_ACTIVE_ROUTE msg\n");
310                 ret = __mm_sound_mgr_ipc_set_active_route(msg);
311                 if (ret != MM_ERROR_NONE) {
312                         debug_error("Error to MM_SOUND_MSG_REQ_SET_ACTIVE_ROUTE.\n");
313                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_ERROR, -1, ret, instance);
314                 } else {
315                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_SET_ACTIVE_ROUTE, 0, MM_ERROR_NONE, instance);
316                 }
317                 break;
318
319         case MM_SOUND_MSG_REQ_GET_ACTIVE_DEVICE:
320                 debug_msg("Recv REQ_GET_ACTIVE_DEVICE msg\n");
321                 ret = __mm_sound_mgr_ipc_get_active_device(msg, &device_in, &device_out);
322                 if (ret != MM_ERROR_NONE) {
323                         debug_error("Error to MM_SOUND_MSG_REQ_GET_ACTIVE_DEVICE.\n");
324                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_ERROR, -1, ret, instance);
325                 } else {
326                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_GET_ACTIVE_DEVICE, 0, MM_ERROR_NONE, instance);
327                         respmsg.sound_msg.device_in = device_in;
328                         respmsg.sound_msg.device_out = device_out;
329                 }
330                 break;
331
332         case MM_SOUND_MSG_REQ_ADD_ACTIVE_DEVICE_CB:
333                 debug_msg("Recv REQ_ADD_ACTIVE_DEVICE_CB msg\n");
334                 ret = __mm_sound_mgr_ipc_add_active_device_changed_cb(msg);
335                 if (ret != MM_ERROR_NONE) {
336                         debug_error("Error to MM_SOUND_MSG_REQ_ADD_DEVICE_CB.\n");
337                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_ERROR, -1, ret, instance);
338                 } else {
339                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_ADD_ACTIVE_DEVICE_CB, 0, MM_ERROR_NONE, instance);
340                 }
341                 break;
342
343         case MM_SOUND_MSG_REQ_REMOVE_ACTIVE_DEVICE_CB:
344                 debug_msg("Recv REQ_REMOVE_ACTIVE_DEVICE_CB msg\n");
345                 ret = __mm_sound_mgr_ipc_remove_active_device_changed_cb(msg);
346                 if (ret != MM_ERROR_NONE) {
347                         debug_error("Error to MM_SOUND_MSG_REQ_REMOVE_DEVICE_CB.\n");
348                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_ERROR, -1, ret, instance);
349                 } else {
350                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_REMOVE_ACTIVE_DEVICE_CB, 0, MM_ERROR_NONE, instance);
351                 }
352                 break;
353
354         case MM_SOUND_MSG_REQ_ADD_AVAILABLE_ROUTE_CB:
355                 debug_msg("Recv REQ_ADD_AVAILABLE_ROUTE_CB msg\n");
356                 ret = __mm_sound_mgr_ipc_add_available_device_changed_cb(msg);
357                 if (ret != MM_ERROR_NONE) {
358                         debug_error("Error to MM_SOUND_MSG_REQ_ADD_DEVICE_CB.\n");
359                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_ERROR, -1, ret, instance);
360                 } else {
361                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_ADD_AVAILABLE_ROUTE_CB, 0, MM_ERROR_NONE, instance);
362                 }
363                 break;
364
365         case MM_SOUND_MSG_REQ_REMOVE_AVAILABLE_ROUTE_CB:
366                 debug_msg("Recv REQ_REMOVE_AVAILABLE_ROUTE_CB msg\n");
367                 ret = __mm_sound_mgr_ipc_remove_available_device_changed_cb(msg);
368                 if (ret != MM_ERROR_NONE) {
369                         debug_error("Error to MM_SOUND_MSG_REQ_REMOVE_DEVICE_CB.\n");
370                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_ERROR, -1, ret, instance);
371                 } else {
372                         SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_REMOVE_AVAILABLE_ROUTE_CB, 0, MM_ERROR_NONE, instance);
373                 }
374                 break;
375
376         default:
377                 /* Response error unknown operation */;
378                 debug_critical("Unexpected msg. %d for PID:%d\n", msg->sound_msg.msgtype, msg->sound_msg.msgid );               
379                 SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_ERROR, -1, MM_ERROR_SOUND_INTERNAL, instance);
380                 break;
381         } /* switch (msg->sound_msg.msgtype) */
382
383         ret = _MMIpcSndMsg(&respmsg);
384         if (ret != MM_ERROR_NONE) {
385                 debug_error ("Fail to send message \n");
386         }
387
388         debug_msg("Sent msg to client msgid [%d] [codechandle %d][message type %d] (code 0x%08X)\n",
389                 msg->sound_msg.msgid, respmsg.sound_msg.handle, respmsg.sound_msg.msgtype, respmsg.sound_msg.code);
390
391         if (msg) {
392                 debug_log ("Free mm_ipc_msg_t [%p]\n", msg);
393                 free (msg);
394         }
395
396         debug_msg("Ready to next msg\n");
397         debug_fleave();
398 }
399
400 static int _MMSoundMgrStopCB(int msgid, void* msgcallback, void *msgdata)
401 {
402         /* msgid means client instance(msg_type) must be unique */
403         mm_ipc_msg_t resp = {0,};
404         int ret = MM_ERROR_SOUND_INTERNAL;
405         
406         debug_fenter();
407
408         SOUND_MSG_SET(resp.sound_msg, MM_SOUND_MSG_INF_STOP_CB, 0, MM_ERROR_NONE, msgid);
409         resp.sound_msg.callback = msgcallback;
410         resp.sound_msg.cbdata = msgdata;
411         
412         ret = _MMIpcCBSndMsg(&resp);
413         if (ret != MM_ERROR_NONE)
414                 debug_error("Fail to send callback message\n");
415
416         debug_fleave();
417         return MM_ERROR_NONE;
418 }
419
420 static int _MMSoundMgrIpcPlayFile(int *codechandle, mm_ipc_msg_t *msg)
421 {
422         mmsound_mgr_codec_param_t param = {0,};
423         MMSourceType *source = NULL;
424         int ret = MM_ERROR_NONE;
425         int mm_session_type = MM_SESSION_TYPE_SHARE;
426         
427         debug_fenter();
428
429         /* Set source */
430         source = (MMSourceType*)malloc(sizeof(MMSourceType));
431
432         ret = mm_source_open_file(msg->sound_msg.filename, source, MM_SOURCE_CHECK_DRM_CONTENTS);
433         if(ret != MM_ERROR_NONE) {
434                 debug_error("Fail to open file\n");
435                 if (source)
436                         free(source);
437                 return ret;             
438         }
439
440         /* Set sound player parameter */
441         param.tone = msg->sound_msg.tone;
442         param.repeat_count = msg->sound_msg.repeat;
443         param.param = (void*)msg->sound_msg.msgid; //this is pid of client
444         param.volume = msg->sound_msg.volume;
445         param.volume_config = msg->sound_msg.volume_config;
446         param.priority = msg->sound_msg.priority;
447         mm_session_type = msg->sound_msg.session_type;
448         param.callback = _MMSoundMgrStopCB;
449         param.keytone =  msg->sound_msg.keytone;
450         param.msgcallback = msg->sound_msg.callback;
451         param.msgdata = msg->sound_msg.cbdata;
452         param.source = source;
453         param.handle_route = msg->sound_msg.handle_route;
454
455         debug_msg("DTMF %d\n", param.tone);
456         debug_msg("Loop %d\n", param.repeat_count);
457         debug_msg("Volume %d\n", param.volume);
458         debug_msg("Priority %d\n", param.priority);
459         debug_msg("VolumeConfig %x\n", param.volume_config);
460         debug_msg("callback %p\n", param.callback);
461         debug_msg("param %d\n", (int)param.param);
462         debug_msg("source type %d\n", param.source->type);
463         debug_msg("source ptr %p\n", param.source->ptr);
464         debug_msg("keytone %d\n", param.keytone);
465         debug_msg("Handle route %d\n", param.handle_route);
466
467         //convert mm_session_type to asm_event_type
468         switch(mm_session_type)
469         {
470         case MM_SESSION_TYPE_SHARE:
471                 param.session_type = ASM_EVENT_SHARE_MMSOUND;
472                 break;
473         case MM_SESSION_TYPE_EXCLUSIVE:
474                 param.session_type = ASM_EVENT_EXCLUSIVE_MMSOUND;
475                 break;
476         case MM_SESSION_TYPE_NOTIFY:
477                 param.session_type = ASM_EVENT_NOTIFY;
478                 break;
479         case MM_SESSION_TYPE_ALARM:
480                 param.session_type = ASM_EVENT_ALARM;
481                 break;
482         case MM_SESSION_TYPE_EMERGENCY:
483                 param.session_type = ASM_EVENT_EMERGENCY;
484                 break;
485         case MM_SESSION_TYPE_CALL:
486                 param.session_type = ASM_EVENT_CALL;
487                 break;
488         case MM_SESSION_TYPE_VIDEOCALL:
489                 param.session_type = ASM_EVENT_VIDEOCALL;
490                 break;
491         default:
492                 debug_error("Unknown session type - use default shared type. %s %d\n", __FUNCTION__, __LINE__);
493                 param.session_type = ASM_EVENT_SHARE_MMSOUND;
494                 break;
495         }
496
497
498         ret = MMSoundMgrCodecPlay(codechandle, &param);
499         if ( ret != MM_ERROR_NONE) {
500                 debug_error("Will be closed a sources, codechandle : 0x%08X\n", *codechandle);
501
502                 return ret;             
503         }
504
505         debug_fleave();
506         return MM_ERROR_NONE;
507 }
508 static int _MMSoundMgrIpcStop(mm_ipc_msg_t *msg)
509 {
510         int ret = MM_ERROR_NONE;
511
512         debug_fenter();
513
514         ret = MMSoundMgrCodecStop(msg->sound_msg.handle);
515
516         if (ret != MM_ERROR_NONE) {
517                 debug_error("Fail to stop sound\n");
518                 return ret;
519         }
520
521         debug_fleave();
522         return MM_ERROR_NONE;
523 }
524
525 static int _MMSoundMgrIpcPlayMemory(int *codechandle, mm_ipc_msg_t *msg)
526 {
527         mmsound_mgr_codec_param_t param = {0,};
528         MMSourceType *source = NULL;
529         int ret = MM_ERROR_NONE;
530         int shm_fd = -1;
531         void* mmap_buf = NULL;
532
533         debug_fenter();
534
535 #ifndef SHM_OPEN
536         if ((shmid = shmget((key_t)(msg->sound_msg.sharedkey), msg->sound_msg.memsize, 0)) == -1)
537         {
538                 if(errno == ENOENT)
539                 {
540                         debug_error("Not initialized.\n");
541                 }
542                 else if(errno == EACCES)
543                 {
544                         debug_error("Require ROOT permission.\n");
545                 }
546                 else if(errno == ENOSPC)
547                 {
548                         debug_critical("Resource is empty.\n");
549                 }
550                 return MM_ERROR_SOUND_INTERNAL;
551         }
552
553         source = (MMSourceType*)malloc(sizeof(MMSourceType));
554
555         if (mm_source_open_full_memory(shmat(shmid, 0, 0), msg->sound_msg.memsize, 0, source) != MM_ERROR_NONE)
556         {
557                 debug_error("Fail to set source\n");
558                 free(source);
559                 return MM_ERROR_SOUND_INTERNAL;
560         }
561 #else
562
563         debug_msg("Shm file name : %s\n", msg->sound_msg.filename);
564
565         if(msg->sound_msg.sharedkey != 1) {
566                 debug_error("NOT memory interface\n");
567                 return MM_ERROR_SOUND_INVALID_PATH;
568         }
569
570         shm_fd = shm_open(msg->sound_msg.filename, O_RDONLY, 0666);
571         if(shm_fd < 0) {
572                 debug_error("Fail to open\n");
573                 return MM_ERROR_SOUND_INTERNAL;
574         }
575
576         mmap_buf = mmap (0, MEMTYPE_SUPPORT_MAX, PROT_READ , MAP_SHARED, shm_fd, 0);
577         if (mmap_buf == MAP_FAILED) {
578                 perror("Fail to mmap\n");
579                 debug_error("MMAP failed \n");
580                 return MM_ERROR_SOUND_INTERNAL;
581         }
582
583         /* Set source */
584         source = (MMSourceType*)malloc(sizeof(MMSourceType));
585         if(!source) {
586                 debug_error("Can not allocate memory");
587                 return MM_ERROR_OUT_OF_MEMORY;
588         }
589
590         if (mm_source_open_full_memory(mmap_buf, msg->sound_msg.memsize, 0, source) != MM_ERROR_NONE) {
591                 debug_error("Fail to set source\n");
592                 free(source);
593                 return MM_ERROR_SOUND_INTERNAL;
594         }
595 #endif  
596
597         /* Set sound player parameter */
598         param.tone = msg->sound_msg.tone;
599         param.repeat_count = msg->sound_msg.repeat;
600         param.param = (void*)msg->sound_msg.msgid;
601         param.volume = msg->sound_msg.volume;
602         param.volume_config = msg->sound_msg.volume_config;
603         param.callback = _MMSoundMgrStopCB;
604         param.keytone =  msg->sound_msg.keytone;
605         param.msgcallback = msg->sound_msg.callback;
606         param.msgdata = msg->sound_msg.cbdata;
607         param.priority = msg->sound_msg.priority;
608         param.source = source;
609
610         debug_msg("DTMF %d\n", param.tone);
611         debug_msg("Loop %d\n", param.repeat_count);
612         debug_msg("Volume %d\n",param.volume);
613         debug_msg("Priority %d\n",param.priority);
614         debug_msg("VolumeConfig %x\n",param.volume_config);
615         debug_msg("callback %p\n", param.callback);
616         debug_msg("param %d\n", (int)param.param);
617         debug_msg("source type %d\n", param.source->type);
618         debug_msg("source ptr %p\n", param.source->ptr);
619         debug_msg("keytone %d\n", param.keytone);
620
621         ret = MMSoundMgrCodecPlay(codechandle, &param);
622         if ( ret != MM_ERROR_NONE) {
623                 debug_error("Will be closed a sources, codec handle : [0x%d]\n", *codechandle);
624                 mm_source_close(source);
625                 if (source)
626                         free(source);
627                 return ret;             
628         }
629
630         debug_fleave();
631         return ret;
632 }
633
634 static int _MMSoundMgrIpcPlayDTMF(int *codechandle, mm_ipc_msg_t *msg)
635 {
636         mmsound_mgr_codec_param_t param = {0,};
637         int ret = MM_ERROR_NONE;
638
639         debug_fenter();
640
641         /* Set sound player parameter */
642         param.tone = msg->sound_msg.tone;
643         param.repeat_count = msg->sound_msg.repeat;
644         param.param = (void*)msg->sound_msg.msgid;
645         param.volume = msg->sound_msg.volume;
646         param.volume_config = msg->sound_msg.volume_config;
647         param.priority = msg->sound_msg.priority;
648         param.callback = _MMSoundMgrStopCB;
649         param.msgcallback = msg->sound_msg.callback;
650         param.msgdata = msg->sound_msg.cbdata;
651
652         //convert mm_session_type to asm_event_type
653         switch(msg->sound_msg.session_type)
654         {
655                 case MM_SESSION_TYPE_SHARE:
656                         param.session_type = ASM_EVENT_SHARE_MMSOUND;
657                         break;
658                 case MM_SESSION_TYPE_EXCLUSIVE:
659                         param.session_type = ASM_EVENT_EXCLUSIVE_MMSOUND;
660                         break;
661                 case MM_SESSION_TYPE_NOTIFY:
662                         param.session_type = ASM_EVENT_NOTIFY;
663                         break;
664                 case MM_SESSION_TYPE_ALARM:
665                         param.session_type = ASM_EVENT_ALARM;
666                         break;
667                 case MM_SESSION_TYPE_EMERGENCY:
668                         param.session_type = ASM_EVENT_EMERGENCY;
669                         break;
670                 case MM_SESSION_TYPE_CALL:
671                         param.session_type = ASM_EVENT_CALL;
672                         break;
673                 case MM_SESSION_TYPE_VIDEOCALL:
674                         param.session_type = ASM_EVENT_VIDEOCALL;
675                         break;
676                 default:
677                         debug_error("Unknown session type - use default shared type. %s %d\n", __FUNCTION__, __LINE__);
678                         param.session_type = ASM_EVENT_SHARE_MMSOUND;
679                         break;
680         }
681
682         debug_msg("DTMF %d\n", param.tone);
683         debug_msg("Loop %d\n", param.repeat_count);
684         debug_msg("Volume %d\n",param.volume);
685         debug_msg("VolumeConfig %x\n",param.volume_config);
686         debug_msg("Priority %d\n", param.priority);
687         debug_msg("callback %p\n", param.callback);
688         debug_msg("param %d\n", (int)param.param);
689         debug_msg("session %d\n", param.session_type);
690
691         ret = MMSoundMgrCodecPlayDtmf(codechandle, &param);
692         if ( ret != MM_ERROR_NONE) {
693                 debug_error("Will be closed a sources, codec handle : [0x%d]\n", *codechandle);
694                 return ret;             
695         }
696
697         debug_fleave();
698         return ret;
699 }
700
701 static int __mm_sound_mgr_ipc_is_route_available(mm_ipc_msg_t *msg, bool *is_available)
702 {
703         _mm_sound_mgr_device_param_t param;
704         int ret = MM_ERROR_NONE;
705
706         debug_fenter();
707
708         param.route = msg->sound_msg.route;
709         ret = _mm_sound_mgr_device_is_route_available(&param, is_available);
710
711         debug_fleave();
712         return ret;
713 }
714
715 static int __mm_sound_mgr_ipc_foreach_available_route_cb(mm_ipc_msg_t *msg)
716 {
717         int ret = MM_ERROR_NONE;
718
719         debug_fenter();
720
721         ret = _mm_sound_mgr_device_foreach_available_route_cb(msg);
722
723         debug_fleave();
724         return ret;
725 }
726
727 static int __mm_sound_mgr_ipc_set_active_route(mm_ipc_msg_t *msg)
728 {
729         _mm_sound_mgr_device_param_t param;
730         int ret = MM_ERROR_NONE;
731
732         debug_fenter();
733
734         param.pid = msg->sound_msg.msgid;
735         param.route = msg->sound_msg.route;
736         ret = _mm_sound_mgr_device_set_active_route(&param);
737
738         debug_fleave();
739         return ret;
740 }
741
742 static int __mm_sound_mgr_ipc_get_active_device(mm_ipc_msg_t *msg, mm_sound_device_in *device_in, mm_sound_device_out *device_out)
743 {
744         _mm_sound_mgr_device_param_t param;
745         int ret = MM_ERROR_NONE;
746
747         debug_fenter();
748
749         memset(&param, 0x00, sizeof(_mm_sound_mgr_device_param_t));
750         param.pid = msg->sound_msg.msgid;
751
752         ret = _mm_sound_mgr_device_get_active_device(&param, device_in, device_out);
753
754         debug_fleave();
755         return ret;
756 }
757
758 static int __mm_sound_mgr_ipc_add_active_device_changed_cb(mm_ipc_msg_t *msg)
759 {
760         _mm_sound_mgr_device_param_t param;
761         int ret = MM_ERROR_NONE;
762
763         debug_fenter();
764
765         memset(&param, 0x00, sizeof(_mm_sound_mgr_device_param_t));
766         param.pid = msg->sound_msg.msgid;
767         param.callback = msg->sound_msg.callback;
768         param.cbdata = msg->sound_msg.cbdata;
769
770         ret = _mm_sound_mgr_device_add_active_device_callback(&param);
771
772         debug_fleave();
773         return ret;
774 }
775
776 static int __mm_sound_mgr_ipc_remove_active_device_changed_cb(mm_ipc_msg_t *msg)
777 {
778         _mm_sound_mgr_device_param_t param;
779         int ret = MM_ERROR_NONE;
780
781         debug_fenter();
782
783         memset(&param, 0x00, sizeof(_mm_sound_mgr_device_param_t));
784         param.pid = msg->sound_msg.msgid;
785
786         ret = _mm_sound_mgr_device_remove_active_device_callback(&param);
787
788         debug_fleave();
789         return ret;
790 }
791
792 static int __mm_sound_mgr_ipc_add_available_device_changed_cb(mm_ipc_msg_t *msg)
793 {
794         _mm_sound_mgr_device_param_t param;
795         int ret = MM_ERROR_NONE;
796
797         debug_fenter();
798
799         memset(&param, 0x00, sizeof(_mm_sound_mgr_device_param_t));
800         param.pid = msg->sound_msg.msgid;
801         param.callback = msg->sound_msg.callback;
802         param.cbdata = msg->sound_msg.cbdata;
803
804         ret = _mm_sound_mgr_device_add_available_route_callback(&param);
805
806         debug_fleave();
807         return ret;
808 }
809
810 static int __mm_sound_mgr_ipc_remove_available_device_changed_cb(mm_ipc_msg_t *msg)
811 {
812         _mm_sound_mgr_device_param_t param;
813         int ret = MM_ERROR_NONE;
814
815         debug_fenter();
816
817         memset(&param, 0x00, sizeof(_mm_sound_mgr_device_param_t));
818         param.pid = msg->sound_msg.msgid;
819
820         ret = _mm_sound_mgr_device_remove_available_route_callback(&param);
821
822         debug_fleave();
823         return ret;
824 }
825
826 static int _MMIpcRecvMsg(int msgtype, mm_ipc_msg_t *msg)
827 {
828         /* rcv message */
829         if(msgrcv(g_rcvid, msg, DSIZE, 0, 0) == -1)
830         {
831                 if(errno == E2BIG) {
832                         debug_warning("Not acces.\n");
833                 } else if(errno == EACCES) {
834                         debug_warning("Access denied\n");
835                 } else if(errno == ENOMSG) {
836                         debug_warning("Blocked process [msgflag & IPC_NOWAIT != 0]\n");
837                 } else if(errno == EIDRM) {
838                         debug_warning("Removed msgid from system\n");
839                 } else if(errno == EINTR) {
840                         debug_warning("Iterrrupted by singnal\n");
841                 } else if(errno == EINVAL) {
842                         debug_warning("Invalid msgid \n");
843                 }
844
845                 debug_warning("Fail to recive msg queue : [%d] \n", g_rcvid);
846                 return MM_ERROR_COMMON_UNKNOWN;
847         }
848         return MM_ERROR_NONE;
849 }
850
851 int _MMIpcSndMsg(mm_ipc_msg_t *msg)
852 {
853         /* snd message */
854         int error = MM_ERROR_NONE;
855         msg->msg_type = msg->sound_msg.msgid;
856         debug_msg("Send message type (for client) : [%ld]\n",msg->msg_type);
857         error = msgsnd(g_sndid, msg,DSIZE, 0);
858         if ( error == -1)
859         {
860                 if(errno == EACCES) {
861                         debug_warning("Not acces.\n");
862                 } else if(errno == EAGAIN) {
863                         debug_warning("Blocked process [msgflag & IPC_NOWAIT != 0]\n");
864                 } else if(errno == EIDRM) {
865                         debug_warning("Removed msgid from system\n");
866                 } else if(errno == EINTR) {
867                         debug_warning("Iterrrupted by singnal\n");
868                 } else if(errno == EINVAL) {
869                         debug_warning("Invalid msgid or msgtype < 1 or out of data size \n");
870                 } else if(errno == EFAULT) {
871                         debug_warning("The address pointed to by msgp isn't accessible \n");
872                 } else if(errno == ENOMEM) {
873                         debug_warning("The system does not have enough memory to make a copy of the message pointed to by msgp\n");
874                 }
875                 debug_critical("Fail to send message msg queue : [%d] \n", g_sndid);
876                 debug_critical("Fail to send message msg queue : [%d] \n", errno);
877                 return MM_ERROR_SOUND_INTERNAL;
878         }
879         return MM_ERROR_NONE;
880 }
881
882 int _MMIpcCBSndMsg(mm_ipc_msg_t *msg)
883 {
884         /* rcv message */
885         msg->msg_type = msg->sound_msg.msgid;
886         debug_msg("Send CB message type (for client) : [%ld]\n",msg->msg_type);
887         if (msgsnd(g_cbid, msg,DSIZE, 0)== -1)
888         {
889                 if(errno == EACCES) {
890                         debug_warning("Not acces.\n");
891                 } else if(errno == EAGAIN) {
892                         debug_warning("Blocked process [msgflag & IPC_NOWAIT != 0]\n");
893                 } else if(errno == EIDRM) {
894                         debug_warning("Removed msgid from system\n");
895                 } else if(errno == EINTR) {
896                         debug_warning("Iterrrupted by singnal\n");
897                 } else if(errno == EINVAL) {
898                         debug_warning("Invalid msgid or msgtype < 1 or out of data size \n");
899                 }
900                 debug_critical("Fail to callback send message msg queue : [%d] \n", g_cbid);
901                 return MM_ERROR_SOUND_INTERNAL;
902         }
903         return MM_ERROR_NONE;
904 }
905