diff options
author | Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com> | 2011-03-16 13:10:20 +0100 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2011-03-23 14:57:45 +0200 |
commit | f9dc0c076258754c0b25314308640eb535db2d4a (patch) | |
tree | 76c6474df225e1baa79edcb575c4815bbce7bfe1 /sap | |
parent | b785550749860cc7de7b65a44d5878fda9c92477 (diff) | |
download | bluez-f9dc0c076258754c0b25314308640eb535db2d4a.tar.gz |
Add Sim Access Profile dummy driver
Add SAP dummy driver implementation and extend configure
with --with-sap=<driver>.
Diffstat (limited to 'sap')
-rw-r--r-- | sap/sap-dummy.c | 269 |
1 files changed, 257 insertions, 12 deletions
diff --git a/sap/sap-dummy.c b/sap/sap-dummy.c index b433ba338..39e1fc9f2 100644 --- a/sap/sap-dummy.c +++ b/sap/sap-dummy.c @@ -2,6 +2,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2010 ST-Ericsson SA + * Copyright (C) 2011 Tieto Poland * * Author: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com> * for ST-Ericsson @@ -21,50 +22,185 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <unistd.h> +#include <stdlib.h> +#include <stdint.h> +#include <glib.h> +#include <gdbus.h> + #include "log.h" #include "sap.h" +#define SAP_DUMMY_IFACE "org.bluez.SimAccessTest" +#define SAP_DUMMY_PATH "/org/bluez/test" + +enum { + SIM_DISCONNECTED= 0x00, + SIM_CONNECTED = 0x01, + SIM_POWERED_OFF = 0x02, + SIM_MISSING = 0x03 +}; + +static DBusConnection *connection = NULL; + +static int sim_card_conn_status = SIM_DISCONNECTED; +static void *sap_data = NULL; /* SAP server private data.*/ +static gboolean ongoing_call_status = FALSE; +static int max_msg_size_supported = 512; + void sap_connect_req(void *sap_device, uint16_t maxmsgsize) { - sap_connect_rsp(sap_device, SAP_STATUS_OK, maxmsgsize); - sap_status_ind(sap_device, SAP_STATUS_CHANGE_CARD_RESET); + DBG("status: %d", sim_card_conn_status); + + if (sim_card_conn_status != SIM_DISCONNECTED) { + sap_connect_rsp(sap_device, SAP_STATUS_CONNECTION_FAILED, + maxmsgsize); + return; + } else if (max_msg_size_supported > maxmsgsize) { + sap_connect_rsp(sap_device, SAP_STATUS_MAX_MSG_SIZE_TOO_SMALL, + max_msg_size_supported); + return; + } else if (max_msg_size_supported < maxmsgsize) { + sap_connect_rsp(sap_device, + SAP_STATUS_MAX_MSG_SIZE_NOT_SUPPORTED, + max_msg_size_supported); + return; + } else if (ongoing_call_status) { + sap_connect_rsp(sap_device, SAP_STATUS_OK_ONGOING_CALL, + maxmsgsize); + return; + } else { + sim_card_conn_status = SIM_CONNECTED; + sap_data = sap_device; + + sap_connect_rsp(sap_device, SAP_STATUS_OK, maxmsgsize); + sap_status_ind(sap_device, SAP_STATUS_CHANGE_CARD_RESET); + } } void sap_disconnect_req(void *sap_device, uint8_t linkloss) { + sim_card_conn_status = SIM_DISCONNECTED; + sap_data = NULL; + ongoing_call_status = FALSE; + + DBG("status: %d", sim_card_conn_status); + + if (linkloss) + return; + sap_disconnect_rsp(sap_device); } void sap_transfer_apdu_req(void *sap_device, struct sap_parameter *param) { - sap_transfer_apdu_rsp(sap_device, SAP_RESULT_OK, NULL, 0); + char apdu[] = "APDU response!"; + + DBG("status: %d", sim_card_conn_status); + + if (sim_card_conn_status == SIM_MISSING) + sap_transfer_apdu_rsp(sap_device, + SAP_RESULT_ERROR_CARD_REMOVED, NULL, 0); + else if (sim_card_conn_status == SIM_POWERED_OFF) + sap_transfer_apdu_rsp(sap_device, SAP_RESULT_ERROR_POWERED_OFF, + NULL, 0); + else if (sim_card_conn_status != SIM_CONNECTED) + sap_transfer_apdu_rsp(sap_device, + SAP_RESULT_ERROR_NOT_ACCESSIBLE, NULL, 0); + else + sap_transfer_apdu_rsp(sap_device, SAP_RESULT_OK, + (uint8_t*)&apdu, sizeof(apdu)); } void sap_transfer_atr_req(void *sap_device) { - sap_transfer_atr_rsp(sap_device, SAP_RESULT_OK, NULL, 0); + char atr[] = "ATR response!"; + + DBG("status: %d", sim_card_conn_status); + + if (sim_card_conn_status == SIM_MISSING) + sap_transfer_atr_rsp(sap_device, SAP_RESULT_ERROR_CARD_REMOVED, + NULL, 0); + else if (sim_card_conn_status == SIM_POWERED_OFF) + sap_transfer_atr_rsp(sap_device, SAP_RESULT_ERROR_POWERED_OFF, + NULL, 0); + else if (sim_card_conn_status != SIM_CONNECTED) + sap_transfer_atr_rsp(sap_device, SAP_RESULT_ERROR_NO_REASON, + NULL, 0); + else + sap_transfer_atr_rsp(sap_device, SAP_RESULT_OK, + (uint8_t*)&atr, sizeof(atr)); } void sap_power_sim_off_req(void *sap_device) { - sap_power_sim_off_rsp(sap_device, SAP_RESULT_OK); + DBG("status: %d", sim_card_conn_status); + + if (sim_card_conn_status == SIM_MISSING) { + sap_power_sim_off_rsp(sap_device, + SAP_RESULT_ERROR_CARD_REMOVED); + } else if (sim_card_conn_status == SIM_POWERED_OFF) { + sap_power_sim_off_rsp(sap_device, + SAP_RESULT_ERROR_POWERED_OFF); + } else if (sim_card_conn_status != SIM_CONNECTED) { + sap_power_sim_off_rsp(sap_device, + SAP_RESULT_ERROR_NO_REASON); + } else { + sap_power_sim_off_rsp(sap_device, SAP_RESULT_OK); + sim_card_conn_status = SIM_POWERED_OFF; + } } void sap_power_sim_on_req(void *sap_device) { - sap_power_sim_on_rsp(sap_device, SAP_RESULT_OK); + DBG("status: %d", sim_card_conn_status); + + if (sim_card_conn_status == SIM_MISSING) { + sap_power_sim_on_rsp(sap_device, + SAP_RESULT_ERROR_CARD_REMOVED); + } else if (sim_card_conn_status == SIM_POWERED_OFF) { + sap_power_sim_on_rsp(sap_device, SAP_RESULT_OK); + sim_card_conn_status = SIM_CONNECTED; + return; + } else if (sim_card_conn_status != SIM_CONNECTED) { + sap_power_sim_on_rsp(sap_device, + SAP_RESULT_ERROR_NOT_ACCESSIBLE); + } else { + sap_power_sim_on_rsp(sap_device, + SAP_RESULT_ERROR_NO_REASON); + } } void sap_reset_sim_req(void *sap_device) { - sap_reset_sim_rsp(sap_device, SAP_RESULT_OK); - sap_status_ind(sap_device, SAP_STATUS_CHANGE_CARD_RESET); + DBG("status: %d", sim_card_conn_status); + + if (sim_card_conn_status == SIM_MISSING) { + sap_reset_sim_rsp(sap_device, SAP_RESULT_ERROR_CARD_REMOVED); + } else if (sim_card_conn_status == SIM_POWERED_OFF) { + sap_reset_sim_rsp(sap_device, SAP_RESULT_ERROR_POWERED_OFF); + } else if (sim_card_conn_status != SIM_CONNECTED) { + sap_reset_sim_rsp(sap_device, SAP_RESULT_ERROR_NO_REASON); + } else { + sap_reset_sim_rsp(sap_device, SAP_RESULT_OK); + } } void sap_transfer_card_reader_status_req(void *sap_device) { - sap_transfer_card_reader_status_rsp(sap_device, SAP_RESULT_OK, - ICC_READER_CARD_POWERED_ON); + DBG("status: %d", sim_card_conn_status); + + if (sim_card_conn_status != SIM_CONNECTED) { + sap_transfer_card_reader_status_rsp(sap_device, + SAP_RESULT_ERROR_NO_REASON, 0xF1); + return; + } + + sap_transfer_card_reader_status_rsp(sap_device, SAP_RESULT_OK, 0xF1); } void sap_set_transport_protocol_req(void *sap_device, @@ -73,13 +209,122 @@ void sap_set_transport_protocol_req(void *sap_device, sap_transport_protocol_rsp(sap_device, SAP_RESULT_NOT_SUPPORTED); } +static inline DBusMessage *invalid_args(DBusMessage *msg) +{ + return g_dbus_create_error(msg, "org.bluez.Error.InvalidArguments", + "Invalid arguments in method call"); +} + +static DBusMessage *ongoing_call(DBusConnection *conn, DBusMessage *msg, + void *data) +{ + dbus_bool_t ongoing; + + if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN, &ongoing, + DBUS_TYPE_INVALID)) + return invalid_args(msg); + + if (ongoing_call_status && !ongoing) { + /* An ongoing call has finished. Continue connection.*/ + sap_connect_rsp(sap_data, SAP_STATUS_OK, + max_msg_size_supported); + sap_status_ind(sap_data, SAP_STATUS_CHANGE_CARD_RESET); + ongoing_call_status = ongoing; + } else if (!ongoing_call_status && ongoing) { + /* An ongoing call has started.*/ + ongoing_call_status = ongoing; + } + + DBG("OngoingCall status set to %d", ongoing_call_status); + + return dbus_message_new_method_return(msg); +} + +static DBusMessage *max_msg_size(DBusConnection *conn, DBusMessage *msg, + void *data) +{ + dbus_uint32_t size; + + if (sim_card_conn_status == SIM_CONNECTED) + return g_dbus_create_error(msg, "org.bluez.Error.Failed", + "Can't change msg size when connected."); + + if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &size, + DBUS_TYPE_INVALID)) + return invalid_args(msg); + + max_msg_size_supported = size; + + DBG("MaxMessageSize set to %d", max_msg_size_supported); + + return dbus_message_new_method_return(msg); +} + +static DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg, + void *data) +{ + sim_card_conn_status = SIM_DISCONNECTED; + sap_status_ind(sap_data, SAP_STATUS_CHANGE_CARD_NOT_ACCESSIBLE); + + return dbus_message_new_method_return(msg); +} + +static DBusMessage *card_status(DBusConnection *conn, DBusMessage *msg, + void *data) +{ + dbus_uint32_t status; + + DBG("status %d", sim_card_conn_status); + + if (sim_card_conn_status != SIM_CONNECTED) + return g_dbus_create_error(msg, "org.bluez.Error.Failed", + "Can't change msg size when not connected."); + + if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &status, + DBUS_TYPE_INVALID)) + return invalid_args(msg); + + if (status) { + if (sim_card_conn_status == SIM_MISSING) { + sim_card_conn_status = SIM_CONNECTED; + sap_status_ind(sap_data, + SAP_STATUS_CHANGE_CARD_INSERTED); + } + } else { + sim_card_conn_status = SIM_MISSING; + sap_status_ind(sap_data, SAP_STATUS_CHANGE_CARD_REMOVED); + } + + DBG("Card status changed to %d", status); + + return dbus_message_new_method_return(msg); +} + +static GDBusMethodTable dummy_methods[] = { + { "OngoingCall", "b", "", ongoing_call}, + { "MaxMessageSize", "u", "", max_msg_size}, + { "Disconnect", "", "", disconnect}, + { "CardStatus", "u", "", card_status}, + { } +}; + int sap_init(void) { - DBG("SAP driver init."); + connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + + if (g_dbus_register_interface(connection, SAP_DUMMY_PATH, + SAP_DUMMY_IFACE, dummy_methods, NULL, NULL, + NULL, NULL) == FALSE) { + error("sap-dummy interface %s init failed on path %s", + SAP_DUMMY_IFACE, SAP_DUMMY_PATH); + return -1; + } + return 0; } void sap_exit(void) { - DBG("SAP driver exit."); + dbus_connection_unref(connection); + connection = NULL; } |