att_db.c (883180d368adc7b0f3f8d7831feca767a652997f) | att_db.c (9b49c4f4cec484bb4c6c1c43b43f3fa86593884d) |
---|---|
1/* 2 * Copyright (C) 2014 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright --- 276 unchanged lines hidden (view full) --- 285static inline uint16_t setup_error_invalid_handle(uint8_t * response_buffer, uint16_t request, uint16_t handle){ 286 return setup_error(response_buffer, request, handle, ATT_ERROR_INVALID_HANDLE); 287} 288 289static inline uint16_t setup_error_invalid_offset(uint8_t * response_buffer, uint16_t request, uint16_t handle){ 290 return setup_error(response_buffer, request, handle, ATT_ERROR_INVALID_OFFSET); 291} 292 | 1/* 2 * Copyright (C) 2014 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright --- 276 unchanged lines hidden (view full) --- 285static inline uint16_t setup_error_invalid_handle(uint8_t * response_buffer, uint16_t request, uint16_t handle){ 286 return setup_error(response_buffer, request, handle, ATT_ERROR_INVALID_HANDLE); 287} 288 289static inline uint16_t setup_error_invalid_offset(uint8_t * response_buffer, uint16_t request, uint16_t handle){ 290 return setup_error(response_buffer, request, handle, ATT_ERROR_INVALID_OFFSET); 291} 292 |
293static inline uint16_t setup_error_invalid_pdu(uint8_t *response_buffer, uint16_t request) { 294 return setup_error(response_buffer, request, 0, ATT_ERROR_INVALID_PDU); 295} 296 |
|
293static uint8_t att_validate_security(att_connection_t * att_connection, att_operation_t operation, att_iterator_t * it){ 294 int required_security_level = 0; 295 int requires_secure_connection = 0; 296 switch (operation){ 297 case ATT_READ: 298 if ((it->flags & ATT_PROPERTY_READ_PERMISSION_BIT_0) != 0){ 299 required_security_level |= 1; 300 } --- 50 unchanged lines hidden (view full) --- 351} 352 353// 354// MARK: ATT_EXCHANGE_MTU_REQUEST 355// 356static uint16_t handle_exchange_mtu_request(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, 357 uint8_t * response_buffer){ 358 | 297static uint8_t att_validate_security(att_connection_t * att_connection, att_operation_t operation, att_iterator_t * it){ 298 int required_security_level = 0; 299 int requires_secure_connection = 0; 300 switch (operation){ 301 case ATT_READ: 302 if ((it->flags & ATT_PROPERTY_READ_PERMISSION_BIT_0) != 0){ 303 required_security_level |= 1; 304 } --- 50 unchanged lines hidden (view full) --- 355} 356 357// 358// MARK: ATT_EXCHANGE_MTU_REQUEST 359// 360static uint16_t handle_exchange_mtu_request(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, 361 uint8_t * response_buffer){ 362 |
359 UNUSED(request_len); | 363 if (request_len != 3) return setup_error_invalid_pdu(response_buffer, ATT_EXCHANGE_MTU_REQUEST); |
360 361 uint16_t client_rx_mtu = little_endian_read_16(request_buffer, 1); 362 363 // find min(local max mtu, remote mtu) and use as mtu for this connection 364 if (client_rx_mtu < att_connection->max_mtu){ 365 att_connection->mtu = client_rx_mtu; 366 } else { 367 att_connection->mtu = att_connection->max_mtu; --- 68 unchanged lines hidden (view full) --- 436 } 437 438 response_buffer[0] = ATT_FIND_INFORMATION_REPLY; 439 return offset; 440} 441 442static uint16_t handle_find_information_request(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, 443 uint8_t * response_buffer, uint16_t response_buffer_size){ | 364 365 uint16_t client_rx_mtu = little_endian_read_16(request_buffer, 1); 366 367 // find min(local max mtu, remote mtu) and use as mtu for this connection 368 if (client_rx_mtu < att_connection->max_mtu){ 369 att_connection->mtu = client_rx_mtu; 370 } else { 371 att_connection->mtu = att_connection->max_mtu; --- 68 unchanged lines hidden (view full) --- 440 } 441 442 response_buffer[0] = ATT_FIND_INFORMATION_REPLY; 443 return offset; 444} 445 446static uint16_t handle_find_information_request(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, 447 uint8_t * response_buffer, uint16_t response_buffer_size){ |
444 UNUSED(request_len); 445 return handle_find_information_request2(att_connection, response_buffer, response_buffer_size, little_endian_read_16(request_buffer, 1), little_endian_read_16(request_buffer, 3)); | 448 449 if (request_len != 5) return setup_error_invalid_pdu(response_buffer, ATT_FIND_INFORMATION_REQUEST); 450 451 uint16_t start_handle = little_endian_read_16(request_buffer, 1); 452 uint16_t end_handle = little_endian_read_16(request_buffer, 3); 453 return handle_find_information_request2(att_connection, response_buffer, response_buffer_size, start_handle, end_handle); |
446} 447 448// 449// MARK: ATT_FIND_BY_TYPE_VALUE 450// 451// "Only attributes with attribute handles between and including the Starting Handle parameter 452// and the Ending Handle parameter that match the requested attri- bute type and the attribute 453// value that have sufficient permissions to allow reading will be returned" -> (1) 454// 455// TODO: handle other types then GATT_PRIMARY_SERVICE_UUID and GATT_SECONDARY_SERVICE_UUID 456// 457// NOTE: doesn't handle DYNAMIC values 458// NOTE: only supports 16 bit UUIDs 459// 460static uint16_t handle_find_by_type_value_request(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, 461 uint8_t * response_buffer, uint16_t response_buffer_size){ 462 UNUSED(att_connection); 463 | 454} 455 456// 457// MARK: ATT_FIND_BY_TYPE_VALUE 458// 459// "Only attributes with attribute handles between and including the Starting Handle parameter 460// and the Ending Handle parameter that match the requested attri- bute type and the attribute 461// value that have sufficient permissions to allow reading will be returned" -> (1) 462// 463// TODO: handle other types then GATT_PRIMARY_SERVICE_UUID and GATT_SECONDARY_SERVICE_UUID 464// 465// NOTE: doesn't handle DYNAMIC values 466// NOTE: only supports 16 bit UUIDs 467// 468static uint16_t handle_find_by_type_value_request(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, 469 uint8_t * response_buffer, uint16_t response_buffer_size){ 470 UNUSED(att_connection); 471 |
472 if (request_len < 7) return setup_error_invalid_pdu(response_buffer, ATT_FIND_BY_TYPE_VALUE_REQUEST); 473 |
|
464 // parse request | 474 // parse request |
465 int attribute_len = request_len - 7; | |
466 uint16_t start_handle = little_endian_read_16(request_buffer, 1); 467 uint16_t end_handle = little_endian_read_16(request_buffer, 3); 468 uint16_t attribute_type = little_endian_read_16(request_buffer, 5); 469 const uint8_t *attribute_value = &request_buffer[7]; | 475 uint16_t start_handle = little_endian_read_16(request_buffer, 1); 476 uint16_t end_handle = little_endian_read_16(request_buffer, 3); 477 uint16_t attribute_type = little_endian_read_16(request_buffer, 5); 478 const uint8_t *attribute_value = &request_buffer[7]; |
479 uint16_t attribute_len = request_len - 7; |
|
470 471 log_info("ATT_FIND_BY_TYPE_VALUE_REQUEST: from %04X to %04X, type %04X, value: ", start_handle, end_handle, attribute_type); 472 log_info_hexdump(attribute_value, attribute_len); 473 uint8_t request_type = ATT_FIND_BY_TYPE_VALUE_REQUEST; 474 475 if ((start_handle > end_handle) || (start_handle == 0)){ 476 return setup_error_invalid_handle(response_buffer, request_type, start_handle); 477 } --- 153 unchanged lines hidden (view full) --- 631 } 632 633 // attribute not found 634 return setup_error_atribute_not_found(response_buffer, request_type, start_handle); 635} 636 637static uint16_t handle_read_by_type_request(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, 638 uint8_t * response_buffer, uint16_t response_buffer_size){ | 480 481 log_info("ATT_FIND_BY_TYPE_VALUE_REQUEST: from %04X to %04X, type %04X, value: ", start_handle, end_handle, attribute_type); 482 log_info_hexdump(attribute_value, attribute_len); 483 uint8_t request_type = ATT_FIND_BY_TYPE_VALUE_REQUEST; 484 485 if ((start_handle > end_handle) || (start_handle == 0)){ 486 return setup_error_invalid_handle(response_buffer, request_type, start_handle); 487 } --- 153 unchanged lines hidden (view full) --- 641 } 642 643 // attribute not found 644 return setup_error_atribute_not_found(response_buffer, request_type, start_handle); 645} 646 647static uint16_t handle_read_by_type_request(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, 648 uint8_t * response_buffer, uint16_t response_buffer_size){ |
639 int attribute_type_len; 640 if (request_len <= 7){ 641 attribute_type_len = 2; 642 } else { 643 attribute_type_len = 16; | 649 650 uint16_t attribute_type_len; 651 switch (request_len){ 652 case 7: 653 attribute_type_len = 2; 654 break; 655 case 21: 656 attribute_type_len = 16; 657 break; 658 default: 659 return setup_error_invalid_pdu(response_buffer, ATT_READ_BY_TYPE_REQUEST); |
644 } | 660 } |
645 return handle_read_by_type_request2(att_connection, response_buffer, response_buffer_size, little_endian_read_16(request_buffer, 1), little_endian_read_16(request_buffer, 3), attribute_type_len, &request_buffer[5]); | 661 662 uint16_t start_handle = little_endian_read_16(request_buffer, 1); 663 uint16_t end_handle = little_endian_read_16(request_buffer, 3); 664 return handle_read_by_type_request2(att_connection, response_buffer, response_buffer_size, start_handle, end_handle, attribute_type_len, &request_buffer[5]); |
646} 647 648// 649// MARK: ATT_READ_BY_TYPE_REQUEST 650// 651static uint16_t handle_read_request2(att_connection_t * att_connection, uint8_t * response_buffer, uint16_t response_buffer_size, uint16_t handle){ 652 653 log_info("ATT_READ_REQUEST: handle %04x", handle); --- 33 unchanged lines hidden (view full) --- 687 offset += bytes_copied; 688 689 response_buffer[0] = ATT_READ_RESPONSE; 690 return offset; 691} 692 693static uint16_t handle_read_request(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, 694 uint8_t * response_buffer, uint16_t response_buffer_size){ | 665} 666 667// 668// MARK: ATT_READ_BY_TYPE_REQUEST 669// 670static uint16_t handle_read_request2(att_connection_t * att_connection, uint8_t * response_buffer, uint16_t response_buffer_size, uint16_t handle){ 671 672 log_info("ATT_READ_REQUEST: handle %04x", handle); --- 33 unchanged lines hidden (view full) --- 706 offset += bytes_copied; 707 708 response_buffer[0] = ATT_READ_RESPONSE; 709 return offset; 710} 711 712static uint16_t handle_read_request(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, 713 uint8_t * response_buffer, uint16_t response_buffer_size){ |
695 UNUSED(request_len); 696 return handle_read_request2(att_connection, response_buffer, response_buffer_size, little_endian_read_16(request_buffer, 1)); | 714 715 if (request_len != 3) return setup_error_invalid_pdu(response_buffer, ATT_READ_REQUEST); 716 717 uint16_t handle = little_endian_read_16(request_buffer, 1); 718 return handle_read_request2(att_connection, response_buffer, response_buffer_size, handle); |
697} 698 | 719} 720 |
699// | 721//s |
700// MARK: ATT_READ_BLOB_REQUEST 0x0c 701// 702static uint16_t handle_read_blob_request2(att_connection_t * att_connection, uint8_t * response_buffer, uint16_t response_buffer_size, uint16_t handle, uint16_t value_offset){ 703 log_info("ATT_READ_BLOB_REQUEST: handle %04x, offset %u", handle, value_offset); 704 uint8_t request_type = ATT_READ_BLOB_REQUEST; 705 706 att_iterator_t it; 707 int ok = att_find_handle(&it, handle); --- 33 unchanged lines hidden (view full) --- 741 offset += bytes_copied; 742 743 response_buffer[0] = ATT_READ_BLOB_RESPONSE; 744 return offset; 745} 746 747static uint16_t handle_read_blob_request(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, 748 uint8_t * response_buffer, uint16_t response_buffer_size){ | 722// MARK: ATT_READ_BLOB_REQUEST 0x0c 723// 724static uint16_t handle_read_blob_request2(att_connection_t * att_connection, uint8_t * response_buffer, uint16_t response_buffer_size, uint16_t handle, uint16_t value_offset){ 725 log_info("ATT_READ_BLOB_REQUEST: handle %04x, offset %u", handle, value_offset); 726 uint8_t request_type = ATT_READ_BLOB_REQUEST; 727 728 att_iterator_t it; 729 int ok = att_find_handle(&it, handle); --- 33 unchanged lines hidden (view full) --- 763 offset += bytes_copied; 764 765 response_buffer[0] = ATT_READ_BLOB_RESPONSE; 766 return offset; 767} 768 769static uint16_t handle_read_blob_request(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, 770 uint8_t * response_buffer, uint16_t response_buffer_size){ |
749 UNUSED(request_len); 750 return handle_read_blob_request2(att_connection, response_buffer, response_buffer_size, little_endian_read_16(request_buffer, 1), little_endian_read_16(request_buffer, 3)); | 771 772 if (request_len != 5) return setup_error_invalid_pdu(response_buffer, ATT_READ_BLOB_REQUEST); 773 774 uint16_t handle = little_endian_read_16(request_buffer, 1); 775 uint16_t value_offset = little_endian_read_16(request_buffer, 3); 776 return handle_read_blob_request2(att_connection, response_buffer, response_buffer_size, handle, value_offset); |
751} 752 753// 754// MARK: ATT_READ_MULTIPLE_REQUEST 0x0e 755// 756static uint16_t handle_read_multiple_request2(att_connection_t * att_connection, uint8_t * response_buffer, uint16_t response_buffer_size, uint16_t num_handles, uint8_t * handles){ 757 log_info("ATT_READ_MULTIPLE_REQUEST: num handles %u", num_handles); 758 uint8_t request_type = ATT_READ_MULTIPLE_REQUEST; --- 60 unchanged lines hidden (view full) --- 819 return setup_error(response_buffer, request_type, handle, error_code); 820 } 821 822 response_buffer[0] = ATT_READ_MULTIPLE_RESPONSE; 823 return offset; 824} 825static uint16_t handle_read_multiple_request(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, 826 uint8_t * response_buffer, uint16_t response_buffer_size){ | 777} 778 779// 780// MARK: ATT_READ_MULTIPLE_REQUEST 0x0e 781// 782static uint16_t handle_read_multiple_request2(att_connection_t * att_connection, uint8_t * response_buffer, uint16_t response_buffer_size, uint16_t num_handles, uint8_t * handles){ 783 log_info("ATT_READ_MULTIPLE_REQUEST: num handles %u", num_handles); 784 uint8_t request_type = ATT_READ_MULTIPLE_REQUEST; --- 60 unchanged lines hidden (view full) --- 845 return setup_error(response_buffer, request_type, handle, error_code); 846 } 847 848 response_buffer[0] = ATT_READ_MULTIPLE_RESPONSE; 849 return offset; 850} 851static uint16_t handle_read_multiple_request(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, 852 uint8_t * response_buffer, uint16_t response_buffer_size){ |
853 854 // 1 byte opcode + two or more attribute handles (2 bytes each) 855 if ( (request_len < 5) || ((request_len & 1) == 0) ) return setup_error_invalid_pdu(response_buffer, 856 ATT_READ_MULTIPLE_REQUEST); 857 |
|
827 int num_handles = (request_len - 1) >> 1; 828 return handle_read_multiple_request2(att_connection, response_buffer, response_buffer_size, num_handles, &request_buffer[1]); 829} 830 831// 832// MARK: ATT_READ_BY_GROUP_TYPE_REQUEST 0x10 833// 834// Only handles GATT_PRIMARY_SERVICE_UUID and GATT_SECONDARY_SERVICE_UUID --- 100 unchanged lines hidden (view full) --- 935 return setup_error_atribute_not_found(response_buffer, request_type, start_handle); 936 } 937 938 response_buffer[0] = ATT_READ_BY_GROUP_TYPE_RESPONSE; 939 return offset; 940} 941static uint16_t handle_read_by_group_type_request(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, 942 uint8_t * response_buffer, uint16_t response_buffer_size){ | 858 int num_handles = (request_len - 1) >> 1; 859 return handle_read_multiple_request2(att_connection, response_buffer, response_buffer_size, num_handles, &request_buffer[1]); 860} 861 862// 863// MARK: ATT_READ_BY_GROUP_TYPE_REQUEST 0x10 864// 865// Only handles GATT_PRIMARY_SERVICE_UUID and GATT_SECONDARY_SERVICE_UUID --- 100 unchanged lines hidden (view full) --- 966 return setup_error_atribute_not_found(response_buffer, request_type, start_handle); 967 } 968 969 response_buffer[0] = ATT_READ_BY_GROUP_TYPE_RESPONSE; 970 return offset; 971} 972static uint16_t handle_read_by_group_type_request(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, 973 uint8_t * response_buffer, uint16_t response_buffer_size){ |
943 int attribute_type_len; 944 if (request_len <= 7){ 945 attribute_type_len = 2; 946 } else { 947 attribute_type_len = 16; | 974 uint16_t attribute_type_len; 975 switch (request_len){ 976 case 7: 977 attribute_type_len = 2; 978 break; 979 case 21: 980 attribute_type_len = 16; 981 break; 982 default: 983 return setup_error_invalid_pdu(response_buffer, ATT_READ_BY_GROUP_TYPE_REQUEST); |
948 } | 984 } |
949 return handle_read_by_group_type_request2(att_connection, response_buffer, response_buffer_size, little_endian_read_16(request_buffer, 1), little_endian_read_16(request_buffer, 3), attribute_type_len, &request_buffer[5]); | 985 986 uint16_t start_handle = little_endian_read_16(request_buffer, 1); 987 uint16_t end_handle = little_endian_read_16(request_buffer, 3); 988 return handle_read_by_group_type_request2(att_connection, response_buffer, response_buffer_size, start_handle, end_handle, attribute_type_len, &request_buffer[5]); |
950} 951 952// 953// MARK: ATT_WRITE_REQUEST 0x12 954static uint16_t handle_write_request(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, 955 uint8_t * response_buffer, uint16_t response_buffer_size){ 956 957 UNUSED(response_buffer_size); --- 38 unchanged lines hidden (view full) --- 996// MARK: ATT_PREPARE_WRITE_REQUEST 0x16 997static uint16_t handle_prepare_write_request(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, 998 uint8_t * response_buffer, uint16_t response_buffer_size){ 999 1000 UNUSED(response_buffer_size); 1001 1002 uint8_t request_type = ATT_PREPARE_WRITE_REQUEST; 1003 | 989} 990 991// 992// MARK: ATT_WRITE_REQUEST 0x12 993static uint16_t handle_write_request(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, 994 uint8_t * response_buffer, uint16_t response_buffer_size){ 995 996 UNUSED(response_buffer_size); --- 38 unchanged lines hidden (view full) --- 1035// MARK: ATT_PREPARE_WRITE_REQUEST 0x16 1036static uint16_t handle_prepare_write_request(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, 1037 uint8_t * response_buffer, uint16_t response_buffer_size){ 1038 1039 UNUSED(response_buffer_size); 1040 1041 uint8_t request_type = ATT_PREPARE_WRITE_REQUEST; 1042 |
1043 if (request_len < 5) return setup_error_invalid_pdu(response_buffer, request_type); 1044 |
|
1004 uint16_t handle = little_endian_read_16(request_buffer, 1); 1005 uint16_t offset = little_endian_read_16(request_buffer, 3); 1006 if (att_write_callback == NULL) { 1007 return setup_error_write_not_permitted(response_buffer, request_type, handle); 1008 } 1009 att_iterator_t it; 1010 if (att_find_handle(&it, handle) == 0) { 1011 return setup_error_invalid_handle(response_buffer, request_type, handle); --- 40 unchanged lines hidden (view full) --- 1052 (*att_write_callback)(att_connection->con_handle, 0, ATT_TRANSACTION_MODE_CANCEL, 0, NULL, 0); 1053} 1054 1055// MARK: ATT_EXECUTE_WRITE_REQUEST 0x18 1056// NOTE: security has been verified by handle_prepare_write_request 1057static uint16_t handle_execute_write_request(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, 1058 uint8_t * response_buffer, uint16_t response_buffer_size){ 1059 | 1045 uint16_t handle = little_endian_read_16(request_buffer, 1); 1046 uint16_t offset = little_endian_read_16(request_buffer, 3); 1047 if (att_write_callback == NULL) { 1048 return setup_error_write_not_permitted(response_buffer, request_type, handle); 1049 } 1050 att_iterator_t it; 1051 if (att_find_handle(&it, handle) == 0) { 1052 return setup_error_invalid_handle(response_buffer, request_type, handle); --- 40 unchanged lines hidden (view full) --- 1093 (*att_write_callback)(att_connection->con_handle, 0, ATT_TRANSACTION_MODE_CANCEL, 0, NULL, 0); 1094} 1095 1096// MARK: ATT_EXECUTE_WRITE_REQUEST 0x18 1097// NOTE: security has been verified by handle_prepare_write_request 1098static uint16_t handle_execute_write_request(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, 1099 uint8_t * response_buffer, uint16_t response_buffer_size){ 1100 |
1060 UNUSED(request_len); | |
1061 UNUSED(response_buffer_size); | 1101 UNUSED(response_buffer_size); |
1062 | 1102 |
1063 uint8_t request_type = ATT_EXECUTE_WRITE_REQUEST; | 1103 uint8_t request_type = ATT_EXECUTE_WRITE_REQUEST; |
1104 1105 if (request_len < 2) return setup_error_invalid_pdu(response_buffer, request_type); 1106 |
|
1064 if (request_buffer[1]) { 1065 // validate queued write 1066 if (att_prepare_write_error_code == 0){ 1067 att_prepare_write_error_code = (*att_write_callback)(att_connection->con_handle, 0, ATT_TRANSACTION_MODE_VALIDATE, 0, NULL, 0); 1068 } 1069#ifdef ENABLE_ATT_DELAYED_RESPONSE 1070 if (att_prepare_write_error_code == ATT_ERROR_WRITE_RESPONSE_PENDING) return ATT_INTERNAL_WRITE_RESPONSE_PENDING; 1071#endif --- 13 unchanged lines hidden (view full) --- 1085 return 1; 1086} 1087 1088// MARK: ATT_WRITE_COMMAND 0x52 1089// Core 4.0, vol 3, part F, 3.4.5.3 1090// "No Error Response or Write Response shall be sent in response to this command" 1091static void handle_write_command(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, uint16_t required_flags){ 1092 | 1107 if (request_buffer[1]) { 1108 // validate queued write 1109 if (att_prepare_write_error_code == 0){ 1110 att_prepare_write_error_code = (*att_write_callback)(att_connection->con_handle, 0, ATT_TRANSACTION_MODE_VALIDATE, 0, NULL, 0); 1111 } 1112#ifdef ENABLE_ATT_DELAYED_RESPONSE 1113 if (att_prepare_write_error_code == ATT_ERROR_WRITE_RESPONSE_PENDING) return ATT_INTERNAL_WRITE_RESPONSE_PENDING; 1114#endif --- 13 unchanged lines hidden (view full) --- 1128 return 1; 1129} 1130 1131// MARK: ATT_WRITE_COMMAND 0x52 1132// Core 4.0, vol 3, part F, 3.4.5.3 1133// "No Error Response or Write Response shall be sent in response to this command" 1134static void handle_write_command(att_connection_t * att_connection, uint8_t * request_buffer, uint16_t request_len, uint16_t required_flags){ 1135 |
1136 if (request_len < 3) return; 1137 |
|
1093 uint16_t handle = little_endian_read_16(request_buffer, 1); 1094 if (att_write_callback == NULL) return; 1095 1096 att_iterator_t it; 1097 int ok = att_find_handle(&it, handle); 1098 if (!ok) return; 1099 if ((it.flags & ATT_PROPERTY_DYNAMIC) == 0) return; 1100 if ((it.flags & required_flags) == 0) return; --- 311 unchanged lines hidden --- | 1138 uint16_t handle = little_endian_read_16(request_buffer, 1); 1139 if (att_write_callback == NULL) return; 1140 1141 att_iterator_t it; 1142 int ok = att_find_handle(&it, handle); 1143 if (!ok) return; 1144 if ((it.flags & ATT_PROPERTY_DYNAMIC) == 0) return; 1145 if ((it.flags & required_flags) == 0) return; --- 311 unchanged lines hidden --- |