Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame^] | 1 | /* |
| 2 | * (C) 2010-2017 by Harald Welte <hwelte@sysmocom.de> |
| 3 | * (C) 2018 by Kevin Redon <kredon@sysmocom.de> |
| 4 | * All Rights Reserved |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 5 | * |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame^] | 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU Affero General Public License as published by |
| 8 | * the Free Software Foundation; either version 3 of the License, or |
| 9 | * (at your option) any later version. |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 10 | * |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame^] | 11 | * This program is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | * GNU Affero General Public License for more details. |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 15 | * |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame^] | 16 | * You should have received a copy of the GNU Affero General Public License |
| 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 18 | * |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 19 | */ |
Kévin Redon | 36abece | 2018-06-04 16:30:01 +0200 | [diff] [blame] | 20 | #include "board.h" |
| 21 | #include "simtrace.h" |
| 22 | |
Harald Welte | 2fb5996 | 2016-02-28 12:34:26 +0100 | [diff] [blame] | 23 | #ifdef HAVE_SNIFFER |
| 24 | |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 25 | /*------------------------------------------------------------------------------ |
| 26 | * Headers |
| 27 | *------------------------------------------------------------------------------*/ |
| 28 | |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 29 | #include <string.h> |
| 30 | |
| 31 | /*------------------------------------------------------------------------------ |
| 32 | * Internal definitions |
| 33 | *------------------------------------------------------------------------------*/ |
| 34 | |
| 35 | /** Maximum ucSize in bytes of the smartcard answer to a command.*/ |
| 36 | #define MAX_ANSWER_SIZE 10 |
| 37 | |
| 38 | /** Maximum ATR ucSize in bytes.*/ |
| 39 | #define MAX_ATR_SIZE 55 |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame^] | 40 | |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 41 | /*------------------------------------------------------------------------------ |
| 42 | * Internal variables |
| 43 | *------------------------------------------------------------------------------*/ |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame^] | 44 | /* Pin configuration to sniff communication (using USART connection to SIM card) */ |
| 45 | static const Pin pins_sniff[] = { PINS_SIM_SNIFF_SIM }; |
| 46 | /* Connect phone to card using bus switch */ |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 47 | static const Pin pins_bus[] = { PINS_BUS_SNIFF }; |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame^] | 48 | /* Power card using phone VCC */ |
| 49 | static const Pin pins_power[] = { PWR_PINS }; |
| 50 | /* Timer Counter pins to measure ETU timing */ |
| 51 | static const Pin pins_tc[] = { PINS_TC }; |
| 52 | /* USART peripheral used to sniff communication */ |
| 53 | static struct Usart_info sniff_usart = { |
| 54 | .base = USART_SIM, |
| 55 | .id = ID_USART_SIM, |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 56 | .state = USART_RCV, |
| 57 | }; |
Kévin Redon | 7b73462 | 2018-06-06 16:13:48 +0200 | [diff] [blame] | 58 | /* Ring buffer to store sniffer communication data */ |
| 59 | static struct ringbuf sniff_buffer; |
| 60 | |
| 61 | /*------------------------------------------------------------------------------ |
| 62 | * Global functions |
| 63 | *------------------------------------------------------------------------------*/ |
| 64 | |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame^] | 65 | void Sniffer_usart0_irq(void) |
Kévin Redon | 7b73462 | 2018-06-06 16:13:48 +0200 | [diff] [blame] | 66 | { |
| 67 | /* Read channel status register */ |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame^] | 68 | uint32_t csr = sniff_usart.base->US_CSR & sniff_usart.base->US_IMR; |
Kévin Redon | 7b73462 | 2018-06-06 16:13:48 +0200 | [diff] [blame] | 69 | /* Verify if character has been received */ |
| 70 | if (csr & US_CSR_RXRDY) { |
| 71 | /* Read communication data byte between phone and SIM */ |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame^] | 72 | uint8_t byte = sniff_usart.base->US_RHR; |
Kévin Redon | 7b73462 | 2018-06-06 16:13:48 +0200 | [diff] [blame] | 73 | /* Store sniffed data into buffer (also clear interrupt */ |
| 74 | rbuf_write(&sniff_buffer, byte); |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | /*------------------------------------------------------------------------------ |
| 79 | * Internal functions |
| 80 | *------------------------------------------------------------------------------*/ |
Kévin Redon | 36abece | 2018-06-04 16:30:01 +0200 | [diff] [blame] | 81 | |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame^] | 82 | static void check_sniffed_data(void) |
Kévin Redon | 36abece | 2018-06-04 16:30:01 +0200 | [diff] [blame] | 83 | { |
Kévin Redon | 7b73462 | 2018-06-06 16:13:48 +0200 | [diff] [blame] | 84 | /* Display sniffed data */ |
| 85 | while (!rbuf_is_empty(&sniff_buffer)) { |
| 86 | uint8_t byte = rbuf_read(&sniff_buffer); |
| 87 | TRACE_INFO_WP("0x%02x ", byte); |
| 88 | } |
Kévin Redon | 36abece | 2018-06-04 16:30:01 +0200 | [diff] [blame] | 89 | } |
| 90 | |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 91 | /*----------------------------------------------------------------------------- |
Christina Quast | d2b05f0 | 2015-02-25 18:44:24 +0100 | [diff] [blame] | 92 | * Initialization routine |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 93 | *-----------------------------------------------------------------------------*/ |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 94 | |
Harald Welte | ed75c62 | 2017-11-28 21:23:12 +0100 | [diff] [blame] | 95 | /* Called during USB enumeration after device is enumerated by host */ |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 96 | void Sniffer_configure(void) |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 97 | { |
Kévin Redon | 36abece | 2018-06-04 16:30:01 +0200 | [diff] [blame] | 98 | TRACE_INFO("Sniffer config\n\r"); |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 99 | } |
Christina Quast | fb524b9 | 2015-02-27 13:39:45 +0100 | [diff] [blame] | 100 | |
Harald Welte | ed75c62 | 2017-11-28 21:23:12 +0100 | [diff] [blame] | 101 | /* called when *different* configuration is set by host */ |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 102 | void Sniffer_exit(void) |
Christina Quast | fb524b9 | 2015-02-27 13:39:45 +0100 | [diff] [blame] | 103 | { |
Kévin Redon | 36abece | 2018-06-04 16:30:01 +0200 | [diff] [blame] | 104 | TRACE_INFO("Sniffer exit\n\r"); |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame^] | 105 | USART_DisableIt(sniff_usart.base, US_IER_RXRDY); |
| 106 | /* NOTE: don't forget to set the IRQ according to the USART peripheral used */ |
| 107 | NVIC_DisableIRQ(USART0_IRQn); |
| 108 | USART_SetReceiverEnabled(sniff_usart.base, 0); |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 109 | } |
| 110 | |
Kévin Redon | 36abece | 2018-06-04 16:30:01 +0200 | [diff] [blame] | 111 | /* called when *Sniffer* configuration is set by host */ |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 112 | void Sniffer_init(void) |
| 113 | { |
Kévin Redon | 36abece | 2018-06-04 16:30:01 +0200 | [diff] [blame] | 114 | TRACE_INFO("Sniffer Init\n\r"); |
Kévin Redon | 7b73462 | 2018-06-06 16:13:48 +0200 | [diff] [blame] | 115 | |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame^] | 116 | /* Configure pins to sniff communication between phone and card */ |
| 117 | PIO_Configure(pins_sniff, PIO_LISTSIZE(pins_sniff)); |
| 118 | /* Configure pins to connect phone to card */ |
| 119 | PIO_Configure(pins_bus, PIO_LISTSIZE(pins_bus)); |
| 120 | /* Configure pins to forward phone power to card */ |
| 121 | PIO_Configure(pins_power, PIO_LISTSIZE(pins_power)); |
| 122 | |
Kévin Redon | 7b73462 | 2018-06-06 16:13:48 +0200 | [diff] [blame] | 123 | /* Clear ring buffer containing the sniffed data */ |
| 124 | rbuf_reset(&sniff_buffer); |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame^] | 125 | /* Configure USART to as ISO-7816 slave communication to sniff communication */ |
| 126 | ISO7816_Init(&sniff_usart, CLK_SLAVE); |
| 127 | /* Only receive data when sniffing */ |
| 128 | USART_SetReceiverEnabled(sniff_usart.base, 1); |
| 129 | /* Enable interrupt to indicate when data has been received */ |
| 130 | USART_EnableIt(sniff_usart.base, US_IER_RXRDY); |
| 131 | /* Enable interrupt requests for the USART peripheral (warning: use IRQ corresponding to USART) */ |
| 132 | NVIC_EnableIRQ(USART0_IRQn); |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 133 | } |
| 134 | |
Harald Welte | ed75c62 | 2017-11-28 21:23:12 +0100 | [diff] [blame] | 135 | /* main (idle/busy) loop of this USB configuration */ |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 136 | void Sniffer_run(void) |
| 137 | { |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame^] | 138 | check_sniffed_data(); |
Christina Quast | fb524b9 | 2015-02-27 13:39:45 +0100 | [diff] [blame] | 139 | } |
Harald Welte | 2fb5996 | 2016-02-28 12:34:26 +0100 | [diff] [blame] | 140 | #endif /* HAVE_SNIFFER */ |