2 * BlueZ - Bluetooth protocol stack for Linux
4 * Copyright (C) 2010 Instituto Nokia de Tecnologia - INdT
5 * Copyright (C) 2010 ST-Ericsson SA
6 * Copyright (C) 2011 Tieto Poland
8 * Author: Marek Skowron <marek.skowron@tieto.com> for ST-Ericsson.
9 * Author: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
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.
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.
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
35 #include "lib/sdp_lib.h"
38 #include "gdbus/gdbus.h"
40 #include "btio/btio.h"
41 #include "src/adapter.h"
44 #include "src/error.h"
45 #include "src/dbus-common.h"
46 #include "src/shared/util.h"
51 #define SAP_SERVER_INTERFACE "org.bluez.SimAccess1"
52 #define SAP_SERVER_CHANNEL 8
54 #define PADDING4(x) ((4 - ((x) & 0x03)) & 0x03)
55 #define PARAMETER_SIZE(x) (sizeof(struct sap_parameter) + x + PADDING4(x))
57 #define SAP_NO_REQ 0xFF
58 #define SAP_DISCONNECTION_TYPE_CLIENT 0xFF
60 #define SAP_TIMER_GRACEFUL_DISCONNECT 30
61 #define SAP_TIMER_NO_ACTIVITY 30
64 SAP_STATE_DISCONNECTED,
65 SAP_STATE_CONNECT_IN_PROGRESS,
66 SAP_STATE_CONNECT_MODEM_BUSY,
68 SAP_STATE_GRACEFUL_DISCONNECT,
69 SAP_STATE_IMMEDIATE_DISCONNECT,
70 SAP_STATE_CLIENT_DISCONNECT
73 struct sap_connection {
76 uint8_t processing_req;
81 struct btd_adapter *adapter;
83 GIOChannel *listen_io;
84 struct sap_connection *conn;
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);
91 static size_t add_result_parameter(uint8_t result,
92 struct sap_parameter *param)
94 param->id = SAP_PARAM_ID_RESULT_CODE;
95 param->len = htons(SAP_PARAM_ID_RESULT_CODE_LEN);
98 return PARAMETER_SIZE(SAP_PARAM_ID_RESULT_CODE_LEN);
101 static int is_power_sim_off_req_allowed(uint8_t processing_req)
103 switch (processing_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:
116 static int is_reset_sim_req_allowed(uint8_t processing_req)
118 switch (processing_req) {
120 case SAP_TRANSFER_APDU_REQ:
121 case SAP_TRANSFER_ATR_REQ:
122 case SAP_TRANSFER_CARD_READER_STATUS_REQ:
129 static int check_msg(struct sap_message *msg)
132 case SAP_CONNECT_REQ:
133 if (msg->nparam != 0x01)
136 if (msg->param->id != SAP_PARAM_ID_MAX_MSG_SIZE)
139 if (ntohs(msg->param->len) != SAP_PARAM_ID_MAX_MSG_SIZE_LEN)
144 case SAP_TRANSFER_APDU_REQ:
145 if (msg->nparam != 0x01)
148 if (msg->param->id != SAP_PARAM_ID_COMMAND_APDU)
149 if (msg->param->id != SAP_PARAM_ID_COMMAND_APDU7816)
152 if (msg->param->len == 0x00)
157 case SAP_SET_TRANSPORT_PROTOCOL_REQ:
158 if (msg->nparam != 0x01)
161 if (msg->param->id != SAP_PARAM_ID_TRANSPORT_PROTOCOL)
164 if (ntohs(msg->param->len) != SAP_PARAM_ID_TRANSPORT_PROTO_LEN)
167 if (*msg->param->val != SAP_TRANSPORT_PROTOCOL_T0)
168 if (*msg->param->val != SAP_TRANSPORT_PROTOCOL_T1)
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)
188 static sdp_record_t *create_sap_record(uint8_t channel)
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;
196 record = sdp_record_alloc();
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);
205 sdp_uuid16_create(&sap_uuid, SAP_SVCLASS_ID);
206 svclass_id = sdp_list_append(NULL, &sap_uuid);
207 sdp_uuid16_create(>_uuid, GENERIC_TELEPHONY_SVCLASS_ID);
208 svclass_id = sdp_list_append(svclass_id, >_uuid);
210 sdp_set_service_classes(record, svclass_id);
211 sdp_list_free(svclass_id, NULL);
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);
219 sdp_uuid16_create(&l2cap, L2CAP_UUID);
220 proto[0] = sdp_list_append(NULL, &l2cap);
221 apseq = sdp_list_append(NULL, proto[0]);
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]);
229 aproto = sdp_list_append(NULL, apseq);
230 sdp_set_access_protos(record, aproto);
232 sdp_set_info_attr(record, "SIM Access Server", NULL, NULL);
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);
243 static int send_message(struct sap_connection *conn, void *buf, size_t size)
249 SAP_VDBG("conn %p, size %zu", conn, size);
251 gstatus = g_io_channel_write_chars(conn->io, buf, size, &written,
253 if (gstatus != G_IO_STATUS_NORMAL) {
257 error("write error (0x%02x).", gstatus);
261 if (written != size) {
262 error("written %zu bytes out of %zu", written, size);
269 static int disconnect_ind(struct sap_connection *conn, uint8_t disc_type)
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);
276 DBG("data %p state %d disc_type 0x%02x", conn, conn->state, disc_type);
278 memset(buf, 0, sizeof(buf));
279 msg->id = SAP_DISCONNECT_IND;
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);
288 return send_message(conn, buf, size);
291 static int sap_error_rsp(struct sap_connection *conn)
293 struct sap_message msg;
295 memset(&msg, 0, sizeof(msg));
296 msg.id = SAP_ERROR_RESP;
298 error("SAP error (state %d pr 0x%02x).", conn->state,
299 conn->processing_req);
301 return send_message(conn, &msg, sizeof(msg));
304 static void connect_req(struct sap_server *server,
305 struct sap_parameter *param)
307 struct sap_connection *conn = server->conn;
310 DBG("conn %p state %d", conn, conn->state);
315 if (conn->state != SAP_STATE_DISCONNECTED)
318 stop_guard_timer(server);
320 maxmsgsize = get_be16(¶m->val);
322 DBG("Connect MaxMsgSize: 0x%04x", maxmsgsize);
324 conn->state = SAP_STATE_CONNECT_IN_PROGRESS;
326 if (maxmsgsize <= SAP_BUF_SIZE) {
327 conn->processing_req = SAP_CONNECT_REQ;
328 sap_connect_req(server, maxmsgsize);
330 sap_connect_rsp(server, SAP_STATUS_MAX_MSG_SIZE_NOT_SUPPORTED);
339 static int disconnect_req(struct sap_server *server, uint8_t disc_type)
341 struct sap_connection *conn = server->conn;
343 DBG("conn %p state %d disc_type 0x%02x", conn, conn->state, 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)
352 if (conn->state == SAP_STATE_CONNECTED) {
353 conn->state = SAP_STATE_GRACEFUL_DISCONNECT;
354 conn->processing_req = SAP_NO_REQ;
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);
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)
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;
375 stop_guard_timer(server);
376 disconnect_ind(conn, disc_type);
377 sap_disconnect_req(server, 0);
382 case SAP_DISCONNECTION_TYPE_CLIENT:
383 if (conn->state != SAP_STATE_CONNECTED &&
384 conn->state != SAP_STATE_GRACEFUL_DISCONNECT) {
389 conn->state = SAP_STATE_CLIENT_DISCONNECT;
390 conn->processing_req = SAP_NO_REQ;
392 stop_guard_timer(server);
393 sap_disconnect_req(server, 0);
398 error("Unknown disconnection type (0x%02x).", disc_type);
403 static void transfer_apdu_req(struct sap_server *server,
404 struct sap_parameter *param)
406 struct sap_connection *conn = server->conn;
408 SAP_VDBG("conn %p state %d", conn, conn->state);
413 param->len = ntohs(param->len);
415 if (conn->state != SAP_STATE_CONNECTED &&
416 conn->state != SAP_STATE_GRACEFUL_DISCONNECT)
419 if (conn->processing_req != SAP_NO_REQ)
422 conn->processing_req = SAP_TRANSFER_APDU_REQ;
423 sap_transfer_apdu_req(server, param);
431 static void transfer_atr_req(struct sap_server *server)
433 struct sap_connection *conn = server->conn;
435 DBG("conn %p state %d", conn, conn->state);
437 if (conn->state != SAP_STATE_CONNECTED)
440 if (conn->processing_req != SAP_NO_REQ)
443 conn->processing_req = SAP_TRANSFER_ATR_REQ;
444 sap_transfer_atr_req(server);
452 static void power_sim_off_req(struct sap_server *server)
454 struct sap_connection *conn = server->conn;
456 DBG("conn %p state %d", conn, conn->state);
458 if (conn->state != SAP_STATE_CONNECTED)
461 if (!is_power_sim_off_req_allowed(conn->processing_req))
464 conn->processing_req = SAP_POWER_SIM_OFF_REQ;
465 sap_power_sim_off_req(server);
473 static void power_sim_on_req(struct sap_server *server)
475 struct sap_connection *conn = server->conn;
477 DBG("conn %p state %d", conn, conn->state);
479 if (conn->state != SAP_STATE_CONNECTED)
482 if (conn->processing_req != SAP_NO_REQ)
485 conn->processing_req = SAP_POWER_SIM_ON_REQ;
486 sap_power_sim_on_req(server);
494 static void reset_sim_req(struct sap_server *server)
496 struct sap_connection *conn = server->conn;
498 DBG("conn %p state %d", conn, conn->state);
500 if (conn->state != SAP_STATE_CONNECTED)
503 if (!is_reset_sim_req_allowed(conn->processing_req))
506 conn->processing_req = SAP_RESET_SIM_REQ;
507 sap_reset_sim_req(server);
515 static void transfer_card_reader_status_req(struct sap_server *server)
517 struct sap_connection *conn = server->conn;
519 DBG("conn %p state %d", conn, conn->state);
521 if (conn->state != SAP_STATE_CONNECTED)
524 if (conn->processing_req != SAP_NO_REQ)
527 conn->processing_req = SAP_TRANSFER_CARD_READER_STATUS_REQ;
528 sap_transfer_card_reader_status_req(server);
536 static void set_transport_protocol_req(struct sap_server *server,
537 struct sap_parameter *param)
539 struct sap_connection *conn = server->conn;
544 DBG("conn %p state %d param %p", conn, conn->state, param);
546 if (conn->state != SAP_STATE_CONNECTED)
549 if (conn->processing_req != SAP_NO_REQ)
552 conn->processing_req = SAP_SET_TRANSPORT_PROTOCOL_REQ;
553 sap_set_transport_protocol_req(server, param);
561 static void start_guard_timer(struct sap_server *server, guint interval)
563 struct sap_connection *conn = server->conn;
569 conn->timer_id = g_timeout_add_seconds(interval, guard_timeout,
572 error("Timer is already active.");
575 static void stop_guard_timer(struct sap_server *server)
577 struct sap_connection *conn = server->conn;
579 if (conn && conn->timer_id) {
580 g_source_remove(conn->timer_id);
585 static gboolean guard_timeout(gpointer data)
587 struct sap_server *server = data;
588 struct sap_connection *conn = server->conn;
593 DBG("conn %p state %d pr 0x%02x", conn, conn->state,
594 conn->processing_req);
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.*/
604 g_io_channel_shutdown(conn->io, TRUE, NULL);
605 g_io_channel_unref(conn->io);
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);
617 error("Unexpected state (%d).", conn->state);
624 static void sap_set_connected(struct sap_server *server)
626 server->conn->state = SAP_STATE_CONNECTED;
628 g_dbus_emit_property_changed(btd_get_dbus_connection(),
629 adapter_get_path(server->adapter),
630 SAP_SERVER_INTERFACE, "Connected");
633 int sap_connect_rsp(void *sap_device, uint8_t status)
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);
645 DBG("state %d pr 0x%02x status 0x%02x", conn->state,
646 conn->processing_req, status);
648 if (conn->state != SAP_STATE_CONNECT_IN_PROGRESS)
651 memset(buf, 0, sizeof(buf));
652 msg->id = SAP_CONNECT_RESP;
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);
664 sap_set_connected(server);
666 case SAP_STATUS_OK_ONGOING_CALL:
667 DBG("ongoing call. Wait for reset indication!");
668 conn->state = SAP_STATE_CONNECT_MODEM_BUSY;
670 case SAP_STATUS_MAX_MSG_SIZE_NOT_SUPPORTED: /* Add MaxMsgSize */
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, ¶m->val);
676 size += PARAMETER_SIZE(SAP_PARAM_ID_MAX_MSG_SIZE_LEN);
680 conn->state = SAP_STATE_DISCONNECTED;
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);
688 conn->processing_req = SAP_NO_REQ;
690 return send_message(conn, buf, size);
693 int sap_disconnect_rsp(void *sap_device)
695 struct sap_server *server = sap_device;
696 struct sap_connection *conn = server->conn;
697 struct sap_message msg;
702 DBG("state %d pr 0x%02x", conn->state, conn->processing_req);
704 switch (conn->state) {
705 case SAP_STATE_CLIENT_DISCONNECT:
706 memset(&msg, 0, sizeof(msg));
707 msg.id = SAP_DISCONNECT_RESP;
709 conn->state = SAP_STATE_DISCONNECTED;
710 conn->processing_req = SAP_NO_REQ;
712 /* Timer will close channel if client doesn't do it.*/
713 start_guard_timer(server, SAP_TIMER_NO_ACTIVITY);
715 return send_message(conn, &msg, sizeof(msg));
717 case SAP_STATE_IMMEDIATE_DISCONNECT:
718 conn->state = SAP_STATE_DISCONNECTED;
719 conn->processing_req = SAP_NO_REQ;
722 g_io_channel_shutdown(conn->io, TRUE, NULL);
723 g_io_channel_unref(conn->io);
736 int sap_transfer_apdu_rsp(void *sap_device, uint8_t result, uint8_t *apdu,
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);
749 SAP_VDBG("state %d pr 0x%02x", conn->state, conn->processing_req);
751 if (conn->processing_req != SAP_TRANSFER_APDU_REQ)
754 if (result == SAP_RESULT_OK && (!apdu || (apdu && length == 0x00)))
757 memset(buf, 0, sizeof(buf));
758 msg->id = SAP_TRANSFER_APDU_RESP;
760 size += add_result_parameter(result, param);
762 /* Add APDU response. */
763 if (result == SAP_RESULT_OK) {
765 param = (struct sap_parameter *) &buf[size];
766 param->id = SAP_PARAM_ID_RESPONSE_APDU;
767 param->len = htons(length);
769 size += PARAMETER_SIZE(length);
771 if (size > SAP_BUF_SIZE)
774 memcpy(param->val, apdu, length);
777 conn->processing_req = SAP_NO_REQ;
779 return send_message(conn, buf, size);
782 int sap_transfer_atr_rsp(void *sap_device, uint8_t result, uint8_t *atr,
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);
795 DBG("result 0x%02x state %d pr 0x%02x len %d", result, conn->state,
796 conn->processing_req, length);
798 if (conn->processing_req != SAP_TRANSFER_ATR_REQ)
801 if (result == SAP_RESULT_OK && (!atr || (atr && length == 0x00)))
804 memset(buf, 0, sizeof(buf));
805 msg->id = SAP_TRANSFER_ATR_RESP;
807 size += add_result_parameter(result, param);
809 /* Add ATR response */
810 if (result == SAP_RESULT_OK) {
812 param = (struct sap_parameter *) &buf[size];
813 param->id = SAP_PARAM_ID_ATR;
814 param->len = htons(length);
815 size += PARAMETER_SIZE(length);
817 if (size > SAP_BUF_SIZE)
820 memcpy(param->val, atr, length);
823 conn->processing_req = SAP_NO_REQ;
825 return send_message(conn, buf, size);
828 int sap_power_sim_off_rsp(void *sap_device, uint8_t result)
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);
839 DBG("state %d pr 0x%02x", conn->state, conn->processing_req);
841 if (conn->processing_req != SAP_POWER_SIM_OFF_REQ)
844 memset(buf, 0, sizeof(buf));
845 msg->id = SAP_POWER_SIM_OFF_RESP;
847 size += add_result_parameter(result, msg->param);
849 conn->processing_req = SAP_NO_REQ;
851 return send_message(conn, buf, size);
854 int sap_power_sim_on_rsp(void *sap_device, uint8_t result)
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);
865 DBG("state %d pr 0x%02x", conn->state, conn->processing_req);
867 if (conn->processing_req != SAP_POWER_SIM_ON_REQ)
870 memset(buf, 0, sizeof(buf));
871 msg->id = SAP_POWER_SIM_ON_RESP;
873 size += add_result_parameter(result, msg->param);
875 conn->processing_req = SAP_NO_REQ;
877 return send_message(conn, buf, size);
880 int sap_reset_sim_rsp(void *sap_device, uint8_t result)
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);
891 DBG("state %d pr 0x%02x result 0x%02x", conn->state,
892 conn->processing_req, result);
894 if (conn->processing_req != SAP_RESET_SIM_REQ)
897 memset(buf, 0, sizeof(buf));
898 msg->id = SAP_RESET_SIM_RESP;
900 size += add_result_parameter(result, msg->param);
902 conn->processing_req = SAP_NO_REQ;
904 return send_message(conn, buf, size);
907 int sap_transfer_card_reader_status_rsp(void *sap_device, uint8_t result,
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);
920 DBG("state %d pr 0x%02x result 0x%02x", conn->state,
921 conn->processing_req, result);
923 if (conn->processing_req != SAP_TRANSFER_CARD_READER_STATUS_REQ)
926 memset(buf, 0, sizeof(buf));
927 msg->id = SAP_TRANSFER_CARD_READER_STATUS_RESP;
929 size += add_result_parameter(result, param);
931 /* Add card reader status. */
932 if (result == SAP_RESULT_OK) {
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);
941 conn->processing_req = SAP_NO_REQ;
943 return send_message(conn, buf, size);
946 int sap_transport_protocol_rsp(void *sap_device, uint8_t result)
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);
957 DBG("state %d pr 0x%02x result 0x%02x", conn->state,
958 conn->processing_req, result);
960 if (conn->processing_req != SAP_SET_TRANSPORT_PROTOCOL_REQ)
963 memset(buf, 0, sizeof(buf));
964 msg->id = SAP_SET_TRANSPORT_PROTOCOL_RESP;
966 size += add_result_parameter(result, msg->param);
968 conn->processing_req = SAP_NO_REQ;
970 return send_message(conn, buf, size);
973 int sap_status_ind(void *sap_device, uint8_t status_change)
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);
985 DBG("state %d pr 0x%02x sc 0x%02x", conn->state, conn->processing_req,
988 switch (conn->state) {
989 case SAP_STATE_CONNECT_MODEM_BUSY:
990 if (status_change != SAP_STATUS_CHANGE_CARD_RESET)
993 /* Change state to connected after ongoing call ended */
994 sap_set_connected(server);
996 case SAP_STATE_CONNECTED:
997 case SAP_STATE_GRACEFUL_DISCONNECT:
998 memset(buf, 0, sizeof(buf));
999 msg->id = SAP_STATUS_IND;
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);
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:
1019 int sap_disconnect_ind(void *sap_device, uint8_t disc_type)
1021 return disconnect_req(sap_device, SAP_DISCONNECTION_TYPE_IMMEDIATE);
1024 static int handle_cmd(struct sap_server *server, void *buf, size_t size)
1026 struct sap_connection *conn = server->conn;
1027 struct sap_message *msg = buf;
1032 if (size < sizeof(struct sap_message))
1035 if (msg->nparam != 0 && size < (sizeof(struct sap_message) +
1036 sizeof(struct sap_parameter) + 4))
1039 if (check_msg(msg) < 0)
1043 case SAP_CONNECT_REQ:
1044 connect_req(server, msg->param);
1046 case SAP_DISCONNECT_REQ:
1047 disconnect_req(server, SAP_DISCONNECTION_TYPE_CLIENT);
1049 case SAP_TRANSFER_APDU_REQ:
1050 transfer_apdu_req(server, msg->param);
1052 case SAP_TRANSFER_ATR_REQ:
1053 transfer_atr_req(server);
1055 case SAP_POWER_SIM_OFF_REQ:
1056 power_sim_off_req(server);
1058 case SAP_POWER_SIM_ON_REQ:
1059 power_sim_on_req(server);
1061 case SAP_RESET_SIM_REQ:
1062 reset_sim_req(server);
1064 case SAP_TRANSFER_CARD_READER_STATUS_REQ:
1065 transfer_card_reader_status_req(server);
1067 case SAP_SET_TRANSPORT_PROTOCOL_REQ:
1068 set_transport_protocol_req(server, msg->param);
1071 DBG("Unknown SAP message id 0x%02x.", msg->id);
1076 DBG("Invalid SAP message format.");
1077 sap_error_rsp(conn);
1081 static void sap_server_remove_conn(struct sap_server *server)
1083 struct sap_connection *conn = server->conn;
1085 DBG("conn %p", conn);
1091 g_io_channel_shutdown(conn->io, TRUE, NULL);
1092 g_io_channel_unref(conn->io);
1096 server->conn = NULL;
1099 static gboolean sap_io_cb(GIOChannel *io, GIOCondition cond, gpointer data)
1101 char buf[SAP_BUF_SIZE];
1102 size_t bytes_read = 0;
1103 GError *gerr = NULL;
1106 SAP_VDBG("conn %p io %p", conn, io);
1108 if (cond & G_IO_NVAL) {
1109 DBG("ERR (G_IO_NVAL) on rfcomm socket.");
1113 if (cond & G_IO_ERR) {
1114 DBG("ERR (G_IO_ERR) on rfcomm socket.");
1118 if (cond & G_IO_HUP) {
1119 DBG("HUP on rfcomm socket.");
1123 gstatus = g_io_channel_read_chars(io, buf, sizeof(buf) - 1,
1124 &bytes_read, &gerr);
1125 if (gstatus != G_IO_STATUS_NORMAL) {
1132 if (handle_cmd(data, buf, bytes_read) < 0)
1133 error("SAP protocol processing failure.");
1138 static void sap_io_destroy(void *data)
1140 struct sap_server *server = data;
1141 struct sap_connection *conn = server->conn;
1143 DBG("conn %p", conn);
1145 if (!conn || !conn->io)
1148 stop_guard_timer(server);
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,
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);
1163 sap_server_remove_conn(server);
1166 static void sap_connect_cb(GIOChannel *io, GError *gerr, gpointer data)
1168 struct sap_server *server = data;
1169 struct sap_connection *conn = server->conn;
1171 DBG("conn %p, io %p", conn, io);
1176 /* Timer will shutdown the channel in case of lack of client
1178 start_guard_timer(server, SAP_TIMER_NO_ACTIVITY);
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);
1185 static void connect_auth_cb(DBusError *derr, void *data)
1187 struct sap_server *server = data;
1188 struct sap_connection *conn = server->conn;
1189 GError *gerr = NULL;
1191 DBG("conn %p", conn);
1196 if (derr && dbus_error_is_set(derr)) {
1197 error("Access has been denied (%s)", derr->message);
1198 sap_server_remove_conn(server);
1202 if (!bt_io_accept(conn->io, sap_connect_cb, server, NULL, &gerr)) {
1203 error("bt_io_accept: %s", gerr->message);
1205 sap_server_remove_conn(server);
1209 DBG("Access has been granted.");
1212 static void connect_confirm_cb(GIOChannel *io, gpointer data)
1214 struct sap_server *server = data;
1215 struct sap_connection *conn = server->conn;
1216 GError *gerr = NULL;
1221 DBG("conn %p io %p", conn, io);
1227 DBG("Another SAP connection already exists.");
1228 g_io_channel_shutdown(io, TRUE, NULL);
1232 conn = g_try_new0(struct sap_connection, 1);
1234 error("Can't allocate memory for incoming SAP connection.");
1235 g_io_channel_shutdown(io, TRUE, NULL);
1239 g_io_channel_set_encoding(io, NULL, NULL);
1240 g_io_channel_set_buffered(io, FALSE);
1242 server->conn = conn;
1243 conn->io = g_io_channel_ref(io);
1244 conn->state = SAP_STATE_DISCONNECTED;
1246 bt_io_get(io, &gerr,
1247 BT_IO_OPT_SOURCE_BDADDR, &src,
1248 BT_IO_OPT_DEST_BDADDR, &dst,
1251 error("%s", gerr->message);
1253 sap_server_remove_conn(server);
1257 ba2str(&dst, dstaddr);
1259 ret = btd_request_authorization(&src, &dst, SAP_UUID, connect_auth_cb,
1262 error("Authorization failure");
1263 sap_server_remove_conn(server);
1267 DBG("Authorizing incoming SAP connection from %s", dstaddr);
1270 static DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg,
1273 struct sap_server *server = data;
1276 return btd_error_failed(msg, "Server internal error.");
1278 DBG("conn %p", server->conn);
1281 return btd_error_failed(msg, "Client already disconnected");
1283 if (disconnect_req(server, SAP_DISCONNECTION_TYPE_GRACEFUL) < 0)
1284 return btd_error_failed(msg, "There is no active connection");
1286 return dbus_message_new_method_return(msg);
1289 static gboolean server_property_get_connected(
1290 const GDBusPropertyTable *property,
1291 DBusMessageIter *iter, void *data)
1293 struct sap_server *server = data;
1294 struct sap_connection *conn = server->conn;
1295 dbus_bool_t connected;
1302 connected = (conn->state == SAP_STATE_CONNECTED ||
1303 conn->state == SAP_STATE_GRACEFUL_DISCONNECT);
1306 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &connected);
1311 static const GDBusMethodTable server_methods[] = {
1312 { GDBUS_METHOD("Disconnect", NULL, NULL, disconnect) },
1316 static const GDBusPropertyTable server_properties[] = {
1317 { "Connected", "b", server_property_get_connected },
1321 static void server_remove(struct sap_server *server)
1326 sap_server_remove_conn(server);
1328 adapter_service_remove(server->adapter, server->record_id);
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;
1336 btd_adapter_unref(server->adapter);
1340 static void destroy_sap_interface(void *data)
1342 struct sap_server *server = data;
1344 DBG("Unregistered interface %s on path %s", SAP_SERVER_INTERFACE,
1345 adapter_get_path(server->adapter));
1347 server_remove(server);
1350 int sap_server_register(struct btd_adapter *adapter)
1352 sdp_record_t *record = NULL;
1353 GError *gerr = NULL;
1355 struct sap_server *server;
1357 if (sap_init() < 0) {
1358 error("Sap driver initialization failed.");
1362 record = create_sap_record(SAP_SERVER_CHANNEL);
1364 error("Creating SAP SDP record failed.");
1368 if (adapter_service_add(adapter, record) < 0) {
1369 error("Adding SAP SDP record to the SDP server failed.");
1370 sdp_record_free(record);
1374 server = g_new0(struct sap_server, 1);
1375 server->adapter = btd_adapter_ref(adapter);
1376 server->record_id = record->handle;
1378 io = bt_io_listen(NULL, connect_confirm_cb, server,
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,
1387 error("Can't listen at channel %d.", SAP_SERVER_CHANNEL);
1391 server->listen_io = io;
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);
1404 DBG("server %p, listen socket 0x%02x", server,
1405 g_io_channel_unix_get_fd(io));
1410 server_remove(server);
1417 void sap_server_unregister(const char *path)
1419 g_dbus_unregister_interface(btd_get_dbus_connection(),
1420 path, SAP_SERVER_INTERFACE);