[PATCH] Add SAP reader stub.

Max Max.Suraev at fairwaves.ru
Wed Apr 10 13:19:26 UTC 2013


---
 src/sim/Makefile.am  |    4 +-
 src/sim/reader_sap.c |  182 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/sim/reader_sap.h |  162 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 346 insertions(+), 2 deletions(-)
 create mode 100644 src/sim/reader_sap.c
 create mode 100644 src/sim/reader_sap.h

diff --git a/src/sim/Makefile.am b/src/sim/Makefile.am
index fe64278..2fd353a 100644
--- a/src/sim/Makefile.am
+++ b/src/sim/Makefile.am
@@ -9,11 +9,11 @@ AM_LDFLAGS = $(COVERAGE_LDFLAGS)
 if ENABLE_PCSC
 # FIXME: only build the PC/SC dependent part conditional, but always build other parts
 
-noinst_HEADERS = sim_int.h gsm_int.h
+noinst_HEADERS = sim_int.h gsm_int.h reader_sap.h
 
 lib_LTLIBRARIES = libosmosim.la
 
-libosmosim_la_SOURCES = core.c card_fs_sim.c card_fs_usim.c card_fs_uicc.c reader.c reader_pcsc.c
+libosmosim_la_SOURCES = core.c card_fs_sim.c card_fs_usim.c card_fs_uicc.c reader.c reader_pcsc.c reader_sap.c
 libosmosim_la_LDFLAGS = -version-info $(LIBVERSION)
 libosmosim_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(PCSC_LIBS)
 
diff --git a/src/sim/reader_sap.c b/src/sim/reader_sap.c
new file mode 100644
index 0000000..0a74809
--- /dev/null
+++ b/src/sim/reader_sap.c
@@ -0,0 +1,182 @@
+/* SAP card reader backend for libosmosim */
+/*
+ * (C) 2013 by Max <Max.Suraev at fairwaves.ru>
+ *
+ * code shamelessly ripped from Nico Golde's patches to osmocom-bb
+ * 
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <arpa/inet.h>
+
+#include <osmocom/core/talloc.h>
+#include <osmocom/sim/sim.h>
+
+#include "sim_int.h"
+#include "reader_sap.h"
+
+static int osim_sap_send(struct osim_sap_entity *st, struct msgb *msg)
+{
+	if(st->sap_state == SAP_NOT_CONNECTED && !st->sap_state == SAP_CONNECTION_UNDER_NEGOTIATION)
+		sap_connect(st);
+
+	if (st->fd <= 0)
+		return -EINVAL;
+/* FIXME:
+	if (write_queue_enqueue(&ms->sap_wq, msg) != 0) {
+		LOGP(DSAP, LOGL_ERROR, "Failed to enqueue msg.\n");
+		msgb_free(msg);
+		return -1;
+	}
+*/
+	return 0;
+}
+
+static struct msgb *sap_create_msg(uint8_t id, uint8_t num_params, struct sap_param *params)
+{
+	struct msgb *msg;
+	uint8_t *msgp;
+	uint8_t i, plen, padding = 0;
+
+	msg = msgb_alloc(GSM_SAP_LENGTH, "osmosap");
+	if (!msg) {
+		fprintf(stderr, "Failed to allocate msg.\n");
+		return NULL;
+	}
+
+	/* BTSAP 5.1 */
+	msgb_put_u8(msg, id);
+	msgb_put_u8(msg, num_params);
+	msgb_put_u16(msg, 0);
+
+	for(i = 0; i < num_params; i++){
+		plen = params[i].len;
+		msgb_put_u8(msg, params[i].id);
+		msgb_put_u8(msg, 0);
+		msgb_put_u16(msg, plen);
+		if(plen % 4){
+			padding = 4 - (plen % 4);
+		}
+		msgp = msgb_put(msg, plen + padding);
+		memcpy(msgp, params[i].value, plen);
+
+		if(padding){
+			memset(msgp + plen, 0, padding);
+		}
+	}
+
+	return msg;
+}
+
+static void sap_connect(struct osim_sap_entity *st)
+{
+	uint8_t buffer[3];
+	struct msgb *msg;
+	uint16_t size = st->max_msg_size;
+	struct sap_param params[1];
+
+	params[0].id = SAP_MAX_MSG_SIZE;
+	params[0].len = 2;
+
+	if(st->sap_state != SAP_NOT_CONNECTED) {
+		fprintf(stderr, "Attempting to connect while there is an active connection already.\n");
+		return;
+	}
+
+	buffer[0] = (size >> 8) & 0xFF;
+	buffer[1] = size & 0xFF;
+	buffer[2] = 0;
+	params[0].value = buffer;
+
+	msg = sap_create_msg(SAP_CONNECT_REQ, 1, params);
+	if(!msg)
+		return;
+
+	osim_sap_send(st, msg);
+
+	st->sap_state = SAP_CONNECTION_UNDER_NEGOTIATION;
+}
+
+static struct osim_reader_hdl *sap_reader_open(int num, const char *id, void *ctx)
+{
+	struct osim_reader_hdl *rh;
+	ssize_t rc;
+	struct sockaddr_un local;
+	struct osim_sap_entity *st;
+
+	rh = talloc_zero(ctx, struct osim_reader_hdl);
+	st = rh->priv = talloc_zero(rh, struct osim_sap_entity);
+
+	st->fd = socket(AF_UNIX, SOCK_STREAM, 0);
+	if (st->fd < 0) {
+		fprintf(stderr, "Failed to create unix domain socket: %d\n", st->fd);
+		return NULL;
+	}
+
+	local.sun_family = AF_UNIX;
+	strncpy(local.sun_path, id, sizeof(local.sun_path));
+	local.sun_path[sizeof(local.sun_path) - 1] = '\0';
+
+	rc = connect(st->fd, (struct sockaddr *) &local, sizeof(local));
+	if (rc < 0) {
+		fprintf(stderr, "Failed to connect to '%s'\n", local.sun_path);
+		close(st->fd);
+		return NULL;
+	}
+	st->socket_path = strdup(id);
+/* FIXME:
+	write_queue_init(&ms->sap_wq, 100);
+	ms->sap_wq.bfd.data = ms;
+	ms->sap_wq.bfd.when = BSC_FD_READ;
+	ms->sap_wq.read_cb = sap_read;
+	ms->sap_wq.write_cb = sap_write;
+
+	rc = bsc_register_fd(&ms->sap_wq.bfd);
+	if (rc != 0) {
+		fprintf(stderr, "Failed to register fd.\n");
+		return rc;
+	}
+*/
+	sap_connect(st);
+
+	return rh;
+}
+
+static struct osim_card_hdl *sap_card_open(struct osim_reader_hdl *rh)
+{
+
+}
+
+static int sap_transceive(struct osim_reader_hdl *rh, struct msgb *msg)
+{
+
+}
+
+const struct osim_reader_ops sap_reader_ops = {
+	.name = "SAP",
+	.reader_open = sap_reader_open,
+	.card_open = sap_card_open,
+	.transceive = sap_transceive,
+};
diff --git a/src/sim/reader_sap.h b/src/sim/reader_sap.h
new file mode 100644
index 0000000..a4161b1
--- /dev/null
+++ b/src/sim/reader_sap.h
@@ -0,0 +1,162 @@
+/* SAP card reader backend for libosmosim */
+/*
+ * (C) 2013 by Max <Max.Suraev at fairwaves.ru>
+ *
+ * code shamelessly ripped from Nico Golde's patches to osmocom-bb
+ * 
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#define GSM_SAP_LENGTH 300
+#define GSM_SAP_HEADROOM 32
+
+enum osim_sap_state {
+	SAP_NOT_CONNECTED,
+	SAP_IDLE,
+	SAP_CONNECTION_UNDER_NEGOTIATION,
+	SAP_PROCESSING_ATR_REQUEST,
+	SAP_PROCESSING_APDU_REQUEST
+};
+
+/* BTSAP 1.13 */
+enum osim_sap_msg_type {
+	SAP_CONNECT_REQ = 0x00,
+	SAP_CONNECT_RESP = 0x01,
+	SAP_DISCONNECT_REQ = 0x02,
+	SAP_DISCONNECT_RESP = 0x03,
+	SAP_DISCONNECT_IND = 0x04,
+	SAP_TRANSFER_APDU_REQ = 0x05,
+	SAP_TRANSFER_APDU_RESP = 0x06,
+	SAP_TRANSFER_ATR_REQ = 0x07,
+	SAP_TRANSFER_ATR_RESP = 0x08,
+	SAP_POWER_SIM_OFF_REQ = 0x09,
+	SAP_POWER_SIM_OFF_RESP = 0x0A,
+	SAP_POWER_SIM_ON_REQ = 0x0B,
+	SAP_POWER_SIM_ON_RESP = 0x0C,
+	SAP_RESET_SIM_REQ = 0x0D,
+	SAP_RESET_SIM_RESP = 0x0E,
+	SAP_TRANSFER_CARD_READER_STATUS_REQ = 0x0F,
+	SAP_TRANSFER_CARD_READER_STATUS_RESP = 0x10,
+	SAP_STATUS_IND = 0x11,
+	SAP_ERROR_RESP = 0x12,
+	SAP_SET_TRANSPORT_PROTOCOL_REQ = 0x13,
+	SAP_SET_TRANSPORT_PROTOCOL_RESP = 0x14
+};
+
+/* BTSAP 5.2 */
+enum osim_sap_param_type {
+	SAP_MAX_MSG_SIZE = 0x00,
+	SAP_CONNECTION_STATUS = 0x01,
+	SAP_RESULT_CODE = 0x02,
+	SAP_DISCONNECTION_TYPE = 0x03,
+	SAP_COMMAND_APDU = 0x04,
+	SAP_COMMAND_APDU_7816 = 0x10,
+	SAP_RESPONSE_APDU = 0x05,
+	SAP_ATR = 0x06,
+	SAP_CARD_READER_STATUS = 0x07,
+	SAP_STATUS_CHANGE = 0x08,
+	SAP_TRANSPORT_PROTOCOL = 0x09
+};
+
+struct sap_param {
+	uint8_t id;
+	uint16_t len;
+	uint8_t *value;
+};
+
+struct sap_msg {
+	uint8_t id;
+	uint8_t num_params;
+	struct sap_param *params;
+};
+
+struct osim_sap_entity {
+	int fd;
+	uint8_t sap_state;
+	uint16_t max_msg_size;
+	char * socket_path;
+};
+
+static const struct value_string sap_param_names[] = {
+	{SAP_MAX_MSG_SIZE,		"MaxMsgSize"},
+	{SAP_CONNECTION_STATUS, 	"ConnectionStatus"},
+	{SAP_RESULT_CODE,		"ResultCode"},
+	{SAP_DISCONNECTION_TYPE,	"DisconnectionType"},
+	{SAP_COMMAND_APDU,		"CommandAPDU"},
+	{SAP_COMMAND_APDU_7816,		"CommandAPDU7816"},
+	{SAP_RESPONSE_APDU,		"ResponseAPDU"},
+	{SAP_ATR,			"ATR"},
+	{SAP_CARD_READER_STATUS,	"CardReaderStatus"},
+	{SAP_STATUS_CHANGE,		"StatusChange"},
+	{SAP_TRANSPORT_PROTOCOL,	"TransportProtocol"}
+};
+
+static const struct value_string sap_msg_names[] = {
+	{SAP_CONNECT_REQ,			"CONNECT_REQ"},
+	{SAP_CONNECT_RESP,			"CONNECT_RESP"},
+	{SAP_DISCONNECT_REQ,			"DISCONNECT_REQ"},
+	{SAP_DISCONNECT_RESP,			"DISCONNECT_RESP"},
+	{SAP_DISCONNECT_IND,			"DISCONNECT_IND"},
+	{SAP_TRANSFER_APDU_REQ,			"TRANSFER_APDU_REQ"},
+	{SAP_TRANSFER_APDU_RESP,		"TRANSFER_APDU_RESP"},
+	{SAP_TRANSFER_ATR_REQ,			"TRANSFER_ATR_REQ"},
+	{SAP_TRANSFER_ATR_RESP,			"TRANSFER_ATR_RESP"},
+	{SAP_POWER_SIM_OFF_REQ,			"POWER_SIM_OFF_REQ"},
+	{SAP_POWER_SIM_OFF_RESP,		"POWER_SIM_OFF_RESP"},
+	{SAP_POWER_SIM_ON_REQ,			"POWER_SIM_ON_REQ"},
+	{SAP_POWER_SIM_ON_RESP,			"POWER_SIM_ON_RESP"},
+	{SAP_RESET_SIM_REQ,			"RESET_SIM_REQ"},
+	{SAP_RESET_SIM_RESP,			"RESET_SIM_RESP"},
+	{SAP_TRANSFER_CARD_READER_STATUS_REQ,	"TRANSFER_CARD_READER_STATUS_REQ"},
+	{SAP_TRANSFER_CARD_READER_STATUS_RESP,	"TRANSFER_CARD_READER_STATUS_RESP"},
+	{SAP_STATUS_IND,			"STATUS_IND"},
+	{SAP_ERROR_RESP,			"ERROR_RESP"},
+	{SAP_SET_TRANSPORT_PROTOCOL_REQ,	"SET_TRANSPORT_PROTOCOL_REQ"},
+	{SAP_SET_TRANSPORT_PROTOCOL_RESP,	"SET_TRANSPORT_PROTOCOL_RESP"}
+};
+
+/* BTSAP table 5.18 */
+static const struct value_string sap_result_names[] = {
+	{0, "OK, request processed correctly"},
+	{1, "Error, no reason defined"},
+	{2, "Error, card not accessible"},
+	{3, "Error, card (already) powered off"},
+	{4, "Error, card removed"},
+	{5, "Error, card already powered on"},
+	{6, "Error, data not available"},
+	{7, "Error, not supported"}
+};
+
+static const struct value_string sap_status_change_names[] = {
+	{0, "Unknown Error"},
+	{1, "Card reset"},
+	{2, "Card not accessible"},
+	{3, "Card removed"},
+	{4, "Card inserted"},
+	{5, "Card recovered"},
+};
+
+static const struct value_string sap_status_names[] = {
+	{0, "OK, Server can fulfill requirements"},
+	{1, "Error, Server unable to establish connection"},
+	{2, "Error, Server does not support maximum message size"},
+	{3, "Error, maximum message size by Client is too small"},
+	{4, "OK, ongoing call"}
+};
+
+static void sap_connect(struct osim_sap_entity *st);
-- 
1.7.10.4


--------------030201080608040809010804--




More information about the baseband-devel mailing list