summaryrefslogtreecommitdiffstats
path: root/src/host/layer23/include/osmocom/bb/common
diff options
context:
space:
mode:
authorVadim Yanitskiy <axilirator@gmail.com>2018-12-23 05:30:21 +0700
committerVadim Yanitskiy <axilirator@gmail.com>2019-01-15 04:26:46 +0700
commit2986a318b12c26904f87f6da40c3dce852de7952 (patch)
tree0e46ccd5fea3fc06a494de3265098c636a55b7eb /src/host/layer23/include/osmocom/bb/common
parente4e3e6facd1a7e7a81065428a5dba184026652a1 (diff)
layer23/sap_interface.c: reimplement (BT)SAP interface
The (BT)SAP (Bluetooth SIM Access Profile) is a part of Bluetooth specifications, that defines the protocol and procedures that shall be used to access a smart card (usually GSM SIM) via a Bluetooth link. The profile defines two roles: - Server - the side that has direct access to a smart card. It acts as a SIM card reader, which assists the Client in accessing and controlling the smart card. - Client - the side that accesses and controls the smart card inside the Server through the connection with Server. Typical examples of a Server are a simple SIM card holder or a portable phone in the car environment. A typical example of a Client is a car phone, which uses a subscription module in the Server for a connection to the cellular network. OsmocomBB implements the Client role providing abstract SAP interface API to the higher layers. Instead of Bluetooth, a UNIX socket is used to communicate with a Server. The previous implementation of (BT)SAP interface was incomplete and hard to maintain. This change (re)implements it almost from scratch on top of the Osmocom FSM framework. Besides that, the most significant changes are: - The implementation is separated into three parts: - sap_interface.{c|h} - public SAP interface API, - sap_proto.{c|h} - SAP protocol definition, - sap_fsm.{c|h} - SAP FSM implementation. - Both 'sap_message' and 'sap_param' structures follow the SAP message format definition according to 5.1 and 5.2. - The message parsing is done more carefully in order to prevent buffer overflow and NULL-pointer dereference. - Introduced public API for getting / adding message parameters, and checking the ResultCode. - Introduced public API for opening / closing a connection with the server, powering on / off and resetting the SIM card, sending ATR and APDU. - Introduced a call-back for handling the response message. - Card reader state is also a part of the public API. The new implementation was tested against softsim [1]. The only limitation is Server-initiated Release, that allows the Server to 'ask' a Client to release connection as soon as communication with the smart card is finished. This is not implemented (yet), and leads to immediate release. [1] https://git.osmocom.org/softsim/ Change-Id: I77bb108615bb2c94c441568f195b04e0a5421643
Diffstat (limited to 'src/host/layer23/include/osmocom/bb/common')
-rw-r--r--src/host/layer23/include/osmocom/bb/common/Makefile.am2
-rw-r--r--src/host/layer23/include/osmocom/bb/common/osmocom_data.h9
-rw-r--r--src/host/layer23/include/osmocom/bb/common/sap_fsm.h35
-rw-r--r--src/host/layer23/include/osmocom/bb/common/sap_interface.h29
-rw-r--r--src/host/layer23/include/osmocom/bb/common/sap_proto.h45
5 files changed, 96 insertions, 24 deletions
diff --git a/src/host/layer23/include/osmocom/bb/common/Makefile.am b/src/host/layer23/include/osmocom/bb/common/Makefile.am
index eb1dfb74..d66be98a 100644
--- a/src/host/layer23/include/osmocom/bb/common/Makefile.am
+++ b/src/host/layer23/include/osmocom/bb/common/Makefile.am
@@ -1,3 +1,3 @@
noinst_HEADERS = l1ctl.h l1l2_interface.h l23_app.h logging.h \
networks.h gps.h sysinfo.h osmocom_data.h utils.h \
- sap_proto.h sap_interface.h
+ sap_proto.h sap_fsm.h sap_interface.h
diff --git a/src/host/layer23/include/osmocom/bb/common/osmocom_data.h b/src/host/layer23/include/osmocom/bb/common/osmocom_data.h
index a3ecc92c..ee48d6d4 100644
--- a/src/host/layer23/include/osmocom/bb/common/osmocom_data.h
+++ b/src/host/layer23/include/osmocom/bb/common/osmocom_data.h
@@ -23,9 +23,14 @@ struct osmocom_ms;
#include <osmocom/bb/common/l1ctl.h>
struct osmosap_entity {
- sap_cb_t msg_handler;
- uint8_t sap_state;
+ struct osmo_fsm_inst *fi;
uint16_t max_msg_size;
+ uint8_t card_status;
+
+ /* Optional SAP message call-back */
+ sap_msg_cb_t sap_msg_cb;
+ /* Optional response call-back */
+ sap_rsp_cb_t sap_rsp_cb;
};
struct osmol1_entity {
diff --git a/src/host/layer23/include/osmocom/bb/common/sap_fsm.h b/src/host/layer23/include/osmocom/bb/common/sap_fsm.h
new file mode 100644
index 00000000..d79bc1cc
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/common/sap_fsm.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <osmocom/bb/common/osmocom_data.h>
+
+/* How long should we wait for connection establishment */
+#define SAP_FSM_CONN_EST_TIMEOUT 5
+#define SAP_FSM_CONN_EST_T 0
+
+/* How long should we wait for connection release */
+#define SAP_FSM_CONN_REL_TIMEOUT 3
+#define SAP_FSM_CONN_REL_T 1
+
+/* How long should we wait for request to complete */
+#define SAP_FSM_PROC_REQ_TIMEOUT 5
+#define SAP_FSM_PROC_REQ_T 2
+
+#define SAP_STATE_IS_ACTIVE(state) \
+ (state >= SAP_STATE_WAIT_FOR_CARD)
+
+enum sap_fsm_state {
+ SAP_STATE_NOT_CONNECTED = 0,
+ SAP_STATE_CONNECTING,
+ SAP_STATE_DISCONNECTING, /* Auxiliary state (not from specs) */
+ SAP_STATE_WAIT_FOR_CARD, /* Auxiliary state (not from specs) */
+ SAP_STATE_IDLE,
+ SAP_STATE_PROC_ATR_REQ,
+ SAP_STATE_PROC_APDU_REQ,
+ SAP_STATE_PROC_RESET_REQ,
+ SAP_STATE_PROC_STATUS_REQ,
+ SAP_STATE_PROC_SET_TP_REQ,
+ SAP_STATE_PROC_POWERON_REQ,
+ SAP_STATE_PROC_POWEROFF_REQ,
+};
+
+int sap_fsm_alloc(struct osmocom_ms *ms);
diff --git a/src/host/layer23/include/osmocom/bb/common/sap_interface.h b/src/host/layer23/include/osmocom/bb/common/sap_interface.h
index 96d056b4..87a0f851 100644
--- a/src/host/layer23/include/osmocom/bb/common/sap_interface.h
+++ b/src/host/layer23/include/osmocom/bb/common/sap_interface.h
@@ -1,18 +1,23 @@
#pragma once
-typedef int (*sap_cb_t)(struct msgb *msg, struct osmocom_ms *ms);
+#include <stdint.h>
+#include <osmocom/core/msgb.h>
+
+struct osmocom_ms;
+
+typedef int (*sap_msg_cb_t)(struct osmocom_ms *ms, struct msgb *msg);
+typedef int (*sap_rsp_cb_t)(struct osmocom_ms *ms, int res_code,
+ uint8_t res_type, uint16_t param_len, const uint8_t *param_val);
+
+void sap_init(struct osmocom_ms *ms);
int sap_open(struct osmocom_ms *ms);
int sap_close(struct osmocom_ms *ms);
-int sap_send_apdu(struct osmocom_ms *ms, uint8_t *data, uint16_t length);
-int sap_register_handler(struct osmocom_ms *ms, sap_cb_t cb);
-int sap_init(struct osmocom_ms *ms);
+int _sap_close_sock(struct osmocom_ms *ms);
+
+int sap_send_reset_req(struct osmocom_ms *ms);
+int sap_send_poweron_req(struct osmocom_ms *ms);
+int sap_send_poweroff_req(struct osmocom_ms *ms);
-enum sap_state {
- SAP_SOCKET_ERROR,
- SAP_NOT_CONNECTED,
- SAP_IDLE,
- SAP_CONNECTION_UNDER_NEGOTIATION,
- SAP_PROCESSING_ATR_REQUEST,
- SAP_PROCESSING_APDU_REQUEST
-};
+int sap_send_atr_req(struct osmocom_ms *ms);
+int sap_send_apdu(struct osmocom_ms *ms, uint8_t *apdu, uint16_t apdu_len);
diff --git a/src/host/layer23/include/osmocom/bb/common/sap_proto.h b/src/host/layer23/include/osmocom/bb/common/sap_proto.h
index 49b30fc5..e149f00d 100644
--- a/src/host/layer23/include/osmocom/bb/common/sap_proto.h
+++ b/src/host/layer23/include/osmocom/bb/common/sap_proto.h
@@ -3,8 +3,10 @@
#include <stdint.h>
#include <osmocom/core/utils.h>
+#include <osmocom/core/msgb.h>
-/* Table 5.1: Message Overview */
+/* Table 5.1: Message Overview
+ * NOTE: messages are used as events for SAP FSM */
enum sap_msg_type {
SAP_CONNECT_REQ = 0x00,
SAP_CONNECT_RESP = 0x01,
@@ -81,14 +83,39 @@ extern const struct value_string sap_result_names[];
extern const struct value_string sap_card_status_names[];
extern const struct value_string sap_conn_status_names[];
+/* Figure 5.2: Payload Coding */
struct sap_param {
- uint8_t id;
- uint16_t len;
- uint8_t *value;
-};
+ /* Parameter ID, see sap_param_type enum */
+ uint8_t param_id;
+ /* Reserved for further use (shall be set to 0x00) */
+ uint8_t reserved[1];
+ /* Parameter length */
+ uint16_t length;
+ /* Parameter value (and optional padding) */
+ uint8_t value[0];
+} __attribute__((packed));
-struct sap_msg {
- uint8_t id;
+/* Figure 5.1 Message Format */
+struct sap_message {
+ /* Message ID, see sap_msg_type enum */
+ uint8_t msg_id;
+ /* Number of parameters */
uint8_t num_params;
- struct sap_param *params;
-};
+ /* Reserved for further use (shall be set to 0x00) */
+ uint8_t reserved[2];
+ /* Payload, see sap_param struct */
+ uint8_t payload[0];
+} __attribute__((packed));
+
+#define GSM_SAP_LENGTH 300
+#define GSM_SAP_HEADROOM 32
+
+struct msgb *sap_msgb_alloc(uint8_t msg_id);
+struct msgb *sap_msg_parse(const uint8_t *buf, size_t buf_len, int max_msg_size);
+int sap_check_result_code(const struct sap_message *sap_msg);
+
+void sap_msgb_add_param(struct msgb *msg,
+ enum sap_param_type param_type,
+ uint16_t param_len, const uint8_t *param_value);
+struct sap_param *sap_get_param(const struct sap_message *sap_msg,
+ enum sap_param_type param_type, uint16_t *param_len);