|
5 | 5 | #include <furi_hal_nfc.h>
|
6 | 6 |
|
7 | 7 | #define FELICA_LISTENER_MAX_BUFFER_SIZE (128)
|
| 8 | +#define FELICA_CMD_POLLING (0x00U) |
| 9 | +#define FELICA_LISTENER_RESPONSE_POLLING (FELICA_CMD_POLLING | 1U) |
8 | 10 | #define FELICA_LISTENER_RESPONSE_CODE_READ (0x07)
|
9 | 11 | #define FELICA_LISTENER_RESPONSE_CODE_WRITE (0x09)
|
10 | 12 |
|
| 13 | +#define FELICA_POLLING_REQUEST_NONE (0x00U) |
| 14 | +#define FELICA_POLLING_REQUEST_SYSTEM_CODE (0x01U) |
| 15 | +#define FELICA_POLLING_REQUEST_PERFORMANCE (0x02U) |
| 16 | + |
| 17 | +#define FELICA_SYSTEM_CODE_LITES (0xB488U) |
| 18 | + |
11 | 19 | #define TAG "FelicaListener"
|
12 | 20 |
|
13 | 21 | FelicaListener* felica_listener_alloc(Nfc* nfc, FelicaData* data) {
|
@@ -136,6 +144,45 @@ static FelicaError felica_listener_command_handler_write(
|
136 | 144 | return felica_listener_frame_exchange(instance, instance->tx_buffer);
|
137 | 145 | }
|
138 | 146 |
|
| 147 | +static FelicaError felica_listener_user_polling_handler( |
| 148 | + FelicaListener* instance, |
| 149 | + const FelicaListenerGenericRequest* generic_request) { |
| 150 | + switch(generic_request->polling.request_code) { |
| 151 | + case FELICA_POLLING_REQUEST_NONE: { |
| 152 | + if(generic_request->polling.system_code != FELICA_SYSTEM_CODE_CODE) { |
| 153 | + return FelicaErrorIgnoreRequest; |
| 154 | + } else { |
| 155 | + FURI_LOG_E( |
| 156 | + TAG, |
| 157 | + "NFC controller should have handled this Polling request. Please report this issue."); |
| 158 | + return FelicaErrorNotPresent; |
| 159 | + } |
| 160 | + break; |
| 161 | + } |
| 162 | + case FELICA_POLLING_REQUEST_SYSTEM_CODE: { |
| 163 | + FelicaPollingResponseWithRequest* resp = malloc(sizeof(FelicaPollingResponseWithRequest)); |
| 164 | + resp->base.length = sizeof(FelicaPollingResponseWithRequest); |
| 165 | + resp->base.response_code = FELICA_LISTENER_RESPONSE_POLLING; |
| 166 | + resp->base.idm = instance->data->idm; |
| 167 | + resp->base.pmm = instance->data->pmm; |
| 168 | + resp->request_data = FELICA_SYSTEM_CODE_LITES; |
| 169 | + |
| 170 | + bit_buffer_reset(instance->tx_buffer); |
| 171 | + bit_buffer_append_bytes(instance->tx_buffer, (uint8_t*)resp, resp->base.length); |
| 172 | + |
| 173 | + free(resp); |
| 174 | + break; |
| 175 | + } |
| 176 | + default: |
| 177 | + FURI_LOG_E( |
| 178 | + TAG, |
| 179 | + "FeliCa unhandled polling request code %02X", |
| 180 | + generic_request->polling.request_code); |
| 181 | + return FelicaErrorNotPresent; |
| 182 | + } |
| 183 | + return felica_listener_frame_exchange(instance, instance->tx_buffer); |
| 184 | +} |
| 185 | + |
139 | 186 | static FelicaError felica_listener_process_request(
|
140 | 187 | FelicaListener* instance,
|
141 | 188 | const FelicaListenerGenericRequest* generic_request) {
|
@@ -187,7 +234,16 @@ NfcCommand felica_listener_run(NfcGenericEvent event, void* context) {
|
187 | 234 | break;
|
188 | 235 | }
|
189 | 236 |
|
190 |
| - if(!felica_listener_check_idm(instance, &request->header.idm)) { |
| 237 | + if(request->header.code == FELICA_CMD_POLLING) { |
| 238 | + // Catch any Request Code requests that were not handled in hardware. |
| 239 | + FelicaError error = felica_listener_user_polling_handler(instance, request); |
| 240 | + if(error == FelicaErrorIgnoreRequest) { |
| 241 | + command = NfcCommandReset; |
| 242 | + } else if(error != FelicaErrorNone) { |
| 243 | + FURI_LOG_E(TAG, "User polling handler error: %2X", error); |
| 244 | + } |
| 245 | + break; |
| 246 | + } else if(!felica_listener_check_idm(instance, &request->header.idm)) { |
191 | 247 | FURI_LOG_E(TAG, "Wrong IDm");
|
192 | 248 | break;
|
193 | 249 | }
|
|
0 commit comments