1 /* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 2 * Use of this source code is governed by a BSD-style license that can be 3 * found in the LICENSE file. 4 */ 5 6 #define _GNU_SOURCE /* Needed for Linux socket credential passing. */ 7 8 #ifdef CRAS_DBUS 9 #include <dbus/dbus.h> 10 #endif 11 #include <errno.h> 12 #include <poll.h> 13 #include <stdint.h> 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <string.h> 17 #include <sys/param.h> 18 #include <sys/select.h> 19 #include <sys/socket.h> 20 #include <sys/stat.h> 21 #include <sys/types.h> 22 #include <sys/un.h> 23 #include <syslog.h> 24 #include <unistd.h> 25 26 #ifdef CRAS_DBUS 27 #include "cras_a2dp_endpoint.h" 28 #include "cras_bt_manager.h" 29 #include "cras_bt_device.h" 30 #include "cras_bt_player.h" 31 #include "cras_dbus.h" 32 #include "cras_dbus_control.h" 33 #include "cras_hfp_ag_profile.h" 34 #include "cras_telephony.h" 35 #endif 36 #include "cras_alert.h" 37 #include "cras_config.h" 38 #include "cras_device_monitor.h" 39 #include "cras_iodev_list.h" 40 #include "cras_main_message.h" 41 #include "cras_messages.h" 42 #include "cras_metrics.h" 43 #include "cras_observer.h" 44 #include "cras_rclient.h" 45 #include "cras_server.h" 46 #include "cras_server_metrics.h" 47 #include "cras_system_state.h" 48 #include "cras_tm.h" 49 #include "cras_udev.h" 50 #include "cras_util.h" 51 #include "cras_mix.h" 52 #include "utlist.h" 53 54 /* Store a list of clients that are attached to the server. 55 * Members: 56 * id - Unique identifier for this client. 57 * fd - socket file descriptor used to communicate with client. 58 * ucred - Process, user, and group ID of the client. 59 * client - rclient to handle messages from this client. 60 * pollfd - Pointer to struct pollfd for this callback. 61 */ 62 struct attached_client { 63 size_t id; 64 int fd; 65 struct ucred ucred; 66 struct cras_rclient *client; 67 struct pollfd *pollfd; 68 struct attached_client *next, *prev; 69 }; 70 71 /* Stores file descriptors to callback mappings for clients. Callback/fd/data 72 * args are registered by clients. When fd is ready, the callback will be 73 * called on the main server thread and the callback data will be passed back to 74 * it. This allows the use of the main server loop instead of spawning a thread 75 * to watch file descriptors. The client can then read or write the fd. 76 * Members: 77 * fd - The file descriptor passed to select. 78 * callack - The funciton to call when fd is ready. 79 * callback_data - Pointer passed to the callback. 80 * pollfd - Pointer to struct pollfd for this callback. 81 */ 82 struct client_callback { 83 int select_fd; 84 void (*callback)(void *); 85 void *callback_data; 86 struct pollfd *pollfd; 87 int deleted; 88 struct client_callback *prev, *next; 89 }; 90 91 /* Local server data. */ 92 struct server_data { 93 struct attached_client *clients_head; 94 size_t num_clients; 95 struct client_callback *client_callbacks; 96 size_t num_client_callbacks; 97 size_t next_client_id; 98 } server_instance; 99 100 /* Remove a client from the list and destroy it. Calling rclient_destroy will 101 * also free all the streams owned by the client */ 102 static void remove_client(struct attached_client *client) 103 { 104 close(client->fd); 105 DL_DELETE(server_instance.clients_head, client); 106 server_instance.num_clients--; 107 cras_rclient_destroy(client->client); 108 free(client); 109 } 110 111 /* This is called when "select" indicates that the client has written data to 112 * the socket. Read out one message and pass it to the client message handler. 113 */ 114 static void handle_message_from_client(struct attached_client *client) 115 { 116 uint8_t buf[CRAS_SERV_MAX_MSG_SIZE]; 117 struct cras_server_message *msg; 118 int nread; 119 int fd; 120 unsigned int num_fds = 1; 121 122 msg = (struct cras_server_message *)buf; 123 nread = cras_recv_with_fds(client->fd, buf, sizeof(buf), &fd, &num_fds); 124 if (nread < sizeof(msg->length)) 125 goto read_error; 126 if (msg->length != nread) 127 goto read_error; 128 cras_rclient_message_from_client(client->client, msg, fd); 129 return; 130 131 read_error: 132 if (fd != -1) 133 close(fd); 134 switch (nread) { 135 case 0: 136 break; 137 default: 138 syslog(LOG_DEBUG, "read err [%d] '%s', removing client %zu", 139 -nread, strerror(-nread), client->id); 140 break; 141 } 142 remove_client(client); 143 } 144 145 /* Discovers and fills in info about the client that can be obtained from the 146 * socket. The pid of the attaching client identifies it in logs. */ 147 static void fill_client_info(struct attached_client *client) 148 { 149 socklen_t ucred_length = sizeof(client->ucred); 150 151 if (getsockopt(client->fd, SOL_SOCKET, SO_PEERCRED, 152 &client->ucred, &ucred_length)) 153 syslog(LOG_INFO, "Failed to get client socket info\n"); 154 } 155 156 /* Fills the server_state with the current list of attached clients. */ 157 static void send_client_list_to_clients(struct server_data *serv) 158 { 159 struct attached_client *c; 160 struct cras_attached_client_info *info; 161 struct cras_server_state *state; 162 unsigned i; 163 164 state = cras_system_state_update_begin(); 165 if (!state) 166 return; 167 168 state->num_attached_clients = 169 MIN(CRAS_MAX_ATTACHED_CLIENTS, serv->num_clients); 170 171 info = state->client_info; 172 i = 0; 173 DL_FOREACH(serv->clients_head, c) { 174 info->id = c->id; 175 info->pid = c->ucred.pid; 176 info->uid = c->ucred.uid; 177 info->gid = c->ucred.gid; 178 info++; 179 if (++i == CRAS_MAX_ATTACHED_CLIENTS) 180 break; 181 } 182 183 cras_system_state_update_complete(); 184 } 185 186 /* Handles requests from a client to attach to the server. Create a local 187 * structure to track the client, assign it a unique id and let it attach */ 188 static void handle_new_connection(struct sockaddr_un *address, int fd) 189 { 190 int connection_fd; 191 struct attached_client *poll_client; 192 socklen_t address_length; 193 194 poll_client = malloc(sizeof(struct attached_client)); 195 if (poll_client == NULL) { 196 syslog(LOG_ERR, "Allocating poll_client"); 197 return; 198 } 199 200 memset(&address_length, 0, sizeof(address_length)); 201 connection_fd = accept(fd, (struct sockaddr *) address, 202 &address_length); 203 if (connection_fd < 0) { 204 syslog(LOG_ERR, "connecting"); 205 free(poll_client); 206 return; 207 } 208 209 /* find next available client id */ 210 while (1) { 211 struct attached_client *out; 212 DL_SEARCH_SCALAR(server_instance.clients_head, out, id, 213 server_instance.next_client_id); 214 poll_client->id = server_instance.next_client_id; 215 server_instance.next_client_id++; 216 if (out == NULL) 217 break; 218 } 219 220 /* When full, getting an error is preferable to blocking. */ 221 cras_make_fd_nonblocking(connection_fd); 222 223 poll_client->fd = connection_fd; 224 poll_client->next = NULL; 225 poll_client->pollfd = NULL; 226 fill_client_info(poll_client); 227 poll_client->client = cras_rclient_create(connection_fd, 228 poll_client->id); 229 if (poll_client->client == NULL) { 230 syslog(LOG_ERR, "failed to create client"); 231 close(connection_fd); 232 free(poll_client); 233 return; 234 } 235 236 DL_APPEND(server_instance.clients_head, poll_client); 237 server_instance.num_clients++; 238 /* Send a current list of available inputs and outputs. */ 239 cras_iodev_list_update_device_list(); 240 send_client_list_to_clients(&server_instance); 241 } 242 243 /* Add a file descriptor to be passed to select in the main loop. This is 244 * registered with system state so that it is called when any client asks to 245 * have a callback triggered based on an fd being readable. */ 246 static int add_select_fd(int fd, void (*cb)(void *data), 247 void *callback_data, void *server_data) 248 { 249 struct client_callback *new_cb; 250 struct client_callback *client_cb; 251 struct server_data *serv; 252 253 serv = (struct server_data *)server_data; 254 if (serv == NULL) 255 return -EINVAL; 256 257 /* Check if fd already exists. */ 258 DL_FOREACH(serv->client_callbacks, client_cb) 259 if (client_cb->select_fd == fd && !client_cb->deleted) 260 return -EEXIST; 261 262 new_cb = (struct client_callback *)calloc(1, sizeof(*new_cb)); 263 if (new_cb == NULL) 264 return -ENOMEM; 265 266 new_cb->select_fd = fd; 267 new_cb->callback = cb; 268 new_cb->callback_data = callback_data; 269 new_cb->deleted = 0; 270 new_cb->pollfd = NULL; 271 272 DL_APPEND(serv->client_callbacks, new_cb); 273 server_instance.num_client_callbacks++; 274 return 0; 275 } 276 277 /* Removes a file descriptor to be passed to select in the main loop. This is 278 * registered with system state so that it is called when any client asks to 279 * remove a callback added with add_select_fd. */ 280 static void rm_select_fd(int fd, void *server_data) 281 { 282 struct server_data *serv; 283 struct client_callback *client_cb; 284 285 serv = (struct server_data *)server_data; 286 if (serv == NULL) 287 return; 288 289 DL_FOREACH(serv->client_callbacks, client_cb) 290 if (client_cb->select_fd == fd) 291 client_cb->deleted = 1; 292 } 293 294 /* Cleans up the file descriptor list removing items deleted during the main 295 * loop iteration. */ 296 static void cleanup_select_fds(void *server_data) 297 { 298 struct server_data *serv; 299 struct client_callback *client_cb; 300 301 serv = (struct server_data *)server_data; 302 if (serv == NULL) 303 return; 304 305 DL_FOREACH(serv->client_callbacks, client_cb) 306 if (client_cb->deleted) { 307 DL_DELETE(serv->client_callbacks, client_cb); 308 server_instance.num_client_callbacks--; 309 free(client_cb); 310 } 311 } 312 313 /* Checks that at least two outputs are present (one will be the "empty" 314 * default device. */ 315 void check_output_exists(struct cras_timer *t, void *data) 316 { 317 if (cras_iodev_list_get_outputs(NULL) < 2) 318 cras_metrics_log_event(kNoCodecsFoundMetric); 319 } 320 321 #if defined(__amd64__) 322 /* CPU detection - probaby best to move this elsewhere */ 323 static void cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, 324 unsigned int *edx, unsigned int op) 325 { 326 __asm__ __volatile__ ( 327 "cpuid" 328 : "=a" (*eax), 329 "=b" (*ebx), 330 "=c" (*ecx), 331 "=d" (*edx) 332 : "a" (op), "c" (0) 333 ); 334 } 335 336 static unsigned int cpu_x86_flags(void) 337 { 338 unsigned int eax, ebx, ecx, edx, id; 339 unsigned int cpu_flags = 0; 340 341 cpuid(&id, &ebx, &ecx, &edx, 0); 342 343 if (id >= 1) { 344 cpuid(&eax, &ebx, &ecx, &edx, 1); 345 346 if (ecx & (1 << 20)) 347 cpu_flags |= CPU_X86_SSE4_2; 348 349 if (ecx & (1 << 28)) 350 cpu_flags |= CPU_X86_AVX; 351 352 if (ecx & (1 << 12)) 353 cpu_flags |= CPU_X86_FMA; 354 } 355 356 if (id >= 7) { 357 cpuid(&eax, &ebx, &ecx, &edx, 7); 358 359 if (ebx & (1 << 5)) 360 cpu_flags |= CPU_X86_AVX2; 361 } 362 363 return cpu_flags; 364 } 365 #endif 366 367 int cpu_get_flags(void) 368 { 369 #if defined(__amd64__) 370 return cpu_x86_flags(); 371 #endif 372 return 0; 373 } 374 375 /* 376 * Exported Interface. 377 */ 378 379 int cras_server_init() 380 { 381 /* Log to syslog. */ 382 openlog("cras_server", LOG_PID, LOG_USER); 383 384 /* Initialize global observer. */ 385 cras_observer_server_init(); 386 387 /* init mixer with CPU capabilities */ 388 cras_mix_init(cpu_get_flags()); 389 390 /* Allow clients to register callbacks for file descriptors. 391 * add_select_fd and rm_select_fd will add and remove file descriptors 392 * from the list that are passed to select in the main loop below. */ 393 cras_system_set_select_handler(add_select_fd, rm_select_fd, 394 &server_instance); 395 cras_main_message_init(); 396 397 return 0; 398 } 399 400 int cras_server_run(unsigned int profile_disable_mask) 401 { 402 static const unsigned int OUTPUT_CHECK_MS = 5 * 1000; 403 #ifdef CRAS_DBUS 404 DBusConnection *dbus_conn; 405 #endif 406 int socket_fd = -1; 407 int rc = 0; 408 const char *sockdir; 409 struct sockaddr_un addr; 410 struct attached_client *elm; 411 struct client_callback *client_cb; 412 struct cras_tm *tm; 413 struct timespec ts; 414 int timers_active; 415 struct pollfd *pollfds; 416 unsigned int pollfds_size = 32; 417 unsigned int num_pollfds, poll_size_needed; 418 419 pollfds = malloc(sizeof(*pollfds) * pollfds_size); 420 421 cras_udev_start_sound_subsystem_monitor(); 422 #ifdef CRAS_DBUS 423 cras_bt_device_start_monitor(); 424 #endif 425 426 cras_server_metrics_init(); 427 428 cras_device_monitor_init(); 429 430 #ifdef CRAS_DBUS 431 dbus_threads_init_default(); 432 dbus_conn = cras_dbus_connect_system_bus(); 433 if (dbus_conn) { 434 cras_bt_start(dbus_conn); 435 if (!(profile_disable_mask & CRAS_SERVER_PROFILE_MASK_HFP)) 436 cras_hfp_ag_profile_create(dbus_conn); 437 if (!(profile_disable_mask & CRAS_SERVER_PROFILE_MASK_HSP)) 438 cras_hsp_ag_profile_create(dbus_conn); 439 cras_telephony_start(dbus_conn); 440 if (!(profile_disable_mask & CRAS_SERVER_PROFILE_MASK_A2DP)) 441 cras_a2dp_endpoint_create(dbus_conn); 442 cras_bt_player_create(dbus_conn); 443 cras_dbus_control_start(dbus_conn); 444 } 445 #endif 446 447 socket_fd = socket(PF_UNIX, SOCK_SEQPACKET, 0); 448 if (socket_fd < 0) { 449 syslog(LOG_ERR, "Main server socket failed."); 450 rc = socket_fd; 451 goto bail; 452 } 453 454 sockdir = cras_config_get_system_socket_file_dir(); 455 if (sockdir == NULL) { 456 rc = -ENOTDIR; 457 goto bail; 458 } 459 460 memset(&addr, 0, sizeof(addr)); 461 addr.sun_family = AF_UNIX; 462 snprintf(addr.sun_path, sizeof(addr.sun_path), 463 "%s/%s", sockdir, CRAS_SOCKET_FILE); 464 unlink(addr.sun_path); 465 466 /* Linux quirk: calling fchmod before bind, sets the permissions of the 467 * file created by bind, leaving no window for it to be modified. Start 468 * with very restricted permissions. */ 469 rc = fchmod(socket_fd, 0700); 470 if (rc < 0) 471 goto bail; 472 473 if (bind(socket_fd, (struct sockaddr *) &addr, 474 sizeof(struct sockaddr_un)) != 0) { 475 syslog(LOG_ERR, "Bind to server socket failed."); 476 rc = errno; 477 goto bail; 478 } 479 480 /* Let other members in our group play audio through this socket. */ 481 rc = chmod(addr.sun_path, 0770); 482 if (rc < 0) 483 goto bail; 484 485 if (listen(socket_fd, 5) != 0) { 486 syslog(LOG_ERR, "Listen on server socket failed."); 487 rc = errno; 488 goto bail; 489 } 490 491 tm = cras_system_state_get_tm(); 492 if (!tm) { 493 syslog(LOG_ERR, "Getting timer manager."); 494 rc = -ENOMEM; 495 goto bail; 496 } 497 498 /* After a delay, make sure there is at least one real output device. */ 499 cras_tm_create_timer(tm, OUTPUT_CHECK_MS, check_output_exists, 0); 500 501 /* Main server loop - client callbacks are run from this context. */ 502 while (1) { 503 poll_size_needed = 1 + server_instance.num_clients + 504 server_instance.num_client_callbacks; 505 if (poll_size_needed > pollfds_size) { 506 pollfds_size = 2 * poll_size_needed; 507 pollfds = realloc(pollfds, 508 sizeof(*pollfds) * pollfds_size); 509 } 510 511 pollfds[0].fd = socket_fd; 512 pollfds[0].events = POLLIN; 513 num_pollfds = 1; 514 515 DL_FOREACH(server_instance.clients_head, elm) { 516 pollfds[num_pollfds].fd = elm->fd; 517 pollfds[num_pollfds].events = POLLIN; 518 elm->pollfd = &pollfds[num_pollfds]; 519 num_pollfds++; 520 } 521 DL_FOREACH(server_instance.client_callbacks, client_cb) { 522 if (client_cb->deleted) 523 continue; 524 pollfds[num_pollfds].fd = client_cb->select_fd; 525 pollfds[num_pollfds].events = POLLIN; 526 client_cb->pollfd = &pollfds[num_pollfds]; 527 num_pollfds++; 528 } 529 530 timers_active = cras_tm_get_next_timeout(tm, &ts); 531 532 rc = ppoll(pollfds, num_pollfds, 533 timers_active ? &ts : NULL, NULL); 534 if (rc < 0) 535 continue; 536 537 cras_tm_call_callbacks(tm); 538 539 /* Check for new connections. */ 540 if (pollfds[0].revents & POLLIN) 541 handle_new_connection(&addr, socket_fd); 542 /* Check if there are messages pending for any clients. */ 543 DL_FOREACH(server_instance.clients_head, elm) 544 if (elm->pollfd && elm->pollfd->revents & POLLIN) 545 handle_message_from_client(elm); 546 /* Check any client-registered fd/callback pairs. */ 547 DL_FOREACH(server_instance.client_callbacks, client_cb) 548 if (!client_cb->deleted && 549 client_cb->pollfd && 550 (client_cb->pollfd->revents & POLLIN)) 551 client_cb->callback(client_cb->callback_data); 552 553 cleanup_select_fds(&server_instance); 554 555 #ifdef CRAS_DBUS 556 if (dbus_conn) 557 cras_dbus_dispatch(dbus_conn); 558 #endif 559 560 cras_alert_process_all_pending_alerts(); 561 } 562 563 bail: 564 if (socket_fd >= 0) { 565 close(socket_fd); 566 unlink(addr.sun_path); 567 } 568 free(pollfds); 569 cras_observer_server_free(); 570 return rc; 571 } 572 573 void cras_server_send_to_all_clients(const struct cras_client_message *msg) 574 { 575 struct attached_client *client; 576 577 DL_FOREACH(server_instance.clients_head, client) 578 cras_rclient_send_message(client->client, msg, NULL, 0); 579 } 580