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