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_audio_thread_monitor.h"
38 #include "cras_config.h"
39 #include "cras_device_monitor.h"
40 #include "cras_hotword_handler.h"
41 #include "cras_iodev_list.h"
42 #include "cras_main_message.h"
43 #include "cras_messages.h"
44 #include "cras_metrics.h"
45 #include "cras_non_empty_audio_handler.h"
46 #include "cras_observer.h"
47 #include "cras_rclient.h"
48 #include "cras_server.h"
49 #include "cras_server_metrics.h"
50 #include "cras_system_state.h"
51 #include "cras_tm.h"
52 #include "cras_types.h"
53 #include "cras_udev.h"
54 #include "cras_util.h"
55 #include "cras_mix.h"
56 #include "utlist.h"
57
58 /* Store a list of clients that are attached to the server.
59 * Members:
60 * id - Unique identifier for this client.
61 * fd - socket file descriptor used to communicate with client.
62 * ucred - Process, user, and group ID of the client.
63 * client - rclient to handle messages from this client.
64 * pollfd - Pointer to struct pollfd for this callback.
65 */
66 struct attached_client {
67 size_t id;
68 int fd;
69 struct ucred ucred;
70 struct cras_rclient *client;
71 struct pollfd *pollfd;
72 struct attached_client *next, *prev;
73 };
74
75 /* Stores file descriptors to callback mappings for clients. Callback/fd/data
76 * args are registered by clients. When fd is ready, the callback will be
77 * called on the main server thread and the callback data will be passed back to
78 * it. This allows the use of the main server loop instead of spawning a thread
79 * to watch file descriptors. The client can then read or write the fd.
80 * Members:
81 * fd - The file descriptor passed to select.
82 * callback - The funciton to call when fd is ready.
83 * callback_data - Pointer passed to the callback.
84 * pollfd - Pointer to struct pollfd for this callback.
85 * events - The events to poll for.
86 */
87 struct client_callback {
88 int select_fd;
89 void (*callback)(void *data, int revents);
90 void *callback_data;
91 struct pollfd *pollfd;
92 int deleted;
93 int events;
94 struct client_callback *prev, *next;
95 };
96
97 /* Stores callback function and argument data to be executed later. */
98 struct system_task {
99 void (*callback)(void *);
100 void *callback_data;
101 struct system_task *next, *prev;
102 };
103
104 /* A structure wraps data related to server socket. */
105 struct server_socket {
106 struct sockaddr_un addr;
107 int fd;
108 enum CRAS_CONNECTION_TYPE type;
109 };
110
111 /* Local server data. */
112 struct server_data {
113 struct attached_client *clients_head;
114 size_t num_clients;
115 struct client_callback *client_callbacks;
116 struct system_task *system_tasks;
117 size_t num_client_callbacks;
118 size_t next_client_id;
119 struct server_socket server_sockets[CRAS_NUM_CONN_TYPE];
120 } server_instance;
121
122 /* Cleanup a given server_socket */
server_socket_cleanup(struct server_socket * socket)123 static void server_socket_cleanup(struct server_socket *socket)
124 {
125 if (socket && socket->fd >= 0) {
126 close(socket->fd);
127 socket->fd = -1;
128 unlink(socket->addr.sun_path);
129 }
130 }
131
132 /* Remove a client from the list and destroy it. Calling rclient_destroy will
133 * also free all the streams owned by the client */
remove_client(struct attached_client * client)134 static void remove_client(struct attached_client *client)
135 {
136 close(client->fd);
137 DL_DELETE(server_instance.clients_head, client);
138 server_instance.num_clients--;
139 cras_rclient_destroy(client->client);
140 free(client);
141 }
142
143 /* This is called when "select" indicates that the client has written data to
144 * the socket. Read out one message and pass it to the client message handler.
145 */
handle_message_from_client(struct attached_client * client)146 static void handle_message_from_client(struct attached_client *client)
147 {
148 uint8_t buf[CRAS_SERV_MAX_MSG_SIZE];
149 int nread;
150 unsigned int num_fds = 2;
151 int fds[num_fds];
152
153 nread = cras_recv_with_fds(client->fd, buf, sizeof(buf), fds, &num_fds);
154 if (nread < 0)
155 goto read_error;
156 if (cras_rclient_buffer_from_client(client->client, buf, nread, fds,
157 num_fds) < 0)
158 goto read_error;
159 return;
160
161 read_error:
162 for (int i = 0; i < num_fds; i++)
163 if (fds[i] >= 0)
164 close(fds[i]);
165 switch (nread) {
166 case 0:
167 break;
168 default:
169 syslog(LOG_DEBUG, "read err [%d] '%s', removing client %zu",
170 -nread, strerror(-nread), client->id);
171 break;
172 }
173 remove_client(client);
174 }
175
176 /* Discovers and fills in info about the client that can be obtained from the
177 * socket. The pid of the attaching client identifies it in logs. */
fill_client_info(struct attached_client * client)178 static void fill_client_info(struct attached_client *client)
179 {
180 socklen_t ucred_length = sizeof(client->ucred);
181
182 if (getsockopt(client->fd, SOL_SOCKET, SO_PEERCRED, &client->ucred,
183 &ucred_length))
184 syslog(LOG_INFO, "Failed to get client socket info\n");
185 }
186
187 /* Fills the server_state with the current list of attached clients. */
send_client_list_to_clients(struct server_data * serv)188 static void send_client_list_to_clients(struct server_data *serv)
189 {
190 struct attached_client *c;
191 struct cras_attached_client_info *info;
192 struct cras_server_state *state;
193 unsigned i;
194
195 state = cras_system_state_update_begin();
196 if (!state)
197 return;
198
199 state->num_attached_clients =
200 MIN(CRAS_MAX_ATTACHED_CLIENTS, serv->num_clients);
201
202 info = state->client_info;
203 i = 0;
204 DL_FOREACH (serv->clients_head, c) {
205 info->id = c->id;
206 info->pid = c->ucred.pid;
207 info->uid = c->ucred.uid;
208 info->gid = c->ucred.gid;
209 info++;
210 if (++i == CRAS_MAX_ATTACHED_CLIENTS)
211 break;
212 }
213
214 cras_system_state_update_complete();
215 }
216
217 /* Handles requests from a client to attach to the server. Create a local
218 * structure to track the client, assign it a unique id and let it attach */
handle_new_connection(struct server_socket * server_socket)219 static void handle_new_connection(struct server_socket *server_socket)
220 {
221 int connection_fd;
222 struct attached_client *poll_client;
223 socklen_t address_length;
224
225 poll_client = malloc(sizeof(struct attached_client));
226 if (poll_client == NULL) {
227 syslog(LOG_ERR, "Allocating poll_client");
228 return;
229 }
230
231 memset(&address_length, 0, sizeof(address_length));
232 connection_fd = accept(server_socket->fd,
233 (struct sockaddr *)&server_socket->addr,
234 &address_length);
235 if (connection_fd < 0) {
236 syslog(LOG_ERR, "connecting");
237 free(poll_client);
238 return;
239 }
240
241 /* find next available client id */
242 while (1) {
243 struct attached_client *out;
244 DL_SEARCH_SCALAR(server_instance.clients_head, out, id,
245 server_instance.next_client_id);
246 poll_client->id = server_instance.next_client_id;
247 server_instance.next_client_id++;
248 if (out == NULL)
249 break;
250 }
251
252 /* When full, getting an error is preferable to blocking. */
253 cras_make_fd_nonblocking(connection_fd);
254
255 poll_client->fd = connection_fd;
256 poll_client->next = NULL;
257 poll_client->pollfd = NULL;
258 fill_client_info(poll_client);
259
260 poll_client->client = cras_rclient_create(
261 connection_fd, poll_client->id, server_socket->type);
262 if (poll_client->client == NULL) {
263 syslog(LOG_ERR, "failed to create client");
264 goto error;
265 }
266
267 DL_APPEND(server_instance.clients_head, poll_client);
268 server_instance.num_clients++;
269 /* Send a current list of available inputs and outputs. */
270 cras_iodev_list_update_device_list();
271 send_client_list_to_clients(&server_instance);
272 return;
273 error:
274 close(connection_fd);
275 free(poll_client);
276 return;
277 }
278
279 /* Add a file descriptor to be passed to select in the main loop. This is
280 * registered with system state so that it is called when any client asks to
281 * have a callback triggered based on an fd being readable. */
add_select_fd(int fd,void (* cb)(void * data,int events),void * callback_data,int events,void * server_data)282 static int add_select_fd(int fd, void (*cb)(void *data, int events),
283 void *callback_data, int events, void *server_data)
284 {
285 struct client_callback *new_cb;
286 struct client_callback *client_cb;
287 struct server_data *serv;
288
289 serv = (struct server_data *)server_data;
290 if (serv == NULL)
291 return -EINVAL;
292
293 /* Check if fd already exists. */
294 DL_FOREACH (serv->client_callbacks, client_cb)
295 if (client_cb->select_fd == fd && !client_cb->deleted)
296 return -EEXIST;
297
298 new_cb = (struct client_callback *)calloc(1, sizeof(*new_cb));
299 if (new_cb == NULL)
300 return -ENOMEM;
301
302 new_cb->select_fd = fd;
303 new_cb->callback = cb;
304 new_cb->callback_data = callback_data;
305 new_cb->deleted = 0;
306 new_cb->events = events;
307 new_cb->pollfd = NULL;
308
309 DL_APPEND(serv->client_callbacks, new_cb);
310 server_instance.num_client_callbacks++;
311 return 0;
312 }
313
314 /* Removes a file descriptor to be passed to select in the main loop. This is
315 * registered with system state so that it is called when any client asks to
316 * remove a callback added with add_select_fd. */
rm_select_fd(int fd,void * server_data)317 static void rm_select_fd(int fd, void *server_data)
318 {
319 struct server_data *serv;
320 struct client_callback *client_cb;
321
322 serv = (struct server_data *)server_data;
323 if (serv == NULL)
324 return;
325
326 DL_FOREACH (serv->client_callbacks, client_cb)
327 if (client_cb->select_fd == fd)
328 client_cb->deleted = 1;
329 }
330
331 /* Creates a new task entry and append to system_tasks list, which will be
332 * executed in main loop later without wait time.
333 */
add_task(void (* cb)(void * data),void * callback_data,void * server_data)334 static int add_task(void (*cb)(void *data), void *callback_data,
335 void *server_data)
336 {
337 struct server_data *serv;
338 struct system_task *new_task;
339
340 serv = (struct server_data *)server_data;
341 if (serv == NULL)
342 return -EINVAL;
343
344 new_task = (struct system_task *)calloc(1, sizeof(*new_task));
345 if (new_task == NULL)
346 return -ENOMEM;
347
348 new_task->callback = cb;
349 new_task->callback_data = callback_data;
350
351 DL_APPEND(serv->system_tasks, new_task);
352 return 0;
353 }
354
355 /* Cleans up the file descriptor list removing items deleted during the main
356 * loop iteration. */
cleanup_select_fds(void * server_data)357 static void cleanup_select_fds(void *server_data)
358 {
359 struct server_data *serv;
360 struct client_callback *client_cb;
361
362 serv = (struct server_data *)server_data;
363 if (serv == NULL)
364 return;
365
366 DL_FOREACH (serv->client_callbacks, client_cb)
367 if (client_cb->deleted) {
368 DL_DELETE(serv->client_callbacks, client_cb);
369 server_instance.num_client_callbacks--;
370 free(client_cb);
371 }
372 }
373
374 /* Checks that at least two outputs are present (one will be the "empty"
375 * default device. */
check_output_exists(struct cras_timer * t,void * data)376 void check_output_exists(struct cras_timer *t, void *data)
377 {
378 if (cras_iodev_list_get_outputs(NULL) < 2)
379 cras_metrics_log_event(kNoCodecsFoundMetric);
380 }
381
382 #if defined(__amd64__)
383 /* CPU detection - probaby best to move this elsewhere */
cpuid(unsigned int * eax,unsigned int * ebx,unsigned int * ecx,unsigned int * edx,unsigned int op)384 static void cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx,
385 unsigned int *edx, unsigned int op)
386 {
387 // clang-format off
388 __asm__ __volatile__ (
389 "cpuid"
390 : "=a" (*eax),
391 "=b" (*ebx),
392 "=c" (*ecx),
393 "=d" (*edx)
394 : "a" (op), "c" (0)
395 );
396 // clang-format on
397 }
398
cpu_x86_flags(void)399 static unsigned int cpu_x86_flags(void)
400 {
401 unsigned int eax, ebx, ecx, edx, id;
402 unsigned int cpu_flags = 0;
403
404 cpuid(&id, &ebx, &ecx, &edx, 0);
405
406 if (id >= 1) {
407 cpuid(&eax, &ebx, &ecx, &edx, 1);
408
409 if (ecx & (1 << 20))
410 cpu_flags |= CPU_X86_SSE4_2;
411
412 if (ecx & (1 << 28))
413 cpu_flags |= CPU_X86_AVX;
414
415 if (ecx & (1 << 12))
416 cpu_flags |= CPU_X86_FMA;
417 }
418
419 if (id >= 7) {
420 cpuid(&eax, &ebx, &ecx, &edx, 7);
421
422 if (ebx & (1 << 5))
423 cpu_flags |= CPU_X86_AVX2;
424 }
425
426 return cpu_flags;
427 }
428 #endif
429
cpu_get_flags(void)430 int cpu_get_flags(void)
431 {
432 #if defined(__amd64__)
433 return cpu_x86_flags();
434 #endif
435 return 0;
436 }
437
438 /*
439 * Exported Interface.
440 */
441
cras_server_init()442 int cras_server_init()
443 {
444 /* Log to syslog. */
445 openlog("cras_server", LOG_PID, LOG_USER);
446
447 server_instance.next_client_id = RESERVED_CLIENT_IDS;
448
449 /* Initialize global observer. */
450 cras_observer_server_init();
451
452 /* init mixer with CPU capabilities */
453 cras_mix_init(cpu_get_flags());
454
455 /* Allow clients to register callbacks for file descriptors.
456 * add_select_fd and rm_select_fd will add and remove file descriptors
457 * from the list that are passed to select in the main loop below. */
458 cras_system_set_select_handler(add_select_fd, rm_select_fd,
459 &server_instance);
460 cras_system_set_add_task_handler(add_task, &server_instance);
461 cras_main_message_init();
462
463 /* Initializes all server_sockets */
464 for (int conn_type = 0; conn_type < CRAS_NUM_CONN_TYPE; conn_type++) {
465 server_instance.server_sockets[conn_type].fd = -1;
466 }
467
468 return 0;
469 }
470
471 /*
472 * Creates a server socket with given connection type and listens on it.
473 * The socket_file will be created under cras_config_get_system_socket_file_dir
474 * with permission=0770. The socket_fd will be listened with parameter
475 * backlog=5.
476 *
477 * Returns 0 on success and leaves the created fd and the address information
478 * in server_socket.
479 * When error occurs, the created fd will be closed and the file path will be
480 * unlinked and returns negative error code.
481 */
create_and_listen_server_socket(enum CRAS_CONNECTION_TYPE conn_type,struct server_socket * server_socket)482 static int create_and_listen_server_socket(enum CRAS_CONNECTION_TYPE conn_type,
483 struct server_socket *server_socket)
484 {
485 int socket_fd = -1;
486 int rc = 0;
487 struct sockaddr_un *addr = &server_socket->addr;
488
489 socket_fd = socket(PF_UNIX, SOCK_SEQPACKET, 0);
490 if (socket_fd < 0) {
491 syslog(LOG_ERR, "Main server socket failed.");
492 rc = socket_fd;
493 goto error;
494 }
495
496 memset(addr, 0, sizeof(*addr));
497 addr->sun_family = AF_UNIX;
498 rc = cras_fill_socket_path(conn_type, addr->sun_path);
499 if (rc < 0)
500 goto error;
501 unlink(addr->sun_path);
502
503 /* Linux quirk: calling fchmod before bind, sets the permissions of the
504 * file created by bind, leaving no window for it to be modified. Start
505 * with very restricted permissions. */
506 rc = fchmod(socket_fd, 0700);
507 if (rc < 0)
508 goto error;
509
510 rc = bind(socket_fd, (struct sockaddr *)addr,
511 sizeof(struct sockaddr_un));
512 if (rc < 0) {
513 syslog(LOG_ERR, "Bind to server socket failed.");
514 rc = -errno;
515 goto error;
516 }
517
518 /* Let other members in our group play audio through this socket. */
519 rc = chmod(addr->sun_path, 0770);
520 if (rc < 0)
521 goto error;
522
523 if (listen(socket_fd, 5) != 0) {
524 syslog(LOG_ERR, "Listen on server socket failed.");
525 rc = -errno;
526 goto error;
527 }
528
529 server_socket->fd = socket_fd;
530 server_socket->type = conn_type;
531 return 0;
532 error:
533 if (socket_fd >= 0) {
534 close(socket_fd);
535 unlink(addr->sun_path);
536 }
537 return rc;
538 }
539
540 /* Cleans up all server_socket in server_instance */
cleanup_server_sockets()541 static void cleanup_server_sockets()
542 {
543 for (int conn_type = 0; conn_type < CRAS_NUM_CONN_TYPE; conn_type++) {
544 server_socket_cleanup(
545 &server_instance.server_sockets[conn_type]);
546 }
547 }
548
cras_server_run(unsigned int profile_disable_mask)549 int cras_server_run(unsigned int profile_disable_mask)
550 {
551 static const unsigned int OUTPUT_CHECK_MS = 5 * 1000;
552 #ifdef CRAS_DBUS
553 DBusConnection *dbus_conn;
554 #endif
555 int rc = 0;
556 struct attached_client *elm;
557 struct client_callback *client_cb;
558 struct system_task *tasks;
559 struct system_task *system_task;
560 struct cras_tm *tm;
561 struct timespec ts, *poll_timeout;
562 int timers_active;
563 struct pollfd *pollfds;
564 unsigned int pollfds_size = 32;
565 unsigned int num_pollfds, poll_size_needed;
566
567 pollfds = malloc(sizeof(*pollfds) * pollfds_size);
568
569 cras_udev_start_sound_subsystem_monitor();
570 #ifdef CRAS_DBUS
571 cras_bt_device_start_monitor();
572 #endif
573
574 cras_server_metrics_init();
575
576 cras_device_monitor_init();
577
578 cras_hotword_handler_init();
579
580 cras_non_empty_audio_handler_init();
581
582 cras_audio_thread_monitor_init();
583
584 #ifdef CRAS_DBUS
585 dbus_threads_init_default();
586 dbus_conn = cras_dbus_connect_system_bus();
587 if (dbus_conn) {
588 cras_bt_start(dbus_conn);
589 if (!(profile_disable_mask & CRAS_SERVER_PROFILE_MASK_HFP))
590 cras_hfp_ag_profile_create(dbus_conn);
591 if (!(profile_disable_mask & CRAS_SERVER_PROFILE_MASK_HSP))
592 cras_hsp_ag_profile_create(dbus_conn);
593 cras_telephony_start(dbus_conn);
594 if (!(profile_disable_mask & CRAS_SERVER_PROFILE_MASK_A2DP))
595 cras_a2dp_endpoint_create(dbus_conn);
596 cras_bt_player_create(dbus_conn);
597 cras_dbus_control_start(dbus_conn);
598 }
599 #endif
600
601 for (int conn_type = 0; conn_type < CRAS_NUM_CONN_TYPE; conn_type++) {
602 rc = create_and_listen_server_socket(
603 conn_type, &server_instance.server_sockets[conn_type]);
604 if (rc < 0)
605 goto bail;
606 }
607
608 tm = cras_system_state_get_tm();
609 if (!tm) {
610 syslog(LOG_ERR, "Getting timer manager.");
611 rc = -ENOMEM;
612 goto bail;
613 }
614
615 /* After a delay, make sure there is at least one real output device. */
616 cras_tm_create_timer(tm, OUTPUT_CHECK_MS, check_output_exists, 0);
617
618 /* Main server loop - client callbacks are run from this context. */
619 while (1) {
620 poll_size_needed = CRAS_NUM_CONN_TYPE +
621 server_instance.num_clients +
622 server_instance.num_client_callbacks;
623 if (poll_size_needed > pollfds_size) {
624 pollfds_size = 2 * poll_size_needed;
625 pollfds = realloc(pollfds,
626 sizeof(*pollfds) * pollfds_size);
627 }
628
629 for (int conn_type = 0; conn_type < CRAS_NUM_CONN_TYPE;
630 conn_type++) {
631 pollfds[conn_type].fd =
632 server_instance.server_sockets[conn_type].fd;
633 pollfds[conn_type].events = POLLIN;
634 }
635 num_pollfds = CRAS_NUM_CONN_TYPE;
636
637 DL_FOREACH (server_instance.clients_head, elm) {
638 pollfds[num_pollfds].fd = elm->fd;
639 pollfds[num_pollfds].events = POLLIN;
640 elm->pollfd = &pollfds[num_pollfds];
641 num_pollfds++;
642 }
643 DL_FOREACH (server_instance.client_callbacks, client_cb) {
644 if (client_cb->deleted)
645 continue;
646 pollfds[num_pollfds].fd = client_cb->select_fd;
647 pollfds[num_pollfds].events = client_cb->events;
648 client_cb->pollfd = &pollfds[num_pollfds];
649 num_pollfds++;
650 }
651
652 tasks = server_instance.system_tasks;
653 server_instance.system_tasks = NULL;
654 DL_FOREACH (tasks, system_task) {
655 system_task->callback(system_task->callback_data);
656 DL_DELETE(tasks, system_task);
657 free(system_task);
658 }
659
660 timers_active = cras_tm_get_next_timeout(tm, &ts);
661
662 /*
663 * If new client task has been scheduled, no need to wait
664 * for timeout, just do another loop to execute them.
665 */
666 if (server_instance.system_tasks)
667 poll_timeout = NULL;
668 else
669 poll_timeout = timers_active ? &ts : NULL;
670
671 rc = ppoll(pollfds, num_pollfds, poll_timeout, NULL);
672 if (rc < 0)
673 continue;
674
675 cras_tm_call_callbacks(tm);
676
677 /* Check for new connections. */
678 for (int conn_type = 0; conn_type < CRAS_NUM_CONN_TYPE;
679 conn_type++) {
680 if (pollfds[conn_type].revents & POLLIN)
681 handle_new_connection(
682 &server_instance
683 .server_sockets[conn_type]);
684 }
685
686 /* Check if there are messages pending for any clients. */
687 DL_FOREACH (server_instance.clients_head, elm)
688 if (elm->pollfd && elm->pollfd->revents & POLLIN)
689 handle_message_from_client(elm);
690 /* Check any client-registered fd/callback pairs. */
691 DL_FOREACH (server_instance.client_callbacks, client_cb)
692 if (!client_cb->deleted && client_cb->pollfd &&
693 (client_cb->pollfd->revents & client_cb->events))
694 client_cb->callback(client_cb->callback_data,
695 client_cb->pollfd->revents);
696
697 cleanup_select_fds(&server_instance);
698
699 #ifdef CRAS_DBUS
700 if (dbus_conn)
701 cras_dbus_dispatch(dbus_conn);
702 #endif
703
704 cras_alert_process_all_pending_alerts();
705 }
706
707 bail:
708 cleanup_server_sockets();
709 free(pollfds);
710 cras_observer_server_free();
711 return rc;
712 }
713
cras_server_send_to_all_clients(const struct cras_client_message * msg)714 void cras_server_send_to_all_clients(const struct cras_client_message *msg)
715 {
716 struct attached_client *client;
717
718 DL_FOREACH (server_instance.clients_head, client)
719 cras_rclient_send_message(client->client, msg, NULL, 0);
720 }
721