mcap.c revision a0da5dee55a67b75c4825e027bf004f9ad223469
1/*
2 *
3 *  MCAP for BlueZ - Bluetooth protocol stack for Linux
4 *
5 *  Copyright (C) 2010 GSyC/LibreSoft, Universidad Rey Juan Carlos.
6 *
7 *  Authors:
8 *  Santiago Carot-Nemesio <sancane at gmail.com>
9 *  Jose Antonio Santos-Cadenas <santoscadenas at gmail.com>
10 *
11 *  This program is free software; you can redistribute it and/or modify
12 *  it under the terms of the GNU General Public License as published by
13 *  the Free Software Foundation; either version 2 of the License, or
14 *  (at your option) any later version.
15 *
16 *  This program is distributed in the hope that it will be useful,
17 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 *  GNU General Public License for more details.
20 *
21 *  You should have received a copy of the GNU General Public License
22 *  along with this program; if not, write to the Free Software
23 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
24 *
25 */
26
27#include "log.h"
28#include "error.h"
29
30#include <netinet/in.h>
31#include <stdlib.h>
32#include <errno.h>
33#include <unistd.h>
34
35#include "btio.h"
36#include <bluetooth/bluetooth.h>
37#include <bluetooth/l2cap.h>
38#include "mcap.h"
39#include "mcap_lib.h"
40#include "mcap_internal.h"
41
42#define RESPONSE_TIMER	6	/* seconds */
43#define MAX_CACHED	10	/* 10 devices */
44
45#define MCAP_ERROR g_quark_from_static_string("mcap-error-quark")
46
47#define RELEASE_TIMER(__mcl) do {		\
48	if (__mcl->tid) {			\
49		g_source_remove(__mcl->tid);	\
50		__mcl->tid = 0;			\
51	}					\
52} while(0)
53
54struct connect_mcl {
55	struct mcap_mcl		*mcl;		/* MCL for this operation */
56	mcap_mcl_connect_cb	connect_cb;	/* Connect callback */
57	GDestroyNotify		destroy;	/* Destroy callback */
58	gpointer		user_data;	/* Callback user data */
59};
60
61typedef union {
62	mcap_mdl_operation_cb		op;
63	mcap_mdl_operation_conf_cb	op_conf;
64	mcap_mdl_notify_cb		notify;
65} mcap_cb_type;
66
67struct mcap_mdl_op_cb {
68	struct mcap_mdl		*mdl;		/* MDL for this operation */
69	mcap_cb_type		cb;		/* Operation callback */
70	GDestroyNotify		destroy;	/* Destroy callback */
71	gpointer		user_data;	/* Callback user data */
72};
73
74/* MCAP finite state machine functions */
75static void proc_req_connected(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t l);
76static void proc_req_pending(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t l);
77static void proc_req_active(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t l);
78
79static void (*proc_req[])(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t len) = {
80	proc_req_connected,
81	proc_req_pending,
82	proc_req_active
83};
84
85static void mcap_cache_mcl(struct mcap_mcl *mcl);
86
87static void default_mdl_connected_cb(struct mcap_mdl *mdl, gpointer data)
88{
89	DBG("MCAP Unmanaged mdl connection");
90}
91
92static void default_mdl_closed_cb(struct mcap_mdl *mdl, gpointer data)
93{
94	DBG("MCAP Unmanaged mdl closed");
95}
96
97static void default_mdl_deleted_cb(struct mcap_mdl *mdl, gpointer data)
98{
99	DBG("MCAP Unmanaged mdl deleted");
100}
101
102static void default_mdl_aborted_cb(struct mcap_mdl *mdl, gpointer data)
103{
104	DBG("MCAP Unmanaged mdl aborted");
105}
106
107static uint8_t default_mdl_conn_req_cb(struct mcap_mcl *mcl,
108						uint8_t mdepid, uint16_t mdlid,
109						uint8_t *conf, gpointer data)
110{
111	DBG("MCAP mdl remote connection aborted");
112	/* Due to this callback isn't managed this request won't be supported */
113	return MCAP_REQUEST_NOT_SUPPORTED;
114}
115
116static uint8_t default_mdl_reconn_req_cb(struct mcap_mdl *mdl,
117						gpointer data)
118{
119	DBG("MCAP mdl remote reconnection aborted");
120	/* Due to this callback isn't managed this request won't be supported */
121	return MCAP_REQUEST_NOT_SUPPORTED;
122}
123
124static void set_default_cb(struct mcap_mcl *mcl)
125{
126	if (!mcl->cb)
127		mcl->cb = g_new0(struct mcap_mdl_cb, 1);
128
129	mcl->cb->mdl_connected = default_mdl_connected_cb;
130	mcl->cb->mdl_closed = default_mdl_closed_cb;
131	mcl->cb->mdl_deleted = default_mdl_deleted_cb;
132	mcl->cb->mdl_aborted = default_mdl_aborted_cb;
133	mcl->cb->mdl_conn_req = default_mdl_conn_req_cb;
134	mcl->cb->mdl_reconn_req = default_mdl_reconn_req_cb;
135}
136
137static char *error2str(uint8_t rc)
138{
139	switch (rc) {
140	case MCAP_SUCCESS:
141		return "Success";
142	case MCAP_INVALID_OP_CODE:
143		return "Invalid Op Code";
144	case MCAP_INVALID_PARAM_VALUE:
145		return "Invalid Parameter Value";
146	case MCAP_INVALID_MDEP:
147		return "Invalid MDEP";
148	case MCAP_MDEP_BUSY:
149		return "MDEP Busy";
150	case MCAP_INVALID_MDL:
151		return "Invalid MDL";
152	case MCAP_MDL_BUSY:
153		return "MDL Busy";
154	case MCAP_INVALID_OPERATION:
155		return "Invalid Operation";
156	case MCAP_RESOURCE_UNAVAILABLE:
157		return "Resource Unavailable";
158	case MCAP_UNSPECIFIED_ERROR:
159		return "Unspecified Error";
160	case MCAP_REQUEST_NOT_SUPPORTED:
161		return "Request Not Supported";
162	case MCAP_CONFIGURATION_REJECTED:
163		return "Configuration Rejected";
164	default:
165		return "Unknown Response Code";
166	}
167}
168
169static gboolean mcap_send_std_opcode(struct mcap_mcl *mcl, void *cmd,
170						uint32_t size, GError **err)
171{
172	if (mcl->state == MCL_IDLE) {
173		g_set_error(err, MCAP_ERROR, MCAP_ERROR_FAILED,
174							"MCL is not connected");
175		return FALSE;
176	}
177
178	if (mcl->req != MCL_AVAILABLE) {
179		g_set_error(err, MCAP_ERROR, MCAP_ERROR_RESOURCE_UNAVAILABLE,
180							"Pending request");
181		return FALSE;
182	}
183
184	if (!(mcl->ctrl & MCAP_CTRL_STD_OP)) {
185		g_set_error(err, MCAP_ERROR, MCAP_ERROR_REQUEST_NOT_SUPPORTED,
186				"Remote does not support standard opcodes");
187		return FALSE;
188	}
189
190	if (mcl->state == MCL_PENDING) {
191		g_set_error(err, MCAP_ERROR, MCAP_ERROR_INVALID_OPERATION,
192			"Not Std Op. Codes can be sent in PENDING State");
193		return FALSE;
194	}
195
196	if (mcap_send_data(g_io_channel_unix_get_fd(mcl->cc), cmd, size) < 0) {
197		g_set_error(err, MCAP_ERROR, MCAP_ERROR_FAILED,
198					"Command can't be sent, write error");
199		return FALSE;
200	}
201
202	mcl->lcmd = cmd;
203	mcl->req = MCL_WAITING_RSP;
204
205	return TRUE;
206}
207
208static void update_mcl_state(struct mcap_mcl *mcl)
209{
210	GSList *l;
211	struct mcap_mdl *mdl;
212
213	if (mcl->state == MCL_PENDING)
214		return;
215
216	for (l = mcl->mdls; l; l = l->next) {
217		mdl = l->data;
218
219		if (mdl->state == MDL_CONNECTED) {
220			mcl->state = MCL_ACTIVE;
221			return;
222		}
223	}
224
225	mcl->state = MCL_CONNECTED;
226}
227
228static void shutdown_mdl(struct mcap_mdl *mdl)
229{
230	mdl->state = MDL_CLOSED;
231
232	if (mdl->wid) {
233		g_source_remove(mdl->wid);
234		mdl->wid = 0;
235	}
236
237	if (mdl->dc) {
238		g_io_channel_shutdown(mdl->dc, TRUE, NULL);
239		g_io_channel_unref(mdl->dc);
240		mdl->dc = NULL;
241	}
242}
243
244static void free_mdl(struct mcap_mdl *mdl)
245{
246	if (!mdl)
247		return;
248
249	mcap_mcl_unref(mdl->mcl);
250	g_free(mdl);
251}
252
253static gint cmp_mdl_state(gconstpointer a, gconstpointer b)
254{
255	const struct mcap_mdl *mdl = a;
256	const MDLState *st = b;
257
258	if (mdl->state == *st)
259		return 0;
260	else if (mdl->state < *st)
261		return -1;
262	else
263		return 1;
264}
265
266static void free_mcl_priv_data(struct mcap_mcl *mcl)
267{
268	struct mcap_mdl_op_cb *op = mcl->priv_data;
269
270	if (op->destroy)
271		op->destroy(op->user_data);
272
273	g_free(mcl->priv_data);
274	mcl->priv_data = NULL;
275}
276
277static void mcap_notify_error(struct mcap_mcl *mcl, GError *err)
278{
279	struct mcap_mdl_op_cb *con = mcl->priv_data;
280	struct mcap_mdl *mdl;
281	MDLState st;
282	GSList *l;
283
284	if (!con || !mcl->lcmd)
285		return;
286
287	switch (mcl->lcmd[0]) {
288	case MCAP_MD_CREATE_MDL_REQ:
289		st = MDL_WAITING;
290		l = g_slist_find_custom(mcl->mdls, &st, cmp_mdl_state);
291		mdl = l->data;
292		mcl->mdls = g_slist_remove(mcl->mdls, mdl);
293		free_mdl(mdl);
294		update_mcl_state(mcl);
295		con->cb.op_conf(NULL, 0, err, con->user_data);
296		break;
297	case MCAP_MD_ABORT_MDL_REQ:
298		st = MDL_WAITING;
299		l = g_slist_find_custom(mcl->mdls, &st, cmp_mdl_state);
300		shutdown_mdl(l->data);
301		update_mcl_state(mcl);
302		con->cb.notify(err, con->user_data);
303		break;
304	case MCAP_MD_DELETE_MDL_REQ:
305		for (l = mcl->mdls; l; l = l->next) {
306			mdl = l->data;
307			if (mdl->state == MDL_DELETING)
308				mdl->state = (mdl->dc) ? MDL_CONNECTED :
309								MDL_CLOSED;
310		}
311		update_mcl_state(mcl);
312		con->cb.notify(err, con->user_data);
313		break;
314	case MCAP_MD_RECONNECT_MDL_REQ:
315		st = MDL_WAITING;
316		l = g_slist_find_custom(mcl->mdls, &st, cmp_mdl_state);
317		shutdown_mdl(l->data);
318		update_mcl_state(mcl);
319		con->cb.op(NULL, err, con->user_data);
320		break;
321	}
322
323	free_mcl_priv_data(mcl);
324	g_free(mcl->lcmd);
325	mcl->lcmd = NULL;
326}
327
328int mcap_send_data(int sock, const void *buf, uint32_t size)
329{
330	const uint8_t *buf_b = buf;
331	uint32_t sent = 0;
332
333	while (sent < size) {
334		int n = write(sock, buf_b + sent, size - sent);
335		if (n < 0)
336			return -1;
337		sent += n;
338	}
339
340	return 0;
341}
342
343static int mcap_send_cmd(struct mcap_mcl *mcl, uint8_t oc, uint8_t rc,
344					uint16_t mdl, uint8_t *data, size_t len)
345{
346	mcap_rsp *cmd;
347	int sock, sent;
348
349	if (mcl->cc == NULL)
350		return -1;
351
352	sock = g_io_channel_unix_get_fd(mcl->cc);
353
354	cmd = g_malloc(sizeof(mcap_rsp) + len);
355	cmd->op = oc;
356	cmd->rc = rc;
357	cmd->mdl = htons(mdl);
358
359	if (data && len > 0)
360		memcpy(cmd->data, data, len);
361
362	sent = mcap_send_data(sock, cmd, sizeof(mcap_rsp) + len);
363	g_free(cmd);
364
365	return sent;
366}
367
368static struct mcap_mdl *get_mdl(struct mcap_mcl *mcl, uint16_t mdlid)
369{
370	GSList *l;
371	struct mcap_mdl *mdl;
372
373	for (l = mcl->mdls; l; l = l->next) {
374		mdl = l->data;
375		if (mdlid == mdl->mdlid)
376			return mdl;
377	}
378
379	return NULL;
380}
381
382static uint16_t generate_mdlid(struct mcap_mcl *mcl)
383{
384	uint16_t mdlid = mcl->next_mdl;
385	struct mcap_mdl *mdl;
386
387	do {
388		mdl = get_mdl(mcl, mdlid);
389		if (!mdl) {
390			mcl->next_mdl = (mdlid % MCAP_MDLID_FINAL) + 1;
391			return mdlid;
392		} else
393			mdlid = (mdlid % MCAP_MDLID_FINAL) + 1;
394	} while (mdlid != mcl->next_mdl);
395
396	/* No more mdlids availables */
397	return 0;
398}
399
400static mcap_md_req *create_req(uint8_t op, uint16_t mdl_id)
401{
402	mcap_md_req *req_cmd;
403
404	req_cmd = g_new0(mcap_md_req, 1);
405
406	req_cmd->op = op;
407	req_cmd->mdl = htons(mdl_id);
408
409	return req_cmd;
410}
411
412static mcap_md_create_mdl_req *create_mdl_req(uint16_t mdl_id, uint8_t mdep,
413								uint8_t conf)
414{
415	mcap_md_create_mdl_req *req_mdl;
416
417	req_mdl = g_new0(mcap_md_create_mdl_req, 1);
418
419	req_mdl->op = MCAP_MD_CREATE_MDL_REQ;
420	req_mdl->mdl = htons(mdl_id);
421	req_mdl->mdep = mdep;
422	req_mdl->conf = conf;
423
424	return req_mdl;
425}
426
427static gint compare_mdl(gconstpointer a, gconstpointer b)
428{
429	const struct mcap_mdl *mdla = a;
430	const struct mcap_mdl *mdlb = b;
431
432	if (mdla->mdlid == mdlb->mdlid)
433		return 0;
434	else if (mdla->mdlid < mdlb->mdlid)
435		return -1;
436	else
437		return 1;
438}
439
440static gboolean wait_response_timer(gpointer data)
441{
442	struct mcap_mcl *mcl = data;
443
444	GError *gerr = NULL;
445
446	RELEASE_TIMER(mcl);
447
448	g_set_error(&gerr, MCAP_ERROR, MCAP_ERROR_FAILED,
449					"Timeout waiting response");
450
451	mcap_notify_error(mcl, gerr);
452
453	g_error_free(gerr);
454	mcl->ms->mcl_disconnected_cb(mcl, mcl->ms->user_data);
455	mcap_cache_mcl(mcl);
456
457	return FALSE;
458}
459
460gboolean mcap_create_mdl(struct mcap_mcl *mcl,
461				uint8_t mdepid,
462				uint8_t conf,
463				mcap_mdl_operation_conf_cb connect_cb,
464				gpointer user_data,
465				GDestroyNotify destroy,
466				GError **err)
467{
468	struct mcap_mdl *mdl;
469	struct mcap_mdl_op_cb *con;
470	mcap_md_create_mdl_req *cmd;
471	uint16_t id;
472
473	id = generate_mdlid(mcl);
474	if (!id) {
475		g_set_error(err, MCAP_ERROR, MCAP_ERROR_FAILED,
476					"Not more mdlids available");
477		return FALSE;
478	}
479
480	mdl = g_new0(struct mcap_mdl, 1);
481	mdl->mcl = mcap_mcl_ref(mcl);
482	mdl->mdlid = id;
483	mdl->mdep_id = mdepid;
484	mdl->state = MDL_WAITING;
485
486	con = g_new0(struct mcap_mdl_op_cb, 1);
487	con->mdl = mdl;
488	con->cb.op_conf = connect_cb;
489	con->destroy = destroy;
490	con->user_data = user_data;
491
492	cmd = create_mdl_req(id, mdepid, conf);
493	if (!mcap_send_std_opcode(mcl, cmd, sizeof(mcap_md_create_mdl_req),
494									err)) {
495		free_mdl(mdl);
496		g_free(con);
497		g_free(cmd);
498		return FALSE;
499	}
500
501	mcl->state = MCL_ACTIVE;
502	mcl->priv_data = con;
503
504	mcl->mdls = g_slist_insert_sorted(mcl->mdls, mdl, compare_mdl);
505	mcl->tid = g_timeout_add_seconds(RESPONSE_TIMER, wait_response_timer,
506									mcl);
507	return TRUE;
508}
509
510gboolean mcap_reconnect_mdl(struct mcap_mdl *mdl,
511				mcap_mdl_operation_cb reconnect_cb,
512				gpointer user_data,
513				GDestroyNotify destroy,
514				GError **err)
515{
516	struct mcap_mdl_op_cb *con;
517	struct mcap_mcl *mcl = mdl->mcl;
518	mcap_md_req *cmd;
519
520	if (mdl->state != MDL_CLOSED) {
521		g_set_error(err, MCAP_ERROR, MCAP_ERROR_FAILED,
522					"MDL is not closed");
523		return FALSE;
524	}
525	con = g_new0(struct mcap_mdl_op_cb, 1);
526
527	cmd = create_req(MCAP_MD_RECONNECT_MDL_REQ, mdl->mdlid);
528	if (!mcap_send_std_opcode(mcl, cmd, sizeof(mcap_md_req), err)) {
529		g_free(con);
530		g_free(cmd);
531		return FALSE;
532	}
533
534	mdl->state = MDL_WAITING;
535
536	con->mdl = mdl;
537	con->cb.op = reconnect_cb;
538	con->destroy = destroy;
539	con->user_data = user_data;
540
541	mcl->state = MCL_ACTIVE;
542	mcl->priv_data = con;
543
544	mcl->tid = g_timeout_add_seconds(RESPONSE_TIMER, wait_response_timer,
545									mcl);
546	return TRUE;
547}
548
549static gboolean send_delete_req(struct mcap_mcl *mcl,
550						struct mcap_mdl_op_cb *con,
551						uint16_t mdlid,
552						GError **err)
553{
554	mcap_md_req *cmd;
555
556	cmd = create_req(MCAP_MD_DELETE_MDL_REQ, mdlid);
557	if (!mcap_send_std_opcode(mcl, cmd, sizeof(mcap_md_req), err)) {
558		g_free(cmd);
559		return FALSE;
560	}
561
562	mcl->priv_data = con;
563
564	mcl->tid = g_timeout_add_seconds(RESPONSE_TIMER, wait_response_timer,
565									mcl);
566	return TRUE;
567}
568
569gboolean mcap_delete_all_mdls(struct mcap_mcl *mcl,
570					mcap_mdl_notify_cb delete_cb,
571					gpointer user_data,
572					GDestroyNotify destroy,
573					GError **err)
574{
575	GSList *l;
576	struct mcap_mdl *mdl;
577	struct mcap_mdl_op_cb *con;
578
579	DBG("MCL in state: %d", mcl->state);
580	if (!mcl->mdls) {
581		g_set_error(err, MCAP_ERROR, MCAP_ERROR_FAILED,
582				"There are not MDLs created");
583		return FALSE;
584	}
585
586	for (l = mcl->mdls; l; l = l->next) {
587		mdl = l->data;
588		if (mdl->state != MDL_WAITING)
589			mdl->state = MDL_DELETING;
590	}
591
592	con = g_new0(struct mcap_mdl_op_cb, 1);
593	con->mdl = NULL;
594	con->cb.notify = delete_cb;
595	con->destroy = destroy;
596	con->user_data = user_data;
597
598
599	if (!send_delete_req(mcl, con, MCAP_ALL_MDLIDS, err)) {
600		g_free(con);
601		return FALSE;
602	}
603
604	return TRUE;
605}
606
607gboolean mcap_delete_mdl(struct mcap_mdl *mdl, mcap_mdl_notify_cb delete_cb,
608							gpointer user_data,
609							GDestroyNotify destroy,
610							GError **err)
611{
612	struct mcap_mcl *mcl= mdl->mcl;
613	struct mcap_mdl_op_cb *con;
614	GSList *l;
615
616	l = g_slist_find(mcl->mdls, mdl);
617
618	if (!l) {
619		g_set_error(err, MCAP_ERROR, MCAP_ERROR_INVALID_MDL,
620					"%s" , error2str(MCAP_INVALID_MDEP));
621		return FALSE;
622	}
623
624	if (mdl->state == MDL_WAITING) {
625		g_set_error(err, MCAP_ERROR, MCAP_ERROR_FAILED,
626							"Mdl is not created");
627		return FALSE;
628	}
629
630	mdl->state = MDL_DELETING;
631
632	con = g_new0(struct mcap_mdl_op_cb, 1);
633	con->mdl = mdl;
634	con->cb.notify = delete_cb;
635	con->destroy = destroy;
636	con->user_data = user_data;
637
638	if (!send_delete_req(mcl, con, mdl->mdlid, err)) {
639		g_free(con);
640		return FALSE;
641	}
642
643	return TRUE;
644}
645
646gboolean mcap_mdl_abort(struct mcap_mdl *mdl, mcap_mdl_notify_cb abort_cb,
647							gpointer user_data,
648							GDestroyNotify destroy,
649							GError **err)
650{
651	struct mcap_mdl_op_cb *con;
652	struct mcap_mcl *mcl = mdl->mcl;
653	mcap_md_req *cmd;
654
655	if (mdl->state != MDL_WAITING) {
656		g_set_error(err, MCAP_ERROR, MCAP_ERROR_FAILED,
657							"Mdl in invalid state");
658		return FALSE;
659	}
660
661	con = g_new0(struct mcap_mdl_op_cb, 1);
662	cmd = create_req(MCAP_MD_ABORT_MDL_REQ, mdl->mdlid);
663	if (!mcap_send_std_opcode(mcl, cmd, sizeof(mcap_md_req), err)) {
664		g_free(con);
665		g_free(cmd);
666		return FALSE;
667	}
668
669	con->mdl = mdl;
670	con->cb.notify = abort_cb;
671	con->destroy = destroy;
672	con->user_data = user_data;
673
674	mcl->priv_data = con;
675	mcl->tid = g_timeout_add_seconds(RESPONSE_TIMER, wait_response_timer,
676									mcl);
677	return TRUE;
678}
679
680static struct mcap_mcl *find_mcl(GSList *list, const bdaddr_t *addr)
681{
682	GSList *l;
683	struct mcap_mcl *mcl;
684
685	for (l = list; l; l = l->next) {
686		mcl = l->data;
687
688		if (!bacmp(&mcl->addr, addr))
689			return mcl;
690	}
691
692	return NULL;
693}
694
695int mcap_mdl_get_fd(struct mcap_mdl *mdl)
696{
697	if (!mdl || mdl->state != MDL_CONNECTED)
698		return -ENOTCONN;
699
700	return g_io_channel_unix_get_fd(mdl->dc);
701}
702
703uint16_t mcap_mdl_get_mdlid(struct mcap_mdl *mdl)
704{
705	if (!mdl)
706		return MCAP_MDLID_RESERVED;
707
708	return mdl->mdlid;
709}
710
711static void close_mcl(struct mcap_mcl *mcl, gboolean cache_requested)
712{
713	gboolean save = ((!(mcl->ctrl & MCAP_CTRL_FREE)) && cache_requested);
714
715	RELEASE_TIMER(mcl);
716
717	if (mcl->cc) {
718		g_io_channel_shutdown(mcl->cc, TRUE, NULL);
719		g_io_channel_unref(mcl->cc);
720		mcl->cc = NULL;
721	}
722
723	if (mcl->wid) {
724		g_source_remove(mcl->wid);
725		mcl->wid = 0;
726	}
727
728	if (mcl->lcmd) {
729		g_free(mcl->lcmd);
730		mcl->lcmd = NULL;
731	}
732
733	if (mcl->priv_data)
734		free_mcl_priv_data(mcl);
735
736	g_slist_foreach(mcl->mdls, (GFunc) shutdown_mdl, NULL);
737
738	mcap_sync_stop(mcl);
739
740	mcl->state = MCL_IDLE;
741
742	if (save)
743		return;
744
745	g_slist_foreach(mcl->mdls, (GFunc) free_mdl, NULL);
746	g_slist_free(mcl->mdls);
747	mcl->mdls = NULL;
748}
749
750static void mcap_mcl_shutdown(struct mcap_mcl *mcl)
751{
752	close_mcl(mcl, TRUE);
753}
754
755static void mcap_mcl_release(struct mcap_mcl *mcl)
756{
757	close_mcl(mcl, FALSE);
758}
759
760static void mcap_cache_mcl(struct mcap_mcl *mcl)
761{
762	GSList *l;
763	struct mcap_mcl *last;
764	int len;
765
766	if (mcl->ctrl & MCAP_CTRL_CACHED)
767		return;
768
769	mcl->ms->mcls = g_slist_remove(mcl->ms->mcls, mcl);
770
771	if (mcl->ctrl & MCAP_CTRL_NOCACHE) {
772		mcl->ms->cached = g_slist_remove(mcl->ms->cached, mcl);
773		mcap_mcl_release(mcl);
774		mcap_mcl_unref(mcl);
775		return;
776	}
777
778	DBG("Caching MCL");
779
780	len = g_slist_length(mcl->ms->cached);
781	if (len == MAX_CACHED) {
782		/* Remove the latest cached mcl */
783		l = g_slist_last(mcl->ms->cached);
784		last = l->data;
785		mcl->ms->cached = g_slist_remove(mcl->ms->cached, last);
786		last->ctrl &= ~MCAP_CTRL_CACHED;
787		if (last->ctrl & MCAP_CTRL_CONN) {
788			/* We have to release this MCL if */
789			/* connection is not succesful    */
790			last->ctrl |= MCAP_CTRL_FREE;
791		} else {
792			mcap_mcl_release(last);
793			last->ms->mcl_uncached_cb(last, last->ms->user_data);
794		}
795		mcap_mcl_unref(last);
796	}
797
798	mcl->ms->cached = g_slist_prepend(mcl->ms->cached, mcl);
799	mcl->ctrl |= MCAP_CTRL_CACHED;
800	mcap_mcl_shutdown(mcl);
801}
802
803static void mcap_uncache_mcl(struct mcap_mcl *mcl)
804{
805	if (!(mcl->ctrl & MCAP_CTRL_CACHED))
806		return;
807
808	DBG("Got MCL from cache");
809
810	mcl->ms->cached = g_slist_remove(mcl->ms->cached, mcl);
811	mcl->ms->mcls = g_slist_prepend(mcl->ms->mcls, mcl);
812	mcl->ctrl &= ~MCAP_CTRL_CACHED;
813	mcl->ctrl &= ~MCAP_CTRL_FREE;
814}
815
816void mcap_close_mcl(struct mcap_mcl *mcl, gboolean cache)
817{
818	if (!mcl)
819		return;
820
821	if (mcl->ctrl & MCAP_CTRL_FREE) {
822		mcap_mcl_release(mcl);
823		return;
824	}
825
826	if (!cache)
827		mcl->ctrl |= MCAP_CTRL_NOCACHE;
828
829	if (mcl->cc) {
830		g_io_channel_shutdown(mcl->cc, TRUE, NULL);
831		g_io_channel_unref(mcl->cc);
832		mcl->cc = NULL;
833		mcl->state = MCL_IDLE;
834	} else if ((mcl->ctrl & MCAP_CTRL_CACHED) &&
835					(mcl->ctrl & MCAP_CTRL_NOCACHE)) {
836		mcl->ctrl &= ~MCAP_CTRL_CACHED;
837		mcl->ms->cached = g_slist_remove(mcl->ms->cached, mcl);
838		mcap_mcl_release(mcl);
839		mcap_mcl_unref(mcl);
840	}
841}
842
843struct mcap_mcl *mcap_mcl_ref(struct mcap_mcl *mcl)
844{
845	mcl->ref++;
846
847	DBG("mcap_mcl_ref(%p): ref=%d", mcl, mcl->ref);
848
849	return mcl;
850}
851
852void mcap_mcl_unref(struct mcap_mcl *mcl)
853{
854	mcl->ref--;
855
856	DBG("mcap_mcl_unref(%p): ref=%d", mcl, mcl->ref);
857
858	if (mcl->ref > 0)
859		return;
860
861	mcap_mcl_release(mcl);
862
863	g_free(mcl->cb);
864	g_free(mcl);
865}
866
867static gboolean parse_set_opts(struct mcap_mdl_cb *mdl_cb, GError **err,
868						McapMclCb cb1, va_list args)
869{
870	McapMclCb cb = cb1;
871	struct mcap_mdl_cb *c;
872
873	c = g_new0(struct mcap_mdl_cb, 1);
874
875	while (cb != MCAP_MDL_CB_INVALID) {
876		switch (cb) {
877		case MCAP_MDL_CB_CONNECTED:
878			c->mdl_connected = va_arg(args, mcap_mdl_event_cb);
879			break;
880		case MCAP_MDL_CB_CLOSED:
881			c->mdl_closed = va_arg(args, mcap_mdl_event_cb);
882			break;
883		case MCAP_MDL_CB_DELETED:
884			c->mdl_deleted = va_arg(args, mcap_mdl_event_cb);
885			break;
886		case MCAP_MDL_CB_ABORTED:
887			c->mdl_aborted = va_arg(args, mcap_mdl_event_cb);
888			break;
889		case MCAP_MDL_CB_REMOTE_CONN_REQ:
890			c->mdl_conn_req = va_arg(args,
891						mcap_remote_mdl_conn_req_cb);
892			break;
893		case MCAP_MDL_CB_REMOTE_RECONN_REQ:
894			c->mdl_reconn_req = va_arg(args,
895						mcap_remote_mdl_reconn_req_cb);
896			break;
897		default:
898			g_set_error(err, MCAP_ERROR, MCAP_ERROR_INVALID_ARGS,
899						"Unknown option %d", cb);
900			return FALSE;
901		}
902		cb = va_arg(args, int);
903	}
904
905	/* Set new callbacks */
906	if (c->mdl_connected)
907		mdl_cb->mdl_connected = c->mdl_connected;
908	if (c->mdl_closed)
909		mdl_cb->mdl_closed = c->mdl_closed;
910	if (c->mdl_deleted)
911		mdl_cb->mdl_deleted = c->mdl_deleted;
912	if (c->mdl_aborted)
913		mdl_cb->mdl_aborted = c->mdl_aborted;
914	if (c->mdl_conn_req)
915		mdl_cb->mdl_conn_req = c->mdl_conn_req;
916	if (c->mdl_reconn_req)
917		mdl_cb->mdl_reconn_req = c->mdl_reconn_req;
918
919	g_free(c);
920
921	return TRUE;
922}
923
924gboolean mcap_mcl_set_cb(struct mcap_mcl *mcl, gpointer user_data,
925					GError **gerr, McapMclCb cb1, ...)
926{
927	va_list args;
928	gboolean ret;
929
930	va_start(args, cb1);
931	ret = parse_set_opts(mcl->cb, gerr, cb1, args);
932	va_end(args);
933
934	if (!ret)
935		return FALSE;
936
937	mcl->cb->user_data = user_data;
938	return TRUE;
939}
940
941void mcap_mcl_get_addr(struct mcap_mcl *mcl, bdaddr_t *addr)
942{
943	bacpy(addr, &mcl->addr);
944}
945
946static void mcap_del_mdl(gpointer elem, gpointer user_data)
947{
948	struct mcap_mdl *mdl = elem;
949	gboolean notify = *(gboolean *) user_data;
950
951	shutdown_mdl(mdl);
952	if (notify)
953		mdl->mcl->cb->mdl_deleted(mdl, mdl->mcl->cb->user_data);
954
955	free_mdl(mdl);
956}
957
958static gboolean check_cmd_req_length(struct mcap_mcl *mcl, void *cmd,
959				uint32_t rlen, uint32_t explen, uint8_t rspcod)
960{
961	mcap_md_req *req;
962	uint16_t mdl_id;
963
964	if (rlen != explen) {
965		if (rlen >= sizeof(mcap_md_req)) {
966			req = cmd;
967			mdl_id = ntohs(req->mdl);
968		} else {
969			/* We can't get mdlid */
970			mdl_id = MCAP_MDLID_RESERVED;
971		}
972		mcap_send_cmd(mcl, rspcod, MCAP_INVALID_PARAM_VALUE, mdl_id,
973								NULL, 0);
974		return FALSE;
975	}
976	return TRUE;
977}
978
979static void process_md_create_mdl_req(struct mcap_mcl *mcl, void *cmd,
980								uint32_t len)
981{
982	mcap_md_create_mdl_req *req;
983	struct mcap_mdl *mdl;
984	uint16_t mdl_id;
985	uint8_t mdep_id;
986	uint8_t cfga, conf;
987	uint8_t rsp;
988
989	if (!check_cmd_req_length(mcl, cmd, len, sizeof(mcap_md_create_mdl_req),
990							MCAP_MD_CREATE_MDL_RSP))
991		return;
992
993	req = cmd;
994	mdl_id = ntohs(req->mdl);
995	if (mdl_id < MCAP_MDLID_INITIAL || mdl_id > MCAP_MDLID_FINAL) {
996		mcap_send_cmd(mcl, MCAP_MD_CREATE_MDL_RSP, MCAP_INVALID_MDL,
997							mdl_id, NULL, 0);
998		return;
999	}
1000
1001	mdep_id = req->mdep;
1002	if (mdep_id > MCAP_MDEPID_FINAL) {
1003		mcap_send_cmd(mcl, MCAP_MD_CREATE_MDL_RSP, MCAP_INVALID_MDEP,
1004							mdl_id, NULL, 0);
1005		return;
1006	}
1007
1008	mdl = get_mdl(mcl, mdl_id);
1009	if (mdl && (mdl->state == MDL_WAITING || mdl->state == MDL_DELETING )) {
1010		/* Creation request arrives for a MDL that is being managed
1011		* at current moment */
1012		mcap_send_cmd(mcl, MCAP_MD_CREATE_MDL_RSP, MCAP_MDL_BUSY,
1013							mdl_id, NULL, 0);
1014		return;
1015	}
1016
1017	cfga = conf = req->conf;
1018	/* Callback to upper layer */
1019	rsp = mcl->cb->mdl_conn_req(mcl, mdep_id, mdl_id, &conf,
1020							mcl->cb->user_data);
1021	if (mcl->state == MCL_IDLE) {
1022		/* MCL has been closed int the callback */
1023		return;
1024	}
1025
1026	if (cfga != 0 && cfga != conf) {
1027		/* Remote device set default configuration but upper profile */
1028		/* has changed it. Protocol Error: force closing the MCL by */
1029		/* remote device using UNSPECIFIED_ERROR response */
1030		mcap_send_cmd(mcl, MCAP_MD_CREATE_MDL_RSP,
1031				MCAP_UNSPECIFIED_ERROR, mdl_id, NULL, 0);
1032		return;
1033	}
1034	if (rsp != MCAP_SUCCESS) {
1035		mcap_send_cmd(mcl, MCAP_MD_CREATE_MDL_RSP, rsp, mdl_id,
1036								NULL, 0);
1037		return;
1038	}
1039
1040	if (!mdl) {
1041		mdl = g_new0(struct mcap_mdl, 1);
1042		mdl->mcl = mcap_mcl_ref(mcl);
1043		mdl->mdlid = mdl_id;
1044		mcl->mdls = g_slist_insert_sorted(mcl->mdls, mdl, compare_mdl);
1045	} else if (mdl->state == MDL_CONNECTED) {
1046		/* MCAP specification says that we should close the MCL if
1047		 * it is open when we receive a MD_CREATE_MDL_REQ */
1048		shutdown_mdl(mdl);
1049	}
1050
1051	mdl->mdep_id = mdep_id;
1052	mdl->state = MDL_WAITING;
1053
1054	mcl->state = MCL_PENDING;
1055	mcap_send_cmd(mcl, MCAP_MD_CREATE_MDL_RSP, MCAP_SUCCESS, mdl_id,
1056								&conf, 1);
1057}
1058
1059static void process_md_reconnect_mdl_req(struct mcap_mcl *mcl, void *cmd,
1060								uint32_t len)
1061{
1062	mcap_md_req *req;
1063	struct mcap_mdl *mdl;
1064	uint16_t mdl_id;
1065	uint8_t rsp;
1066
1067	if (!check_cmd_req_length(mcl, cmd, len, sizeof(mcap_md_req),
1068						MCAP_MD_RECONNECT_MDL_RSP))
1069		return;
1070
1071	req = cmd;
1072	mdl_id = ntohs(req->mdl);
1073
1074	mdl = get_mdl(mcl, mdl_id);
1075	if (!mdl) {
1076		mcap_send_cmd(mcl, MCAP_MD_RECONNECT_MDL_RSP, MCAP_INVALID_MDL,
1077							mdl_id, NULL, 0);
1078		return;
1079	} else if (mdl->state == MDL_WAITING || mdl->state == MDL_DELETING ) {
1080		/* Creation request arrives for a MDL that is being managed
1081		* at current moment */
1082		mcap_send_cmd(mcl, MCAP_MD_RECONNECT_MDL_RSP, MCAP_MDL_BUSY,
1083							mdl_id, NULL, 0);
1084		return;
1085	}
1086
1087	/* Callback to upper layer */
1088	rsp = mcl->cb->mdl_reconn_req(mdl, mcl->cb->user_data);
1089	if (mcl->state == MCL_IDLE)
1090		return;
1091
1092	if (rsp != MCAP_SUCCESS) {
1093		mcap_send_cmd(mcl, MCAP_MD_RECONNECT_MDL_RSP, rsp, mdl_id,
1094								NULL, 0);
1095		return;
1096	}
1097
1098	if (mdl->state == MDL_CONNECTED)
1099		shutdown_mdl(mdl);
1100
1101	mdl->state = MDL_WAITING;
1102	mcl->state = MCL_PENDING;
1103	mcap_send_cmd(mcl, MCAP_MD_RECONNECT_MDL_RSP, MCAP_SUCCESS, mdl_id,
1104								NULL, 0);
1105}
1106
1107static void process_md_abort_mdl_req(struct mcap_mcl *mcl, void *cmd,
1108								uint32_t len)
1109{
1110	mcap_md_req *req;
1111	GSList *l;
1112	struct mcap_mdl *mdl, *abrt;
1113	uint16_t mdl_id;
1114
1115	if (!check_cmd_req_length(mcl, cmd, len, sizeof(mcap_md_req),
1116							MCAP_MD_ABORT_MDL_RSP))
1117		return;
1118
1119	req = cmd;
1120	mdl_id = ntohs(req->mdl);
1121	mcl->state = MCL_CONNECTED;
1122	for (l = mcl->mdls; l; l = l->next) {
1123		mdl = l->data;
1124		if (mdl_id == mdl->mdlid && mdl->state == MDL_WAITING) {
1125			abrt = mdl;
1126			if (mcl->state != MCL_CONNECTED)
1127				break;
1128			continue;
1129		}
1130		if (mdl->state == MDL_CONNECTED && mcl->state != MCL_ACTIVE)
1131			mcl->state = MCL_ACTIVE;
1132
1133		if (abrt && mcl->state == MCL_ACTIVE)
1134			break;
1135	}
1136
1137	if (!abrt) {
1138		mcap_send_cmd(mcl, MCAP_MD_ABORT_MDL_RSP, MCAP_INVALID_MDL,
1139							mdl_id, NULL, 0);
1140		return;
1141	}
1142
1143	mcl->cb->mdl_aborted(abrt, mcl->cb->user_data);
1144	abrt->state = MDL_CLOSED;
1145	mcap_send_cmd(mcl, MCAP_MD_ABORT_MDL_RSP, MCAP_SUCCESS, mdl_id,
1146								NULL, 0);
1147}
1148
1149static void process_md_delete_mdl_req(struct mcap_mcl *mcl, void *cmd,
1150								uint32_t len)
1151{
1152	mcap_md_req *req;
1153	struct mcap_mdl *mdl, *aux;
1154	uint16_t mdlid;
1155	gboolean notify;
1156	GSList *l;
1157
1158	if (!check_cmd_req_length(mcl, cmd, len, sizeof(mcap_md_req),
1159							MCAP_MD_DELETE_MDL_RSP))
1160		return;
1161
1162	req = cmd;
1163	mdlid = ntohs(req->mdl);
1164	if (mdlid == MCAP_ALL_MDLIDS) {
1165		notify = FALSE;
1166		g_slist_foreach(mcl->mdls, mcap_del_mdl, &notify);
1167		g_slist_free(mcl->mdls);
1168		mcl->mdls = NULL;
1169		mcl->state = MCL_CONNECTED;
1170		/* NULL mdl means ALL_MDLS */
1171		mcl->cb->mdl_deleted(NULL, mcl->cb->user_data);
1172		goto resp;
1173	}
1174
1175	if (mdlid < MCAP_MDLID_INITIAL || mdlid > MCAP_MDLID_FINAL) {
1176		mcap_send_cmd(mcl, MCAP_MD_DELETE_MDL_RSP, MCAP_INVALID_MDL,
1177								mdlid, NULL, 0);
1178		return;
1179	}
1180
1181	for (l = mcl->mdls, mdl = NULL; l; l = l->next) {
1182		aux = l->data;
1183		if (aux->mdlid == mdlid) {
1184			mdl = aux;
1185			break;
1186		}
1187	}
1188
1189	if (!mdl || mdl->state == MDL_WAITING) {
1190		mcap_send_cmd(mcl, MCAP_MD_DELETE_MDL_RSP, MCAP_INVALID_MDL,
1191								mdlid, NULL, 0);
1192		return;
1193	}
1194
1195	mcl->mdls = g_slist_remove(mcl->mdls, mdl);
1196	update_mcl_state(mcl);
1197	notify = TRUE;
1198	mcap_del_mdl(mdl, &notify);
1199
1200resp:
1201	mcap_send_cmd(mcl, MCAP_MD_DELETE_MDL_RSP, MCAP_SUCCESS, mdlid,
1202								NULL, 0);
1203}
1204
1205static void invalid_req_state(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t len)
1206{
1207	uint16_t mdlr;
1208
1209	error("Invalid cmd received (op code = %d) in state %d", cmd[0],
1210								mcl->state);
1211	/* Get previously mdlid sent to generate an appropriate
1212	 * response if it is possible */
1213	mdlr = len < sizeof(mcap_md_req) ? MCAP_MDLID_RESERVED :
1214					ntohs(((mcap_md_req *) cmd)->mdl);
1215	mcap_send_cmd(mcl, cmd[0]+1, MCAP_INVALID_OPERATION, mdlr, NULL, 0);
1216}
1217
1218/* Function used to process commands depending of MCL state */
1219static void proc_req_connected(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t len)
1220{
1221	switch (cmd[0]) {
1222	case MCAP_MD_CREATE_MDL_REQ:
1223		process_md_create_mdl_req(mcl, cmd, len);
1224		break;
1225	case MCAP_MD_RECONNECT_MDL_REQ:
1226		process_md_reconnect_mdl_req(mcl, cmd, len);
1227		break;
1228	case MCAP_MD_DELETE_MDL_REQ:
1229		process_md_delete_mdl_req(mcl, cmd, len);
1230		break;
1231	default:
1232		invalid_req_state(mcl, cmd, len);
1233	}
1234}
1235
1236static void proc_req_pending(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t len)
1237{
1238	if (cmd[0] == MCAP_MD_ABORT_MDL_REQ)
1239		process_md_abort_mdl_req(mcl, cmd, len);
1240	else
1241		invalid_req_state(mcl, cmd, len);
1242}
1243
1244static void proc_req_active(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t len)
1245{
1246	switch (cmd[0]) {
1247	case MCAP_MD_CREATE_MDL_REQ:
1248		process_md_create_mdl_req(mcl, cmd, len);
1249		break;
1250	case MCAP_MD_RECONNECT_MDL_REQ:
1251		process_md_reconnect_mdl_req(mcl, cmd, len);
1252		break;
1253	case MCAP_MD_DELETE_MDL_REQ:
1254		process_md_delete_mdl_req(mcl, cmd, len);
1255		break;
1256	default:
1257		invalid_req_state(mcl, cmd, len);
1258	}
1259}
1260
1261/* Function used to process replies */
1262static gboolean check_err_rsp(struct mcap_mcl *mcl, mcap_rsp *rsp,
1263				uint32_t rlen, uint32_t len, GError **gerr)
1264{
1265	mcap_md_req *cmdlast = (mcap_md_req *) mcl->lcmd;
1266	gint err = MCAP_ERROR_FAILED;
1267	gboolean close = FALSE;
1268	char *msg;
1269
1270	if (rsp->op == MCAP_ERROR_RSP) {
1271		msg = "MCAP_ERROR_RSP received";
1272		close = FALSE;
1273		goto fail;
1274	}
1275
1276	/* Check if the response matches with the last request */
1277	if (rlen < sizeof(mcap_rsp) || (mcl->lcmd[0] + 1) != rsp->op) {
1278		msg = "Protocol error";
1279		close = FALSE;
1280		goto fail;
1281	}
1282
1283	if (rlen < len) {
1284		msg = "Protocol error";
1285		close = FALSE;
1286		goto fail;
1287	}
1288
1289	if (rsp->mdl != cmdlast->mdl) {
1290		msg = "MDLID received doesn't match with MDLID sent";
1291		close = TRUE;
1292		goto fail;
1293	}
1294
1295	if (rsp->rc == MCAP_REQUEST_NOT_SUPPORTED) {
1296		msg = "Remote does not support opcodes";
1297		mcl->ctrl &= ~MCAP_CTRL_STD_OP;
1298		goto fail;
1299	}
1300
1301	if (rsp->rc == MCAP_UNSPECIFIED_ERROR) {
1302		msg = "Unspecified error";
1303		close = TRUE;
1304		goto fail;
1305	}
1306
1307	if (rsp->rc != MCAP_SUCCESS) {
1308		msg = error2str(rsp->rc);
1309		err = rsp->rc;
1310		goto fail;
1311	}
1312
1313	return FALSE;
1314
1315fail:
1316	g_set_error(gerr, MCAP_ERROR, err, "%s", msg);
1317	return close;
1318}
1319
1320static gboolean process_md_create_mdl_rsp(struct mcap_mcl *mcl,
1321						mcap_rsp *rsp, uint32_t len)
1322{
1323	mcap_md_create_mdl_req *cmdlast = (mcap_md_create_mdl_req *) mcl->lcmd;
1324	struct mcap_mdl_op_cb *conn = mcl->priv_data;
1325	mcap_mdl_operation_conf_cb connect_cb = conn->cb.op_conf;
1326	gpointer user_data = conn->user_data;
1327	struct mcap_mdl *mdl = conn->mdl;
1328	uint8_t conf = cmdlast->conf;
1329	gboolean close;
1330	GError *gerr = NULL;
1331
1332	close = check_err_rsp(mcl, rsp, len, sizeof(mcap_rsp) + 1, &gerr);
1333	g_free(mcl->lcmd);
1334	mcl->lcmd = NULL;
1335	mcl->req = MCL_AVAILABLE;
1336
1337	if (gerr)
1338		goto fail;
1339
1340	/* Check if preferences changed */
1341	if (conf != 0x00 && rsp->data[0] != conf) {
1342		g_set_error(&gerr, MCAP_ERROR, MCAP_ERROR_FAILED,
1343						"Configuration changed");
1344		close = TRUE;
1345		goto fail;
1346	}
1347
1348	connect_cb(mdl, rsp->data[0], gerr, user_data);
1349	return close;
1350
1351fail:
1352	connect_cb(NULL, 0, gerr, user_data);
1353	mcl->mdls = g_slist_remove(mcl->mdls, mdl);
1354	free_mdl(mdl);
1355	g_error_free(gerr);
1356	update_mcl_state(mcl);
1357	return close;
1358}
1359
1360static gboolean process_md_reconnect_mdl_rsp(struct mcap_mcl *mcl,
1361						mcap_rsp *rsp, uint32_t len)
1362{
1363	struct mcap_mdl_op_cb *reconn = mcl->priv_data;
1364	mcap_mdl_operation_cb reconn_cb = reconn->cb.op;
1365	gpointer user_data = reconn->user_data;
1366	struct mcap_mdl *mdl = reconn->mdl;
1367	GError *gerr = NULL;
1368	gboolean close;
1369
1370	close = check_err_rsp(mcl, rsp, len, sizeof(mcap_rsp), &gerr);
1371
1372	g_free(mcl->lcmd);
1373	mcl->lcmd = NULL;
1374	mcl->req = MCL_AVAILABLE;
1375
1376	reconn_cb(mdl, gerr, user_data);
1377	if (!gerr)
1378		return close;
1379
1380	g_error_free(gerr);
1381	shutdown_mdl(mdl);
1382	update_mcl_state(mcl);
1383
1384	if (rsp->rc != MCAP_INVALID_MDL)
1385		return close;
1386
1387	/* Remove cached mdlid */
1388	mcl->mdls = g_slist_remove(mcl->mdls, mdl);
1389	mcl->cb->mdl_deleted(mdl, mcl->cb->user_data);
1390	free_mdl(mdl);
1391
1392	return close;
1393}
1394
1395static gboolean process_md_abort_mdl_rsp(struct mcap_mcl *mcl,
1396						mcap_rsp *rsp, uint32_t len)
1397{
1398	struct mcap_mdl_op_cb *abrt = mcl->priv_data;
1399	mcap_mdl_notify_cb abrt_cb = abrt->cb.notify;
1400	gpointer user_data = abrt->user_data;
1401	struct mcap_mdl *mdl = abrt->mdl;
1402	GError *gerr = NULL;
1403	gboolean close;
1404
1405	close = check_err_rsp(mcl, rsp, len, sizeof(mcap_rsp), &gerr);
1406
1407	g_free(mcl->lcmd);
1408	mcl->lcmd = NULL;
1409	mcl->req = MCL_AVAILABLE;
1410
1411	abrt_cb(gerr, user_data);
1412	shutdown_mdl(mdl);
1413
1414	if (len >= sizeof(mcap_rsp) && rsp->rc == MCAP_INVALID_MDL) {
1415		mcl->mdls = g_slist_remove(mcl->mdls, mdl);
1416		free_mdl(mdl);
1417	}
1418
1419	if (gerr)
1420		g_error_free(gerr);
1421
1422	update_mcl_state(mcl);
1423
1424	return close;
1425}
1426
1427static void restore_mdl(gpointer elem, gpointer data)
1428{
1429	struct mcap_mdl *mdl = elem;
1430
1431	if (mdl->state == MDL_DELETING) {
1432		if (mdl->dc)
1433			mdl->state = MDL_CONNECTED;
1434		else
1435			mdl->state = MDL_CLOSED;
1436	} else if (mdl->state == MDL_CLOSED)
1437		mdl->mcl->cb->mdl_closed(mdl, mdl->mcl->cb->user_data);
1438}
1439
1440static void check_mdl_del_err(struct mcap_mdl *mdl, mcap_rsp *rsp)
1441{
1442	if (rsp->rc != MCAP_ERROR_INVALID_MDL) {
1443		restore_mdl(mdl, NULL);
1444		return;
1445	}
1446
1447	/* MDL does not exist in remote side, we can delete it */
1448	mdl->mcl->mdls = g_slist_remove(mdl->mcl->mdls, mdl);
1449	free_mdl(mdl);
1450}
1451
1452static gboolean process_md_delete_mdl_rsp(struct mcap_mcl *mcl, mcap_rsp *rsp,
1453								uint32_t len)
1454{
1455	struct mcap_mdl_op_cb *del = mcl->priv_data;
1456	struct mcap_mdl *mdl = del->mdl;
1457	mcap_mdl_notify_cb deleted_cb = del->cb.notify;
1458	gpointer user_data = del->user_data;
1459	mcap_md_req *cmdlast = (mcap_md_req *) mcl->lcmd;
1460	uint16_t mdlid = ntohs(cmdlast->mdl);
1461	GError *gerr = NULL;
1462	gboolean close;
1463	gboolean notify = FALSE;
1464
1465	close = check_err_rsp(mcl, rsp, len, sizeof(mcap_rsp), &gerr);
1466
1467	g_free(mcl->lcmd);
1468	mcl->lcmd = NULL;
1469	mcl->req = MCL_AVAILABLE;
1470
1471	if (gerr) {
1472		if (mdl)
1473			check_mdl_del_err(mdl, rsp);
1474		else
1475			g_slist_foreach(mcl->mdls, restore_mdl, NULL);
1476		deleted_cb(gerr, user_data);
1477		g_error_free(gerr);
1478		return close;
1479	}
1480
1481	if (mdlid == MCAP_ALL_MDLIDS) {
1482		g_slist_foreach(mcl->mdls, mcap_del_mdl, &notify);
1483		g_slist_free(mcl->mdls);
1484		mcl->mdls = NULL;
1485		mcl->state = MCL_CONNECTED;
1486	} else {
1487		mcl->mdls = g_slist_remove(mcl->mdls, mdl);
1488		update_mcl_state(mcl);
1489		mcap_del_mdl(mdl, &notify);
1490	}
1491
1492	deleted_cb(gerr, user_data);
1493
1494	return close;
1495}
1496
1497static void post_process_rsp(struct mcap_mcl *mcl, struct mcap_mdl_op_cb *op)
1498{
1499	if (op->destroy)
1500		op->destroy(op->user_data);
1501
1502	if (mcl->priv_data != op) {
1503		/* Queued MCAP request in some callback. */
1504		/* We sould not delete the mcl private data */
1505		g_free(op);
1506	} else {
1507		/* This is not queued requets. It's safe */
1508		/* delete the mcl private data here. */
1509		g_free(mcl->priv_data);
1510		mcl->priv_data = NULL;
1511	}
1512}
1513
1514static void proc_response(struct mcap_mcl *mcl, void *buf, uint32_t len)
1515{
1516	struct mcap_mdl_op_cb *op = mcl->priv_data;
1517	mcap_rsp *rsp = buf;
1518	gboolean close;
1519
1520	RELEASE_TIMER(mcl);
1521
1522	switch (mcl->lcmd[0] + 1) {
1523	case MCAP_MD_CREATE_MDL_RSP:
1524		close = process_md_create_mdl_rsp(mcl, rsp, len);
1525		post_process_rsp(mcl, op);
1526		break;
1527	case MCAP_MD_RECONNECT_MDL_RSP:
1528		close = process_md_reconnect_mdl_rsp(mcl, rsp, len);
1529		post_process_rsp(mcl, op);
1530		break;
1531	case MCAP_MD_ABORT_MDL_RSP:
1532		close = process_md_abort_mdl_rsp(mcl, rsp, len);
1533		post_process_rsp(mcl, op);
1534		break;
1535	case MCAP_MD_DELETE_MDL_RSP:
1536		close = process_md_delete_mdl_rsp(mcl, rsp, len);
1537		post_process_rsp(mcl, op);
1538		break;
1539	default:
1540		DBG("Unknown cmd response received (op code = %d)", rsp->op);
1541		close = TRUE;
1542		break;
1543	}
1544
1545	if (close) {
1546		mcl->ms->mcl_disconnected_cb(mcl, mcl->ms->user_data);
1547		mcap_cache_mcl(mcl);
1548	}
1549}
1550
1551static void proc_cmd(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t len)
1552{
1553	GError *gerr = NULL;
1554
1555	if (cmd[0] > MCAP_MD_SYNC_INFO_IND ||
1556					(cmd[0] > MCAP_MD_DELETE_MDL_RSP &&
1557					cmd[0] < MCAP_MD_SYNC_CAP_REQ)) {
1558		error("Unknown cmd received (op code = %d)", cmd[0]);
1559		mcap_send_cmd(mcl, MCAP_ERROR_RSP, MCAP_INVALID_OP_CODE,
1560						MCAP_MDLID_RESERVED, NULL, 0);
1561		return;
1562	}
1563
1564	if (cmd[0] >= MCAP_MD_SYNC_CAP_REQ &&
1565					cmd[0] <= MCAP_MD_SYNC_INFO_IND) {
1566		proc_sync_cmd(mcl, cmd, len);
1567		return;
1568	}
1569
1570	if (!(mcl->ctrl & MCAP_CTRL_STD_OP)) {
1571		/* In case the remote device doesn't work correctly */
1572		error("Remote device does not support opcodes, cmd ignored");
1573		return;
1574	}
1575
1576	if (mcl->req == MCL_WAITING_RSP) {
1577		if (cmd[0] & 0x01) {
1578			/* Request arrived when a response is expected */
1579			if (mcl->role == MCL_INITIATOR)
1580				/* ignore */
1581				return;
1582			/* Initiator will ignore our last request */
1583			RELEASE_TIMER(mcl);
1584			mcl->req = MCL_AVAILABLE;
1585			g_set_error(&gerr, MCAP_ERROR, MCAP_ERROR_REQ_IGNORED,
1586				"Initiator sent a request with more priority");
1587			mcap_notify_error(mcl, gerr);
1588			proc_req[mcl->state](mcl, cmd, len);
1589			return;
1590		}
1591		proc_response(mcl, cmd, len);
1592	} else if (cmd[0] & 0x01)
1593		proc_req[mcl->state](mcl, cmd, len);
1594}
1595
1596static gboolean mdl_event_cb(GIOChannel *chan, GIOCondition cond, gpointer data)
1597{
1598
1599	struct mcap_mdl *mdl = data;
1600	gboolean notify;
1601
1602	DBG("Close MDL %d", mdl->mdlid);
1603
1604	notify = (mdl->state == MDL_CONNECTED);
1605	shutdown_mdl(mdl);
1606
1607	update_mcl_state(mdl->mcl);
1608
1609	if (notify) {
1610		/*Callback to upper layer */
1611		mdl->mcl->cb->mdl_closed(mdl, mdl->mcl->cb->user_data);
1612	}
1613
1614	return FALSE;
1615}
1616
1617static void mcap_connect_mdl_cb(GIOChannel *chan, GError *conn_err,
1618								gpointer data)
1619{
1620	struct mcap_mdl_op_cb *con = data;
1621	struct mcap_mdl *mdl = con->mdl;
1622	mcap_mdl_operation_cb cb = con->cb.op;
1623	gpointer user_data = con->user_data;
1624
1625	DBG("mdl connect callback");
1626
1627	if (conn_err) {
1628		DBG("ERROR: mdl connect callback");
1629		mdl->state = MDL_CLOSED;
1630		g_io_channel_unref(mdl->dc);
1631		mdl->dc = NULL;
1632		cb(mdl, conn_err, user_data);
1633		return;
1634	}
1635
1636	mdl->state = MDL_CONNECTED;
1637	mdl->wid = g_io_add_watch(mdl->dc, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
1638						(GIOFunc) mdl_event_cb, mdl);
1639
1640	cb(mdl, conn_err, user_data);
1641}
1642
1643static void mdl_io_destroy(gpointer data)
1644{
1645	struct mcap_mdl_op_cb *con = data;
1646
1647	if (con->destroy)
1648		con->destroy(con->user_data);
1649
1650	g_free(con);
1651}
1652
1653gboolean mcap_connect_mdl(struct mcap_mdl *mdl, uint8_t mode,
1654					uint16_t dcpsm,
1655					mcap_mdl_operation_cb connect_cb,
1656					gpointer user_data,
1657					GDestroyNotify destroy,
1658					GError **err)
1659{
1660	struct mcap_mdl_op_cb *con;
1661
1662	if (mdl->state != MDL_WAITING) {
1663		g_set_error(err, MCAP_ERROR, MCAP_ERROR_INVALID_MDL,
1664					"%s", error2str(MCAP_INVALID_MDL));
1665		return FALSE;
1666	}
1667
1668	if ((mode != L2CAP_MODE_ERTM) && (mode != L2CAP_MODE_STREAMING)) {
1669		g_set_error(err, MCAP_ERROR, MCAP_ERROR_INVALID_ARGS,
1670						"Invalid MDL configuration");
1671		return FALSE;
1672	}
1673
1674	con = g_new0(struct mcap_mdl_op_cb, 1);
1675	con->mdl = mdl;
1676	con->cb.op = connect_cb;
1677	con->destroy = destroy;
1678	con->user_data = user_data;
1679
1680	mdl->dc = bt_io_connect(BT_IO_L2CAP, mcap_connect_mdl_cb, con,
1681				mdl_io_destroy, err,
1682				BT_IO_OPT_SOURCE_BDADDR, &mdl->mcl->ms->src,
1683				BT_IO_OPT_DEST_BDADDR, &mdl->mcl->addr,
1684				BT_IO_OPT_PSM, dcpsm,
1685				BT_IO_OPT_MTU, MCAP_DC_MTU,
1686				BT_IO_OPT_SEC_LEVEL, mdl->mcl->ms->sec,
1687				BT_IO_OPT_MODE, mode,
1688				BT_IO_OPT_INVALID);
1689	if (!mdl->dc) {
1690		DBG("MDL Connection error");
1691		mdl->state = MDL_CLOSED;
1692		g_free(con);
1693		return FALSE;
1694	}
1695
1696	return TRUE;
1697}
1698
1699static gboolean mcl_control_cb(GIOChannel *chan, GIOCondition cond,
1700								gpointer data)
1701{
1702	GError *gerr = NULL;
1703	struct mcap_mcl *mcl = data;
1704	int sk, len;
1705	uint8_t buf[MCAP_CC_MTU];
1706
1707	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
1708		goto fail;
1709
1710	sk = g_io_channel_unix_get_fd(chan);
1711	len = read(sk, buf, sizeof(buf));
1712	if (len < 0)
1713		goto fail;
1714
1715	proc_cmd(mcl, buf, (uint32_t) len);
1716	return TRUE;
1717
1718fail:
1719	if (mcl->state != MCL_IDLE) {
1720		if (mcl->req == MCL_WAITING_RSP) {
1721			/* notify error in pending callback */
1722			g_set_error(&gerr, MCAP_ERROR, MCAP_ERROR_MCL_CLOSED,
1723								"MCL closed");
1724			mcap_notify_error(mcl, gerr);
1725			g_error_free(gerr);
1726		}
1727		mcl->ms->mcl_disconnected_cb(mcl, mcl->ms->user_data);
1728	}
1729	mcap_cache_mcl(mcl);
1730	return FALSE;
1731}
1732
1733static void mcap_connect_mcl_cb(GIOChannel *chan, GError *conn_err,
1734							gpointer user_data)
1735{
1736	char dstaddr[18];
1737	struct connect_mcl *con = user_data;
1738	struct mcap_mcl *aux, *mcl = con->mcl;
1739	mcap_mcl_connect_cb connect_cb = con->connect_cb;
1740	gpointer data = con->user_data;
1741	GError *gerr = NULL;
1742
1743	mcl->ctrl &= ~MCAP_CTRL_CONN;
1744
1745	if (conn_err) {
1746		if (mcl->ctrl & MCAP_CTRL_FREE) {
1747			mcap_mcl_release(mcl);
1748			mcl->ms->mcl_uncached_cb(mcl, mcl->ms->user_data);
1749		}
1750		connect_cb(NULL, conn_err, data);
1751		return;
1752	}
1753
1754	ba2str(&mcl->addr, dstaddr);
1755
1756	aux = find_mcl(mcl->ms->mcls, &mcl->addr);
1757	if (aux) {
1758		/* Double MCL connection case */
1759		error("MCL error: Device %s is already connected", dstaddr);
1760		g_set_error(&gerr, MCAP_ERROR, MCAP_ERROR_ALREADY_EXISTS,
1761					"MCL %s is already connected", dstaddr);
1762		connect_cb(NULL, gerr, data);
1763		g_error_free(gerr);
1764		return;
1765	}
1766
1767	mcl->state = MCL_CONNECTED;
1768	mcl->role = MCL_INITIATOR;
1769	mcl->req = MCL_AVAILABLE;
1770	mcl->ctrl |= MCAP_CTRL_STD_OP;
1771
1772	mcap_sync_init(mcl);
1773
1774	if (mcl->ctrl & MCAP_CTRL_CACHED)
1775		mcap_uncache_mcl(mcl);
1776	else {
1777		mcl->ctrl &= ~MCAP_CTRL_FREE;
1778		mcl->ms->mcls = g_slist_prepend(mcl->ms->mcls,
1779							mcap_mcl_ref(mcl));
1780	}
1781
1782	mcl->wid = g_io_add_watch(mcl->cc,
1783				G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
1784				(GIOFunc) mcl_control_cb, mcl);
1785	connect_cb(mcl, gerr, data);
1786}
1787
1788static void set_mdl_properties(GIOChannel *chan, struct mcap_mdl *mdl)
1789{
1790	struct mcap_mcl *mcl = mdl->mcl;
1791
1792	mdl->state = MDL_CONNECTED;
1793	mdl->dc = g_io_channel_ref(chan);
1794	mdl->wid = g_io_add_watch(mdl->dc, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
1795						(GIOFunc) mdl_event_cb, mdl);
1796
1797	mcl->state = MCL_ACTIVE;
1798	mcl->cb->mdl_connected(mdl, mcl->cb->user_data);
1799}
1800
1801static void mcl_io_destroy(gpointer data)
1802{
1803	struct connect_mcl *con = data;
1804
1805	mcap_mcl_unref(con->mcl);
1806	if (con->destroy)
1807		con->destroy(con->user_data);
1808	g_free(con);
1809}
1810
1811gboolean mcap_create_mcl(struct mcap_instance *ms,
1812				const bdaddr_t *addr,
1813				uint16_t ccpsm,
1814				mcap_mcl_connect_cb connect_cb,
1815				gpointer user_data,
1816				GDestroyNotify destroy,
1817				GError **err)
1818{
1819	struct mcap_mcl *mcl;
1820	struct connect_mcl *con;
1821
1822	mcl = find_mcl(ms->mcls, addr);
1823	if (mcl) {
1824		g_set_error(err, MCAP_ERROR, MCAP_ERROR_ALREADY_EXISTS,
1825					"MCL is already connected.");
1826		return FALSE;
1827	}
1828
1829	mcl = find_mcl(ms->cached, addr);
1830	if (!mcl) {
1831		mcl = g_new0(struct mcap_mcl, 1);
1832		mcl->ms = ms;
1833		mcl->state = MCL_IDLE;
1834		bacpy(&mcl->addr, addr);
1835		set_default_cb(mcl);
1836		mcl->next_mdl = (rand() % MCAP_MDLID_FINAL) + 1;
1837	}
1838
1839	mcl->ctrl |= MCAP_CTRL_CONN;
1840
1841	con = g_new0(struct connect_mcl, 1);
1842	con->mcl = mcap_mcl_ref(mcl);
1843	con->connect_cb = connect_cb;
1844	con->destroy = destroy;
1845	con->user_data = user_data;
1846
1847	mcl->cc = bt_io_connect(BT_IO_L2CAP, mcap_connect_mcl_cb, con,
1848				mcl_io_destroy, err,
1849				BT_IO_OPT_SOURCE_BDADDR, &ms->src,
1850				BT_IO_OPT_DEST_BDADDR, addr,
1851				BT_IO_OPT_PSM, ccpsm,
1852				BT_IO_OPT_MTU, MCAP_CC_MTU,
1853				BT_IO_OPT_SEC_LEVEL, ms->sec,
1854				BT_IO_OPT_MODE, L2CAP_MODE_ERTM,
1855				BT_IO_OPT_INVALID);
1856	if (!mcl->cc) {
1857		mcl->ctrl &= ~MCAP_CTRL_CONN;
1858		if (mcl->ctrl & MCAP_CTRL_FREE) {
1859			mcap_mcl_release(mcl);
1860			mcl->ms->mcl_uncached_cb(mcl, mcl->ms->user_data);
1861		}
1862		mcap_mcl_unref(con->mcl);
1863		g_free(con);
1864		return FALSE;
1865	}
1866
1867	return TRUE;
1868}
1869
1870static void connect_dc_event_cb(GIOChannel *chan, GError *gerr,
1871							gpointer user_data)
1872{
1873	struct mcap_instance *ms = user_data;
1874	struct mcap_mcl *mcl;
1875	struct mcap_mdl *mdl;
1876	GError *err = NULL;
1877	bdaddr_t dst;
1878	GSList *l;
1879
1880	if (gerr)
1881		return;
1882
1883	bt_io_get(chan, BT_IO_L2CAP, &err,
1884			BT_IO_OPT_DEST_BDADDR, &dst,
1885			BT_IO_OPT_INVALID);
1886	if (err) {
1887		error("%s", err->message);
1888		g_error_free(err);
1889		goto drop;
1890	}
1891
1892	mcl = find_mcl(ms->mcls, &dst);
1893	if (!mcl || mcl->state != MCL_PENDING)
1894		goto drop;
1895
1896	for (l = mcl->mdls; l; l = l->next) {
1897		mdl = l->data;
1898		if (mdl->state == MDL_WAITING) {
1899			set_mdl_properties(chan, mdl);
1900			return;
1901		}
1902	}
1903
1904drop:
1905	g_io_channel_shutdown(chan, TRUE, NULL);
1906}
1907
1908static void set_mcl_conf(GIOChannel *chan, struct mcap_mcl *mcl)
1909{
1910	gboolean reconn;
1911
1912	mcl->state = MCL_CONNECTED;
1913	mcl->role = MCL_ACCEPTOR;
1914	mcl->req = MCL_AVAILABLE;
1915	mcl->cc = g_io_channel_ref(chan);
1916	mcl->ctrl |= MCAP_CTRL_STD_OP;
1917
1918	mcap_sync_init(mcl);
1919
1920	reconn = (mcl->ctrl & MCAP_CTRL_CACHED);
1921	if (reconn)
1922		mcap_uncache_mcl(mcl);
1923	else
1924		mcl->ms->mcls = g_slist_prepend(mcl->ms->mcls,
1925							mcap_mcl_ref(mcl));
1926
1927	mcl->wid = g_io_add_watch(mcl->cc,
1928			G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
1929			(GIOFunc) mcl_control_cb, mcl);
1930
1931	/* Callback to report new MCL */
1932	if (reconn)
1933		mcl->ms->mcl_reconnected_cb(mcl, mcl->ms->user_data);
1934	else
1935		mcl->ms->mcl_connected_cb(mcl, mcl->ms->user_data);
1936}
1937
1938static void connect_mcl_event_cb(GIOChannel *chan, GError *gerr,
1939							gpointer user_data)
1940{
1941	struct mcap_instance *ms = user_data;
1942	struct mcap_mcl *mcl;
1943	bdaddr_t dst;
1944	char address[18], srcstr[18];
1945	GError *err = NULL;
1946
1947	if (gerr)
1948		return;
1949
1950	bt_io_get(chan, BT_IO_L2CAP, &err,
1951			BT_IO_OPT_DEST_BDADDR, &dst,
1952			BT_IO_OPT_DEST, address,
1953			BT_IO_OPT_INVALID);
1954	if (err) {
1955		error("%s", err->message);
1956		g_error_free(err);
1957		goto drop;
1958	}
1959
1960	ba2str(&ms->src, srcstr);
1961	mcl = find_mcl(ms->mcls, &dst);
1962	if (mcl) {
1963		error("Control channel already created with %s on adapter %s",
1964				address, srcstr);
1965		goto drop;
1966	}
1967
1968	mcl = find_mcl(ms->cached, &dst);
1969	if (!mcl) {
1970		mcl = g_new0(struct mcap_mcl, 1);
1971		mcl->ms = ms;
1972		bacpy(&mcl->addr, &dst);
1973		set_default_cb(mcl);
1974		mcl->next_mdl = (rand() % MCAP_MDLID_FINAL) + 1;
1975	}
1976
1977	set_mcl_conf(chan, mcl);
1978
1979	return;
1980drop:
1981	g_io_channel_shutdown(chan, TRUE, NULL);
1982}
1983
1984struct mcap_instance *mcap_create_instance(bdaddr_t *src,
1985					BtIOSecLevel sec,
1986					uint16_t ccpsm,
1987					uint16_t dcpsm,
1988					mcap_mcl_event_cb mcl_connected,
1989					mcap_mcl_event_cb mcl_reconnected,
1990					mcap_mcl_event_cb mcl_disconnected,
1991					mcap_mcl_event_cb mcl_uncached,
1992					mcap_info_ind_event_cb mcl_sync_info_ind,
1993					gpointer user_data,
1994					GError **gerr)
1995{
1996	struct mcap_instance *ms;
1997
1998	if (sec < BT_IO_SEC_MEDIUM) {
1999		g_set_error(gerr, MCAP_ERROR, MCAP_ERROR_INVALID_ARGS,
2000				"Security level can't be minor of %d",
2001				BT_IO_SEC_MEDIUM);
2002		return NULL;
2003	}
2004
2005	if (!(mcl_connected && mcl_reconnected &&
2006			mcl_disconnected && mcl_uncached)) {
2007		g_set_error(gerr, MCAP_ERROR, MCAP_ERROR_INVALID_ARGS,
2008				"The callbacks can't be null");
2009		return NULL;
2010	}
2011
2012	ms = g_new0(struct mcap_instance, 1);
2013
2014	bacpy(&ms->src, src);
2015
2016	ms->sec = sec;
2017	ms->mcl_connected_cb = mcl_connected;
2018	ms->mcl_reconnected_cb = mcl_reconnected;
2019	ms->mcl_disconnected_cb = mcl_disconnected;
2020	ms->mcl_uncached_cb = mcl_uncached;
2021	ms->mcl_sync_infoind_cb = mcl_sync_info_ind;
2022	ms->user_data = user_data;
2023	ms->csp_enabled = FALSE;
2024
2025	/* Listen incoming connections in control channel */
2026	ms->ccio = bt_io_listen(BT_IO_L2CAP, connect_mcl_event_cb, NULL, ms,
2027				NULL, gerr,
2028				BT_IO_OPT_SOURCE_BDADDR, &ms->src,
2029				BT_IO_OPT_PSM, ccpsm,
2030				BT_IO_OPT_MTU, MCAP_CC_MTU,
2031				BT_IO_OPT_SEC_LEVEL, sec,
2032				BT_IO_OPT_MODE, L2CAP_MODE_ERTM,
2033				BT_IO_OPT_INVALID);
2034	if (!ms->ccio) {
2035		error("%s", (*gerr)->message);
2036		g_free(ms);
2037		return NULL;
2038	}
2039
2040	/* Listen incoming connections in data channels */
2041	ms->dcio = bt_io_listen(BT_IO_L2CAP, connect_dc_event_cb, NULL, ms,
2042				NULL, gerr,
2043				BT_IO_OPT_SOURCE_BDADDR, &ms->src,
2044				BT_IO_OPT_PSM, dcpsm,
2045				BT_IO_OPT_MTU, MCAP_DC_MTU,
2046				BT_IO_OPT_SEC_LEVEL, sec,
2047				BT_IO_OPT_INVALID);
2048	if (!ms->dcio) {
2049		g_io_channel_shutdown(ms->ccio, TRUE, NULL);
2050		g_io_channel_unref(ms->ccio);
2051		ms->ccio = NULL;
2052		error("%s", (*gerr)->message);
2053		g_free(ms);
2054		return NULL;
2055	}
2056
2057	/* Initialize random seed to generate mdlids for this instance */
2058	srand(time(NULL));
2059
2060	return ms;
2061}
2062
2063void mcap_release_instance(struct mcap_instance *mi)
2064{
2065	GSList *l;
2066
2067	if (!mi)
2068		return;
2069
2070	if (mi->ccio) {
2071		g_io_channel_shutdown(mi->ccio, TRUE, NULL);
2072		g_io_channel_unref(mi->ccio);
2073		mi->ccio = NULL;
2074	}
2075
2076	if (mi->dcio) {
2077		g_io_channel_shutdown(mi->dcio, TRUE, NULL);
2078		g_io_channel_unref(mi->dcio);
2079		mi->dcio = NULL;
2080	}
2081
2082	for (l = mi->mcls; l; l = l->next) {
2083		mcap_mcl_release(l->data);
2084		mcap_mcl_unref(l->data);
2085	}
2086	g_slist_free(mi->mcls);
2087	mi->mcls = NULL;
2088
2089	for (l = mi->cached; l; l = l->next) {
2090		mcap_mcl_release(l->data);
2091		mcap_mcl_unref(l->data);
2092	}
2093	g_slist_free(mi->cached);
2094	mi->cached = NULL;
2095
2096	g_free(mi);
2097}
2098
2099uint16_t mcap_get_ctrl_psm(struct mcap_instance *mi, GError **err)
2100{
2101	uint16_t lpsm;
2102
2103	if (!(mi && mi->ccio)) {
2104		g_set_error(err, MCAP_ERROR, MCAP_ERROR_INVALID_ARGS,
2105			"Invalid MCAP instance");
2106		return 0;
2107	}
2108
2109	if (!bt_io_get(mi->ccio, BT_IO_L2CAP, err,
2110			BT_IO_OPT_PSM, &lpsm,
2111			BT_IO_OPT_INVALID))
2112		return 0;
2113
2114	return lpsm;
2115}
2116
2117uint16_t mcap_get_data_psm(struct mcap_instance *mi, GError **err)
2118{
2119	uint16_t lpsm;
2120
2121	if (!(mi && mi->dcio)) {
2122		g_set_error(err, MCAP_ERROR, MCAP_ERROR_INVALID_ARGS,
2123			"Invalid MCAP instance");
2124		return 0;
2125	}
2126
2127	if (!bt_io_get(mi->dcio, BT_IO_L2CAP, err,
2128			BT_IO_OPT_PSM, &lpsm,
2129			BT_IO_OPT_INVALID))
2130		return 0;
2131
2132	return lpsm;
2133}
2134