tizen 2.3.1 release
[framework/connectivity/bluez.git] / profiles / sap / server.c
1 /*
2  *  BlueZ - Bluetooth protocol stack for Linux
3  *
4  *  Copyright (C) 2010 Instituto Nokia de Tecnologia - INdT
5  *  Copyright (C) 2010 ST-Ericsson SA
6  *  Copyright (C) 2011 Tieto Poland
7  *
8  *  Author: Marek Skowron <marek.skowron@tieto.com> for ST-Ericsson.
9  *  Author: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
10  *          for ST-Ericsson.
11  *
12  *  This program is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation; either version 2 of the License, or
15  *  (at your option) any later version.
16  *
17  *  This program is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program; if not, write to the Free Software
24  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
25  */
26
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30
31 #include <errno.h>
32 #include <glib.h>
33
34 #include "lib/sdp.h"
35 #include "lib/sdp_lib.h"
36 #include "lib/uuid.h"
37
38 #include "gdbus/gdbus.h"
39
40 #include "btio/btio.h"
41 #include "src/adapter.h"
42 #include "src/sdpd.h"
43 #include "src/log.h"
44 #include "src/error.h"
45 #include "src/dbus-common.h"
46 #include "src/shared/util.h"
47
48 #include "sap.h"
49 #include "server.h"
50
51 #define SAP_SERVER_INTERFACE    "org.bluez.SimAccess1"
52 #define SAP_SERVER_CHANNEL      8
53
54 #define PADDING4(x) ((4 - ((x) & 0x03)) & 0x03)
55 #define PARAMETER_SIZE(x) (sizeof(struct sap_parameter) + x + PADDING4(x))
56
57 #define SAP_NO_REQ 0xFF
58 #define SAP_DISCONNECTION_TYPE_CLIENT 0xFF
59
60 #define SAP_TIMER_GRACEFUL_DISCONNECT 30
61 #define SAP_TIMER_NO_ACTIVITY 30
62
63 enum {
64         SAP_STATE_DISCONNECTED,
65         SAP_STATE_CONNECT_IN_PROGRESS,
66         SAP_STATE_CONNECT_MODEM_BUSY,
67         SAP_STATE_CONNECTED,
68         SAP_STATE_GRACEFUL_DISCONNECT,
69         SAP_STATE_IMMEDIATE_DISCONNECT,
70         SAP_STATE_CLIENT_DISCONNECT
71 };
72
73 struct sap_connection {
74         GIOChannel *io;
75         uint32_t state;
76         uint8_t processing_req;
77         guint timer_id;
78 };
79
80 struct sap_server {
81         struct btd_adapter *adapter;
82         uint32_t record_id;
83         GIOChannel *listen_io;
84         struct sap_connection *conn;
85 };
86
87 static void start_guard_timer(struct sap_server *server, guint interval);
88 static void stop_guard_timer(struct sap_server *server);
89 static gboolean guard_timeout(gpointer data);
90
91 static size_t add_result_parameter(uint8_t result,
92                                         struct sap_parameter *param)
93 {
94         param->id = SAP_PARAM_ID_RESULT_CODE;
95         param->len = htons(SAP_PARAM_ID_RESULT_CODE_LEN);
96         *param->val = result;
97
98         return PARAMETER_SIZE(SAP_PARAM_ID_RESULT_CODE_LEN);
99 }
100
101 static int is_power_sim_off_req_allowed(uint8_t processing_req)
102 {
103         switch (processing_req) {
104         case SAP_NO_REQ:
105         case SAP_TRANSFER_APDU_REQ:
106         case SAP_TRANSFER_ATR_REQ:
107         case SAP_POWER_SIM_ON_REQ:
108         case SAP_RESET_SIM_REQ:
109         case SAP_TRANSFER_CARD_READER_STATUS_REQ:
110                 return 1;
111         default:
112                 return 0;
113         }
114 }
115
116 static int is_reset_sim_req_allowed(uint8_t processing_req)
117 {
118         switch (processing_req) {
119         case SAP_NO_REQ:
120         case SAP_TRANSFER_APDU_REQ:
121         case SAP_TRANSFER_ATR_REQ:
122         case SAP_TRANSFER_CARD_READER_STATUS_REQ:
123                 return 1;
124         default:
125                 return 0;
126         }
127 }
128
129 static int check_msg(struct sap_message *msg)
130 {
131         switch (msg->id) {
132         case SAP_CONNECT_REQ:
133                 if (msg->nparam != 0x01)
134                         return -EBADMSG;
135
136                 if (msg->param->id != SAP_PARAM_ID_MAX_MSG_SIZE)
137                         return -EBADMSG;
138
139                 if (ntohs(msg->param->len) != SAP_PARAM_ID_MAX_MSG_SIZE_LEN)
140                         return -EBADMSG;
141
142                 break;
143
144         case SAP_TRANSFER_APDU_REQ:
145                 if (msg->nparam != 0x01)
146                         return -EBADMSG;
147
148                 if (msg->param->id != SAP_PARAM_ID_COMMAND_APDU)
149                         if (msg->param->id != SAP_PARAM_ID_COMMAND_APDU7816)
150                                 return -EBADMSG;
151
152                 if (msg->param->len == 0x00)
153                         return -EBADMSG;
154
155                 break;
156
157         case SAP_SET_TRANSPORT_PROTOCOL_REQ:
158                 if (msg->nparam != 0x01)
159                         return -EBADMSG;
160
161                 if (msg->param->id != SAP_PARAM_ID_TRANSPORT_PROTOCOL)
162                         return -EBADMSG;
163
164                 if (ntohs(msg->param->len) != SAP_PARAM_ID_TRANSPORT_PROTO_LEN)
165                         return -EBADMSG;
166
167                 if (*msg->param->val != SAP_TRANSPORT_PROTOCOL_T0)
168                         if (*msg->param->val != SAP_TRANSPORT_PROTOCOL_T1)
169                                 return -EBADMSG;
170
171                 break;
172
173         case SAP_DISCONNECT_REQ:
174         case SAP_TRANSFER_ATR_REQ:
175         case SAP_POWER_SIM_OFF_REQ:
176         case SAP_POWER_SIM_ON_REQ:
177         case SAP_RESET_SIM_REQ:
178         case SAP_TRANSFER_CARD_READER_STATUS_REQ:
179                 if (msg->nparam != 0x00)
180                         return -EBADMSG;
181
182                 break;
183         }
184
185         return 0;
186 }
187
188 static sdp_record_t *create_sap_record(uint8_t channel)
189 {
190         sdp_list_t *apseq, *aproto, *profiles, *proto[2], *root, *svclass_id;
191         uuid_t sap_uuid, gt_uuid, root_uuid, l2cap, rfcomm;
192         sdp_profile_desc_t profile;
193         sdp_record_t *record;
194         sdp_data_t *ch;
195
196         record = sdp_record_alloc();
197         if (!record)
198                 return NULL;
199
200         sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
201         root = sdp_list_append(NULL, &root_uuid);
202         sdp_set_browse_groups(record, root);
203         sdp_list_free(root, NULL);
204
205         sdp_uuid16_create(&sap_uuid, SAP_SVCLASS_ID);
206         svclass_id = sdp_list_append(NULL, &sap_uuid);
207         sdp_uuid16_create(&gt_uuid, GENERIC_TELEPHONY_SVCLASS_ID);
208         svclass_id = sdp_list_append(svclass_id, &gt_uuid);
209
210         sdp_set_service_classes(record, svclass_id);
211         sdp_list_free(svclass_id, NULL);
212
213         sdp_uuid16_create(&profile.uuid, SAP_PROFILE_ID);
214         profile.version = SAP_VERSION;
215         profiles = sdp_list_append(NULL, &profile);
216         sdp_set_profile_descs(record, profiles);
217         sdp_list_free(profiles, NULL);
218
219         sdp_uuid16_create(&l2cap, L2CAP_UUID);
220         proto[0] = sdp_list_append(NULL, &l2cap);
221         apseq = sdp_list_append(NULL, proto[0]);
222
223         sdp_uuid16_create(&rfcomm, RFCOMM_UUID);
224         proto[1] = sdp_list_append(NULL, &rfcomm);
225         ch = sdp_data_alloc(SDP_UINT8, &channel);
226         proto[1] = sdp_list_append(proto[1], ch);
227         apseq = sdp_list_append(apseq, proto[1]);
228
229         aproto = sdp_list_append(NULL, apseq);
230         sdp_set_access_protos(record, aproto);
231
232         sdp_set_info_attr(record, "SIM Access Server", NULL, NULL);
233
234         sdp_data_free(ch);
235         sdp_list_free(proto[0], NULL);
236         sdp_list_free(proto[1], NULL);
237         sdp_list_free(apseq, NULL);
238         sdp_list_free(aproto, NULL);
239
240         return record;
241 }
242
243 static int send_message(struct sap_connection *conn, void *buf, size_t size)
244 {
245         size_t written = 0;
246         GError *gerr = NULL;
247         GIOStatus gstatus;
248
249         SAP_VDBG("conn %p, size %zu", conn, size);
250
251         gstatus = g_io_channel_write_chars(conn->io, buf, size, &written,
252                                                                         &gerr);
253         if (gstatus != G_IO_STATUS_NORMAL) {
254                 if (gerr)
255                         g_error_free(gerr);
256
257                 error("write error (0x%02x).", gstatus);
258                 return -EIO;
259         }
260
261         if (written != size) {
262                 error("written %zu bytes out of %zu", written, size);
263                 return -EIO;
264         }
265
266         return written;
267 }
268
269 static int disconnect_ind(struct sap_connection *conn, uint8_t disc_type)
270 {
271         char buf[SAP_BUF_SIZE];
272         struct sap_message *msg = (struct sap_message *) buf;
273         struct sap_parameter *param = (struct sap_parameter *) msg->param;
274         size_t size = sizeof(struct sap_message);
275
276         DBG("data %p state %d disc_type 0x%02x", conn, conn->state, disc_type);
277
278         memset(buf, 0, sizeof(buf));
279         msg->id = SAP_DISCONNECT_IND;
280         msg->nparam = 0x01;
281
282         /* Add disconnection type param. */
283         param->id  = SAP_PARAM_ID_DISCONNECT_IND;
284         param->len = htons(SAP_PARAM_ID_DISCONNECT_IND_LEN);
285         *param->val = disc_type;
286         size += PARAMETER_SIZE(SAP_PARAM_ID_DISCONNECT_IND_LEN);
287
288         return send_message(conn, buf, size);
289 }
290
291 static int sap_error_rsp(struct sap_connection *conn)
292 {
293         struct sap_message msg;
294
295         memset(&msg, 0, sizeof(msg));
296         msg.id = SAP_ERROR_RESP;
297
298         error("SAP error (state %d pr 0x%02x).", conn->state,
299                                                         conn->processing_req);
300
301         return send_message(conn, &msg, sizeof(msg));
302 }
303
304 static void connect_req(struct sap_server *server,
305                                 struct sap_parameter *param)
306 {
307         struct sap_connection *conn = server->conn;
308         uint16_t maxmsgsize;
309
310         DBG("conn %p state %d", conn, conn->state);
311
312         if (!param)
313                 goto error_rsp;
314
315         if (conn->state != SAP_STATE_DISCONNECTED)
316                 goto error_rsp;
317
318         stop_guard_timer(server);
319
320         maxmsgsize = get_be16(&param->val);
321
322         DBG("Connect MaxMsgSize: 0x%04x", maxmsgsize);
323
324         conn->state = SAP_STATE_CONNECT_IN_PROGRESS;
325
326         if (maxmsgsize <= SAP_BUF_SIZE) {
327                 conn->processing_req = SAP_CONNECT_REQ;
328                 sap_connect_req(server, maxmsgsize);
329         } else {
330                 sap_connect_rsp(server, SAP_STATUS_MAX_MSG_SIZE_NOT_SUPPORTED);
331         }
332
333         return;
334
335 error_rsp:
336         sap_error_rsp(conn);
337 }
338
339 static int disconnect_req(struct sap_server *server, uint8_t disc_type)
340 {
341         struct sap_connection *conn = server->conn;
342
343         DBG("conn %p state %d disc_type 0x%02x", conn, conn->state, disc_type);
344
345         switch (disc_type) {
346         case SAP_DISCONNECTION_TYPE_GRACEFUL:
347                 if (conn->state == SAP_STATE_DISCONNECTED ||
348                                 conn->state == SAP_STATE_CONNECT_IN_PROGRESS ||
349                                 conn->state == SAP_STATE_CONNECT_MODEM_BUSY)
350                         return -EPERM;
351
352                 if (conn->state == SAP_STATE_CONNECTED) {
353                         conn->state = SAP_STATE_GRACEFUL_DISCONNECT;
354                         conn->processing_req = SAP_NO_REQ;
355
356                         disconnect_ind(conn, disc_type);
357                         /* Timer will disconnect if client won't do.*/
358                         start_guard_timer(server,
359                                         SAP_TIMER_GRACEFUL_DISCONNECT);
360                 }
361
362                 return 0;
363
364         case SAP_DISCONNECTION_TYPE_IMMEDIATE:
365                 if (conn->state == SAP_STATE_DISCONNECTED ||
366                                 conn->state == SAP_STATE_CONNECT_IN_PROGRESS ||
367                                 conn->state == SAP_STATE_CONNECT_MODEM_BUSY)
368                         return -EPERM;
369
370                 if (conn->state == SAP_STATE_CONNECTED ||
371                                 conn->state == SAP_STATE_GRACEFUL_DISCONNECT) {
372                         conn->state = SAP_STATE_IMMEDIATE_DISCONNECT;
373                         conn->processing_req = SAP_NO_REQ;
374
375                         stop_guard_timer(server);
376                         disconnect_ind(conn, disc_type);
377                         sap_disconnect_req(server, 0);
378                 }
379
380                 return 0;
381
382         case SAP_DISCONNECTION_TYPE_CLIENT:
383                 if (conn->state != SAP_STATE_CONNECTED &&
384                                 conn->state != SAP_STATE_GRACEFUL_DISCONNECT) {
385                         sap_error_rsp(conn);
386                         return -EPERM;
387                 }
388
389                 conn->state = SAP_STATE_CLIENT_DISCONNECT;
390                 conn->processing_req = SAP_NO_REQ;
391
392                 stop_guard_timer(server);
393                 sap_disconnect_req(server, 0);
394
395                 return 0;
396
397         default:
398                 error("Unknown disconnection type (0x%02x).", disc_type);
399                 return -EINVAL;
400         }
401 }
402
403 static void transfer_apdu_req(struct sap_server *server,
404                                         struct sap_parameter *param)
405 {
406         struct sap_connection *conn = server->conn;
407
408         SAP_VDBG("conn %p state %d", conn, conn->state);
409
410         if (!param)
411                 goto error_rsp;
412
413         param->len = ntohs(param->len);
414
415         if (conn->state != SAP_STATE_CONNECTED &&
416                         conn->state != SAP_STATE_GRACEFUL_DISCONNECT)
417                 goto error_rsp;
418
419         if (conn->processing_req != SAP_NO_REQ)
420                 goto error_rsp;
421
422         conn->processing_req = SAP_TRANSFER_APDU_REQ;
423         sap_transfer_apdu_req(server, param);
424
425         return;
426
427 error_rsp:
428         sap_error_rsp(conn);
429 }
430
431 static void transfer_atr_req(struct sap_server *server)
432 {
433         struct sap_connection *conn = server->conn;
434
435         DBG("conn %p state %d", conn, conn->state);
436
437         if (conn->state != SAP_STATE_CONNECTED)
438                 goto error_rsp;
439
440         if (conn->processing_req != SAP_NO_REQ)
441                 goto error_rsp;
442
443         conn->processing_req = SAP_TRANSFER_ATR_REQ;
444         sap_transfer_atr_req(server);
445
446         return;
447
448 error_rsp:
449         sap_error_rsp(conn);
450 }
451
452 static void power_sim_off_req(struct sap_server *server)
453 {
454         struct sap_connection *conn = server->conn;
455
456         DBG("conn %p state %d", conn, conn->state);
457
458         if (conn->state != SAP_STATE_CONNECTED)
459                 goto error_rsp;
460
461         if (!is_power_sim_off_req_allowed(conn->processing_req))
462                 goto error_rsp;
463
464         conn->processing_req = SAP_POWER_SIM_OFF_REQ;
465         sap_power_sim_off_req(server);
466
467         return;
468
469 error_rsp:
470         sap_error_rsp(conn);
471 }
472
473 static void power_sim_on_req(struct sap_server *server)
474 {
475         struct sap_connection *conn = server->conn;
476
477         DBG("conn %p state %d", conn, conn->state);
478
479         if (conn->state != SAP_STATE_CONNECTED)
480                 goto error_rsp;
481
482         if (conn->processing_req != SAP_NO_REQ)
483                 goto error_rsp;
484
485         conn->processing_req = SAP_POWER_SIM_ON_REQ;
486         sap_power_sim_on_req(server);
487
488         return;
489
490 error_rsp:
491         sap_error_rsp(conn);
492 }
493
494 static void reset_sim_req(struct sap_server *server)
495 {
496         struct sap_connection *conn = server->conn;
497
498         DBG("conn %p state %d", conn, conn->state);
499
500         if (conn->state != SAP_STATE_CONNECTED)
501                 goto error_rsp;
502
503         if (!is_reset_sim_req_allowed(conn->processing_req))
504                 goto error_rsp;
505
506         conn->processing_req = SAP_RESET_SIM_REQ;
507         sap_reset_sim_req(server);
508
509         return;
510
511 error_rsp:
512         sap_error_rsp(conn);
513 }
514
515 static void transfer_card_reader_status_req(struct sap_server *server)
516 {
517         struct sap_connection *conn = server->conn;
518
519         DBG("conn %p state %d", conn, conn->state);
520
521         if (conn->state != SAP_STATE_CONNECTED)
522                 goto error_rsp;
523
524         if (conn->processing_req != SAP_NO_REQ)
525                 goto error_rsp;
526
527         conn->processing_req = SAP_TRANSFER_CARD_READER_STATUS_REQ;
528         sap_transfer_card_reader_status_req(server);
529
530         return;
531
532 error_rsp:
533         sap_error_rsp(conn);
534 }
535
536 static void set_transport_protocol_req(struct sap_server *server,
537                                         struct sap_parameter *param)
538 {
539         struct sap_connection *conn = server->conn;
540
541         if (!param)
542                 goto error_rsp;
543
544         DBG("conn %p state %d param %p", conn, conn->state, param);
545
546         if (conn->state != SAP_STATE_CONNECTED)
547                 goto error_rsp;
548
549         if (conn->processing_req != SAP_NO_REQ)
550                 goto error_rsp;
551
552         conn->processing_req = SAP_SET_TRANSPORT_PROTOCOL_REQ;
553         sap_set_transport_protocol_req(server, param);
554
555         return;
556
557 error_rsp:
558         sap_error_rsp(conn);
559 }
560
561 static void start_guard_timer(struct sap_server *server, guint interval)
562 {
563         struct sap_connection *conn = server->conn;
564
565         if (!conn)
566                 return;
567
568         if (!conn->timer_id)
569                 conn->timer_id = g_timeout_add_seconds(interval, guard_timeout,
570                                                                 server);
571         else
572                 error("Timer is already active.");
573 }
574
575 static void stop_guard_timer(struct sap_server *server)
576 {
577         struct sap_connection *conn = server->conn;
578
579         if (conn  && conn->timer_id) {
580                 g_source_remove(conn->timer_id);
581                 conn->timer_id = 0;
582         }
583 }
584
585 static gboolean guard_timeout(gpointer data)
586 {
587         struct sap_server *server = data;
588         struct sap_connection *conn = server->conn;
589
590         if (!conn)
591                 return FALSE;
592
593         DBG("conn %p state %d pr 0x%02x", conn, conn->state,
594                                                 conn->processing_req);
595
596         conn->timer_id = 0;
597
598         switch (conn->state) {
599         case SAP_STATE_DISCONNECTED:
600                 /* Client opened RFCOMM channel but didn't send CONNECT_REQ,
601                  * in fixed time or client disconnected SAP connection but
602                  * didn't closed RFCOMM channel in fixed time.*/
603                 if (conn->io) {
604                         g_io_channel_shutdown(conn->io, TRUE, NULL);
605                         g_io_channel_unref(conn->io);
606                         conn->io = NULL;
607                 }
608                 break;
609
610         case SAP_STATE_GRACEFUL_DISCONNECT:
611                 /* Client didn't disconnect SAP connection in fixed time,
612                  * so close SAP connection immediately. */
613                 disconnect_req(server, SAP_DISCONNECTION_TYPE_IMMEDIATE);
614                 break;
615
616         default:
617                 error("Unexpected state (%d).", conn->state);
618                 break;
619         }
620
621         return FALSE;
622 }
623
624 static void sap_set_connected(struct sap_server *server)
625 {
626         server->conn->state = SAP_STATE_CONNECTED;
627
628         g_dbus_emit_property_changed(btd_get_dbus_connection(),
629                                         adapter_get_path(server->adapter),
630                                         SAP_SERVER_INTERFACE, "Connected");
631 }
632
633 int sap_connect_rsp(void *sap_device, uint8_t status)
634 {
635         struct sap_server *server = sap_device;
636         struct sap_connection *conn = server->conn;
637         char buf[SAP_BUF_SIZE];
638         struct sap_message *msg = (struct sap_message *) buf;
639         struct sap_parameter *param = (struct sap_parameter *) msg->param;
640         size_t size = sizeof(struct sap_message);
641
642         if (!conn)
643                 return -EINVAL;
644
645         DBG("state %d pr 0x%02x status 0x%02x", conn->state,
646                                                 conn->processing_req, status);
647
648         if (conn->state != SAP_STATE_CONNECT_IN_PROGRESS)
649                 return -EPERM;
650
651         memset(buf, 0, sizeof(buf));
652         msg->id = SAP_CONNECT_RESP;
653         msg->nparam = 0x01;
654
655         /* Add connection status */
656         param->id = SAP_PARAM_ID_CONN_STATUS;
657         param->len = htons(SAP_PARAM_ID_CONN_STATUS_LEN);
658         *param->val = status;
659         size += PARAMETER_SIZE(SAP_PARAM_ID_CONN_STATUS_LEN);
660
661
662         switch (status) {
663         case SAP_STATUS_OK:
664                 sap_set_connected(server);
665                 break;
666         case SAP_STATUS_OK_ONGOING_CALL:
667                 DBG("ongoing call. Wait for reset indication!");
668                 conn->state = SAP_STATE_CONNECT_MODEM_BUSY;
669                 break;
670         case SAP_STATUS_MAX_MSG_SIZE_NOT_SUPPORTED: /* Add MaxMsgSize */
671                 msg->nparam++;
672                 param = (struct sap_parameter *) &buf[size];
673                 param->id = SAP_PARAM_ID_MAX_MSG_SIZE;
674                 param->len = htons(SAP_PARAM_ID_MAX_MSG_SIZE_LEN);
675                 put_be16(SAP_BUF_SIZE, &param->val);
676                 size += PARAMETER_SIZE(SAP_PARAM_ID_MAX_MSG_SIZE_LEN);
677
678                 /* fall */
679         default:
680                 conn->state = SAP_STATE_DISCONNECTED;
681
682                 /* Timer will shutdown channel if client doesn't send
683                  * CONNECT_REQ or doesn't shutdown channel itself.*/
684                 start_guard_timer(server, SAP_TIMER_NO_ACTIVITY);
685                 break;
686         }
687
688         conn->processing_req = SAP_NO_REQ;
689
690         return send_message(conn, buf, size);
691 }
692
693 int sap_disconnect_rsp(void *sap_device)
694 {
695         struct sap_server *server = sap_device;
696         struct sap_connection *conn = server->conn;
697         struct sap_message msg;
698
699         if (!conn)
700                 return -EINVAL;
701
702         DBG("state %d pr 0x%02x", conn->state, conn->processing_req);
703
704         switch (conn->state) {
705         case SAP_STATE_CLIENT_DISCONNECT:
706                 memset(&msg, 0, sizeof(msg));
707                 msg.id = SAP_DISCONNECT_RESP;
708
709                 conn->state = SAP_STATE_DISCONNECTED;
710                 conn->processing_req = SAP_NO_REQ;
711
712                 /* Timer will close channel if client doesn't do it.*/
713                 start_guard_timer(server, SAP_TIMER_NO_ACTIVITY);
714
715                 return send_message(conn, &msg, sizeof(msg));
716
717         case SAP_STATE_IMMEDIATE_DISCONNECT:
718                 conn->state = SAP_STATE_DISCONNECTED;
719                 conn->processing_req = SAP_NO_REQ;
720
721                 if (conn->io) {
722                         g_io_channel_shutdown(conn->io, TRUE, NULL);
723                         g_io_channel_unref(conn->io);
724                         conn->io = NULL;
725                 }
726
727                 return 0;
728
729         default:
730                 break;
731         }
732
733         return 0;
734 }
735
736 int sap_transfer_apdu_rsp(void *sap_device, uint8_t result, uint8_t *apdu,
737                                         uint16_t length)
738 {
739         struct sap_server *server = sap_device;
740         struct sap_connection *conn = server->conn;
741         char buf[SAP_BUF_SIZE];
742         struct sap_message *msg = (struct sap_message *) buf;
743         struct sap_parameter *param = (struct sap_parameter *) msg->param;
744         size_t size = sizeof(struct sap_message);
745
746         if (!conn)
747                 return -EINVAL;
748
749         SAP_VDBG("state %d pr 0x%02x", conn->state, conn->processing_req);
750
751         if (conn->processing_req != SAP_TRANSFER_APDU_REQ)
752                 return 0;
753
754         if (result == SAP_RESULT_OK && (!apdu || (apdu && length == 0x00)))
755                 return -EINVAL;
756
757         memset(buf, 0, sizeof(buf));
758         msg->id = SAP_TRANSFER_APDU_RESP;
759         msg->nparam = 0x01;
760         size += add_result_parameter(result, param);
761
762         /* Add APDU response. */
763         if (result == SAP_RESULT_OK) {
764                 msg->nparam++;
765                 param = (struct sap_parameter *) &buf[size];
766                 param->id = SAP_PARAM_ID_RESPONSE_APDU;
767                 param->len = htons(length);
768
769                 size += PARAMETER_SIZE(length);
770
771                 if (size > SAP_BUF_SIZE)
772                         return -EOVERFLOW;
773
774                 memcpy(param->val, apdu, length);
775         }
776
777         conn->processing_req = SAP_NO_REQ;
778
779         return send_message(conn, buf, size);
780 }
781
782 int sap_transfer_atr_rsp(void *sap_device, uint8_t result, uint8_t *atr,
783                                         uint16_t length)
784 {
785         struct sap_server *server = sap_device;
786         struct sap_connection *conn = server->conn;
787         char buf[SAP_BUF_SIZE];
788         struct sap_message *msg = (struct sap_message *) buf;
789         struct sap_parameter *param = (struct sap_parameter *) msg->param;
790         size_t size = sizeof(struct sap_message);
791
792         if (!conn)
793                 return -EINVAL;
794
795         DBG("result 0x%02x state %d pr 0x%02x len %d", result, conn->state,
796                         conn->processing_req, length);
797
798         if (conn->processing_req != SAP_TRANSFER_ATR_REQ)
799                 return 0;
800
801         if (result == SAP_RESULT_OK && (!atr || (atr && length == 0x00)))
802                 return -EINVAL;
803
804         memset(buf, 0, sizeof(buf));
805         msg->id = SAP_TRANSFER_ATR_RESP;
806         msg->nparam = 0x01;
807         size += add_result_parameter(result, param);
808
809         /* Add ATR response */
810         if (result == SAP_RESULT_OK) {
811                 msg->nparam++;
812                 param = (struct sap_parameter *) &buf[size];
813                 param->id = SAP_PARAM_ID_ATR;
814                 param->len = htons(length);
815                 size += PARAMETER_SIZE(length);
816
817                 if (size > SAP_BUF_SIZE)
818                         return -EOVERFLOW;
819
820                 memcpy(param->val, atr, length);
821         }
822
823         conn->processing_req = SAP_NO_REQ;
824
825         return send_message(conn, buf, size);
826 }
827
828 int sap_power_sim_off_rsp(void *sap_device, uint8_t result)
829 {
830         struct sap_server *server = sap_device;
831         struct sap_connection *conn = server->conn;
832         char buf[SAP_BUF_SIZE];
833         struct sap_message *msg = (struct sap_message *) buf;
834         size_t size = sizeof(struct sap_message);
835
836         if (!conn)
837                 return -EINVAL;
838
839         DBG("state %d pr 0x%02x", conn->state, conn->processing_req);
840
841         if (conn->processing_req != SAP_POWER_SIM_OFF_REQ)
842                 return 0;
843
844         memset(buf, 0, sizeof(buf));
845         msg->id = SAP_POWER_SIM_OFF_RESP;
846         msg->nparam = 0x01;
847         size += add_result_parameter(result, msg->param);
848
849         conn->processing_req = SAP_NO_REQ;
850
851         return send_message(conn, buf, size);
852 }
853
854 int sap_power_sim_on_rsp(void *sap_device, uint8_t result)
855 {
856         struct sap_server *server = sap_device;
857         struct sap_connection *conn = server->conn;
858         char buf[SAP_BUF_SIZE];
859         struct sap_message *msg = (struct sap_message *) buf;
860         size_t size = sizeof(struct sap_message);
861
862         if (!conn)
863                 return -EINVAL;
864
865         DBG("state %d pr 0x%02x", conn->state, conn->processing_req);
866
867         if (conn->processing_req != SAP_POWER_SIM_ON_REQ)
868                 return 0;
869
870         memset(buf, 0, sizeof(buf));
871         msg->id = SAP_POWER_SIM_ON_RESP;
872         msg->nparam = 0x01;
873         size += add_result_parameter(result, msg->param);
874
875         conn->processing_req = SAP_NO_REQ;
876
877         return send_message(conn, buf, size);
878 }
879
880 int sap_reset_sim_rsp(void *sap_device, uint8_t result)
881 {
882         struct sap_server *server = sap_device;
883         struct sap_connection *conn = server->conn;
884         char buf[SAP_BUF_SIZE];
885         struct sap_message *msg = (struct sap_message *) buf;
886         size_t size = sizeof(struct sap_message);
887
888         if (!conn)
889                 return -EINVAL;
890
891         DBG("state %d pr 0x%02x result 0x%02x", conn->state,
892                                                 conn->processing_req, result);
893
894         if (conn->processing_req != SAP_RESET_SIM_REQ)
895                 return 0;
896
897         memset(buf, 0, sizeof(buf));
898         msg->id = SAP_RESET_SIM_RESP;
899         msg->nparam = 0x01;
900         size += add_result_parameter(result, msg->param);
901
902         conn->processing_req = SAP_NO_REQ;
903
904         return send_message(conn, buf, size);
905 }
906
907 int sap_transfer_card_reader_status_rsp(void *sap_device, uint8_t result,
908                                                 uint8_t status)
909 {
910         struct sap_server *server = sap_device;
911         struct sap_connection *conn = server->conn;
912         char buf[SAP_BUF_SIZE];
913         struct sap_message *msg = (struct sap_message *) buf;
914         struct sap_parameter *param = (struct sap_parameter *) msg->param;
915         size_t size = sizeof(struct sap_message);
916
917         if (!conn)
918                 return -EINVAL;
919
920         DBG("state %d pr 0x%02x result 0x%02x", conn->state,
921                                                 conn->processing_req, result);
922
923         if (conn->processing_req != SAP_TRANSFER_CARD_READER_STATUS_REQ)
924                 return 0;
925
926         memset(buf, 0, sizeof(buf));
927         msg->id = SAP_TRANSFER_CARD_READER_STATUS_RESP;
928         msg->nparam = 0x01;
929         size += add_result_parameter(result, param);
930
931         /* Add card reader status. */
932         if (result == SAP_RESULT_OK) {
933                 msg->nparam++;
934                 param = (struct sap_parameter *) &buf[size];
935                 param->id = SAP_PARAM_ID_CARD_READER_STATUS;
936                 param->len = htons(SAP_PARAM_ID_CARD_READER_STATUS_LEN);
937                 *param->val = status;
938                 size += PARAMETER_SIZE(SAP_PARAM_ID_CARD_READER_STATUS_LEN);
939         }
940
941         conn->processing_req = SAP_NO_REQ;
942
943         return send_message(conn, buf, size);
944 }
945
946 int sap_transport_protocol_rsp(void *sap_device, uint8_t result)
947 {
948         struct sap_server *server = sap_device;
949         struct sap_connection *conn = server->conn;
950         char buf[SAP_BUF_SIZE];
951         struct sap_message *msg = (struct sap_message *) buf;
952         size_t size = sizeof(struct sap_message);
953
954         if (!conn)
955                 return -EINVAL;
956
957         DBG("state %d pr 0x%02x result 0x%02x", conn->state,
958                                                 conn->processing_req, result);
959
960         if (conn->processing_req != SAP_SET_TRANSPORT_PROTOCOL_REQ)
961                 return 0;
962
963         memset(buf, 0, sizeof(buf));
964         msg->id = SAP_SET_TRANSPORT_PROTOCOL_RESP;
965         msg->nparam = 0x01;
966         size += add_result_parameter(result, msg->param);
967
968         conn->processing_req = SAP_NO_REQ;
969
970         return send_message(conn, buf, size);
971 }
972
973 int sap_status_ind(void *sap_device, uint8_t status_change)
974 {
975         struct sap_server *server = sap_device;
976         struct sap_connection *conn = server->conn;
977         char buf[SAP_BUF_SIZE];
978         struct sap_message *msg = (struct sap_message *) buf;
979         struct sap_parameter *param = (struct sap_parameter *) msg->param;
980         size_t size = sizeof(struct sap_message);
981
982         if (!conn)
983                 return -EINVAL;
984
985         DBG("state %d pr 0x%02x sc 0x%02x", conn->state, conn->processing_req,
986                                                                 status_change);
987
988         switch (conn->state) {
989         case SAP_STATE_CONNECT_MODEM_BUSY:
990                 if (status_change != SAP_STATUS_CHANGE_CARD_RESET)
991                         break;
992
993                 /* Change state to connected after ongoing call ended */
994                 sap_set_connected(server);
995                 /* fall */
996         case SAP_STATE_CONNECTED:
997         case SAP_STATE_GRACEFUL_DISCONNECT:
998                 memset(buf, 0, sizeof(buf));
999                 msg->id = SAP_STATUS_IND;
1000                 msg->nparam = 0x01;
1001
1002                 /* Add status change. */
1003                 param->id  = SAP_PARAM_ID_STATUS_CHANGE;
1004                 param->len = htons(SAP_PARAM_ID_STATUS_CHANGE_LEN);
1005                 *param->val = status_change;
1006                 size += PARAMETER_SIZE(SAP_PARAM_ID_STATUS_CHANGE_LEN);
1007
1008                 return send_message(conn, buf, size);
1009         case SAP_STATE_DISCONNECTED:
1010         case SAP_STATE_CONNECT_IN_PROGRESS:
1011         case SAP_STATE_IMMEDIATE_DISCONNECT:
1012         case SAP_STATE_CLIENT_DISCONNECT:
1013                 break;
1014         }
1015
1016         return 0;
1017 }
1018
1019 int sap_disconnect_ind(void *sap_device, uint8_t disc_type)
1020 {
1021         return disconnect_req(sap_device, SAP_DISCONNECTION_TYPE_IMMEDIATE);
1022 }
1023
1024 static int handle_cmd(struct sap_server *server, void *buf, size_t size)
1025 {
1026         struct sap_connection *conn = server->conn;
1027         struct sap_message *msg = buf;
1028
1029         if (!conn)
1030                 return -EINVAL;
1031
1032         if (size < sizeof(struct sap_message))
1033                 goto error_rsp;
1034
1035         if (msg->nparam != 0 && size < (sizeof(struct sap_message) +
1036                                         sizeof(struct sap_parameter) + 4))
1037                 goto error_rsp;
1038
1039         if (check_msg(msg) < 0)
1040                 goto error_rsp;
1041
1042         switch (msg->id) {
1043         case SAP_CONNECT_REQ:
1044                 connect_req(server, msg->param);
1045                 return 0;
1046         case SAP_DISCONNECT_REQ:
1047                 disconnect_req(server, SAP_DISCONNECTION_TYPE_CLIENT);
1048                 return 0;
1049         case SAP_TRANSFER_APDU_REQ:
1050                 transfer_apdu_req(server, msg->param);
1051                 return 0;
1052         case SAP_TRANSFER_ATR_REQ:
1053                 transfer_atr_req(server);
1054                 return 0;
1055         case SAP_POWER_SIM_OFF_REQ:
1056                 power_sim_off_req(server);
1057                 return 0;
1058         case SAP_POWER_SIM_ON_REQ:
1059                 power_sim_on_req(server);
1060                 return 0;
1061         case SAP_RESET_SIM_REQ:
1062                 reset_sim_req(server);
1063                 return 0;
1064         case SAP_TRANSFER_CARD_READER_STATUS_REQ:
1065                 transfer_card_reader_status_req(server);
1066                 return 0;
1067         case SAP_SET_TRANSPORT_PROTOCOL_REQ:
1068                 set_transport_protocol_req(server, msg->param);
1069                 return 0;
1070         default:
1071                 DBG("Unknown SAP message id 0x%02x.", msg->id);
1072                 break;
1073         }
1074
1075 error_rsp:
1076         DBG("Invalid SAP message format.");
1077         sap_error_rsp(conn);
1078         return -EBADMSG;
1079 }
1080
1081 static void sap_server_remove_conn(struct sap_server *server)
1082 {
1083         struct sap_connection *conn = server->conn;
1084
1085         DBG("conn %p", conn);
1086
1087         if (!conn)
1088                 return;
1089
1090         if (conn->io) {
1091                 g_io_channel_shutdown(conn->io, TRUE, NULL);
1092                 g_io_channel_unref(conn->io);
1093         }
1094
1095         g_free(conn);
1096         server->conn = NULL;
1097 }
1098
1099 static gboolean sap_io_cb(GIOChannel *io, GIOCondition cond, gpointer data)
1100 {
1101         char buf[SAP_BUF_SIZE];
1102         size_t bytes_read = 0;
1103         GError *gerr = NULL;
1104         GIOStatus gstatus;
1105
1106         SAP_VDBG("conn %p io %p", conn, io);
1107
1108         if (cond & G_IO_NVAL) {
1109                 DBG("ERR (G_IO_NVAL) on rfcomm socket.");
1110                 return FALSE;
1111         }
1112
1113         if (cond & G_IO_ERR) {
1114                 DBG("ERR (G_IO_ERR) on rfcomm socket.");
1115                 return FALSE;
1116         }
1117
1118         if (cond & G_IO_HUP) {
1119                 DBG("HUP on rfcomm socket.");
1120                 return FALSE;
1121         }
1122
1123         gstatus = g_io_channel_read_chars(io, buf, sizeof(buf) - 1,
1124                                                         &bytes_read, &gerr);
1125         if (gstatus != G_IO_STATUS_NORMAL) {
1126                 if (gerr)
1127                         g_error_free(gerr);
1128
1129                 return TRUE;
1130         }
1131
1132         if (handle_cmd(data, buf, bytes_read) < 0)
1133                 error("SAP protocol processing failure.");
1134
1135         return TRUE;
1136 }
1137
1138 static void sap_io_destroy(void *data)
1139 {
1140         struct sap_server *server = data;
1141         struct sap_connection *conn = server->conn;
1142
1143         DBG("conn %p", conn);
1144
1145         if (!conn || !conn->io)
1146                 return;
1147
1148         stop_guard_timer(server);
1149
1150         if (conn->state != SAP_STATE_CONNECT_IN_PROGRESS &&
1151                                 conn->state != SAP_STATE_CONNECT_MODEM_BUSY)
1152                 g_dbus_emit_property_changed(btd_get_dbus_connection(),
1153                                         adapter_get_path(server->adapter),
1154                                         SAP_SERVER_INTERFACE,
1155                                         "Connected");
1156
1157         if (conn->state == SAP_STATE_CONNECT_IN_PROGRESS ||
1158                         conn->state == SAP_STATE_CONNECT_MODEM_BUSY ||
1159                         conn->state == SAP_STATE_CONNECTED ||
1160                         conn->state == SAP_STATE_GRACEFUL_DISCONNECT)
1161                 sap_disconnect_req(server, 1);
1162
1163         sap_server_remove_conn(server);
1164 }
1165
1166 static void sap_connect_cb(GIOChannel *io, GError *gerr, gpointer data)
1167 {
1168         struct sap_server *server = data;
1169         struct sap_connection *conn = server->conn;
1170
1171         DBG("conn %p, io %p", conn, io);
1172
1173         if (!conn)
1174                 return;
1175
1176         /* Timer will shutdown the channel in case of lack of client
1177            activity */
1178         start_guard_timer(server, SAP_TIMER_NO_ACTIVITY);
1179
1180         g_io_add_watch_full(io, G_PRIORITY_DEFAULT,
1181                         G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
1182                         sap_io_cb, server, sap_io_destroy);
1183 }
1184
1185 static void connect_auth_cb(DBusError *derr, void *data)
1186 {
1187         struct sap_server *server = data;
1188         struct sap_connection *conn = server->conn;
1189         GError *gerr = NULL;
1190
1191         DBG("conn %p", conn);
1192
1193         if (!conn)
1194                 return;
1195
1196         if (derr && dbus_error_is_set(derr)) {
1197                 error("Access has been denied (%s)", derr->message);
1198                 sap_server_remove_conn(server);
1199                 return;
1200         }
1201
1202         if (!bt_io_accept(conn->io, sap_connect_cb, server, NULL, &gerr)) {
1203                 error("bt_io_accept: %s", gerr->message);
1204                 g_error_free(gerr);
1205                 sap_server_remove_conn(server);
1206                 return;
1207         }
1208
1209         DBG("Access has been granted.");
1210 }
1211
1212 static void connect_confirm_cb(GIOChannel *io, gpointer data)
1213 {
1214         struct sap_server *server = data;
1215         struct sap_connection *conn = server->conn;
1216         GError *gerr = NULL;
1217         bdaddr_t src, dst;
1218         char dstaddr[18];
1219         guint ret;
1220
1221         DBG("conn %p io %p", conn, io);
1222
1223         if (!io)
1224                 return;
1225
1226         if (conn) {
1227                 DBG("Another SAP connection already exists.");
1228                 g_io_channel_shutdown(io, TRUE, NULL);
1229                 return;
1230         }
1231
1232         conn = g_try_new0(struct sap_connection, 1);
1233         if (!conn) {
1234                 error("Can't allocate memory for incoming SAP connection.");
1235                 g_io_channel_shutdown(io, TRUE, NULL);
1236                 return;
1237         }
1238
1239         g_io_channel_set_encoding(io, NULL, NULL);
1240         g_io_channel_set_buffered(io, FALSE);
1241
1242         server->conn = conn;
1243         conn->io = g_io_channel_ref(io);
1244         conn->state = SAP_STATE_DISCONNECTED;
1245
1246         bt_io_get(io, &gerr,
1247                         BT_IO_OPT_SOURCE_BDADDR, &src,
1248                         BT_IO_OPT_DEST_BDADDR, &dst,
1249                         BT_IO_OPT_INVALID);
1250         if (gerr) {
1251                 error("%s", gerr->message);
1252                 g_error_free(gerr);
1253                 sap_server_remove_conn(server);
1254                 return;
1255         }
1256
1257         ba2str(&dst, dstaddr);
1258
1259         ret = btd_request_authorization(&src, &dst, SAP_UUID, connect_auth_cb,
1260                                                                 server);
1261         if (ret == 0) {
1262                 error("Authorization failure");
1263                 sap_server_remove_conn(server);
1264                 return;
1265         }
1266
1267         DBG("Authorizing incoming SAP connection from %s", dstaddr);
1268 }
1269
1270 static DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg,
1271                                                                 void *data)
1272 {
1273         struct sap_server *server = data;
1274
1275         if (!server)
1276                 return btd_error_failed(msg, "Server internal error.");
1277
1278         DBG("conn %p", server->conn);
1279
1280         if (!server->conn)
1281                 return btd_error_failed(msg, "Client already disconnected");
1282
1283         if (disconnect_req(server, SAP_DISCONNECTION_TYPE_GRACEFUL) < 0)
1284                 return btd_error_failed(msg, "There is no active connection");
1285
1286         return dbus_message_new_method_return(msg);
1287 }
1288
1289 static gboolean server_property_get_connected(
1290                                         const GDBusPropertyTable *property,
1291                                         DBusMessageIter *iter, void *data)
1292 {
1293         struct sap_server *server = data;
1294         struct sap_connection *conn = server->conn;
1295         dbus_bool_t connected;
1296
1297         if (!conn) {
1298                 connected = FALSE;
1299                 goto append;
1300         }
1301
1302         connected = (conn->state == SAP_STATE_CONNECTED ||
1303                                 conn->state == SAP_STATE_GRACEFUL_DISCONNECT);
1304
1305 append:
1306         dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &connected);
1307
1308         return TRUE;
1309 }
1310
1311 static const GDBusMethodTable server_methods[] = {
1312         { GDBUS_METHOD("Disconnect", NULL, NULL, disconnect) },
1313         { }
1314 };
1315
1316 static const GDBusPropertyTable server_properties[] = {
1317         { "Connected", "b", server_property_get_connected },
1318         { }
1319 };
1320
1321 static void server_remove(struct sap_server *server)
1322 {
1323         if (!server)
1324                 return;
1325
1326         sap_server_remove_conn(server);
1327
1328         adapter_service_remove(server->adapter, server->record_id);
1329
1330         if (server->listen_io) {
1331                 g_io_channel_shutdown(server->listen_io, TRUE, NULL);
1332                 g_io_channel_unref(server->listen_io);
1333                 server->listen_io = NULL;
1334         }
1335
1336         btd_adapter_unref(server->adapter);
1337         g_free(server);
1338 }
1339
1340 static void destroy_sap_interface(void *data)
1341 {
1342         struct sap_server *server = data;
1343
1344         DBG("Unregistered interface %s on path %s", SAP_SERVER_INTERFACE,
1345                                         adapter_get_path(server->adapter));
1346
1347         server_remove(server);
1348 }
1349
1350 int sap_server_register(struct btd_adapter *adapter)
1351 {
1352         sdp_record_t *record = NULL;
1353         GError *gerr = NULL;
1354         GIOChannel *io;
1355         struct sap_server *server;
1356
1357         if (sap_init() < 0) {
1358                 error("Sap driver initialization failed.");
1359                 return -1;
1360         }
1361
1362         record = create_sap_record(SAP_SERVER_CHANNEL);
1363         if (!record) {
1364                 error("Creating SAP SDP record failed.");
1365                 goto sdp_err;
1366         }
1367
1368         if (adapter_service_add(adapter, record) < 0) {
1369                 error("Adding SAP SDP record to the SDP server failed.");
1370                 sdp_record_free(record);
1371                 goto sdp_err;
1372         }
1373
1374         server = g_new0(struct sap_server, 1);
1375         server->adapter = btd_adapter_ref(adapter);
1376         server->record_id = record->handle;
1377
1378         io = bt_io_listen(NULL, connect_confirm_cb, server,
1379                         NULL, &gerr,
1380                         BT_IO_OPT_SOURCE_BDADDR,
1381                         btd_adapter_get_address(adapter),
1382                         BT_IO_OPT_CHANNEL, SAP_SERVER_CHANNEL,
1383                         BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_HIGH,
1384                         BT_IO_OPT_MASTER, TRUE,
1385                         BT_IO_OPT_INVALID);
1386         if (!io) {
1387                 error("Can't listen at channel %d.", SAP_SERVER_CHANNEL);
1388                 g_error_free(gerr);
1389                 goto server_err;
1390         }
1391         server->listen_io = io;
1392
1393         if (!g_dbus_register_interface(btd_get_dbus_connection(),
1394                                         adapter_get_path(server->adapter),
1395                                         SAP_SERVER_INTERFACE,
1396                                         server_methods, NULL,
1397                                         server_properties, server,
1398                                         destroy_sap_interface)) {
1399                 error("D-Bus failed to register %s interface",
1400                                                         SAP_SERVER_INTERFACE);
1401                 goto server_err;
1402         }
1403
1404         DBG("server %p, listen socket 0x%02x", server,
1405                                                 g_io_channel_unix_get_fd(io));
1406
1407         return 0;
1408
1409 server_err:
1410         server_remove(server);
1411 sdp_err:
1412         sap_exit();
1413
1414         return -1;
1415 }
1416
1417 void sap_server_unregister(const char *path)
1418 {
1419         g_dbus_unregister_interface(btd_get_dbus_connection(),
1420                                                 path, SAP_SERVER_INTERFACE);
1421
1422         sap_exit();
1423 }