summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Albrecht <prom@berlin.ccc.de>2010-07-20 19:14:38 +0200
committerIngo Albrecht <prom@berlin.ccc.de>2010-08-17 00:28:37 +0200
commit8e6ba80c8adc38fdad92d626d2b1c005140497e8 (patch)
tree49da16f5ea5b3c3575d7142513411b126d7f5929
parentff7ce383a16d4eeede22039873f060341630294a (diff)
btsap: prototypical client, protocol definitions, parsing helpers, osmocon tool server.
-rw-r--r--src/host/osmocon/osmocon.c11
-rw-r--r--src/target/firmware/comm/Makefile2
-rw-r--r--src/target/firmware/comm/btsap.c67
-rw-r--r--src/target/firmware/comm/sim_btsap.c131
-rw-r--r--src/target/firmware/include/btsap.h144
-rw-r--r--src/target/firmware/include/comm/sercomm.h5
6 files changed, 356 insertions, 4 deletions
diff --git a/src/host/osmocon/osmocon.c b/src/host/osmocon/osmocon.c
index d702d745..f0e52486 100644
--- a/src/host/osmocon/osmocon.c
+++ b/src/host/osmocon/osmocon.c
@@ -158,6 +158,7 @@ struct dnload {
int echo_bytecount;
struct tool_server layer2_server;
+ struct tool_server sap_server;
struct tool_server loader_server;
};
@@ -1448,12 +1449,13 @@ int main(int argc, char **argv)
uint32_t tmp_load_address = ROMLOAD_ADDRESS;
const char *serial_dev = "/dev/ttyUSB1";
const char *layer2_un_path = "/tmp/osmocom_l2";
+ const char *sap_un_path = "/tmp/osmocom_sap";
const char *loader_un_path = "/tmp/osmocom_loader";
dnload.mode = MODE_C123;
dnload.chainload_filename = NULL;
- while ((opt = getopt(argc, argv, "d:hl:p:m:c:s:v")) != -1) {
+ while ((opt = getopt(argc, argv, "d:hl:p:m:c:s:a:v")) != -1) {
switch (opt) {
case 'p':
serial_dev = optarg;
@@ -1469,6 +1471,9 @@ int main(int argc, char **argv)
case 'l':
loader_un_path = optarg;
break;
+ case 'a':
+ sap_un_path = optarg;
+ break;
case 'v':
version(argv[0]);
break;
@@ -1520,6 +1525,10 @@ int main(int argc, char **argv)
SC_DLCI_L1A_L23) != 0)
exit(1);
+ if (register_tool_server(&dnload.sap_server, sap_un_path,
+ SC_DLCI_SAP) != 0)
+ exit(1);
+
if (register_tool_server(&dnload.loader_server, loader_un_path,
SC_DLCI_LOADER) != 0)
exit(1);
diff --git a/src/target/firmware/comm/Makefile b/src/target/firmware/comm/Makefile
index 25fbb983..bdf951ee 100644
--- a/src/target/firmware/comm/Makefile
+++ b/src/target/firmware/comm/Makefile
@@ -1,5 +1,5 @@
LIBRARIES+=comm
comm_DIR=comm
-comm_SRCS=msgb.c sercomm.c sercomm_cons.c timer.c
+comm_SRCS=msgb.c sercomm.c sercomm_cons.c timer.c btsap.c sim_btsap.c
diff --git a/src/target/firmware/comm/btsap.c b/src/target/firmware/comm/btsap.c
new file mode 100644
index 00000000..62d97de9
--- /dev/null
+++ b/src/target/firmware/comm/btsap.c
@@ -0,0 +1,67 @@
+
+#include <btsap.h>
+
+#include <comm/sercomm.h>
+
+struct msgb *sap_alloc_msg(uint8_t id, uint8_t nparams)
+{
+ struct msgb *m = msgb_alloc(HACK_MAX_MSG, "btsap");
+
+ if(!m) {
+ return m;
+ }
+
+ msgb_put_u8(m, id);
+ msgb_put_u8(m, nparams);
+ msgb_put_u16(m, 0); // reserved
+
+ return m;
+}
+
+void sap_parse_msg(struct msgb *m, uint8_t *id, uint8_t *nparams)
+{
+ *id = msgb_get_u8(m);
+ *nparams = msgb_get_u8(m);
+ msgb_get_u16(m);
+}
+
+void sap_put_param(struct msgb *m, uint8_t id, uint16_t length, const uint8_t *value)
+{
+ /* write header */
+ msgb_put_u8(m, id);
+ msgb_put_u8(m, 0); // reserved
+ msgb_put_u16(m, length);
+
+ /* need to align payload to 4 bytes */
+ size_t align = length % 4;
+ if(align) {
+ align = 4 - align;
+ }
+
+ /* append value and pad */
+ uint8_t *p = msgb_put(m, length + align);
+ memcpy(p, value, length);
+ memset(p + length, 0, align);
+}
+
+void sap_get_param(struct msgb *m, uint8_t *id, uint16_t *length, const uint8_t **value)
+{
+ /* consume header */
+ *id = msgb_get_u8(m);
+ msgb_get_u8(m); // reserved
+ *length = msgb_get_u16(m);
+
+ /* need to align payload to 4 bytes */
+ size_t align = *length % 4;
+ if(align) {
+ align = 4 - align;
+ }
+
+ /* consume data and pad */
+ *value = msgb_get(m, (*length) + align);
+}
+
+void sap_send(struct msgb *m)
+{
+ sercomm_sendmsg(SC_DLCI_SAP, m);
+}
diff --git a/src/target/firmware/comm/sim_btsap.c b/src/target/firmware/comm/sim_btsap.c
new file mode 100644
index 00000000..c7bd5b59
--- /dev/null
+++ b/src/target/firmware/comm/sim_btsap.c
@@ -0,0 +1,131 @@
+/* Client for Bluetooth SIM Access Profile */
+
+/* (C) 2010 by Ingo Albrecht <prom@berlin.ccc.de>
+ *
+ * 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 <sim.h>
+#include <btsap.h>
+#include <errno.h>
+#include <stdio.h>
+#include <comm/sercomm.h>
+
+/* XXX memdump_range */
+#include <calypso/misc.h>
+
+struct {
+ int state;
+} btsap;
+
+static void handle_sap_response(uint8_t dlci, struct msgb *msg)
+{
+ puts("Received SAP response:");
+ memdump_range(msg->data, msg->data_len);
+}
+
+int sim_init(void)
+{
+ btsap.state = SAP_State_NOT_CONNECTED;
+
+ sercomm_register_rx_cb(SC_DLCI_SAP, &handle_sap_response);
+
+ return 0;
+}
+
+int sim_connect(void)
+{
+ struct msgb *m;
+
+ /* check state */
+ if(btsap.state == SAP_State_NOT_CONNECTED) {
+ btsap.state = SAP_State_NEGOTIATING;
+ } else if (!btsap.state == SAP_State_NEGOTIATING) {
+ return -EINVAL;
+ }
+
+ /* build and send connect request */
+ m = sap_alloc_msg(SAP_CONNECT_REQ, 1);
+
+ uint16_t maxmsgsize = htons(HACK_MAX_MSG);
+ sap_put_param(m, SAP_Parameter_MaxMsgSize, 2, &maxmsgsize);
+
+ return sap_send(m);
+}
+
+int sim_disconnect(void)
+{
+ struct msgb *m;
+
+ if(btsap.state == SAP_State_NOT_CONNECTED
+ || btsap.state == SAP_State_NEGOTIATING) {
+ return -EINVAL;
+ }
+
+ btsap.state = SAP_State_NOT_CONNECTED;
+
+ m = sap_alloc_msg(SAP_DISCONNECT_REQ, 0);
+ return sap_send(m);
+}
+
+int sim_power_on(void)
+{
+ struct msgb *m;
+
+ if(btsap.state != SAP_State_IDLE) {
+ return -EINVAL;
+ }
+
+ btsap.state = SAP_State_PROCESSING_SIM_ON_REQ;
+
+ m = sap_alloc_msg(SAP_POWER_SIM_ON_REQ, 0);
+ sap_send(m);
+}
+
+int sim_power_off(void)
+{
+ struct msgb *m;
+
+ if(btsap.state == SAP_State_NOT_CONNECTED
+ || btsap.state == SAP_State_NEGOTIATING) {
+ return -EINVAL;
+ }
+
+ btsap.state = SAP_State_PROCESSING_SIM_OFF_REQ;
+
+ m = sap_alloc_msg(SAP_POWER_SIM_OFF_REQ, 0);
+ sap_send(m);
+}
+
+int sim_reset(void)
+{
+ struct msgb *m;
+
+ if(btsap.state == SAP_State_NOT_CONNECTED
+ || btsap.state == SAP_State_NEGOTIATING) {
+ return -EINVAL;
+ }
+
+ btsap.state = SAP_State_PROCESSING_SIM_RESET_REQ;
+
+ m = sap_alloc_msg(SAP_RESET_SIM_REQ, 0);
+ sap_send(m);
+}
+
+int sim_transfer_atr(/* callback */);
+int sim_transfer_apdu(/* callback, struct msgb *request */);
diff --git a/src/target/firmware/include/btsap.h b/src/target/firmware/include/btsap.h
new file mode 100644
index 00000000..0704a67b
--- /dev/null
+++ b/src/target/firmware/include/btsap.h
@@ -0,0 +1,144 @@
+/* Protocol constants and helpers for Bluetooth SIM Access Profile */
+
+/* (C) 2010 by Ingo Albrecht <prom@berlin.ccc.de>
+ *
+ * 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.
+ *
+ */
+
+/* This intends to cover SAP 1.1 */
+
+#ifndef btsap_h
+#define btsap_h
+
+#include <stdint.h>
+
+/* XXX put this somewhere serious and clean up uses */
+#define HACK_MAX_MSG 128
+
+
+/* Message type ids */
+enum {
+ 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
+};
+
+/* Parameter type ids */
+enum {
+ SAP_Parameter_MaxMsgSize = 0x00,
+ SAP_Parameter_ConnectionStatus = 0x01,
+ SAP_Parameter_ResultCode = 0x02,
+ SAP_Parameter_DisconnectionType = 0x03,
+ SAP_Parameter_CommandAPDU = 0x04,
+ SAP_Parameter_ResponseAPDU = 0x05,
+ SAP_Parameter_ATR = 0x06,
+ SAP_Parameter_CardReaderStatus = 0x07,
+ SAP_Parameter_StatusChange = 0x08,
+ SAP_Parameter_TransportProtocol = 0x09,
+ SAP_Parameter_CommandAPDU7816 = 0x10
+};
+
+/* Parameter enums */
+
+enum {
+ SAP_ConnectionStatus_OK = 0x00,
+ SAP_ConnectionStatus_SERVER_UNABLE_CONN = 0x01,
+ SAP_ConnectionStatus_SERVER_MSGSIZE_NOT_SUPP = 0x02,
+ SAP_ConnectionStatus_MSGSIZE_TOO_SMALL = 0x03,
+ SAP_ConnectionStatus_OK_ONGOING_CALL = 0x04
+};
+
+enum {
+ SAP_ResultCode_OK = 0x00,
+ SAP_ResultCode_FAULT = 0x01,
+ SAP_ResultCode_CARD_NOT_ACCESSIBLE = 0x02,
+ SAP_ResultCode_CARD_POWERED_OFF = 0x03,
+ SAP_ResultCode_CARD_REMOVED = 0x04,
+ SAP_ResultCode_CARD_ALREADY_POWERED_ON = 0x05,
+ SAP_ResultCode_DATA_NOT_AVAILABLE = 0x06,
+ SAP_ResultCode_NOT_SUPPORTED = 0x07
+};
+
+enum {
+ SAP_DisconnectionType_GRACEFUL = 0x00,
+ SAP_DisconnectionType_IMMEDIATE = 0x01
+};
+
+/* XXX SAP_CardReaderStatus from GSM 11.14 and TS31.111 */
+
+enum {
+ SAP_StatusChange_UNKNOWN_ERROR = 0x00,
+ SAP_StatusChange_CARD_RESET = 0x01,
+ SAP_StatusChange_CARD_NOT_ACCESSIBLE = 0x02,
+ SAP_StatusChange_CARD_REMOVED = 0x03,
+ SAP_StatusChange_CARD_INSERTED = 0x04,
+ SAP_StatusChange_CARD_RECOVERED = 0x05
+};
+
+enum {
+ SAP_TransportProtocol_T0 = 0x00,
+ SAP_TransportProtocol_T1 = 0x01
+};
+
+
+/* client and server state machine */
+
+/* The following enum is not from the spec
+ * but has been cobbled together from a simplified
+ * state chart found in the spec.
+ */
+enum {
+ SAP_State_NOT_CONNECTED,
+ SAP_State_NEGOTIATING,
+ SAP_State_IDLE,
+ SAP_State_PROCESSING_APDU_REQ,
+ SAP_State_PROCESSING_ATR_REQ,
+ SAP_State_PROCESSING_SIM_RESET_REQ,
+ SAP_State_PROCESSING_SIM_OFF_REQ,
+ SAP_State_PROCESSING_SIM_ON_REQ,
+ SAP_State_PROCESSING_CARD_READER_STATUS_REQ,
+ SAP_State_PROCESSING_SET_TRANSPORT_PROTOCOL_REQ,
+};
+
+/* parsing and formatting helpers */
+
+struct msgb *sap_alloc_msg(uint8_t id, uint8_t nparams);
+void sap_parse_msg(struct msgb *m, uint8_t *id, uint8_t *nparams);
+
+void sap_put_param(struct msgb *m, uint8_t id, uint16_t length, const uint8_t *value);
+void sap_get_param(struct msgb *m, uint8_t *id, uint16_t *length, const uint8_t **value);
+
+#endif /* !btsap_h */
diff --git a/src/target/firmware/include/comm/sercomm.h b/src/target/firmware/include/comm/sercomm.h
index 8fbbff97..c6dd3cb0 100644
--- a/src/target/firmware/include/comm/sercomm.h
+++ b/src/target/firmware/include/comm/sercomm.h
@@ -19,8 +19,9 @@ enum sercomm_dlci {
SC_DLCI_HIGHEST = 0,
SC_DLCI_DEBUG = 4,
SC_DLCI_L1A_L23 = 5,
- SC_DLCI_LOADER = 9,
- SC_DLCI_CONSOLE = 10,
+ SC_DLCI_SAP = 6,
+ SC_DLCI_LOADER = 50,
+ SC_DLCI_CONSOLE = 60,
SC_DLCI_ECHO = 128,
_SC_DLCI_MAX
};