From 2961ad5ee1aa184752abd58d1cd85260755dc3fd Mon Sep 17 00:00:00 2001 From: gornekich Date: Thu, 7 Mar 2024 15:59:27 +0000 Subject: [PATCH 1/5] slix: fix incorrect default privacy passwords --- lib/nfc/protocols/slix/slix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/nfc/protocols/slix/slix.c b/lib/nfc/protocols/slix/slix.c index b575baa72..6361787d3 100644 --- a/lib/nfc/protocols/slix/slix.c +++ b/lib/nfc/protocols/slix/slix.c @@ -78,8 +78,8 @@ typedef struct { static const SlixPasswordConfig slix_password_configs[] = { [SlixPasswordTypeRead] = {SLIX_PASSWORD_READ_KEY, SLIX_TYPE_FEATURE_READ, 0x00000000U}, [SlixPasswordTypeWrite] = {SLIX_PASSWORD_WRITE_KEY, SLIX_TYPE_FEATURE_WRITE, 0x00000000U}, - [SlixPasswordTypePrivacy] = {SLIX_PASSWORD_PRIVACY_KEY, SLIX_TYPE_FEATURE_PRIVACY, 0xFFFFFFFFU}, - [SlixPasswordTypeDestroy] = {SLIX_PASSWORD_DESTROY_KEY, SLIX_TYPE_FEATURE_DESTROY, 0xFFFFFFFFU}, + [SlixPasswordTypePrivacy] = {SLIX_PASSWORD_PRIVACY_KEY, SLIX_TYPE_FEATURE_PRIVACY, 0x0F0F0F0FU}, + [SlixPasswordTypeDestroy] = {SLIX_PASSWORD_DESTROY_KEY, SLIX_TYPE_FEATURE_DESTROY, 0x0F0F0F0FU}, [SlixPasswordTypeEasAfi] = {SLIX_PASSWORD_EAS_KEY, SLIX_TYPE_FEATURE_EAS, 0x00000000U}, }; From bf97209c9b5859a498579a3736956315d905b26e Mon Sep 17 00:00:00 2001 From: gornekich Date: Thu, 7 Mar 2024 17:31:53 +0000 Subject: [PATCH 2/5] slix poller: add check privacy password state --- lib/nfc/protocols/slix/slix_poller.c | 51 +++++++++++++++++++++++++- lib/nfc/protocols/slix/slix_poller_i.h | 2 + 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/lib/nfc/protocols/slix/slix_poller.c b/lib/nfc/protocols/slix/slix_poller.c index d9d38d102..3c9a7cce4 100644 --- a/lib/nfc/protocols/slix/slix_poller.c +++ b/lib/nfc/protocols/slix/slix_poller.c @@ -73,17 +73,62 @@ static NfcCommand slix_poller_handler_read_signature(SlixPoller* instance) { if(slix_type_has_features(instance->type, SLIX_TYPE_FEATURE_SIGNATURE)) { instance->error = slix_poller_read_signature(instance, &instance->data->signature); if(instance->error == SlixErrorNone) { - instance->poller_state = SlixPollerStateReady; + instance->poller_state = SlixPollerStateCheckPrivacyPassword; } else { instance->poller_state = SlixPollerStateError; } } else { - instance->poller_state = SlixPollerStateReady; + instance->poller_state = SlixPollerStateCheckPrivacyPassword; } return NfcCommandContinue; } +static NfcCommand slix_poller_handler_check_privacy_password(SlixPoller* instance) { + NfcCommand command = NfcCommandContinue; + + do { + if(!slix_type_has_features(instance->type, SLIX_TYPE_FEATURE_PRIVACY)) { + instance->poller_state = SlixPollerStateReady; + break; + } + if(instance->privacy_password_checked) { + instance->poller_state = SlixPollerStateReady; + break; + } + + instance->slix_event.type = SlixPollerEventTypePrivacyUnlockRequest; + command = instance->callback(instance->general_event, instance->context); + + if(!instance->slix_event_data.privacy_password.password_set) { + instance->poller_state = SlixPollerStateReady; + break; + } + + SlixPassword pwd = instance->slix_event_data.privacy_password.password; + FURI_LOG_I(TAG, "Trying to check privacy password: %08lX", pwd); + + instance->error = slix_poller_get_random_number(instance, &instance->random_number); + if(instance->error != SlixErrorNone) { + instance->poller_state = SlixPollerStateReady; + break; + } + + instance->error = slix_poller_set_password(instance, SlixPasswordTypePrivacy, pwd); + if(instance->error != SlixErrorNone) { + command = NfcCommandReset; + break; + } + + FURI_LOG_I(TAG, "Found privacy password"); + instance->data->passwords[SlixPasswordTypePrivacy] = pwd; + instance->privacy_password_checked = true; + instance->poller_state = SlixPollerStateReady; + } while(false); + + return command; +} + static NfcCommand slix_poller_handler_privacy_unlock(SlixPoller* instance) { NfcCommand command = NfcCommandContinue; instance->poller_state = SlixPollerStateError; @@ -108,6 +153,7 @@ static NfcCommand slix_poller_handler_privacy_unlock(SlixPoller* instance) { FURI_LOG_I(TAG, "Privacy mode disabled"); instance->data->passwords[SlixPasswordTypePrivacy] = pwd; + instance->privacy_password_checked = true; instance->poller_state = SlixPollerStateIdle; slix_unlocked = true; } while(false); @@ -140,6 +186,7 @@ static const SlixPollerStateHandler slix_poller_state_handler[SlixPollerStateNum [SlixPollerStateError] = slix_poller_handler_error, [SlixPollerStateGetNxpSysInfo] = slix_poller_handler_get_nfc_system_info, [SlixPollerStateReadSignature] = slix_poller_handler_read_signature, + [SlixPollerStateCheckPrivacyPassword] = slix_poller_handler_check_privacy_password, [SlixPollerStatePrivacyUnlock] = slix_poller_handler_privacy_unlock, [SlixPollerStateReady] = slix_poller_handler_ready, }; diff --git a/lib/nfc/protocols/slix/slix_poller_i.h b/lib/nfc/protocols/slix/slix_poller_i.h index 7a3b543b7..38c23c297 100644 --- a/lib/nfc/protocols/slix/slix_poller_i.h +++ b/lib/nfc/protocols/slix/slix_poller_i.h @@ -14,6 +14,7 @@ typedef enum { SlixPollerStateIdle, SlixPollerStateGetNxpSysInfo, SlixPollerStateReadSignature, + SlixPollerStateCheckPrivacyPassword, SlixPollerStatePrivacyUnlock, SlixPollerStateReady, SlixPollerStateError, @@ -27,6 +28,7 @@ struct SlixPoller { SlixPollerState poller_state; SlixError error; SlixRandomNumber random_number; + bool privacy_password_checked; BitBuffer* tx_buffer; BitBuffer* rx_buffer; From 8f9fbc3a79c9266cb22074d3f8fb3f06409ed46c Mon Sep 17 00:00:00 2001 From: gornekich Date: Thu, 7 Mar 2024 18:48:14 +0000 Subject: [PATCH 3/5] mf desfire: change detect algorithm --- lib/nfc/protocols/mf_desfire/mf_desfire_poller.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/nfc/protocols/mf_desfire/mf_desfire_poller.c b/lib/nfc/protocols/mf_desfire/mf_desfire_poller.c index 5af033d4c..864ca09a4 100644 --- a/lib/nfc/protocols/mf_desfire/mf_desfire_poller.c +++ b/lib/nfc/protocols/mf_desfire/mf_desfire_poller.c @@ -225,8 +225,8 @@ static bool mf_desfire_poller_detect(NfcGenericEvent event, void* context) { bool protocol_detected = false; if(iso14443_4a_event->type == Iso14443_4aPollerEventTypeReady) { - MfDesfireVersion version = {}; - const MfDesfireError error = mf_desfire_poller_read_version(instance, &version); + MfDesfireKeySettings key_settings = {}; + MfDesfireError error = mf_desfire_poller_read_key_settings(instance, &key_settings); protocol_detected = (error == MfDesfireErrorNone); } From b1a9904ea5a2ef6c70022ad979360406bc07c7e3 Mon Sep 17 00:00:00 2001 From: gornekich Date: Thu, 7 Mar 2024 19:29:18 +0000 Subject: [PATCH 4/5] mf desfire: change detection algorithm to check master key version --- .../protocols/mf_desfire/mf_desfire_poller.c | 4 +-- .../protocols/mf_desfire/mf_desfire_poller.h | 15 ++++++++ .../mf_desfire/mf_desfire_poller_i.c | 35 ++++++++++++------- targets/f18/api_symbols.csv | 2 +- targets/f7/api_symbols.csv | 3 +- 5 files changed, 43 insertions(+), 16 deletions(-) diff --git a/lib/nfc/protocols/mf_desfire/mf_desfire_poller.c b/lib/nfc/protocols/mf_desfire/mf_desfire_poller.c index 864ca09a4..f6e638d7c 100644 --- a/lib/nfc/protocols/mf_desfire/mf_desfire_poller.c +++ b/lib/nfc/protocols/mf_desfire/mf_desfire_poller.c @@ -225,8 +225,8 @@ static bool mf_desfire_poller_detect(NfcGenericEvent event, void* context) { bool protocol_detected = false; if(iso14443_4a_event->type == Iso14443_4aPollerEventTypeReady) { - MfDesfireKeySettings key_settings = {}; - MfDesfireError error = mf_desfire_poller_read_key_settings(instance, &key_settings); + MfDesfireKeyVersion key_version = 0; + MfDesfireError error = mf_desfire_poller_read_key_version(instance, 0, &key_version); protocol_detected = (error == MfDesfireErrorNone); } diff --git a/lib/nfc/protocols/mf_desfire/mf_desfire_poller.h b/lib/nfc/protocols/mf_desfire/mf_desfire_poller.h index 6ef2f3f68..707df42cd 100644 --- a/lib/nfc/protocols/mf_desfire/mf_desfire_poller.h +++ b/lib/nfc/protocols/mf_desfire/mf_desfire_poller.h @@ -91,6 +91,21 @@ MfDesfireError MfDesfireError mf_desfire_poller_read_key_settings(MfDesfirePoller* instance, MfDesfireKeySettings* data); +/** + * @brief Read key version on MfDesfire card. + * + * Must ONLY be used inside the callback function. + * + * @param[in, out] instance pointer to the instance to be used in the transaction. + * @param[out] key_num key number. + * @param[in] data pointer to the MfDesfireKeyVersion structure to be filled with key version data. + * @return MfDesfireErrorNone on success, an error code on failure. + */ +MfDesfireError mf_desfire_poller_read_key_version( + MfDesfirePoller* instance, + uint8_t key_num, + MfDesfireKeyVersion* data); + /** * @brief Read key versions on MfDesfire card. * diff --git a/lib/nfc/protocols/mf_desfire/mf_desfire_poller_i.c b/lib/nfc/protocols/mf_desfire/mf_desfire_poller_i.c index 0b2d84138..1a91c5261 100644 --- a/lib/nfc/protocols/mf_desfire/mf_desfire_poller_i.c +++ b/lib/nfc/protocols/mf_desfire/mf_desfire_poller_i.c @@ -139,6 +139,28 @@ MfDesfireError return error; } +MfDesfireError mf_desfire_poller_read_key_version( + MfDesfirePoller* instance, + uint8_t key_num, + MfDesfireKeyVersion* data) { + furi_assert(instance); + furi_assert(data); + + bit_buffer_set_size_bytes(instance->input_buffer, sizeof(uint8_t) * 2); + bit_buffer_set_byte(instance->input_buffer, 0, MF_DESFIRE_CMD_GET_KEY_VERSION); + bit_buffer_set_byte(instance->input_buffer, 1, key_num); + + MfDesfireError error = + mf_desfire_send_chunks(instance, instance->input_buffer, instance->result_buffer); + if(error == MfDesfireErrorNone) { + if(!mf_desfire_key_version_parse(data, instance->result_buffer)) { + error = MfDesfireErrorProtocol; + } + } + + return error; +} + MfDesfireError mf_desfire_poller_read_key_versions( MfDesfirePoller* instance, SimpleArray* data, @@ -148,22 +170,11 @@ MfDesfireError mf_desfire_poller_read_key_versions( simple_array_init(data, count); - bit_buffer_set_size_bytes(instance->input_buffer, sizeof(uint8_t) * 2); - bit_buffer_set_byte(instance->input_buffer, 0, MF_DESFIRE_CMD_GET_KEY_VERSION); - MfDesfireError error = MfDesfireErrorNone; for(uint32_t i = 0; i < count; ++i) { - bit_buffer_set_byte(instance->input_buffer, 1, i); - - error = mf_desfire_send_chunks(instance, instance->input_buffer, instance->result_buffer); - + error = mf_desfire_poller_read_key_version(instance, i, simple_array_get(data, i)); if(error != MfDesfireErrorNone) break; - - if(!mf_desfire_key_version_parse(simple_array_get(data, i), instance->result_buffer)) { - error = MfDesfireErrorProtocol; - break; - } } return error; diff --git a/targets/f18/api_symbols.csv b/targets/f18/api_symbols.csv index bdfa8c7a4..8f6b8530e 100644 --- a/targets/f18/api_symbols.csv +++ b/targets/f18/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,58.0,, +Version,+,58.1,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index d856dc694..b0a3d1610 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,58.0,, +Version,+,58.1,, Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, @@ -2444,6 +2444,7 @@ Function,+,mf_desfire_poller_read_file_settings_multi,MfDesfireError,"MfDesfireP Function,+,mf_desfire_poller_read_file_value,MfDesfireError,"MfDesfirePoller*, MfDesfireFileId, MfDesfireFileData*" Function,+,mf_desfire_poller_read_free_memory,MfDesfireError,"MfDesfirePoller*, MfDesfireFreeMemory*" Function,+,mf_desfire_poller_read_key_settings,MfDesfireError,"MfDesfirePoller*, MfDesfireKeySettings*" +Function,+,mf_desfire_poller_read_key_version,MfDesfireError,"MfDesfirePoller*, uint8_t, MfDesfireKeyVersion*" Function,+,mf_desfire_poller_read_key_versions,MfDesfireError,"MfDesfirePoller*, SimpleArray*, uint32_t" Function,+,mf_desfire_poller_read_version,MfDesfireError,"MfDesfirePoller*, MfDesfireVersion*" Function,+,mf_desfire_poller_select_application,MfDesfireError,"MfDesfirePoller*, const MfDesfireApplicationId*" From 2da05bfa6c58052baf6ced029a7d9cb49ba48005 Mon Sep 17 00:00:00 2001 From: Anna Prosvetova Date: Tue, 12 Mar 2024 00:24:29 +0100 Subject: [PATCH 5/5] Infrared: Add Fujitsu ASYG24KMTB --- .../infrared/resources/infrared/assets/ac.ir | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/applications/main/infrared/resources/infrared/assets/ac.ir b/applications/main/infrared/resources/infrared/assets/ac.ir index 64d473def..4e1735246 100644 --- a/applications/main/infrared/resources/infrared/assets/ac.ir +++ b/applications/main/infrared/resources/infrared/assets/ac.ir @@ -788,3 +788,41 @@ type: raw frequency: 38000 duty_cycle: 0.330000 data: 664 17757 3057 8901 528 469 550 1434 556 465 553 440 529 465 554 439 555 439 555 438 555 440 553 1435 552 443 550 470 524 1466 522 472 522 472 521 1467 523 1466 549 1440 549 1440 548 1440 548 445 549 445 549 445 549 446 548 470 524 471 523 471 523 471 523 472 522 472 522 473 522 472 523 472 548 446 549 445 550 445 548 446 548 446 548 446 548 446 548 447 547 470 524 471 523 471 523 471 523 471 523 474 519 474 521 474 521 473 522 473 546 447 547 1441 548 1442 546 1442 547 1442 546 2947 3023 8935 522 1466 522 472 522 498 496 498 495 499 496 498 496 498 521 473 522 471 523 1466 522 471 523 471 522 1466 523 471 523 1467 522 1467 522 1467 521 1493 495 1494 496 1493 521 473 522 472 522 471 523 472 522 471 523 472 522 472 522 472 522 472 522 472 522 472 522 472 522 473 521 499 495 499 495 499 495 499 496 498 522 473 522 472 523 471 522 472 522 472 522 472 522 472 522 472 522 472 522 473 521 473 521 473 521 473 521 499 495 500 494 500 495 499 496 498 522 2947 3023 8937 521 1468 520 473 521 473 521 473 521 473 521 473 521 473 521 474 520 474 520 1470 518 500 494 500 494 500 494 500 494 1494 521 1468 521 473 521 1468 520 1468 520 1469 520 1469 520 1470 518 1495 493 1496 493 1495 494 500 519 475 520 474 520 1469 519 1469 520 1469 519 474 520 474 520 475 519 477 517 500 494 1496 493 1496 493 1496 493 500 495 1495 519 475 518 475 519 475 518 476 518 475 519 1470 519 500 494 500 494 501 493 501 493 501 493 1499 490 1497 493 1497 492 1496 518 +# +# Model: Fujitsu ASYG24KMTB +# +name: Dh +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 3302 1639 405 423 407 420 410 1234 405 421 409 1210 440 387 432 420 410 417 413 1231 408 1238 412 388 431 422 408 392 438 1233 406 1238 412 389 430 396 434 419 411 390 440 413 406 394 436 391 439 388 431 421 409 417 413 414 405 421 409 392 438 1233 406 421 409 417 413 414 405 395 435 418 412 388 432 421 409 1236 414 387 432 420 410 390 440 388 431 1213 437 1208 431 1239 411 1234 405 1213 437 1208 431 1214 436 1235 415 386 433 420 410 1234 405 422 408 418 412 389 431 396 434 1211 439 388 432 422 408 418 412 1233 406 1238 412 415 404 422 408 1237 413 388 432 422 408 1236 414 1205 434 1210 440 1205 434 392 438 390 440 1231 408 392 438 415 404 396 434 392 438 415 404 422 408 419 411 416 414 412 407 394 436 417 413 414 405 421 409 417 413 1232 407 419 411 390 440 1204 435 418 412 415 415 412 407 419 411 1208 431 421 409 418 412 388 432 421 409 392 438 415 404 395 435 1211 439 388 432 1213 437 416 414 386 433 1212 438 415 404 396 434 392 438 416 414 413 406 420 410 417 413 1231 409 418 412 389 430 1240 410 391 439 1205 434 420 410 390 440 387 432 420 410 417 413 +# +name: Cool_hi +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 3293 1649 405 396 434 419 411 1207 432 395 435 1236 414 413 406 394 436 417 413 1232 407 1212 438 415 404 396 434 419 411 1234 405 1239 411 417 413 414 405 421 409 419 411 389 430 423 407 393 437 416 414 387 432 394 436 417 413 388 431 421 409 1236 414 387 432 421 409 418 412 414 405 422 408 418 412 415 404 1240 410 391 439 414 405 421 409 419 411 1234 405 1239 411 1208 431 1239 411 1235 404 1214 436 1210 440 1205 434 419 411 416 414 1204 435 418 412 415 404 396 434 393 437 1235 404 396 434 420 410 416 414 1231 408 1210 440 387 432 421 409 1235 415 414 405 395 435 418 412 1232 407 420 410 1208 431 422 408 1237 413 415 404 396 434 419 411 416 414 413 406 420 410 417 413 414 405 421 409 418 412 415 404 422 408 419 411 416 414 413 406 1238 412 415 404 422 408 1237 413 414 405 421 409 418 412 416 414 1231 408 418 412 415 404 422 408 419 411 416 414 413 406 420 410 1235 404 423 407 420 410 1234 405 422 408 1210 440 414 405 421 409 392 438 415 404 422 408 420 410 417 413 1231 408 419 411 416 414 413 406 1237 413 415 404 1239 411 417 413 1232 407 420 410 417 413 +# +name: Cool_lo +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 3302 1614 440 414 405 421 409 1235 414 413 406 1238 411 415 404 422 408 419 411 1234 405 1240 409 418 412 415 404 422 408 1237 412 1232 407 420 410 417 413 414 405 422 408 419 411 416 414 413 406 420 410 417 413 414 405 421 409 418 412 415 404 1239 410 418 412 415 404 422 408 419 411 416 414 413 406 420 410 1234 405 422 408 419 411 416 414 414 405 1239 411 1207 432 1239 410 1235 414 1230 409 1236 413 1232 407 1237 412 415 415 412 407 1237 412 414 405 422 408 419 411 416 414 1231 408 419 411 416 414 413 406 1238 411 1206 433 421 409 418 412 1206 433 421 409 418 412 1206 433 1238 412 1207 432 1213 436 390 440 1232 407 420 410 417 413 414 405 421 409 418 412 415 404 422 408 419 411 416 414 413 406 421 409 418 412 415 404 422 408 419 411 1233 406 421 409 418 412 1232 407 420 410 418 412 389 430 422 408 1210 440 414 405 395 435 418 412 415 404 423 407 420 410 416 414 414 405 422 408 418 412 415 404 1240 409 1235 414 413 406 420 410 417 413 414 405 422 408 419 411 416 414 1231 408 418 412 415 404 1240 409 1209 440 387 432 1212 437 1234 405 1214 435 1209 440 1204 435 +# +name: Heat_hi +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 3301 1615 439 415 404 422 408 1210 439 414 405 1239 410 416 414 414 405 395 435 1209 440 1205 434 419 411 417 413 414 405 1212 437 1207 432 422 408 419 411 416 414 414 405 421 409 418 412 415 404 422 408 393 437 416 414 413 406 420 410 417 413 1205 434 420 410 417 413 414 405 421 409 418 412 415 404 422 408 1210 439 414 405 422 408 419 411 417 413 1205 434 1236 413 1206 433 1211 438 1207 432 1212 437 1209 440 1204 435 418 412 415 415 1204 435 418 412 415 404 422 408 419 411 1208 441 412 407 420 410 417 413 1205 434 1237 412 414 405 422 408 1210 439 415 404 396 434 419 411 1207 432 1213 436 417 413 1205 434 420 410 417 413 1231 408 419 411 416 414 413 406 421 409 418 412 414 405 422 408 419 411 415 404 424 406 421 409 418 412 415 404 1239 410 417 413 414 405 1239 410 416 414 413 406 422 408 419 411 1233 406 421 409 418 412 415 404 423 407 419 411 416 414 413 406 1238 411 416 414 413 406 421 409 1235 414 1230 409 418 412 415 415 412 407 420 410 417 413 414 405 422 408 1236 413 413 406 421 409 1235 414 1204 435 1210 439 1206 433 1212 437 1207 432 395 435 1236 413 +# +name: Heat_lo +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 3295 1646 408 420 410 390 440 1205 434 393 437 1234 405 421 409 419 411 415 415 1230 409 1210 440 414 405 421 409 418 412 1233 406 1212 437 416 414 413 406 394 436 418 412 415 404 422 408 393 437 416 414 413 406 420 410 417 413 414 405 421 409 1236 413 414 405 421 409 418 412 415 404 423 407 419 411 416 414 1231 408 418 412 415 415 412 407 421 409 1235 414 1204 435 1209 441 1205 434 1210 440 1205 434 1212 437 1207 432 395 435 419 411 1233 406 421 409 418 412 415 404 422 408 1238 411 415 404 396 434 419 411 1234 405 1239 410 417 413 414 405 1213 436 417 413 414 405 1213 436 1235 404 1214 435 1209 441 413 406 421 409 418 412 1206 433 394 436 418 412 388 431 422 408 419 411 415 415 386 433 420 410 418 412 414 405 422 408 419 411 389 430 1241 408 418 412 415 404 1240 409 417 413 414 405 395 435 419 411 1233 406 395 435 418 412 415 404 422 408 419 411 416 414 413 406 421 409 1236 413 413 406 394 436 1235 414 1230 409 418 412 415 404 422 408 420 410 417 413 414 405 421 409 1236 413 413 406 420 410 417 413 1232 407 1237 412 416 414 1230 409 1236 413 1205 434 1210 439 +# +name: Off +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 3302 1640 404 423 407 420 410 1212 437 390 440 1234 405 395 435 392 438 415 415 1207 432 1242 407 420 410 391 439 414 405 1243 406 1241 408 392 438 415 415 386 433 393 437 390 440 414 405 396 434 419 411 389 441 412 407 420 410 390 440 387 432 1242 407 393 437 390 440 414 405 395 435 392 438 389 430 396 434 1240 409 417 413 414 405 395 435 419 411 1237 412 389 430 396 434 393 437 416 414 387 432 394 436 1212 437 389 441 1234 405 1217 432 1241 408 1213 436 1212 437 1210 439