2 * BlueZ - Bluetooth protocol stack for Linux
4 * SAP Driver for ST-Ericsson U8500 platform
6 * Copyright (C) 2010-2011 ST-Ericsson SA
8 * Author: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com> for
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 2 of the License.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
37 #include <sys/socket.h>
43 #define STE_SIMD_SOCK "/dev/socket/catd_a"
44 #define STE_CLIENT_TAG 0x0000
46 #define sap_error(fmt, arg...) do { \
47 error("STE U8500 SAP: " fmt, ## arg); \
50 #define sap_info(fmt, arg...) do { \
51 info("STE U8500 SAP: " fmt, ## arg); \
59 } __attribute__((packed));
61 #define STE_MSG_PAYLOAD_SIZE(msg) (msg->len - sizeof(*msg) + sizeof(msg->len))
64 STE_START_SAP_REQ = 0x2D01,
65 STE_START_SAP_RSP = 0x2E01,
66 STE_END_SAP_REQ = 0x2D02,
67 STE_END_SAP_RSP = 0x2E02,
68 STE_POWER_OFF_REQ = 0x2D03,
69 STE_POWER_OFF_RSP = 0x2E03,
70 STE_POWER_ON_REQ = 0x2D04,
71 STE_POWER_ON_RSP = 0x2E04,
72 STE_RESET_REQ = 0x2D05,
73 STE_RESET_RSP = 0x2E05,
74 STE_SEND_APDU_REQ = 0x2D06,
75 STE_SEND_APDU_RSP = 0x2E06,
76 STE_GET_ATR_REQ = 0x2D07,
77 STE_GET_ATR_RSP = 0x2E07,
78 STE_GET_STATUS_REQ = 0x2D08,
79 STE_GET_STATUS_RSP = 0x2E08,
80 STE_STATUS_IND = 0x2F02,
81 STE_SIM_READY_IND = 0x2F03,
95 STE_STATUS_OK = 0x00000000,
96 STE_STATUS_FAILURE = 0x00000001,
97 STE_STATUS_BUSY_CALL = 0x00000002,
100 enum ste_card_status {
101 STE_CARD_STATUS_UNKNOWN = 0x00,
102 STE_CARD_STATUS_ACTIVE = 0x01,
103 STE_CARD_STATUS_NOT_ACTIVE = 0x02,
104 STE_CARD_STATUS_MISSING = 0x03,
105 STE_CARD_STATUS_INVALID = 0x04,
106 STE_CARD_STATUS_DISCONNECTED = 0x05,
109 /* Card reader status bits as described in GSM 11.14, Section 12.33
110 * Bits 0-2 are for card reader identity and always zeros. */
111 #define ICC_READER_REMOVABLE (1 << 3)
112 #define ICC_READER_PRESENT (1 << 4)
113 #define ICC_READER_ID1 (1 << 5)
114 #define ICC_READER_CARD_PRESENT (1 << 6)
115 #define ICC_READER_CARD_POWERED (1 << 7)
118 STE_DISABLED, /* Reader not present or removed */
119 STE_POWERED_OFF, /* Card in the reader but powered off */
120 STE_NO_CARD, /* No card in the reader */
121 STE_ENABLED, /* Card in the reader and powered on */
122 STE_SIM_BUSY, /* Modem is busy with ongoing call.*/
128 enum ste_state state;
132 typedef int(*recv_state_change_cb)(void *sap, uint8_t result);
133 typedef int(*recv_pdu_cb)(void *sap, uint8_t result, uint8_t *data,
136 static struct ste_u8500 u8500;
138 static const uint8_t sim2sap_result[STE_MSG_MAX][STE_STATE_MAX] = {
139 /* SAP results for SEND APDU message */
141 SAP_RESULT_ERROR_NOT_ACCESSIBLE, /* STE_DISABLED */
142 SAP_RESULT_ERROR_POWERED_OFF, /* STE_POWERED_OFF */
143 SAP_RESULT_ERROR_CARD_REMOVED, /* STE_NO_CARD */
144 SAP_RESULT_ERROR_NO_REASON /* STE_ENABLED */
147 /* SAP results for GET_ATR message */
149 SAP_RESULT_ERROR_NO_REASON,
150 SAP_RESULT_ERROR_POWERED_OFF,
151 SAP_RESULT_ERROR_CARD_REMOVED,
152 SAP_RESULT_ERROR_NO_REASON
155 /* SAP results POWER OFF message */
157 SAP_RESULT_ERROR_NO_REASON,
158 SAP_RESULT_ERROR_POWERED_OFF,
159 SAP_RESULT_ERROR_CARD_REMOVED,
160 SAP_RESULT_ERROR_NO_REASON
163 /* SAP results POWER ON message */
165 SAP_RESULT_ERROR_NO_REASON,
166 SAP_RESULT_ERROR_NOT_ACCESSIBLE,
167 SAP_RESULT_ERROR_CARD_REMOVED,
168 SAP_RESULT_ERROR_POWERED_ON
171 /* SAP results SIM RESET message */
173 SAP_RESULT_ERROR_NO_REASON,
174 SAP_RESULT_ERROR_POWERED_OFF,
175 SAP_RESULT_ERROR_CARD_REMOVED,
176 SAP_RESULT_ERROR_NOT_ACCESSIBLE
179 /* SAP results GET STATUS message */
181 SAP_RESULT_ERROR_NO_REASON,
182 SAP_RESULT_ERROR_NO_REASON,
183 SAP_RESULT_ERROR_NO_REASON,
184 SAP_RESULT_ERROR_NO_REASON
188 static uint8_t get_sap_result(enum ste_msg msg, uint32_t status)
191 return SAP_RESULT_ERROR_NO_REASON;
195 return SAP_RESULT_OK;
197 case STE_STATUS_FAILURE:
198 return sim2sap_result[msg][u8500.state];
201 DBG("Can't convert a result (status %u)", status);
202 return SAP_RESULT_ERROR_NO_REASON;
206 static int get_sap_reader_status(uint32_t card_status, uint8_t *icc_status)
208 /* Card reader is present, not removable and not ID-1 size. */
209 *icc_status = ICC_READER_PRESENT;
211 switch (card_status) {
212 case STE_CARD_STATUS_ACTIVE:
213 *icc_status |= ICC_READER_CARD_POWERED;
215 case STE_CARD_STATUS_NOT_ACTIVE:
216 case STE_CARD_STATUS_INVALID:
217 *icc_status |= ICC_READER_CARD_PRESENT;
219 case STE_CARD_STATUS_MISSING:
220 case STE_CARD_STATUS_DISCONNECTED:
224 DBG("Can't convert reader status %u", card_status);
226 case STE_CARD_STATUS_UNKNOWN:
231 static uint8_t get_sap_status_change(uint32_t card_status)
234 return SAP_STATUS_CHANGE_UNKNOWN_ERROR;
236 switch (card_status) {
237 case STE_CARD_STATUS_UNKNOWN:
238 return SAP_STATUS_CHANGE_UNKNOWN_ERROR;
240 case STE_CARD_STATUS_ACTIVE:
241 u8500.state = STE_ENABLED;
242 return SAP_STATUS_CHANGE_CARD_RESET;
244 case STE_CARD_STATUS_NOT_ACTIVE:
245 u8500.state = STE_DISABLED;
246 return SAP_STATUS_CHANGE_CARD_NOT_ACCESSIBLE;
248 case STE_CARD_STATUS_MISSING:
249 u8500.state = STE_DISABLED;
250 return SAP_STATUS_CHANGE_CARD_REMOVED;
252 case STE_CARD_STATUS_INVALID:
253 u8500.state = STE_DISABLED;
254 return SAP_STATUS_CHANGE_CARD_NOT_ACCESSIBLE;
257 DBG("Can't convert status change %u", card_status);
258 return SAP_STATUS_CHANGE_UNKNOWN_ERROR;
262 static int send_message(GIOChannel *io, void *buf, size_t size)
266 SAP_VDBG("io %p, size %zu", io, size);
268 if (g_io_channel_write_chars(io, buf, size, &written, NULL) !=
275 static int send_request(GIOChannel *io, uint16_t id,
276 struct sap_parameter *param)
279 struct ste_message *msg;
280 size_t size = sizeof(*msg);
282 SAP_VDBG("io %p", io);
287 msg = g_try_malloc0(size);
289 sap_error("sending request failed: %s", strerror(ENOMEM));
293 msg->len = size - sizeof(msg->len);
295 msg->client_tag = STE_CLIENT_TAG;
298 memcpy(msg->payload, param->val, param->len);
300 ret = send_message(io, msg, size);
302 sap_error("sending request failed: %s", strerror(-ret));
303 } else if (ret != (int) size) {
304 sap_error("sending request failed: %d out of %zu bytes sent",
314 static void recv_status(uint32_t status)
316 sap_status_ind(u8500.sap_data, get_sap_status_change(status));
319 static void recv_card_status(uint32_t status, uint8_t *param)
321 uint32_t card_status;
325 if (status != STE_STATUS_OK)
328 memcpy(&card_status, param, sizeof(card_status));
330 if (get_sap_reader_status(card_status, &iccrs) < 0)
331 result = SAP_RESULT_ERROR_NO_REASON;
333 result = get_sap_result(STE_GET_STATUS_MSG, status);
335 sap_transfer_card_reader_status_rsp(u8500.sap_data, result, iccrs);
338 static void recv_state_change(uint32_t ste_msg, uint32_t status,
339 uint32_t new_state, recv_state_change_cb callback)
341 if (status != STE_STATUS_OK)
344 u8500.state = new_state;
347 callback(u8500.sap_data, get_sap_result(ste_msg, status));
350 static void recv_pdu(uint32_t ste_msg, struct ste_message *msg, uint32_t status,
351 uint8_t *param, recv_pdu_cb callback)
353 uint8_t *data = NULL;
357 if (status == STE_STATUS_OK) {
359 size = STE_MSG_PAYLOAD_SIZE(msg) - sizeof(status);
362 result = get_sap_result(ste_msg, status);
365 callback(u8500.sap_data, result, data, size);
368 static void simd_close(void)
370 DBG("io %p", u8500.io);
373 g_io_channel_shutdown(u8500.io, TRUE, NULL);
374 g_io_channel_unref(u8500.io);
377 u8500.state = STE_DISABLED;
379 u8500.sap_data = NULL;
382 static void recv_sim_ready(void)
384 sap_info("sim is ready. Try to connect again");
386 if (send_request(u8500.io, STE_START_SAP_REQ, NULL) < 0) {
387 sap_connect_rsp(u8500.sap_data, SAP_STATUS_CONNECTION_FAILED);
392 static void recv_connect_rsp(uint32_t status)
396 if (u8500.state != STE_SIM_BUSY)
397 sap_connect_rsp(u8500.sap_data, SAP_STATUS_OK);
399 case STE_STATUS_BUSY_CALL:
400 if (u8500.state != STE_SIM_BUSY) {
401 sap_connect_rsp(u8500.sap_data,
402 SAP_STATUS_OK_ONGOING_CALL);
404 u8500.state = STE_SIM_BUSY;
408 sap_connect_rsp(u8500.sap_data, SAP_STATUS_CONNECTION_FAILED);
414 static void recv_response(struct ste_message *msg)
419 SAP_VDBG("msg_id 0x%x", msg->id);
421 if (msg->id == STE_END_SAP_RSP) {
422 sap_disconnect_rsp(u8500.sap_data);
427 param = msg->payload;
428 memcpy(&status, param, sizeof(status));
429 param += sizeof(status);
431 SAP_VDBG("status 0x%x", status);
434 case STE_START_SAP_RSP:
435 recv_connect_rsp(status);
437 case STE_SEND_APDU_RSP:
438 recv_pdu(STE_SEND_APDU_MSG, msg, status, param,
439 sap_transfer_apdu_rsp);
442 case STE_GET_ATR_RSP:
443 recv_pdu(STE_GET_ATR_MSG, msg, status, param,
444 sap_transfer_atr_rsp);
447 case STE_POWER_OFF_RSP:
448 recv_state_change(STE_POWER_OFF_MSG, status, STE_POWERED_OFF,
449 sap_power_sim_off_rsp);
452 case STE_POWER_ON_RSP:
453 recv_state_change(STE_POWER_ON_MSG, status, STE_ENABLED,
454 sap_power_sim_on_rsp);
458 recv_state_change(STE_RESET_MSG, status, STE_ENABLED,
462 case STE_GET_STATUS_RSP:
463 recv_card_status(status, param);
470 case STE_SIM_READY_IND:
475 sap_error("unsupported message received (id 0x%x)", msg->id);
479 static int recv_message(void *buf, size_t size)
482 struct ste_message *msg = buf;
485 SAP_VDBG("size %zu msg->len %u.", size, msg->len);
487 if (size < sizeof(*msg)) {
488 sap_error("invalid message received (%zu bytes)", size);
492 /* Message must be complete. */
493 if (size < (msg->len + sizeof(msg->len))) {
494 sap_error("incomplete message received (%zu bytes)",
501 /* Reduce total buffer size by just handled frame size. */
502 size -= msg->len + sizeof(msg->len);
504 /* Move msg pointer to the next message if any. */
505 iter += msg->len + sizeof(msg->len);
506 msg = (struct ste_message *)iter;
512 static gboolean simd_data_cb(GIOChannel *io, GIOCondition cond, gpointer data)
514 char buf[SAP_BUF_SIZE];
518 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
519 DBG("Error condition on sim socket (0x%x)", cond);
523 gstatus = g_io_channel_read_chars(io, buf, sizeof(buf), &bytes_read,
525 if (gstatus != G_IO_STATUS_NORMAL) {
526 sap_error("error while reading from channel (%d)", gstatus);
530 if (recv_message(buf, bytes_read) < 0)
531 sap_error("error while parsing STE Sim message");
536 static void simd_watch(int sock, void *sap_data)
540 DBG("sock %d, sap_data %p ", sock, sap_data);
542 io = g_io_channel_unix_new(sock);
544 g_io_channel_set_close_on_unref(io, TRUE);
545 g_io_channel_set_encoding(io, NULL, NULL);
546 g_io_channel_set_buffered(io, FALSE);
549 u8500.sap_data = sap_data;
550 u8500.state = STE_DISABLED;
552 g_io_add_watch_full(io, G_PRIORITY_DEFAULT,
553 G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
554 simd_data_cb, NULL, NULL);
557 static int simd_connect(void *sap_data)
559 struct sockaddr_un addr;
563 /* Already connected to simd */
567 sock = socket(PF_UNIX, SOCK_STREAM, 0);
570 sap_error("creating socket failed: %s", strerror(-err));
574 memset(&addr, 0, sizeof(addr));
575 addr.sun_family = AF_UNIX;
576 memcpy(addr.sun_path, STE_SIMD_SOCK, sizeof(STE_SIMD_SOCK) - 1);
578 if (connect(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
580 sap_error("connect to the socket failed: %s", strerror(-err));
584 if (fcntl(sock, F_SETFL, O_NONBLOCK) > 0) {
586 sap_error("setting up socket failed: %s", strerror(-err));
590 simd_watch(sock, sap_data);
599 void sap_connect_req(void *sap_device, uint16_t maxmsgsize)
601 DBG("sap_device %p maxmsgsize %u", sap_device, maxmsgsize);
603 sap_info("connect request");
605 if (simd_connect(sap_device) < 0) {
606 sap_connect_rsp(sap_device, SAP_STATUS_CONNECTION_FAILED);
610 if (send_request(u8500.io, STE_START_SAP_REQ, NULL) < 0) {
611 sap_connect_rsp(sap_device, SAP_STATUS_CONNECTION_FAILED);
616 void sap_disconnect_req(void *sap_device, uint8_t linkloss)
618 DBG("sap_device %p linkloss %u", sap_device, linkloss);
620 sap_info("disconnect request %s", linkloss ? "by link loss" : "");
622 if (u8500.state == STE_DISABLED) {
623 sap_disconnect_rsp(sap_device);
633 if (send_request(u8500.io, STE_END_SAP_REQ, NULL) < 0) {
634 sap_disconnect_rsp(sap_device);
639 void sap_transfer_apdu_req(void *sap_device, struct sap_parameter *param)
643 SAP_VDBG("sap_device %p param %p", sap_device, param);
645 if (u8500.state != STE_ENABLED) {
646 result = get_sap_result(STE_SEND_APDU_MSG, STE_STATUS_FAILURE);
647 sap_transfer_apdu_rsp(sap_device, result, NULL, 0);
651 if (send_request(u8500.io, STE_SEND_APDU_REQ, param) < 0)
652 sap_transfer_apdu_rsp(sap_device, SAP_RESULT_ERROR_NO_DATA,
656 void sap_transfer_atr_req(void *sap_device)
660 DBG("sap_device %p", sap_device);
662 if (u8500.state != STE_ENABLED) {
663 result = get_sap_result(STE_GET_ATR_MSG, STE_STATUS_FAILURE);
664 sap_transfer_atr_rsp(sap_device, result, NULL, 0);
668 if (send_request(u8500.io, STE_GET_ATR_REQ, NULL) < 0)
669 sap_transfer_atr_rsp(sap_device, SAP_RESULT_ERROR_NO_DATA, NULL,
673 void sap_power_sim_off_req(void *sap_device)
677 DBG("sap_device %p", sap_device);
679 if (u8500.state != STE_ENABLED) {
680 result = get_sap_result(STE_POWER_OFF_MSG, STE_STATUS_FAILURE);
681 sap_power_sim_off_rsp(sap_device, result);
685 if (send_request(u8500.io, STE_POWER_OFF_REQ, NULL) < 0)
686 sap_power_sim_off_rsp(sap_device, SAP_RESULT_ERROR_NO_REASON);
689 void sap_power_sim_on_req(void *sap_device)
693 DBG("sap_device %p", sap_device);
695 if (u8500.state != STE_POWERED_OFF) {
696 result = get_sap_result(STE_POWER_ON_MSG, STE_STATUS_FAILURE);
697 sap_power_sim_on_rsp(sap_device, result);
701 if (send_request(u8500.io, STE_POWER_ON_REQ, NULL) < 0)
702 sap_power_sim_on_rsp(sap_device, SAP_RESULT_ERROR_NO_REASON);
705 void sap_reset_sim_req(void *sap_device)
709 DBG("sap_device %p", sap_device);
711 if (u8500.state != STE_ENABLED) {
712 result = get_sap_result(STE_RESET_MSG, STE_STATUS_FAILURE);
713 sap_reset_sim_rsp(sap_device, result);
717 if (send_request(u8500.io, STE_RESET_REQ, NULL) < 0)
718 sap_reset_sim_rsp(sap_device, SAP_RESULT_ERROR_NO_REASON);
721 void sap_transfer_card_reader_status_req(void *sap_device)
725 DBG("sap_device %p", sap_device);
727 if (u8500.state == STE_DISABLED) {
728 result = get_sap_result(STE_GET_STATUS_MSG, STE_STATUS_FAILURE);
729 sap_transfer_card_reader_status_rsp(sap_device, result, 0);
733 if (send_request(u8500.io, STE_GET_STATUS_REQ, NULL) < 0)
734 sap_transfer_card_reader_status_rsp(sap_device,
735 SAP_RESULT_ERROR_NO_DATA, 0);
738 void sap_set_transport_protocol_req(void *sap_device,
739 struct sap_parameter *param)
741 DBG("sap_device %p", sap_device);
743 sap_transport_protocol_rsp(sap_device, SAP_RESULT_NOT_SUPPORTED);
748 u8500.state = STE_DISABLED;
749 info("STE U8500 SAP driver initialized");