1 /* Spa SCO Sink
2  *
3  * Copyright © 2019 Collabora Ltd.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24 
25 #include <unistd.h>
26 #include <stddef.h>
27 #include <stdio.h>
28 #include <arpa/inet.h>
29 #include <sys/ioctl.h>
30 
31 #include <spa/support/plugin.h>
32 #include <spa/support/loop.h>
33 #include <spa/support/log.h>
34 #include <spa/support/system.h>
35 #include <spa/utils/result.h>
36 #include <spa/utils/list.h>
37 #include <spa/utils/keys.h>
38 #include <spa/utils/names.h>
39 #include <spa/utils/string.h>
40 #include <spa/monitor/device.h>
41 
42 #include <spa/node/node.h>
43 #include <spa/node/utils.h>
44 #include <spa/node/io.h>
45 #include <spa/node/keys.h>
46 #include <spa/param/param.h>
47 #include <spa/param/latency-utils.h>
48 #include <spa/param/audio/format.h>
49 #include <spa/param/audio/format-utils.h>
50 #include <spa/pod/filter.h>
51 
52 #include <sbc/sbc.h>
53 
54 #include "defs.h"
55 
56 static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.sink.sco");
57 #undef SPA_LOG_TOPIC_DEFAULT
58 #define SPA_LOG_TOPIC_DEFAULT &log_topic
59 
60 #define DEFAULT_CLOCK_NAME	"clock.system.monotonic"
61 
62 struct props {
63 	uint32_t min_latency;
64 	uint32_t max_latency;
65 	char clock_name[64];
66 };
67 
68 #define MAX_BUFFERS 32
69 
70 struct buffer {
71 	uint32_t id;
72 	unsigned int outstanding:1;
73 	struct spa_buffer *buf;
74 	struct spa_meta_header *h;
75 	struct spa_list link;
76 };
77 
78 struct port {
79 	struct spa_audio_info current_format;
80 	int frame_size;
81 	unsigned int have_format:1;
82 
83 	uint64_t info_all;
84 	struct spa_port_info info;
85 	struct spa_io_buffers *io;
86 	struct spa_io_rate_match *rate_match;
87 	struct spa_latency_info latency;
88 #define IDX_EnumFormat	0
89 #define IDX_Meta	1
90 #define IDX_IO		2
91 #define IDX_Format	3
92 #define IDX_Buffers	4
93 #define IDX_Latency	5
94 #define N_PORT_PARAMS	6
95 	struct spa_param_info params[N_PORT_PARAMS];
96 
97 	struct buffer buffers[MAX_BUFFERS];
98 	uint32_t n_buffers;
99 
100 	struct spa_list free;
101 	struct spa_list ready;
102 
103 	struct buffer *current_buffer;
104 	uint32_t ready_offset;
105 	uint8_t write_buffer[4096];
106 	uint32_t write_buffer_size;
107 };
108 
109 struct impl {
110 	struct spa_handle handle;
111 	struct spa_node node;
112 
113 	/* Support */
114 	struct spa_log *log;
115 	struct spa_loop *data_loop;
116 	struct spa_system *data_system;
117 
118 	/* Hooks and callbacks */
119 	struct spa_hook_list hooks;
120 	struct spa_callbacks callbacks;
121 
122 	/* Info */
123 	uint64_t info_all;
124 	struct spa_node_info info;
125 #define IDX_PropInfo	0
126 #define IDX_Props	1
127 #define N_NODE_PARAMS	2
128 	struct spa_param_info params[N_NODE_PARAMS];
129 	struct props props;
130 
131 	/* Transport */
132 	struct spa_bt_transport *transport;
133 	struct spa_hook transport_listener;
134 
135 	/* Port */
136 	struct port port;
137 
138 	/* Flags */
139 	unsigned int started:1;
140 	unsigned int following:1;
141 
142 	/* Sources */
143 	struct spa_source source;
144 
145 	/* Timer */
146 	int timerfd;
147 	struct timespec now;
148 	struct spa_io_clock *clock;
149 	struct spa_io_position *position;
150 
151 	/* mSBC */
152 	sbc_t msbc;
153 	uint8_t *buffer;
154 	uint8_t *buffer_head;
155 	uint8_t *buffer_next;
156 	int buffer_size;
157 
158 	/* Times */
159 	uint64_t start_time;
160 	uint64_t total_samples;
161 };
162 
163 #define CHECK_PORT(this,d,p)	((d) == SPA_DIRECTION_INPUT && (p) == 0)
164 
165 static const uint32_t default_min_latency = MIN_LATENCY;
166 static const uint32_t default_max_latency = MAX_LATENCY;
167 static const char sntable[4] = { 0x08, 0x38, 0xC8, 0xF8 };
168 
reset_props(struct props * props)169 static void reset_props(struct props *props)
170 {
171 	props->min_latency = default_min_latency;
172 	props->max_latency = default_max_latency;
173 	strncpy(props->clock_name, DEFAULT_CLOCK_NAME, sizeof(props->clock_name));
174 }
175 
impl_node_enum_params(void * object,int seq,uint32_t id,uint32_t start,uint32_t num,const struct spa_pod * filter)176 static int impl_node_enum_params(void *object, int seq,
177 			uint32_t id, uint32_t start, uint32_t num,
178 			const struct spa_pod *filter)
179 {
180 	struct impl *this = object;
181 	struct spa_pod *param;
182 	struct spa_pod_builder b = { 0 };
183 	uint8_t buffer[1024];
184 	struct spa_result_node_params result;
185 	uint32_t count = 0;
186 
187 	spa_return_val_if_fail(this != NULL, -EINVAL);
188 	spa_return_val_if_fail(num != 0, -EINVAL);
189 
190 	result.id = id;
191 	result.next = start;
192       next:
193 	result.index = result.next++;
194 
195 	spa_pod_builder_init(&b, buffer, sizeof(buffer));
196 
197 	switch (id) {
198 	case SPA_PARAM_PropInfo:
199 	{
200 		struct props *p = &this->props;
201 
202 		switch (result.index) {
203 		case 0:
204 			param = spa_pod_builder_add_object(&b,
205 				SPA_TYPE_OBJECT_PropInfo, id,
206 				SPA_PROP_INFO_id,   SPA_POD_Id(SPA_PROP_minLatency),
207 				SPA_PROP_INFO_name, SPA_POD_String("The minimum latency"),
208 				SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(p->min_latency, 1, INT32_MAX));
209 			break;
210 		case 1:
211 			param = spa_pod_builder_add_object(&b,
212 				SPA_TYPE_OBJECT_PropInfo, id,
213 				SPA_PROP_INFO_id,   SPA_POD_Id(SPA_PROP_maxLatency),
214 				SPA_PROP_INFO_name, SPA_POD_String("The maximum latency"),
215 				SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(p->max_latency, 1, INT32_MAX));
216 			break;
217 		default:
218 			return 0;
219 		}
220 		break;
221 	}
222 	case SPA_PARAM_Props:
223 	{
224 		struct props *p = &this->props;
225 
226 		switch (result.index) {
227 		case 0:
228 			param = spa_pod_builder_add_object(&b,
229 				SPA_TYPE_OBJECT_Props, id,
230 				SPA_PROP_minLatency, SPA_POD_Int(p->min_latency),
231 				SPA_PROP_maxLatency, SPA_POD_Int(p->max_latency));
232 			break;
233 		default:
234 			return 0;
235 		}
236 		break;
237 	}
238 	default:
239 		return -ENOENT;
240 	}
241 
242 	if (spa_pod_filter(&b, &result.param, param, filter) < 0)
243 		goto next;
244 
245 	spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result);
246 
247 	if (++count != num)
248 		goto next;
249 
250 	return 0;
251 }
252 
set_timeout(struct impl * this,uint64_t time)253 static int set_timeout(struct impl *this, uint64_t time)
254 {
255 	struct itimerspec ts;
256 	ts.it_value.tv_sec = time / SPA_NSEC_PER_SEC;
257 	ts.it_value.tv_nsec = time % SPA_NSEC_PER_SEC;
258 	ts.it_interval.tv_sec = 0;
259 	ts.it_interval.tv_nsec = 0;
260 	return spa_system_timerfd_settime(this->data_system,
261 			this->timerfd, 0, &ts, NULL);
262 }
263 
set_timers(struct impl * this)264 static int set_timers(struct impl *this)
265 {
266 	return set_timeout(this, this->following ? 0 : 1);
267 }
268 
get_next_timeout(struct impl * this,uint64_t now_time,uint64_t processed_samples)269 static uint64_t get_next_timeout(struct impl *this, uint64_t now_time, uint64_t processed_samples)
270 {
271 	struct port *port = &this->port;
272 	uint64_t playback_time = 0, elapsed_time = 0, next_time = 1;
273 
274 	this->total_samples += processed_samples;
275 
276 	playback_time = (this->total_samples * SPA_NSEC_PER_SEC) / port->current_format.info.raw.rate;
277 	if (now_time > this->start_time)
278 		elapsed_time = now_time - this->start_time;
279 	if (elapsed_time < playback_time)
280 		next_time = playback_time - elapsed_time;
281 
282 	return next_time;
283 }
284 
do_reassign_follower(struct spa_loop * loop,bool async,uint32_t seq,const void * data,size_t size,void * user_data)285 static int do_reassign_follower(struct spa_loop *loop,
286 			bool async,
287 			uint32_t seq,
288 			const void *data,
289 			size_t size,
290 			void *user_data)
291 {
292 	struct impl *this = user_data;
293 	set_timers(this);
294 	return 0;
295 }
296 
is_following(struct impl * this)297 static inline bool is_following(struct impl *this)
298 {
299 	return this->position && this->clock && this->position->clock.id != this->clock->id;
300 }
301 
impl_node_set_io(void * object,uint32_t id,void * data,size_t size)302 static int impl_node_set_io(void *object, uint32_t id, void *data, size_t size)
303 {
304 	struct impl *this = object;
305 	bool following;
306 
307 	spa_return_val_if_fail(this != NULL, -EINVAL);
308 
309 	switch (id) {
310 	case SPA_IO_Clock:
311 		this->clock = data;
312 		if (this->clock != NULL) {
313 			spa_scnprintf(this->clock->name,
314 					sizeof(this->clock->name),
315 					"%s", this->props.clock_name);
316 		}
317 		break;
318 	case SPA_IO_Position:
319 		this->position = data;
320 		break;
321 	default:
322 		return -ENOENT;
323 	}
324 
325 	following = is_following(this);
326 	if (this->started && following != this->following) {
327 		spa_log_debug(this->log, "%p: reassign follower %d->%d", this, this->following, following);
328 		this->following = following;
329 		spa_loop_invoke(this->data_loop, do_reassign_follower, 0, NULL, 0, true, this);
330 	}
331 	return 0;
332 }
333 
334 static void emit_node_info(struct impl *this, bool full);
335 
apply_props(struct impl * this,const struct spa_pod * param)336 static int apply_props(struct impl *this, const struct spa_pod *param)
337 {
338 	struct props new_props = this->props;
339 	int changed = 0;
340 
341 	if (param == NULL) {
342 		reset_props(&new_props);
343 	} else {
344 		spa_pod_parse_object(param,
345 				SPA_TYPE_OBJECT_Props, NULL,
346 				SPA_PROP_minLatency, SPA_POD_OPT_Int(&new_props.min_latency),
347 				SPA_PROP_maxLatency, SPA_POD_OPT_Int(&new_props.max_latency));
348 	}
349 
350 	changed = (memcmp(&new_props, &this->props, sizeof(struct props)) != 0);
351 	this->props = new_props;
352 	return changed;
353 }
354 
impl_node_set_param(void * object,uint32_t id,uint32_t flags,const struct spa_pod * param)355 static int impl_node_set_param(void *object, uint32_t id, uint32_t flags,
356 			       const struct spa_pod *param)
357 {
358 	struct impl *this = object;
359 
360 	spa_return_val_if_fail(this != NULL, -EINVAL);
361 
362 	switch (id) {
363 	case SPA_PARAM_Props:
364 	{
365 		if (apply_props(this, param) > 0) {
366 			this->info.change_mask |= SPA_NODE_CHANGE_MASK_PARAMS;
367 			this->params[IDX_Props].flags ^= SPA_PARAM_INFO_SERIAL;
368 			emit_node_info(this, false);
369 		}
370 		break;
371 	}
372 	default:
373 		return -ENOENT;
374 	}
375 
376 	return 0;
377 }
378 
flush_data(struct impl * this)379 static void flush_data(struct impl *this)
380 {
381 	struct port *port = &this->port;
382 	struct spa_data *datas;
383 	uint64_t next_timeout = 1;
384 	const uint32_t min_in_size =
385 		(this->transport->codec == HFP_AUDIO_CODEC_MSBC) ?
386 		MSBC_DECODED_SIZE : this->transport->write_mtu;
387 	uint8_t * const packet =
388 		(this->transport->codec == HFP_AUDIO_CODEC_MSBC) ?
389 		this->buffer_head : port->write_buffer;
390 
391 	if (this->transport == NULL || this->transport->sco_io == NULL)
392 		return;
393 
394 	if (!spa_list_is_empty(&port->ready)) {
395 		/* get buffer */
396 		if (!port->current_buffer) {
397 			spa_return_if_fail(!spa_list_is_empty(&port->ready));
398 			port->current_buffer = spa_list_first(&port->ready, struct buffer, link);
399 			port->ready_offset = 0;
400 		}
401 		datas = port->current_buffer->buf->datas;
402 
403 		/* if buffer has data, copy it into the write buffer */
404 		if (datas[0].chunk->size - port->ready_offset > 0) {
405 			const uint32_t avail =
406 				SPA_MIN(min_in_size, datas[0].chunk->size - port->ready_offset);
407 			const uint32_t size =
408 				(avail + port->write_buffer_size) > min_in_size ?
409 				min_in_size - port->write_buffer_size : avail;
410 			memcpy(port->write_buffer + port->write_buffer_size,
411 				(uint8_t *)datas[0].data + port->ready_offset,
412 				size);
413 			port->write_buffer_size += size;
414 			port->ready_offset += size;
415 		} else {
416 			struct buffer *b;
417 
418 			b = port->current_buffer;
419 			port->current_buffer = NULL;
420 
421 			/* reuse buffer */
422 			spa_list_remove(&b->link);
423 			b->outstanding = true;
424 			spa_log_trace(this->log, "sco-sink %p: reuse buffer %u", this, b->id);
425 			port->io->buffer_id = b->id;
426 			spa_node_call_reuse_buffer(&this->callbacks, 0, b->id);
427 		}
428 	}
429 
430 	/* send the data if the write buffer is full */
431 	if (port->write_buffer_size >= min_in_size) {
432 		uint64_t now_time;
433 		static int sn = 0;
434 		int processed = 0;
435 		ssize_t out_encoded;
436 		int written;
437 
438 		spa_system_clock_gettime(this->data_system, CLOCK_MONOTONIC, &this->now);
439 		now_time = SPA_TIMESPEC_TO_NSEC(&this->now);
440 		if (this->start_time == 0)
441 			this->start_time = now_time;
442 
443 		if (this->transport->codec == HFP_AUDIO_CODEC_MSBC) {
444 			/* Encode */
445 			if (this->buffer_next + MSBC_ENCODED_SIZE > this->buffer + this->buffer_size) {
446 				/* Buffer overrun; shouldn't usually happen. Drop data and reset. */
447 				this->buffer_head = this->buffer_next = this->buffer;
448 				spa_log_warn(this->log, "sco-sink: mSBC buffer overrun, dropping data");
449 			}
450 			this->buffer_next[0] = 0x01;
451 			this->buffer_next[1] = sntable[sn];
452 			this->buffer_next[59] = 0x00;
453 			sn = (sn + 1) % 4;
454 			processed = sbc_encode(&this->msbc, port->write_buffer, port->write_buffer_size,
455 			                       this->buffer_next + 2, MSBC_ENCODED_SIZE - 3, &out_encoded);
456 			if (processed < 0) {
457 				spa_log_warn(this->log, "sbc_encode failed: %d", processed);
458 				return;
459 			}
460 			this->buffer_next += out_encoded + 3;
461 			port->write_buffer_size = 0;
462 
463 			/* Write */
464 			written = spa_bt_sco_io_write(this->transport->sco_io, packet,
465 					this->buffer_next - this->buffer_head);
466 			if (written < 0) {
467 				spa_log_warn(this->log, "failed to write data: %d (%s)",
468 						written, spa_strerror(written));
469 				goto stop;
470 			}
471 			spa_log_trace(this->log, "wrote socket data %d", written);
472 
473 			this->buffer_head += written;
474 
475 			if (this->buffer_head == this->buffer_next)
476 				this->buffer_head = this->buffer_next = this->buffer;
477 			else if (this->buffer_next + MSBC_ENCODED_SIZE > this->buffer + this->buffer_size) {
478 				/* Written bytes is not necessarily commensurate
479 				 * with MSBC_ENCODED_SIZE. If this occurs, copy data.
480 				 */
481 				int size = this->buffer_next - this->buffer_head;
482 				spa_memmove(this->buffer, this->buffer_head, size);
483 				this->buffer_next = this->buffer + size;
484 				this->buffer_head = this->buffer;
485 			}
486 		} else {
487 			written = spa_bt_sco_io_write(this->transport->sco_io, packet,
488 					port->write_buffer_size);
489 			if (written < 0) {
490 				spa_log_warn(this->log, "sco-sink: write failure: %d (%s)",
491 						written, spa_strerror(written));
492 				goto stop;
493 			} else if (written == 0) {
494 				/* EAGAIN or similar, just skip ahead */
495 				written = SPA_MIN(port->write_buffer_size, (uint32_t)48);
496 			}
497 
498 			processed = written;
499 			port->write_buffer_size -= written;
500 
501 			if (port->write_buffer_size > 0 && written > 0) {
502 				spa_memmove(port->write_buffer, port->write_buffer + written, port->write_buffer_size);
503 			}
504 		}
505 
506 		spa_log_trace(this->log, "write socket data %d", written);
507 
508 		next_timeout = get_next_timeout(this, now_time, processed / port->frame_size);
509 
510 		if (this->clock) {
511 			this->clock->nsec = now_time;
512 			this->clock->position = this->total_samples;
513 			this->clock->delay = processed / port->frame_size;
514 			this->clock->rate_diff = 1.0f;
515 			this->clock->next_nsec = next_timeout;
516 		}
517 	}
518 
519 	/* schedule next timeout */
520 	set_timeout(this, next_timeout);
521 	return;
522 
523 stop:
524 	if (this->source.loop)
525 		spa_loop_remove_source(this->data_loop, &this->source);
526 }
527 
sco_on_timeout(struct spa_source * source)528 static void sco_on_timeout(struct spa_source *source)
529 {
530 	struct impl *this = source->data;
531 	struct port *port = &this->port;
532 	uint64_t exp;
533 
534 	if (this->transport == NULL)
535 		return;
536 
537 	/* Read the timerfd */
538 	if (this->started && spa_system_timerfd_read(this->data_system, this->timerfd, &exp) < 0)
539 		spa_log_warn(this->log, "error reading timerfd: %s", strerror(errno));
540 
541 	/* delay if no buffers available */
542 	if (!this->following && spa_list_is_empty(&port->ready)) {
543 		set_timeout(this, this->transport->write_mtu / port->frame_size * SPA_NSEC_PER_SEC / port->current_format.info.raw.rate);
544 		port->io->status = SPA_STATUS_NEED_DATA;
545 		spa_node_call_ready(&this->callbacks, SPA_STATUS_NEED_DATA);
546 		return;
547 	}
548 
549 	/* Flush data */
550 	flush_data(this);
551 }
552 
553 /* greater common divider */
gcd(int a,int b)554 static int gcd(int a, int b) {
555     while(b) {
556         int c = b;
557         b = a % b;
558         a = c;
559     }
560     return a;
561 }
562 /* least common multiple */
lcm(int a,int b)563 static int lcm(int a, int b) {
564     return (a*b)/gcd(a,b);
565 }
566 
do_start(struct impl * this)567 static int do_start(struct impl *this)
568 {
569 	bool do_accept;
570 	int res;
571 
572 	/* Don't do anything if the node has already started */
573 	if (this->started)
574 		return 0;
575 
576 	/* Make sure the transport is valid */
577 	spa_return_val_if_fail(this->transport != NULL, -EIO);
578 
579 	this->following = is_following(this);
580 
581 	spa_log_debug(this->log, "%p: start following:%d", this, this->following);
582 
583 	/* Do accept if Gateway; otherwise do connect for Head Unit */
584 	do_accept = this->transport->profile & SPA_BT_PROFILE_HEADSET_AUDIO_GATEWAY;
585 
586 	/* acquire the socket fd (false -> connect | true -> accept) */
587 	if ((res = spa_bt_transport_acquire(this->transport, do_accept)) < 0)
588 		return res;
589 
590 	/* Init mSBC if needed */
591 	if (this->transport->codec == HFP_AUDIO_CODEC_MSBC) {
592 		sbc_init_msbc(&this->msbc, 0);
593 		/* Libsbc expects audio samples by default in host endianness, mSBC requires little endian */
594 		this->msbc.endian = SBC_LE;
595 
596 		/* write_mtu might not be correct at this point, so we'll throw
597 		 * in some common ones, at the cost of a potentially larger
598 		 * allocation (size <= 120 * write_mtu). If it still fails to be
599 		 * commensurate, we may end up doing memmoves, but nothing worse
600 		 * is going to happen.
601 		 */
602 		this->buffer_size = lcm(24, lcm(60, lcm(this->transport->write_mtu, 2 * MSBC_ENCODED_SIZE)));
603 		this->buffer = calloc(this->buffer_size, sizeof(uint8_t));
604 		this->buffer_head = this->buffer_next = this->buffer;
605 	}
606 
607 	spa_return_val_if_fail(this->transport->write_mtu <= sizeof(this->port.write_buffer), -EINVAL);
608 
609 	/* start socket i/o */
610 	if ((res = spa_bt_transport_ensure_sco_io(this->transport, this->data_loop)) < 0)
611 		goto fail;
612 
613 	/* Add the timeout callback */
614 	this->source.data = this;
615 	this->source.fd = this->timerfd;
616 	this->source.func = sco_on_timeout;
617 	this->source.mask = SPA_IO_IN;
618 	this->source.rmask = 0;
619 	spa_loop_add_source(this->data_loop, &this->source);
620 
621 	/* start processing */
622 	set_timers(this);
623 
624 	/* Set the started flag */
625 	this->started = true;
626 
627 	return 0;
628 
629 fail:
630 	free(this->buffer);
631 	this->buffer = NULL;
632 	spa_bt_transport_release(this->transport);
633 	return res;
634 }
635 
636 /* Drop any buffered data remaining in the port */
drop_port_output(struct impl * this)637 static void drop_port_output(struct impl *this)
638 {
639 	struct port *port = &this->port;
640 
641 	port->write_buffer_size = 0;
642 	port->current_buffer = NULL;
643 	port->ready_offset = 0;
644 
645 	while (!spa_list_is_empty(&port->ready)) {
646 		struct buffer *b;
647 		b = spa_list_first(&port->ready, struct buffer, link);
648 
649 		spa_list_remove(&b->link);
650 		b->outstanding = true;
651 		port->io->buffer_id = b->id;
652 		spa_node_call_reuse_buffer(&this->callbacks, 0, b->id);
653 	}
654 }
655 
do_remove_source(struct spa_loop * loop,bool async,uint32_t seq,const void * data,size_t size,void * user_data)656 static int do_remove_source(struct spa_loop *loop,
657 			    bool async,
658 			    uint32_t seq,
659 			    const void *data,
660 			    size_t size,
661 			    void *user_data)
662 {
663 	struct impl *this = user_data;
664 
665 	this->start_time = 0;
666 	this->total_samples = 0;
667 	set_timeout(this, 0);
668 	if (this->source.loop)
669 		spa_loop_remove_source(this->data_loop, &this->source);
670 
671 	/* Drop buffered data in the ready queue. Ideally there shouldn't be any. */
672 	drop_port_output(this);
673 
674 	return 0;
675 }
676 
do_stop(struct impl * this)677 static int do_stop(struct impl *this)
678 {
679 	int res = 0;
680 
681 	if (!this->started)
682 		return 0;
683 
684 	spa_log_trace(this->log, "sco-sink %p: stop", this);
685 
686 	spa_loop_invoke(this->data_loop, do_remove_source, 0, NULL, 0, true, this);
687 
688 	this->started = false;
689 
690 	if (this->buffer) {
691 		free(this->buffer);
692 		this->buffer = NULL;
693 		this->buffer_head = this->buffer_next = this->buffer;
694 	}
695 
696 	if (this->transport) {
697 		/* Release the transport; it is responsible for closing the fd */
698 		res = spa_bt_transport_release(this->transport);
699 	}
700 
701 	return res;
702 }
703 
impl_node_send_command(void * object,const struct spa_command * command)704 static int impl_node_send_command(void *object, const struct spa_command *command)
705 {
706 	struct impl *this = object;
707 	struct port *port;
708 	int res;
709 
710 	spa_return_val_if_fail(this != NULL, -EINVAL);
711 	spa_return_val_if_fail(command != NULL, -EINVAL);
712 
713 	port = &this->port;
714 
715 	switch (SPA_NODE_COMMAND_ID(command)) {
716 	case SPA_NODE_COMMAND_Start:
717 		if (!port->have_format)
718 			return -EIO;
719 		if (port->n_buffers == 0)
720 			return -EIO;
721 		if ((res = do_start(this)) < 0)
722 			return res;
723 		break;
724 	case SPA_NODE_COMMAND_Pause:
725 	case SPA_NODE_COMMAND_Suspend:
726 		if ((res = do_stop(this)) < 0)
727 			return res;
728 		break;
729 	default:
730 		return -ENOTSUP;
731 	}
732 	return 0;
733 }
734 
emit_node_info(struct impl * this,bool full)735 static void emit_node_info(struct impl *this, bool full)
736 {
737 	static const struct spa_dict_item hu_node_info_items[] = {
738 		{ SPA_KEY_DEVICE_API, "bluez5" },
739 		{ SPA_KEY_MEDIA_CLASS, "Audio/Sink" },
740 		{ SPA_KEY_NODE_DRIVER, "true" },
741 	};
742 
743 	const struct spa_dict_item ag_node_info_items[] = {
744 		{ SPA_KEY_DEVICE_API, "bluez5" },
745 		{ SPA_KEY_MEDIA_CLASS, "Stream/Input/Audio" },
746 		{ "media.name", ((this->transport && this->transport->device->name) ?
747 		                 this->transport->device->name : "HSP/HFP") },
748 	};
749 	bool is_ag = this->transport &&
750 		(this->transport->profile & SPA_BT_PROFILE_HEADSET_AUDIO_GATEWAY);
751 	uint64_t old = full ? this->info.change_mask : 0;
752 
753 	if (full)
754 		this->info.change_mask = this->info_all;
755 	if (this->info.change_mask) {
756 		this->info.props = is_ag ?
757 			&SPA_DICT_INIT_ARRAY(ag_node_info_items) :
758 			&SPA_DICT_INIT_ARRAY(hu_node_info_items);
759 		spa_node_emit_info(&this->hooks, &this->info);
760 		this->info.change_mask = old;
761 	}
762 }
763 
emit_port_info(struct impl * this,struct port * port,bool full)764 static void emit_port_info(struct impl *this, struct port *port, bool full)
765 {
766 	uint64_t old = full ? port->info.change_mask : 0;
767 	if (full)
768 		port->info.change_mask = port->info_all;
769 	if (port->info.change_mask) {
770 		spa_node_emit_port_info(&this->hooks,
771 				SPA_DIRECTION_INPUT, 0, &port->info);
772 		port->info.change_mask = old;
773 	}
774 }
775 
776 static int
impl_node_add_listener(void * object,struct spa_hook * listener,const struct spa_node_events * events,void * data)777 impl_node_add_listener(void *object,
778 		struct spa_hook *listener,
779 		const struct spa_node_events *events,
780 		void *data)
781 {
782 	struct impl *this = object;
783 	struct spa_hook_list save;
784 
785 	spa_return_val_if_fail(this != NULL, -EINVAL);
786 
787 	spa_hook_list_isolate(&this->hooks, &save, listener, events, data);
788 
789 	emit_node_info(this, true);
790 	emit_port_info(this, &this->port, true);
791 
792 	spa_hook_list_join(&this->hooks, &save);
793 
794 	return 0;
795 }
796 
797 static int
impl_node_set_callbacks(void * object,const struct spa_node_callbacks * callbacks,void * data)798 impl_node_set_callbacks(void *object,
799 			const struct spa_node_callbacks *callbacks,
800 			void *data)
801 {
802 	struct impl *this = object;
803 
804 	spa_return_val_if_fail(this != NULL, -EINVAL);
805 
806 	this->callbacks = SPA_CALLBACKS_INIT(callbacks, data);
807 
808 	return 0;
809 }
810 
impl_node_sync(void * object,int seq)811 static int impl_node_sync(void *object, int seq)
812 {
813 	struct impl *this = object;
814 
815 	spa_return_val_if_fail(this != NULL, -EINVAL);
816 
817 	spa_node_emit_result(&this->hooks, seq, 0, 0, NULL);
818 
819 	return 0;
820 }
821 
impl_node_add_port(void * object,enum spa_direction direction,uint32_t port_id,const struct spa_dict * props)822 static int impl_node_add_port(void *object, enum spa_direction direction, uint32_t port_id,
823 		const struct spa_dict *props)
824 {
825 	return -ENOTSUP;
826 }
827 
impl_node_remove_port(void * object,enum spa_direction direction,uint32_t port_id)828 static int impl_node_remove_port(void *object, enum spa_direction direction, uint32_t port_id)
829 {
830 	return -ENOTSUP;
831 }
832 
833 static int
impl_node_port_enum_params(void * object,int seq,enum spa_direction direction,uint32_t port_id,uint32_t id,uint32_t start,uint32_t num,const struct spa_pod * filter)834 impl_node_port_enum_params(void *object, int seq,
835 			enum spa_direction direction, uint32_t port_id,
836 			uint32_t id, uint32_t start, uint32_t num,
837 			const struct spa_pod *filter)
838 {
839 
840 	struct impl *this = object;
841 	struct port *port;
842 	struct spa_pod *param;
843 	struct spa_pod_builder b = { 0 };
844 	uint8_t buffer[1024];
845 	struct spa_result_node_params result;
846 	uint32_t count = 0;
847 
848 	spa_return_val_if_fail(this != NULL, -EINVAL);
849 	spa_return_val_if_fail(num != 0, -EINVAL);
850 
851 	spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
852 	port = &this->port;
853 
854 	result.id = id;
855 	result.next = start;
856       next:
857 	result.index = result.next++;
858 
859 	spa_pod_builder_init(&b, buffer, sizeof(buffer));
860 
861 	switch (id) {
862 	case SPA_PARAM_EnumFormat:
863 		if (result.index > 0)
864 			return 0;
865 		if (this->transport == NULL)
866 			return -EIO;
867 
868 		/* set the info structure */
869 		struct spa_audio_info_raw info = { 0, };
870 		info.format = SPA_AUDIO_FORMAT_S16_LE;
871 		info.channels = 1;
872 		info.position[0] = SPA_AUDIO_CHANNEL_MONO;
873 
874 		/* CVSD format has a rate of 8kHz
875 		 * MSBC format has a rate of 16kHz */
876 		if (this->transport->codec == HFP_AUDIO_CODEC_MSBC)
877 			info.rate = 16000;
878 		else
879 			info.rate = 8000;
880 
881 		/* build the param */
882 		param = spa_format_audio_raw_build(&b, id, &info);
883 
884 		break;
885 
886 	case SPA_PARAM_Format:
887 		if (!port->have_format)
888 			return -EIO;
889 		if (result.index > 0)
890 			return 0;
891 
892 		param = spa_format_audio_raw_build(&b, id, &port->current_format.info.raw);
893 		break;
894 
895 	case SPA_PARAM_Buffers:
896 		if (!port->have_format)
897 			return -EIO;
898 		if (result.index > 0)
899 			return 0;
900 
901 		param = spa_pod_builder_add_object(&b,
902 			SPA_TYPE_OBJECT_ParamBuffers, id,
903 			SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(2, 1, MAX_BUFFERS),
904 			SPA_PARAM_BUFFERS_blocks,  SPA_POD_Int(1),
905 			SPA_PARAM_BUFFERS_size,    SPA_POD_CHOICE_RANGE_Int(
906 							this->props.max_latency * port->frame_size,
907 							this->props.min_latency * port->frame_size,
908 							INT32_MAX),
909 			SPA_PARAM_BUFFERS_stride,  SPA_POD_Int(port->frame_size));
910 		break;
911 
912 	case SPA_PARAM_Meta:
913 		switch (result.index) {
914 		case 0:
915 			param = spa_pod_builder_add_object(&b,
916 				SPA_TYPE_OBJECT_ParamMeta, id,
917 				SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header),
918 				SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_header)));
919 			break;
920 		default:
921 			return 0;
922 		}
923 		break;
924 
925 	case SPA_PARAM_IO:
926 		switch (result.index) {
927 		case 0:
928 			param = spa_pod_builder_add_object(&b,
929 				SPA_TYPE_OBJECT_ParamIO, id,
930 				SPA_PARAM_IO_id,   SPA_POD_Id(SPA_IO_Buffers),
931 				SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_buffers)));
932 			break;
933 		case 1:
934 			param = spa_pod_builder_add_object(&b,
935 				SPA_TYPE_OBJECT_ParamIO, id,
936 				SPA_PARAM_IO_id,   SPA_POD_Id(SPA_IO_RateMatch),
937 				SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_rate_match)));
938 			break;
939 		default:
940 			return 0;
941 		}
942 		break;
943 
944 	case SPA_PARAM_Latency:
945 		switch (result.index) {
946 		case 0:
947 			param = spa_latency_build(&b, id, &port->latency);
948 			break;
949 		default:
950 			return 0;
951 		}
952 		break;
953 
954 	default:
955 		return -ENOENT;
956 	}
957 
958 	if (spa_pod_filter(&b, &result.param, param, filter) < 0)
959 		goto next;
960 
961 	spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result);
962 
963 	if (++count != num)
964 		goto next;
965 
966 	return 0;
967 }
968 
clear_buffers(struct impl * this,struct port * port)969 static int clear_buffers(struct impl *this, struct port *port)
970 {
971 	do_stop(this);
972 	if (port->n_buffers > 0) {
973 		spa_list_init(&port->ready);
974 		port->n_buffers = 0;
975 	}
976 	return 0;
977 }
978 
port_set_format(struct impl * this,struct port * port,uint32_t flags,const struct spa_pod * format)979 static int port_set_format(struct impl *this, struct port *port,
980 			   uint32_t flags,
981 			   const struct spa_pod *format)
982 {
983 	int err;
984 
985 	if (format == NULL) {
986 		spa_log_debug(this->log, "clear format");
987 		clear_buffers(this, port);
988 		port->have_format = false;
989 	} else {
990 		struct spa_audio_info info = { 0 };
991 
992 		if ((err = spa_format_parse(format, &info.media_type, &info.media_subtype)) < 0)
993 			return err;
994 
995 		if (info.media_type != SPA_MEDIA_TYPE_audio ||
996 		    info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
997 			return -EINVAL;
998 
999 		if (spa_format_audio_raw_parse(format, &info.info.raw) < 0)
1000 			return -EINVAL;
1001 
1002 		port->frame_size = info.info.raw.channels * 2;
1003 		port->current_format = info;
1004 		port->have_format = true;
1005 	}
1006 
1007 	port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
1008 	if (port->have_format) {
1009 		port->info.change_mask |= SPA_PORT_CHANGE_MASK_FLAGS;
1010 		port->info.flags = SPA_PORT_FLAG_LIVE;
1011 		port->info.change_mask |= SPA_PORT_CHANGE_MASK_RATE;
1012 		port->info.rate = SPA_FRACTION(1, port->current_format.info.raw.rate);
1013 		port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE);
1014 		port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
1015 		port->params[IDX_Latency].flags ^= SPA_PARAM_INFO_SERIAL;
1016 	} else {
1017 		port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
1018 		port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
1019 	}
1020 	emit_port_info(this, port, false);
1021 
1022 	return 0;
1023 }
1024 
1025 static int
impl_node_port_set_param(void * object,enum spa_direction direction,uint32_t port_id,uint32_t id,uint32_t flags,const struct spa_pod * param)1026 impl_node_port_set_param(void *object,
1027 			 enum spa_direction direction, uint32_t port_id,
1028 			 uint32_t id, uint32_t flags,
1029 			 const struct spa_pod *param)
1030 {
1031 	struct impl *this = object;
1032 	struct port *port;
1033 	int res;
1034 
1035 	spa_return_val_if_fail(this != NULL, -EINVAL);
1036 	spa_return_val_if_fail(CHECK_PORT(node, direction, port_id), -EINVAL);
1037 	port = &this->port;
1038 
1039 	switch (id) {
1040 	case SPA_PARAM_Format:
1041 		res = port_set_format(this, port, flags, param);
1042 		break;
1043 	case SPA_PARAM_Latency:
1044 		res = 0;
1045 		break;
1046 	default:
1047 		res = -ENOENT;
1048 		break;
1049 	}
1050 	return res;
1051 }
1052 
1053 static int
impl_node_port_use_buffers(void * object,enum spa_direction direction,uint32_t port_id,uint32_t flags,struct spa_buffer ** buffers,uint32_t n_buffers)1054 impl_node_port_use_buffers(void *object,
1055 			   enum spa_direction direction, uint32_t port_id,
1056 			   uint32_t flags,
1057 			   struct spa_buffer **buffers, uint32_t n_buffers)
1058 {
1059 	struct impl *this = object;
1060 	struct port *port;
1061 	uint32_t i;
1062 
1063 	spa_return_val_if_fail(this != NULL, -EINVAL);
1064 	spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
1065 	port = &this->port;
1066 
1067 	spa_log_debug(this->log, "use buffers %d", n_buffers);
1068 
1069 	if (!port->have_format)
1070 		return -EIO;
1071 
1072 	clear_buffers(this, port);
1073 
1074 	for (i = 0; i < n_buffers; i++) {
1075 		struct buffer *b = &port->buffers[i];
1076 
1077 		b->buf = buffers[i];
1078 		b->id = i;
1079 		b->outstanding = true;
1080 
1081 		b->h = spa_buffer_find_meta_data(buffers[i], SPA_META_Header, sizeof(*b->h));
1082 
1083 		if (buffers[i]->datas[0].data == NULL) {
1084 			spa_log_error(this->log, "%p: need mapped memory", this);
1085 			return -EINVAL;
1086 		}
1087 	}
1088 	port->n_buffers = n_buffers;
1089 
1090 	return 0;
1091 }
1092 
1093 static int
impl_node_port_set_io(void * object,enum spa_direction direction,uint32_t port_id,uint32_t id,void * data,size_t size)1094 impl_node_port_set_io(void *object,
1095 		      enum spa_direction direction,
1096 		      uint32_t port_id,
1097 		      uint32_t id,
1098 		      void *data, size_t size)
1099 {
1100 	struct impl *this = object;
1101 	struct port *port;
1102 
1103 	spa_return_val_if_fail(this != NULL, -EINVAL);
1104 
1105 	spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
1106 	port = &this->port;
1107 
1108 	switch (id) {
1109 	case SPA_IO_Buffers:
1110 		port->io = data;
1111 		break;
1112 	case SPA_IO_RateMatch:
1113 		port->rate_match = data;
1114 		break;
1115 	default:
1116 		return -ENOENT;
1117 	}
1118 	return 0;
1119 }
1120 
impl_node_port_reuse_buffer(void * object,uint32_t port_id,uint32_t buffer_id)1121 static int impl_node_port_reuse_buffer(void *object, uint32_t port_id, uint32_t buffer_id)
1122 {
1123 	return -ENOTSUP;
1124 }
1125 
impl_node_process(void * object)1126 static int impl_node_process(void *object)
1127 {
1128 	struct impl *this = object;
1129 	struct port *port;
1130 	struct spa_io_buffers *io;
1131 
1132 	spa_return_val_if_fail(this != NULL, -EINVAL);
1133 
1134 	port = &this->port;
1135 	io = port->io;
1136 	spa_return_val_if_fail(io != NULL, -EIO);
1137 
1138 	if (io->status == SPA_STATUS_HAVE_DATA && io->buffer_id < port->n_buffers) {
1139 		struct buffer *b = &port->buffers[io->buffer_id];
1140 
1141 		if (!b->outstanding) {
1142 			spa_log_warn(this->log, "%p: buffer %u in use", this, io->buffer_id);
1143 			io->status = -EINVAL;
1144 			return -EINVAL;
1145 		}
1146 
1147 		spa_log_trace(this->log, "%p: queue buffer %u", this, io->buffer_id);
1148 
1149 		spa_list_append(&port->ready, &b->link);
1150 		b->outstanding = false;
1151 		io->buffer_id = SPA_ID_INVALID;
1152 		io->status = SPA_STATUS_OK;
1153 	}
1154 
1155 	if (!spa_list_is_empty(&port->ready))
1156 		flush_data(this);
1157 
1158 	return SPA_STATUS_HAVE_DATA;
1159 }
1160 
1161 static const struct spa_node_methods impl_node = {
1162 	SPA_VERSION_NODE_METHODS,
1163 	.add_listener = impl_node_add_listener,
1164 	.set_callbacks = impl_node_set_callbacks,
1165 	.sync = impl_node_sync,
1166 	.enum_params = impl_node_enum_params,
1167 	.set_param = impl_node_set_param,
1168 	.set_io = impl_node_set_io,
1169 	.send_command = impl_node_send_command,
1170 	.add_port = impl_node_add_port,
1171 	.remove_port = impl_node_remove_port,
1172 	.port_enum_params = impl_node_port_enum_params,
1173 	.port_set_param = impl_node_port_set_param,
1174 	.port_use_buffers = impl_node_port_use_buffers,
1175 	.port_set_io = impl_node_port_set_io,
1176 	.port_reuse_buffer = impl_node_port_reuse_buffer,
1177 	.process = impl_node_process,
1178 };
1179 
do_transport_destroy(struct spa_loop * loop,bool async,uint32_t seq,const void * data,size_t size,void * user_data)1180 static int do_transport_destroy(struct spa_loop *loop,
1181 				bool async,
1182 				uint32_t seq,
1183 				const void *data,
1184 				size_t size,
1185 				void *user_data)
1186 {
1187 	struct impl *this = user_data;
1188 	this->transport = NULL;
1189 	return 0;
1190 }
1191 
transport_destroy(void * data)1192 static void transport_destroy(void *data)
1193 {
1194 	struct impl *this = data;
1195 	spa_log_debug(this->log, "transport %p destroy", this->transport);
1196 	spa_loop_invoke(this->data_loop, do_transport_destroy, 0, NULL, 0, true, this);
1197 }
1198 
1199 static const struct spa_bt_transport_events transport_events = {
1200 	SPA_VERSION_BT_TRANSPORT_EVENTS,
1201 	.destroy = transport_destroy,
1202 };
1203 
impl_get_interface(struct spa_handle * handle,const char * type,void ** interface)1204 static int impl_get_interface(struct spa_handle *handle, const char *type, void **interface)
1205 {
1206 	struct impl *this;
1207 
1208 	spa_return_val_if_fail(handle != NULL, -EINVAL);
1209 	spa_return_val_if_fail(interface != NULL, -EINVAL);
1210 
1211 	this = (struct impl *) handle;
1212 
1213 	if (spa_streq(type, SPA_TYPE_INTERFACE_Node))
1214 		*interface = &this->node;
1215 	else
1216 		return -ENOENT;
1217 
1218 	return 0;
1219 }
1220 
impl_clear(struct spa_handle * handle)1221 static int impl_clear(struct spa_handle *handle)
1222 {
1223 	struct impl *this = (struct impl *) handle;
1224 	if (this->transport)
1225 		spa_hook_remove(&this->transport_listener);
1226 	spa_system_close(this->data_system, this->timerfd);
1227 	return 0;
1228 }
1229 
1230 static size_t
impl_get_size(const struct spa_handle_factory * factory,const struct spa_dict * params)1231 impl_get_size(const struct spa_handle_factory *factory,
1232 	      const struct spa_dict *params)
1233 {
1234 	return sizeof(struct impl);
1235 }
1236 
1237 static int
impl_init(const struct spa_handle_factory * factory,struct spa_handle * handle,const struct spa_dict * info,const struct spa_support * support,uint32_t n_support)1238 impl_init(const struct spa_handle_factory *factory,
1239 	  struct spa_handle *handle,
1240 	  const struct spa_dict *info,
1241 	  const struct spa_support *support,
1242 	  uint32_t n_support)
1243 {
1244 	struct impl *this;
1245 	struct port *port;
1246 	const char *str;
1247 
1248 	spa_return_val_if_fail(factory != NULL, -EINVAL);
1249 	spa_return_val_if_fail(handle != NULL, -EINVAL);
1250 
1251 	handle->get_interface = impl_get_interface;
1252 	handle->clear = impl_clear;
1253 
1254 	this = (struct impl *) handle;
1255 
1256 	this->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
1257 	this->data_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DataLoop);
1258 	this->data_system = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DataSystem);
1259 
1260 	spa_log_topic_init(this->log, &log_topic);
1261 
1262 	if (this->data_loop == NULL) {
1263 		spa_log_error(this->log, "a data loop is needed");
1264 		return -EINVAL;
1265 	}
1266 	if (this->data_system == NULL) {
1267 		spa_log_error(this->log, "a data system is needed");
1268 		return -EINVAL;
1269 	}
1270 
1271 	this->node.iface = SPA_INTERFACE_INIT(
1272 			SPA_TYPE_INTERFACE_Node,
1273 			SPA_VERSION_NODE,
1274 			&impl_node, this);
1275 	spa_hook_list_init(&this->hooks);
1276 
1277 	reset_props(&this->props);
1278 
1279 	this->info_all = SPA_NODE_CHANGE_MASK_FLAGS |
1280 			SPA_NODE_CHANGE_MASK_PARAMS |
1281 			SPA_NODE_CHANGE_MASK_PROPS;
1282 	this->info = SPA_NODE_INFO_INIT();
1283 	this->info.max_input_ports = 1;
1284 	this->info.max_output_ports = 0;
1285 	this->info.flags = SPA_NODE_FLAG_RT;
1286 	this->params[IDX_PropInfo] = SPA_PARAM_INFO(SPA_PARAM_PropInfo, SPA_PARAM_INFO_READ);
1287 	this->params[IDX_Props] = SPA_PARAM_INFO(SPA_PARAM_Props, SPA_PARAM_INFO_READWRITE);
1288 	this->info.params = this->params;
1289 	this->info.n_params = N_NODE_PARAMS;
1290 
1291 	port = &this->port;
1292 	port->info_all = SPA_PORT_CHANGE_MASK_FLAGS |
1293 			SPA_PORT_CHANGE_MASK_PARAMS;
1294 	port->info = SPA_PORT_INFO_INIT();
1295 	port->info.flags = 0;
1296 	port->params[IDX_EnumFormat] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ);
1297 	port->params[IDX_Meta] = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ);
1298 	port->params[IDX_IO] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
1299 	port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
1300 	port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
1301 	port->params[IDX_Latency] = SPA_PARAM_INFO(SPA_PARAM_Latency, SPA_PARAM_INFO_READWRITE);
1302 	port->info.params = port->params;
1303 	port->info.n_params = N_PORT_PARAMS;
1304 
1305 	port->latency = SPA_LATENCY_INFO(SPA_DIRECTION_INPUT);
1306 	port->latency.min_quantum = 1.0f;
1307 	port->latency.max_quantum = 1.0f;
1308 
1309 	spa_list_init(&port->ready);
1310 
1311 	if (info && (str = spa_dict_lookup(info, SPA_KEY_API_BLUEZ5_TRANSPORT)))
1312 		sscanf(str, "pointer:%p", &this->transport);
1313 
1314 	if (this->transport == NULL) {
1315 		spa_log_error(this->log, "a transport is needed");
1316 		return -EINVAL;
1317 	}
1318 	spa_bt_transport_add_listener(this->transport,
1319 			&this->transport_listener, &transport_events, this);
1320 
1321 	this->timerfd = spa_system_timerfd_create(this->data_system,
1322 			CLOCK_MONOTONIC, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK);
1323 
1324 	return 0;
1325 }
1326 
1327 static const struct spa_interface_info impl_interfaces[] = {
1328 	{SPA_TYPE_INTERFACE_Node,},
1329 };
1330 
1331 static int
impl_enum_interface_info(const struct spa_handle_factory * factory,const struct spa_interface_info ** info,uint32_t * index)1332 impl_enum_interface_info(const struct spa_handle_factory *factory,
1333 			 const struct spa_interface_info **info, uint32_t *index)
1334 {
1335 	spa_return_val_if_fail(factory != NULL, -EINVAL);
1336 	spa_return_val_if_fail(info != NULL, -EINVAL);
1337 	spa_return_val_if_fail(index != NULL, -EINVAL);
1338 
1339 	switch (*index) {
1340 	case 0:
1341 		*info = &impl_interfaces[*index];
1342 		break;
1343 	default:
1344 		return 0;
1345 	}
1346 	(*index)++;
1347 	return 1;
1348 }
1349 
1350 static const struct spa_dict_item info_items[] = {
1351 	{ SPA_KEY_FACTORY_AUTHOR, "Collabora Ltd. <contact@collabora.com>" },
1352 	{ SPA_KEY_FACTORY_DESCRIPTION, "Play bluetooth audio with hsp/hfp" },
1353 	{ SPA_KEY_FACTORY_USAGE, SPA_KEY_API_BLUEZ5_TRANSPORT"=<transport>" },
1354 };
1355 
1356 static const struct spa_dict info = SPA_DICT_INIT_ARRAY(info_items);
1357 
1358 const struct spa_handle_factory spa_sco_sink_factory = {
1359 	SPA_VERSION_HANDLE_FACTORY,
1360 	SPA_NAME_API_BLUEZ5_SCO_SINK,
1361 	&info,
1362 	impl_get_size,
1363 	impl_init,
1364 	impl_enum_interface_info,
1365 };
1366