tizen 2.3.1 release
[framework/connectivity/bluez.git] / profiles / sap / sap-u8500.c
1 /*
2  *  BlueZ - Bluetooth protocol stack for Linux
3  *
4  *  SAP Driver for ST-Ericsson U8500 platform
5  *
6  *  Copyright (C) 2010-2011 ST-Ericsson SA
7  *
8  *  Author: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com> for
9  *  ST-Ericsson.
10  *
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.
14  *
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.
19  *
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
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <fcntl.h>
32 #include <unistd.h>
33 #include <errno.h>
34 #include <glib.h>
35 #include <string.h>
36
37 #include <sys/socket.h>
38 #include <sys/un.h>
39
40 #include "src/log.h"
41 #include "sap.h"
42
43 #define STE_SIMD_SOCK  "/dev/socket/catd_a"
44 #define STE_CLIENT_TAG 0x0000
45
46 #define sap_error(fmt, arg...) do { \
47         error("STE U8500 SAP: " fmt, ## arg); \
48         } while (0)
49
50 #define sap_info(fmt, arg...) do { \
51         info("STE U8500 SAP: " fmt, ## arg); \
52         } while (0)
53
54 struct ste_message {
55         uint16_t len;
56         uint16_t id;
57         uint32_t client_tag;
58         uint8_t payload[0];
59 } __attribute__((packed));
60
61 #define STE_MSG_PAYLOAD_SIZE(msg) (msg->len - sizeof(*msg) + sizeof(msg->len))
62
63 enum ste_protocol {
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,
82 };
83
84 enum ste_msg {
85         STE_SEND_APDU_MSG,
86         STE_GET_ATR_MSG,
87         STE_POWER_OFF_MSG,
88         STE_POWER_ON_MSG,
89         STE_RESET_MSG,
90         STE_GET_STATUS_MSG,
91         STE_MSG_MAX,
92 };
93
94 enum ste_status {
95         STE_STATUS_OK           = 0x00000000,
96         STE_STATUS_FAILURE      = 0x00000001,
97         STE_STATUS_BUSY_CALL    = 0x00000002,
98 };
99
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,
107 };
108
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)
116
117 enum ste_state {
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.*/
123         STE_STATE_MAX
124 };
125
126 struct ste_u8500 {
127         GIOChannel *io;
128         enum ste_state state;
129         void *sap_data;
130 };
131
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,
134                                                                 uint16_t len);
135
136 static struct ste_u8500 u8500;
137
138 static const uint8_t sim2sap_result[STE_MSG_MAX][STE_STATE_MAX] = {
139         /* SAP results for SEND APDU message */
140         {
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 */
145         },
146
147         /* SAP results for GET_ATR message */
148         {
149                 SAP_RESULT_ERROR_NO_REASON,
150                 SAP_RESULT_ERROR_POWERED_OFF,
151                 SAP_RESULT_ERROR_CARD_REMOVED,
152                 SAP_RESULT_ERROR_NO_REASON
153         },
154
155         /* SAP results POWER OFF message */
156         {
157                 SAP_RESULT_ERROR_NO_REASON,
158                 SAP_RESULT_ERROR_POWERED_OFF,
159                 SAP_RESULT_ERROR_CARD_REMOVED,
160                 SAP_RESULT_ERROR_NO_REASON
161         },
162
163         /* SAP results POWER ON message */
164         {
165                 SAP_RESULT_ERROR_NO_REASON,
166                 SAP_RESULT_ERROR_NOT_ACCESSIBLE,
167                 SAP_RESULT_ERROR_CARD_REMOVED,
168                 SAP_RESULT_ERROR_POWERED_ON
169         },
170
171         /* SAP results SIM RESET message */
172         {
173                 SAP_RESULT_ERROR_NO_REASON,
174                 SAP_RESULT_ERROR_POWERED_OFF,
175                 SAP_RESULT_ERROR_CARD_REMOVED,
176                 SAP_RESULT_ERROR_NOT_ACCESSIBLE
177         },
178
179         /* SAP results GET STATUS message */
180         {
181                 SAP_RESULT_ERROR_NO_REASON,
182                 SAP_RESULT_ERROR_NO_REASON,
183                 SAP_RESULT_ERROR_NO_REASON,
184                 SAP_RESULT_ERROR_NO_REASON
185         }
186 };
187
188 static uint8_t get_sap_result(enum ste_msg msg, uint32_t status)
189 {
190         if (!u8500.io)
191                 return SAP_RESULT_ERROR_NO_REASON;
192
193         switch (status) {
194         case STE_STATUS_OK:
195                 return SAP_RESULT_OK;
196
197         case STE_STATUS_FAILURE:
198                 return sim2sap_result[msg][u8500.state];
199
200         default:
201                 DBG("Can't convert a result (status %u)", status);
202                 return SAP_RESULT_ERROR_NO_REASON;
203         }
204 }
205
206 static int get_sap_reader_status(uint32_t card_status, uint8_t *icc_status)
207 {
208         /* Card reader is present, not removable and not ID-1 size. */
209         *icc_status = ICC_READER_PRESENT;
210
211         switch (card_status) {
212         case STE_CARD_STATUS_ACTIVE:
213                 *icc_status |= ICC_READER_CARD_POWERED;
214
215         case STE_CARD_STATUS_NOT_ACTIVE:
216         case STE_CARD_STATUS_INVALID:
217                 *icc_status |= ICC_READER_CARD_PRESENT;
218
219         case STE_CARD_STATUS_MISSING:
220         case STE_CARD_STATUS_DISCONNECTED:
221                 return 0;
222
223         default:
224                 DBG("Can't convert reader status %u", card_status);
225
226         case STE_CARD_STATUS_UNKNOWN:
227                 return -1;
228         }
229 }
230
231 static uint8_t get_sap_status_change(uint32_t card_status)
232 {
233         if (!u8500.io)
234                 return SAP_STATUS_CHANGE_UNKNOWN_ERROR;
235
236         switch (card_status) {
237         case STE_CARD_STATUS_UNKNOWN:
238                 return SAP_STATUS_CHANGE_UNKNOWN_ERROR;
239
240         case STE_CARD_STATUS_ACTIVE:
241                 u8500.state = STE_ENABLED;
242                 return SAP_STATUS_CHANGE_CARD_RESET;
243
244         case STE_CARD_STATUS_NOT_ACTIVE:
245                 u8500.state = STE_DISABLED;
246                 return SAP_STATUS_CHANGE_CARD_NOT_ACCESSIBLE;
247
248         case STE_CARD_STATUS_MISSING:
249                 u8500.state = STE_DISABLED;
250                 return SAP_STATUS_CHANGE_CARD_REMOVED;
251
252         case STE_CARD_STATUS_INVALID:
253                 u8500.state = STE_DISABLED;
254                 return SAP_STATUS_CHANGE_CARD_NOT_ACCESSIBLE;
255
256         default:
257                 DBG("Can't convert status change %u", card_status);
258                 return SAP_STATUS_CHANGE_UNKNOWN_ERROR;
259         }
260 }
261
262 static int send_message(GIOChannel *io, void *buf, size_t size)
263 {
264         gsize written;
265
266         SAP_VDBG("io %p, size %zu", io, size);
267
268         if (g_io_channel_write_chars(io, buf, size, &written, NULL) !=
269                                                         G_IO_STATUS_NORMAL)
270                 return -EIO;
271
272         return written;
273 }
274
275 static int send_request(GIOChannel *io, uint16_t id,
276                                                 struct sap_parameter *param)
277 {
278         int ret;
279         struct ste_message *msg;
280         size_t size = sizeof(*msg);
281
282         SAP_VDBG("io %p", io);
283
284         if (param)
285                 size += param->len;
286
287         msg = g_try_malloc0(size);
288         if (!msg) {
289                 sap_error("sending request failed: %s", strerror(ENOMEM));
290                 return -ENOMEM;
291         }
292
293         msg->len = size - sizeof(msg->len);
294         msg->id = id;
295         msg->client_tag = STE_CLIENT_TAG;
296
297         if (param)
298                 memcpy(msg->payload, param->val, param->len);
299
300         ret = send_message(io, msg, size);
301         if (ret < 0) {
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",
305                                                                 ret, size);
306                 ret = -EIO;
307         }
308
309         g_free(msg);
310
311         return ret;
312 }
313
314 static void recv_status(uint32_t status)
315 {
316         sap_status_ind(u8500.sap_data, get_sap_status_change(status));
317 }
318
319 static void recv_card_status(uint32_t status, uint8_t *param)
320 {
321         uint32_t card_status;
322         uint8_t result;
323         uint8_t iccrs;
324
325         if (status != STE_STATUS_OK)
326                 return;
327
328         memcpy(&card_status, param, sizeof(card_status));
329
330         if (get_sap_reader_status(card_status, &iccrs) < 0)
331                 result = SAP_RESULT_ERROR_NO_REASON;
332         else
333                 result = get_sap_result(STE_GET_STATUS_MSG, status);
334
335         sap_transfer_card_reader_status_rsp(u8500.sap_data, result, iccrs);
336 }
337
338 static void recv_state_change(uint32_t ste_msg, uint32_t status,
339                         uint32_t new_state, recv_state_change_cb callback)
340 {
341         if (status != STE_STATUS_OK)
342                 return;
343
344         u8500.state = new_state;
345
346         if (callback)
347                 callback(u8500.sap_data, get_sap_result(ste_msg, status));
348 }
349
350 static void recv_pdu(uint32_t ste_msg, struct ste_message *msg, uint32_t status,
351                                         uint8_t *param, recv_pdu_cb callback)
352 {
353         uint8_t *data = NULL;
354         uint8_t result;
355         int size = 0;
356
357         if (status == STE_STATUS_OK) {
358                 data = param;
359                 size = STE_MSG_PAYLOAD_SIZE(msg) - sizeof(status);
360         }
361
362         result = get_sap_result(ste_msg, status);
363
364         if (callback)
365                 callback(u8500.sap_data, result, data, size);
366 }
367
368 static void simd_close(void)
369 {
370         DBG("io %p", u8500.io);
371
372         if (u8500.io) {
373                 g_io_channel_shutdown(u8500.io, TRUE, NULL);
374                 g_io_channel_unref(u8500.io);
375         }
376
377         u8500.state = STE_DISABLED;
378         u8500.io = NULL;
379         u8500.sap_data = NULL;
380 }
381
382 static void recv_sim_ready(void)
383 {
384         sap_info("sim is ready. Try to connect again");
385
386         if (send_request(u8500.io, STE_START_SAP_REQ, NULL) < 0) {
387                 sap_connect_rsp(u8500.sap_data, SAP_STATUS_CONNECTION_FAILED);
388                 simd_close();
389         }
390 }
391
392 static void recv_connect_rsp(uint32_t status)
393 {
394         switch (status) {
395         case STE_STATUS_OK:
396                 if (u8500.state != STE_SIM_BUSY)
397                         sap_connect_rsp(u8500.sap_data, SAP_STATUS_OK);
398                 break;
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);
403
404                         u8500.state = STE_SIM_BUSY;
405                 }
406                 break;
407         default:
408                 sap_connect_rsp(u8500.sap_data, SAP_STATUS_CONNECTION_FAILED);
409                 simd_close();
410                 break;
411         }
412 }
413
414 static void recv_response(struct ste_message *msg)
415 {
416         uint32_t status;
417         uint8_t *param;
418
419         SAP_VDBG("msg_id 0x%x", msg->id);
420
421         if (msg->id == STE_END_SAP_RSP) {
422                 sap_disconnect_rsp(u8500.sap_data);
423                 simd_close();
424                 return;
425         }
426
427         param = msg->payload;
428         memcpy(&status, param, sizeof(status));
429         param += sizeof(status);
430
431         SAP_VDBG("status 0x%x", status);
432
433         switch (msg->id) {
434         case STE_START_SAP_RSP:
435                 recv_connect_rsp(status);
436                 break;
437         case STE_SEND_APDU_RSP:
438                 recv_pdu(STE_SEND_APDU_MSG, msg, status, param,
439                                                         sap_transfer_apdu_rsp);
440                 break;
441
442         case STE_GET_ATR_RSP:
443                 recv_pdu(STE_GET_ATR_MSG, msg, status, param,
444                                                         sap_transfer_atr_rsp);
445                 break;
446
447         case STE_POWER_OFF_RSP:
448                 recv_state_change(STE_POWER_OFF_MSG, status, STE_POWERED_OFF,
449                                                         sap_power_sim_off_rsp);
450                 break;
451
452         case STE_POWER_ON_RSP:
453                 recv_state_change(STE_POWER_ON_MSG, status, STE_ENABLED,
454                                                         sap_power_sim_on_rsp);
455                 break;
456
457         case STE_RESET_RSP:
458                 recv_state_change(STE_RESET_MSG, status, STE_ENABLED,
459                                                         sap_reset_sim_rsp);
460                 break;
461
462         case STE_GET_STATUS_RSP:
463                 recv_card_status(status, param);
464                 break;
465
466         case STE_STATUS_IND:
467                 recv_status(status);
468                 break;
469
470         case STE_SIM_READY_IND:
471                 recv_sim_ready();
472                 break;
473
474         default:
475                 sap_error("unsupported message received (id 0x%x)", msg->id);
476         }
477 }
478
479 static int recv_message(void *buf, size_t size)
480 {
481         uint8_t *iter = buf;
482         struct ste_message *msg = buf;
483
484         do {
485                 SAP_VDBG("size %zu msg->len %u.", size, msg->len);
486
487                 if (size < sizeof(*msg)) {
488                         sap_error("invalid message received (%zu bytes)", size);
489                         return -EBADMSG;
490                 }
491
492                 /* Message must be complete. */
493                 if (size < (msg->len + sizeof(msg->len))) {
494                         sap_error("incomplete message received (%zu bytes)",
495                                                                         size);
496                         return -EBADMSG;
497                 }
498
499                 recv_response(msg);
500
501                 /* Reduce total buffer size by just handled frame size. */
502                 size -= msg->len + sizeof(msg->len);
503
504                 /* Move msg pointer to the next message if any. */
505                 iter += msg->len + sizeof(msg->len);
506                 msg = (struct ste_message *)iter;
507         } while (size > 0);
508
509         return 0;
510 }
511
512 static gboolean simd_data_cb(GIOChannel *io, GIOCondition cond, gpointer data)
513 {
514         char buf[SAP_BUF_SIZE];
515         gsize bytes_read;
516         GIOStatus gstatus;
517
518         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
519                 DBG("Error condition on sim socket (0x%x)", cond);
520                 return FALSE;
521         }
522
523         gstatus = g_io_channel_read_chars(io, buf, sizeof(buf), &bytes_read,
524                                                                         NULL);
525         if (gstatus != G_IO_STATUS_NORMAL) {
526                 sap_error("error while reading from channel (%d)", gstatus);
527                 return TRUE;
528         }
529
530         if (recv_message(buf, bytes_read) < 0)
531                 sap_error("error while parsing STE Sim message");
532
533         return TRUE;
534 }
535
536 static void simd_watch(int sock, void *sap_data)
537 {
538         GIOChannel *io;
539
540         DBG("sock %d, sap_data %p ", sock, sap_data);
541
542         io = g_io_channel_unix_new(sock);
543
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);
547
548         u8500.io = io;
549         u8500.sap_data = sap_data;
550         u8500.state = STE_DISABLED;
551
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);
555 }
556
557 static int simd_connect(void *sap_data)
558 {
559         struct sockaddr_un addr;
560         int sock;
561         int err;
562
563         /* Already connected to simd */
564         if (u8500.io)
565                 return -EALREADY;
566
567         sock = socket(PF_UNIX, SOCK_STREAM, 0);
568         if (sock < 0) {
569                 err = -errno;
570                 sap_error("creating socket failed: %s", strerror(-err));
571                 return err;
572         }
573
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);
577
578         if (connect(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
579                 err = -errno;
580                 sap_error("connect to the socket failed: %s", strerror(-err));
581                 goto failed;
582         }
583
584         if (fcntl(sock, F_SETFL, O_NONBLOCK) > 0) {
585                 err = -errno;
586                 sap_error("setting up socket failed: %s", strerror(-err));
587                 goto failed;
588         }
589
590         simd_watch(sock, sap_data);
591
592         return 0;
593
594 failed:
595         close(sock);
596         return err;
597 }
598
599 void sap_connect_req(void *sap_device, uint16_t maxmsgsize)
600 {
601         DBG("sap_device %p maxmsgsize %u", sap_device, maxmsgsize);
602
603         sap_info("connect request");
604
605         if (simd_connect(sap_device) < 0) {
606                 sap_connect_rsp(sap_device, SAP_STATUS_CONNECTION_FAILED);
607                 return;
608         }
609
610         if (send_request(u8500.io, STE_START_SAP_REQ, NULL) < 0) {
611                 sap_connect_rsp(sap_device, SAP_STATUS_CONNECTION_FAILED);
612                 simd_close();
613         }
614 }
615
616 void sap_disconnect_req(void *sap_device, uint8_t linkloss)
617 {
618         DBG("sap_device %p linkloss %u", sap_device, linkloss);
619
620         sap_info("disconnect request %s", linkloss ? "by link loss" : "");
621
622         if (u8500.state == STE_DISABLED) {
623                 sap_disconnect_rsp(sap_device);
624                 simd_close();
625                 return;
626         }
627
628         if (linkloss) {
629                 simd_close();
630                 return;
631         }
632
633         if (send_request(u8500.io, STE_END_SAP_REQ, NULL) < 0) {
634                 sap_disconnect_rsp(sap_device);
635                 return;
636         }
637 }
638
639 void sap_transfer_apdu_req(void *sap_device, struct sap_parameter *param)
640 {
641         uint8_t result;
642
643         SAP_VDBG("sap_device %p param %p", sap_device, param);
644
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);
648                 return;
649         }
650
651         if (send_request(u8500.io, STE_SEND_APDU_REQ, param) < 0)
652                 sap_transfer_apdu_rsp(sap_device, SAP_RESULT_ERROR_NO_DATA,
653                                                                 NULL, 0);
654 }
655
656 void sap_transfer_atr_req(void *sap_device)
657 {
658         uint8_t result;
659
660         DBG("sap_device %p", sap_device);
661
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);
665                 return;
666         }
667
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,
670                                                                         0);
671 }
672
673 void sap_power_sim_off_req(void *sap_device)
674 {
675         uint8_t result;
676
677         DBG("sap_device %p", sap_device);
678
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);
682                 return;
683         }
684
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);
687 }
688
689 void sap_power_sim_on_req(void *sap_device)
690 {
691         uint8_t result;
692
693         DBG("sap_device %p", sap_device);
694
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);
698                 return;
699         }
700
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);
703 }
704
705 void sap_reset_sim_req(void *sap_device)
706 {
707         uint8_t result;
708
709         DBG("sap_device %p", sap_device);
710
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);
714                 return;
715         }
716
717         if (send_request(u8500.io, STE_RESET_REQ, NULL) < 0)
718                 sap_reset_sim_rsp(sap_device, SAP_RESULT_ERROR_NO_REASON);
719 }
720
721 void sap_transfer_card_reader_status_req(void *sap_device)
722 {
723         uint8_t result;
724
725         DBG("sap_device %p", sap_device);
726
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);
730                 return;
731         }
732
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);
736 }
737
738 void sap_set_transport_protocol_req(void *sap_device,
739                                                 struct sap_parameter *param)
740 {
741         DBG("sap_device %p", sap_device);
742
743         sap_transport_protocol_rsp(sap_device, SAP_RESULT_NOT_SUPPORTED);
744 }
745
746 int sap_init(void)
747 {
748         u8500.state = STE_DISABLED;
749         info("STE U8500 SAP driver initialized");
750         return 0;
751 }
752
753 void sap_exit(void)
754 {
755 }