4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Seungbae Shin <seungbae.shin@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
34 #include "include/mm_sound_mgr_common.h"
35 #include "include/mm_sound_mgr_ipc.h"
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"
44 #include <audio-session-manager.h>
49 #include "include/mm_sound_mgr_pulse.h"
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);
76 int MMSoundMgrIpcInit(void)
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);
86 if ((g_rcvid == -1 || g_sndid == -1 || g_cbid == -1) != MM_ERROR_NONE) {
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");
96 debug_error("Fail to create msgid\n");
98 return MM_ERROR_SOUND_INTERNAL;
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);
106 return MM_ERROR_NONE;
109 int MMSoundMgrIpcFini(void)
111 return MM_ERROR_NONE;
114 int MMSoundMgrIpcReady(void)
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,};
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);
127 /* Ready to recive message */
129 ret = _MMIpcRecvMsg(0, &msg);
130 if (ret != MM_ERROR_NONE) {
131 debug_critical("Fail recieve message. \n");
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);
147 switch (msg.sound_msg.msgtype)
149 case MM_SOUND_MSG_REQ_FILE:
150 case MM_SOUND_MSG_REQ_MEMORY:
151 case MM_SOUND_MSG_REQ_STOP:
153 case MM_SOUND_MSG_REQ_GET_AUDIO_ROUTE:
154 case MM_SOUND_MSG_REQ_SET_AUDIO_ROUTE:
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:
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));
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]");
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");
184 debug_error ("failed to alloc msg\n");
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");
198 } /* end : switch (msg.sound_msg.msgtype) */
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);
206 if (err1 == -1 ||err2 == -1 ||err3 ==-1) {
207 debug_error("Base message node destroy fail");
208 return MM_ERROR_SOUND_INTERNAL;
212 return MM_ERROR_NONE;
215 static void _MMSoundMgrRun(void *data)
217 mm_ipc_msg_t respmsg = {0,};
218 int ret = MM_ERROR_NONE;
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;
228 instance = msg->sound_msg.msgid;
230 switch (msg->sound_msg.msgtype)
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);
239 SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_FILE, handle, MM_ERROR_NONE, instance);
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);
250 SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_MEMORY, handle, MM_ERROR_NONE, instance);
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);
262 SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_STOP, msg->sound_msg.handle, MM_ERROR_NONE, instance);
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);
271 #endif // PULSE_CLIENT
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);
281 SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_DTMF, handle, MM_ERROR_NONE, instance);
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);
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;
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);
304 SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_FOREACH_AVAILABLE_ROUTE_CB, 0, MM_ERROR_NONE, instance);
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);
315 SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_SET_ACTIVE_ROUTE, 0, MM_ERROR_NONE, instance);
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);
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;
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);
339 SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_ADD_ACTIVE_DEVICE_CB, 0, MM_ERROR_NONE, instance);
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);
350 SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_REMOVE_ACTIVE_DEVICE_CB, 0, MM_ERROR_NONE, instance);
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);
361 SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_ADD_AVAILABLE_ROUTE_CB, 0, MM_ERROR_NONE, instance);
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);
372 SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_REMOVE_AVAILABLE_ROUTE_CB, 0, MM_ERROR_NONE, instance);
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);
381 } /* switch (msg->sound_msg.msgtype) */
383 ret = _MMIpcSndMsg(&respmsg);
384 if (ret != MM_ERROR_NONE) {
385 debug_error ("Fail to send message \n");
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);
392 debug_log ("Free mm_ipc_msg_t [%p]\n", msg);
396 debug_msg("Ready to next msg\n");
400 static int _MMSoundMgrStopCB(int msgid, void* msgcallback, void *msgdata)
402 /* msgid means client instance(msg_type) must be unique */
403 mm_ipc_msg_t resp = {0,};
404 int ret = MM_ERROR_SOUND_INTERNAL;
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;
412 ret = _MMIpcCBSndMsg(&resp);
413 if (ret != MM_ERROR_NONE)
414 debug_error("Fail to send callback message\n");
417 return MM_ERROR_NONE;
420 static int _MMSoundMgrIpcPlayFile(int *codechandle, mm_ipc_msg_t *msg)
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;
430 source = (MMSourceType*)malloc(sizeof(MMSourceType));
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");
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;
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);
467 //convert mm_session_type to asm_event_type
468 switch(mm_session_type)
470 case MM_SESSION_TYPE_SHARE:
471 param.session_type = ASM_EVENT_SHARE_MMSOUND;
473 case MM_SESSION_TYPE_EXCLUSIVE:
474 param.session_type = ASM_EVENT_EXCLUSIVE_MMSOUND;
476 case MM_SESSION_TYPE_NOTIFY:
477 param.session_type = ASM_EVENT_NOTIFY;
479 case MM_SESSION_TYPE_ALARM:
480 param.session_type = ASM_EVENT_ALARM;
482 case MM_SESSION_TYPE_EMERGENCY:
483 param.session_type = ASM_EVENT_EMERGENCY;
485 case MM_SESSION_TYPE_CALL:
486 param.session_type = ASM_EVENT_CALL;
488 case MM_SESSION_TYPE_VIDEOCALL:
489 param.session_type = ASM_EVENT_VIDEOCALL;
492 debug_error("Unknown session type - use default shared type. %s %d\n", __FUNCTION__, __LINE__);
493 param.session_type = ASM_EVENT_SHARE_MMSOUND;
498 ret = MMSoundMgrCodecPlay(codechandle, ¶m);
499 if ( ret != MM_ERROR_NONE) {
500 debug_error("Will be closed a sources, codechandle : 0x%08X\n", *codechandle);
506 return MM_ERROR_NONE;
508 static int _MMSoundMgrIpcStop(mm_ipc_msg_t *msg)
510 int ret = MM_ERROR_NONE;
514 ret = MMSoundMgrCodecStop(msg->sound_msg.handle);
516 if (ret != MM_ERROR_NONE) {
517 debug_error("Fail to stop sound\n");
522 return MM_ERROR_NONE;
525 static int _MMSoundMgrIpcPlayMemory(int *codechandle, mm_ipc_msg_t *msg)
527 mmsound_mgr_codec_param_t param = {0,};
528 MMSourceType *source = NULL;
529 int ret = MM_ERROR_NONE;
531 void* mmap_buf = NULL;
536 if ((shmid = shmget((key_t)(msg->sound_msg.sharedkey), msg->sound_msg.memsize, 0)) == -1)
540 debug_error("Not initialized.\n");
542 else if(errno == EACCES)
544 debug_error("Require ROOT permission.\n");
546 else if(errno == ENOSPC)
548 debug_critical("Resource is empty.\n");
550 return MM_ERROR_SOUND_INTERNAL;
553 source = (MMSourceType*)malloc(sizeof(MMSourceType));
555 if (mm_source_open_full_memory(shmat(shmid, 0, 0), msg->sound_msg.memsize, 0, source) != MM_ERROR_NONE)
557 debug_error("Fail to set source\n");
559 return MM_ERROR_SOUND_INTERNAL;
563 debug_msg("Shm file name : %s\n", msg->sound_msg.filename);
565 if(msg->sound_msg.sharedkey != 1) {
566 debug_error("NOT memory interface\n");
567 return MM_ERROR_SOUND_INVALID_PATH;
570 shm_fd = shm_open(msg->sound_msg.filename, O_RDONLY, 0666);
572 debug_error("Fail to open\n");
573 return MM_ERROR_SOUND_INTERNAL;
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;
584 source = (MMSourceType*)malloc(sizeof(MMSourceType));
586 debug_error("Can not allocate memory");
587 return MM_ERROR_OUT_OF_MEMORY;
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");
593 return MM_ERROR_SOUND_INTERNAL;
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;
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);
621 ret = MMSoundMgrCodecPlay(codechandle, ¶m);
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);
634 static int _MMSoundMgrIpcPlayDTMF(int *codechandle, mm_ipc_msg_t *msg)
636 mmsound_mgr_codec_param_t param = {0,};
637 int ret = MM_ERROR_NONE;
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;
652 //convert mm_session_type to asm_event_type
653 switch(msg->sound_msg.session_type)
655 case MM_SESSION_TYPE_SHARE:
656 param.session_type = ASM_EVENT_SHARE_MMSOUND;
658 case MM_SESSION_TYPE_EXCLUSIVE:
659 param.session_type = ASM_EVENT_EXCLUSIVE_MMSOUND;
661 case MM_SESSION_TYPE_NOTIFY:
662 param.session_type = ASM_EVENT_NOTIFY;
664 case MM_SESSION_TYPE_ALARM:
665 param.session_type = ASM_EVENT_ALARM;
667 case MM_SESSION_TYPE_EMERGENCY:
668 param.session_type = ASM_EVENT_EMERGENCY;
670 case MM_SESSION_TYPE_CALL:
671 param.session_type = ASM_EVENT_CALL;
673 case MM_SESSION_TYPE_VIDEOCALL:
674 param.session_type = ASM_EVENT_VIDEOCALL;
677 debug_error("Unknown session type - use default shared type. %s %d\n", __FUNCTION__, __LINE__);
678 param.session_type = ASM_EVENT_SHARE_MMSOUND;
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);
691 ret = MMSoundMgrCodecPlayDtmf(codechandle, ¶m);
692 if ( ret != MM_ERROR_NONE) {
693 debug_error("Will be closed a sources, codec handle : [0x%d]\n", *codechandle);
701 static int __mm_sound_mgr_ipc_is_route_available(mm_ipc_msg_t *msg, bool *is_available)
703 _mm_sound_mgr_device_param_t param;
704 int ret = MM_ERROR_NONE;
708 param.route = msg->sound_msg.route;
709 ret = _mm_sound_mgr_device_is_route_available(¶m, is_available);
715 static int __mm_sound_mgr_ipc_foreach_available_route_cb(mm_ipc_msg_t *msg)
717 int ret = MM_ERROR_NONE;
721 ret = _mm_sound_mgr_device_foreach_available_route_cb(msg);
727 static int __mm_sound_mgr_ipc_set_active_route(mm_ipc_msg_t *msg)
729 _mm_sound_mgr_device_param_t param;
730 int ret = MM_ERROR_NONE;
734 param.pid = msg->sound_msg.msgid;
735 param.route = msg->sound_msg.route;
736 ret = _mm_sound_mgr_device_set_active_route(¶m);
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)
744 _mm_sound_mgr_device_param_t param;
745 int ret = MM_ERROR_NONE;
749 memset(¶m, 0x00, sizeof(_mm_sound_mgr_device_param_t));
750 param.pid = msg->sound_msg.msgid;
752 ret = _mm_sound_mgr_device_get_active_device(¶m, device_in, device_out);
758 static int __mm_sound_mgr_ipc_add_active_device_changed_cb(mm_ipc_msg_t *msg)
760 _mm_sound_mgr_device_param_t param;
761 int ret = MM_ERROR_NONE;
765 memset(¶m, 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;
770 ret = _mm_sound_mgr_device_add_active_device_callback(¶m);
776 static int __mm_sound_mgr_ipc_remove_active_device_changed_cb(mm_ipc_msg_t *msg)
778 _mm_sound_mgr_device_param_t param;
779 int ret = MM_ERROR_NONE;
783 memset(¶m, 0x00, sizeof(_mm_sound_mgr_device_param_t));
784 param.pid = msg->sound_msg.msgid;
786 ret = _mm_sound_mgr_device_remove_active_device_callback(¶m);
792 static int __mm_sound_mgr_ipc_add_available_device_changed_cb(mm_ipc_msg_t *msg)
794 _mm_sound_mgr_device_param_t param;
795 int ret = MM_ERROR_NONE;
799 memset(¶m, 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;
804 ret = _mm_sound_mgr_device_add_available_route_callback(¶m);
810 static int __mm_sound_mgr_ipc_remove_available_device_changed_cb(mm_ipc_msg_t *msg)
812 _mm_sound_mgr_device_param_t param;
813 int ret = MM_ERROR_NONE;
817 memset(¶m, 0x00, sizeof(_mm_sound_mgr_device_param_t));
818 param.pid = msg->sound_msg.msgid;
820 ret = _mm_sound_mgr_device_remove_available_route_callback(¶m);
826 static int _MMIpcRecvMsg(int msgtype, mm_ipc_msg_t *msg)
829 if(msgrcv(g_rcvid, msg, DSIZE, 0, 0) == -1)
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");
845 debug_warning("Fail to recive msg queue : [%d] \n", g_rcvid);
846 return MM_ERROR_COMMON_UNKNOWN;
848 return MM_ERROR_NONE;
851 int _MMIpcSndMsg(mm_ipc_msg_t *msg)
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);
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");
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;
879 return MM_ERROR_NONE;
882 int _MMIpcCBSndMsg(mm_ipc_msg_t *msg)
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)
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");
900 debug_critical("Fail to callback send message msg queue : [%d] \n", g_cbid);
901 return MM_ERROR_SOUND_INTERNAL;
903 return MM_ERROR_NONE;