4 * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Sangchul Lee <sc11.lee@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.
25 #include <sys/socket.h>
27 #include "include/mm_sound.h"
28 #include "include/mm_sound_common.h"
29 #include "include/mm_sound_focus_socket.h"
31 #define FILL_SOCKET_PARAM(x_param, x_func_name, x_instance, x_id, x_focus_type, x_option, x_ext_info, x_is_in_thread, x_is_for_session) \
33 MMSOUND_STRNCPY(x_param.func_name, x_func_name, MM_SOUND_NAME_NUM); \
34 x_param.pid = x_instance; \
35 x_param.handle_id = x_id; \
36 x_param.focus_type = x_focus_type; \
37 x_param.option = x_option; \
38 MMSOUND_STRNCPY(x_param.ext_info, x_ext_info, MM_SOUND_NAME_NUM); \
39 x_param.is_in_thread = x_is_in_thread; \
40 x_param.is_for_session = x_is_for_session; \
43 static int _convert_error_from_string(const char *error_string)
45 int ret = MM_ERROR_NONE;
47 if (error_string == NULL) {
48 debug_error("error_string is null\n");
49 return MM_ERROR_INVALID_ARGUMENT;
52 if (!strncmp(error_string, FOCUS_ERROR_NONE, MAX_ERROR_LEN))
54 else if (!strncmp(error_string, FOCUS_ERROR_INVALID_PARAMETER, MAX_ERROR_LEN))
55 ret = MM_ERROR_INVALID_ARGUMENT;
56 else if (!strncmp(error_string, FOCUS_ERROR_POLICY, MAX_ERROR_LEN))
57 ret = MM_ERROR_POLICY_BLOCKED;
58 else if (!strncmp(error_string, FOCUS_ERROR_INVALID_STATE, MAX_ERROR_LEN))
59 ret = MM_ERROR_SOUND_INVALID_STATE;
60 else if (!strncmp(error_string, FOCUS_ERROR_INTERNAL, MAX_ERROR_LEN))
61 ret = MM_ERROR_SOUND_INTERNAL;
63 ret = MM_ERROR_SOUND_INTERNAL;
65 debug_msg("error_string[%s], ret[0x%x]\n", error_string, ret);
70 static int _get_client_socket_fd(int *fd)
73 char str_error[128] = {'\0',};
76 debug_error("input param fd is null\n");
77 return MM_ERROR_INVALID_ARGUMENT;
80 socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
82 strerror_r(errno, str_error, sizeof(str_error));
83 debug_error("failed to socket(), err: %s", str_error);
84 return MM_ERROR_SOUND_INTERNAL;
87 debug_log("focus client socket fd[%d]", socket_fd);
94 static int _connect_socket_fd(int fd)
96 struct sockaddr_un addr_un;
97 char str_error[128] = {'\0',};
100 debug_error("invalid fd[%d]\n", fd);
101 return MM_ERROR_INVALID_ARGUMENT;
104 memset(&addr_un, 0, sizeof(addr_un));
105 addr_un.sun_family = AF_UNIX;
106 strncpy(addr_un.sun_path, FOCUS_SERVER_SOCK, sizeof(addr_un.sun_path));
108 if (connect(fd, (struct sockaddr *)&addr_un, sizeof(addr_un)) < 0) {
109 strerror_r(errno, str_error, sizeof(str_error));
110 debug_error("failed to connect() to %s, err: %s", addr_un.sun_path, fd, str_error);
111 return MM_ERROR_SOUND_INTERNAL;
114 debug_log("connected successfully, fd[%d]", fd);
116 return MM_ERROR_NONE;
119 static int _send_data_to_server(int fd, _mm_sound_mgr_focus_socket_param_t *data)
121 char str_error[MAX_ERROR_LEN] = {'\0',};
122 char ret_buf[MAX_ERROR_LEN] = {'\0',};
125 if (fd < 0 || data == NULL) {
126 debug_error("invalid parameter, fd[%d], data[%p]", fd, data);
127 return MM_ERROR_INVALID_ARGUMENT;
130 if (write(fd, data, sizeof(_mm_sound_mgr_focus_socket_param_t)) < 0) {
131 strerror_r(errno, str_error, sizeof(str_error));
132 debug_error("failed to write(), err: %s", str_error);
133 return MM_ERROR_SOUND_INTERNAL;
136 /* return message from server */
137 if ((rval = read(fd, ret_buf, sizeof(ret_buf))) < 0) {
138 strerror_r(errno, str_error, sizeof(str_error));
139 debug_error("failed to read(), err: %s", str_error);
140 return MM_ERROR_SOUND_INTERNAL;
143 debug_log("rval[%d], ret_buf[%s]", rval, ret_buf);
145 return _convert_error_from_string(ret_buf);
149 int mm_sound_focus_socket_acquire(int instance, int id, mm_sound_focus_type_e focus_type, int option, const char *ext_info, bool is_in_thread, bool is_for_session)
151 int ret = MM_ERROR_NONE;
153 _mm_sound_mgr_focus_socket_param_t data;
157 if (instance <= 0 || id < 0 || option < 0) {
158 debug_error("invalid parameter, instance[%d], id[%d], option[%d]", instance, id, option);
159 return MM_ERROR_INVALID_ARGUMENT;
161 if (focus_type < FOCUS_FOR_PLAYBACK || focus_type > FOCUS_FOR_BOTH) {
162 debug_error("focus type[%d] is not valid", focus_type);
163 return MM_ERROR_INVALID_ARGUMENT;
166 if ((ret = _get_client_socket_fd(&fd))) {
167 debug_error("failed to _get_client_socket_fd()\n");
168 return MM_ERROR_SOUND_INTERNAL;
170 if ((ret = _connect_socket_fd(fd))) {
171 debug_error("failed to _connect_socket_fd()\n");
173 return MM_ERROR_SOUND_INTERNAL;
176 memset(&data, 0x00, sizeof(_mm_sound_mgr_focus_socket_param_t));
177 FILL_SOCKET_PARAM(data, FOCUS_FUNC_NAME_ACQUIRE, instance, id, focus_type,
178 option, ext_info, is_in_thread, is_for_session);
180 if ((ret = _send_data_to_server(fd, &data))) {
181 debug_error("failed to _send_data_to_server(), ret[0x%x]\n", ret);
190 return MM_ERROR_NONE;
194 int mm_sound_focus_socket_release(int instance, int id, mm_sound_focus_type_e focus_type, int option, const char *ext_info, bool is_in_thread, bool is_for_session)
196 int ret = MM_ERROR_NONE;
198 _mm_sound_mgr_focus_socket_param_t data;
202 if (instance <= 0 || id < 0 || option < 0) {
203 debug_error("invalid parameter, instance[%d], id[%d], option[%d]", instance, id, option);
204 return MM_ERROR_INVALID_ARGUMENT;
206 if (focus_type < FOCUS_FOR_PLAYBACK || focus_type > FOCUS_FOR_BOTH) {
207 debug_error("focus type is not valid\n");
208 return MM_ERROR_INVALID_ARGUMENT;
211 if ((ret = _get_client_socket_fd(&fd))) {
212 debug_error("failed to _get_client_socket_fd()");
213 return MM_ERROR_SOUND_INTERNAL;
215 if ((ret = _connect_socket_fd(fd))) {
216 debug_error("failed to _connect_socket_fd()");
218 return MM_ERROR_SOUND_INTERNAL;
221 memset(&data, 0x00, sizeof(_mm_sound_mgr_focus_socket_param_t));
222 FILL_SOCKET_PARAM(data, FOCUS_FUNC_NAME_RELEASE, instance, id, focus_type,
223 option, ext_info, is_in_thread, is_for_session);
225 if ((ret = _send_data_to_server(fd, &data))) {
226 debug_error("failed to _send_data_to_server()");
228 return MM_ERROR_SOUND_INTERNAL;