gatt_client.c (9305033e0290a73b79a29900c5b9f35f77d880b1) | gatt_client.c (1979f09cf045e87f55a9cd8067e8ef902cc8d78b) |
---|---|
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 --- 869 unchanged lines hidden (view full) --- 878 uint16_t value_offset = little_endian_read_16(packet, 3); 879 880 if (gatt_client->attribute_handle != attribute_handle) return 0; 881 if (gatt_client->attribute_offset != value_offset) return 0; 882 return memcmp(&gatt_client->attribute_value[gatt_client->attribute_offset], &packet[5], size - 5u) == 0u; 883} 884 885// returns 1 if packet was sent | 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 --- 869 unchanged lines hidden (view full) --- 878 uint16_t value_offset = little_endian_read_16(packet, 3); 879 880 if (gatt_client->attribute_handle != attribute_handle) return 0; 881 if (gatt_client->attribute_offset != value_offset) return 0; 882 return memcmp(&gatt_client->attribute_value[gatt_client->attribute_offset], &packet[5], size - 5u) == 0u; 883} 884 885// returns 1 if packet was sent |
886static int gatt_client_run_for_gatt_client(gatt_client_t * gatt_client){ | 886static bool gatt_client_run_for_gatt_client(gatt_client_t * gatt_client){ |
887 888 // wait until re-encryption is complete | 887 888 // wait until re-encryption is complete |
889 if (gap_reconnect_security_setup_active(gatt_client->con_handle)) return 0; | 889 if (gap_reconnect_security_setup_active(gatt_client->con_handle)) return false; |
890 891 // wait until re-encryption is complete | 890 891 // wait until re-encryption is complete |
892 if (gatt_client->reencryption_active) return 0; | 892 if (gatt_client->reencryption_active) return false; |
893 894 // wait until pairing complete (either reactive authentication or due to required security level) | 893 894 // wait until pairing complete (either reactive authentication or due to required security level) |
895 if (gatt_client->wait_for_authentication_complete) return 0; | 895 if (gatt_client->wait_for_authentication_complete) return false; |
896 897 bool client_request_pending = gatt_client->gatt_client_state != P_READY; 898 899 // verify security level for Mandatory Authentication 900 if (client_request_pending && (gatt_client_required_security_level > gatt_client->security_level)){ 901 log_info("Trigger pairing, current security level %u, required %u\n", gatt_client->security_level, gatt_client_required_security_level); 902 gatt_client->wait_for_authentication_complete = 1; 903 // set att error code for pairing failure based on required level 904 switch (gatt_client_required_security_level){ 905 case LEVEL_4: 906 case LEVEL_3: 907 gatt_client->pending_error_code = ATT_ERROR_INSUFFICIENT_AUTHENTICATION; 908 break; 909 default: 910 gatt_client->pending_error_code = ATT_ERROR_INSUFFICIENT_ENCRYPTION; 911 break; 912 } 913 sm_request_pairing(gatt_client->con_handle); 914 // sm probably just sent a pdu | 896 897 bool client_request_pending = gatt_client->gatt_client_state != P_READY; 898 899 // verify security level for Mandatory Authentication 900 if (client_request_pending && (gatt_client_required_security_level > gatt_client->security_level)){ 901 log_info("Trigger pairing, current security level %u, required %u\n", gatt_client->security_level, gatt_client_required_security_level); 902 gatt_client->wait_for_authentication_complete = 1; 903 // set att error code for pairing failure based on required level 904 switch (gatt_client_required_security_level){ 905 case LEVEL_4: 906 case LEVEL_3: 907 gatt_client->pending_error_code = ATT_ERROR_INSUFFICIENT_AUTHENTICATION; 908 break; 909 default: 910 gatt_client->pending_error_code = ATT_ERROR_INSUFFICIENT_ENCRYPTION; 911 break; 912 } 913 sm_request_pairing(gatt_client->con_handle); 914 // sm probably just sent a pdu |
915 return 1; | 915 return true; |
916 } 917 918 switch (gatt_client->mtu_state) { 919 case SEND_MTU_EXCHANGE: 920 gatt_client->mtu_state = SENT_MTU_EXCHANGE; 921 att_exchange_mtu_request(gatt_client->con_handle); | 916 } 917 918 switch (gatt_client->mtu_state) { 919 case SEND_MTU_EXCHANGE: 920 gatt_client->mtu_state = SENT_MTU_EXCHANGE; 921 att_exchange_mtu_request(gatt_client->con_handle); |
922 return 1; | 922 return true; |
923 case SENT_MTU_EXCHANGE: | 923 case SENT_MTU_EXCHANGE: |
924 return 0; | 924 return false; |
925 default: 926 break; 927 } 928 929 if (gatt_client->send_confirmation){ 930 gatt_client->send_confirmation = 0; 931 att_confirmation(gatt_client->con_handle); | 925 default: 926 break; 927 } 928 929 if (gatt_client->send_confirmation){ 930 gatt_client->send_confirmation = 0; 931 att_confirmation(gatt_client->con_handle); |
932 return 1; | 932 return true; |
933 } 934 935 // check MTU for writes 936 switch (gatt_client->gatt_client_state){ 937 case P_W2_SEND_WRITE_CHARACTERISTIC_VALUE: 938 case P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR: 939 if (gatt_client->attribute_length <= (gatt_client->mtu - 3u)) break; 940 log_error("gatt_client_run: value len %u > MTU %u - 3\n", gatt_client->attribute_length,gatt_client->mtu); 941 gatt_client_handle_transaction_complete(gatt_client); 942 emit_gatt_complete_event(gatt_client, ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LENGTH); | 933 } 934 935 // check MTU for writes 936 switch (gatt_client->gatt_client_state){ 937 case P_W2_SEND_WRITE_CHARACTERISTIC_VALUE: 938 case P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR: 939 if (gatt_client->attribute_length <= (gatt_client->mtu - 3u)) break; 940 log_error("gatt_client_run: value len %u > MTU %u - 3\n", gatt_client->attribute_length,gatt_client->mtu); 941 gatt_client_handle_transaction_complete(gatt_client); 942 emit_gatt_complete_event(gatt_client, ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LENGTH); |
943 return 0; | 943 return false; |
944 default: 945 break; 946 } 947 948 switch (gatt_client->gatt_client_state){ 949 case P_W2_SEND_SERVICE_QUERY: 950 gatt_client->gatt_client_state = P_W4_SERVICE_QUERY_RESULT; 951 send_gatt_services_request(gatt_client); | 944 default: 945 break; 946 } 947 948 switch (gatt_client->gatt_client_state){ 949 case P_W2_SEND_SERVICE_QUERY: 950 gatt_client->gatt_client_state = P_W4_SERVICE_QUERY_RESULT; 951 send_gatt_services_request(gatt_client); |
952 return 1; | 952 return true; |
953 954 case P_W2_SEND_SERVICE_WITH_UUID_QUERY: 955 gatt_client->gatt_client_state = P_W4_SERVICE_WITH_UUID_RESULT; 956 send_gatt_services_by_uuid_request(gatt_client); | 953 954 case P_W2_SEND_SERVICE_WITH_UUID_QUERY: 955 gatt_client->gatt_client_state = P_W4_SERVICE_WITH_UUID_RESULT; 956 send_gatt_services_by_uuid_request(gatt_client); |
957 return 1; | 957 return true; |
958 959 case P_W2_SEND_ALL_CHARACTERISTICS_OF_SERVICE_QUERY: 960 gatt_client->gatt_client_state = P_W4_ALL_CHARACTERISTICS_OF_SERVICE_QUERY_RESULT; 961 send_gatt_characteristic_request(gatt_client); | 958 959 case P_W2_SEND_ALL_CHARACTERISTICS_OF_SERVICE_QUERY: 960 gatt_client->gatt_client_state = P_W4_ALL_CHARACTERISTICS_OF_SERVICE_QUERY_RESULT; 961 send_gatt_characteristic_request(gatt_client); |
962 return 1; | 962 return true; |
963 964 case P_W2_SEND_CHARACTERISTIC_WITH_UUID_QUERY: 965 gatt_client->gatt_client_state = P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT; 966 send_gatt_characteristic_request(gatt_client); | 963 964 case P_W2_SEND_CHARACTERISTIC_WITH_UUID_QUERY: 965 gatt_client->gatt_client_state = P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT; 966 send_gatt_characteristic_request(gatt_client); |
967 return 1; | 967 return true; |
968 969 case P_W2_SEND_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY: 970 gatt_client->gatt_client_state = P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT; 971 send_gatt_characteristic_descriptor_request(gatt_client); | 968 969 case P_W2_SEND_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY: 970 gatt_client->gatt_client_state = P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT; 971 send_gatt_characteristic_descriptor_request(gatt_client); |
972 return 1; | 972 return true; |
973 974 case P_W2_SEND_INCLUDED_SERVICE_QUERY: 975 gatt_client->gatt_client_state = P_W4_INCLUDED_SERVICE_QUERY_RESULT; 976 send_gatt_included_service_request(gatt_client); | 973 974 case P_W2_SEND_INCLUDED_SERVICE_QUERY: 975 gatt_client->gatt_client_state = P_W4_INCLUDED_SERVICE_QUERY_RESULT; 976 send_gatt_included_service_request(gatt_client); |
977 return 1; | 977 return true; |
978 979 case P_W2_SEND_INCLUDED_SERVICE_WITH_UUID_QUERY: 980 gatt_client->gatt_client_state = P_W4_INCLUDED_SERVICE_UUID_WITH_QUERY_RESULT; 981 send_gatt_included_service_uuid_request(gatt_client); | 978 979 case P_W2_SEND_INCLUDED_SERVICE_WITH_UUID_QUERY: 980 gatt_client->gatt_client_state = P_W4_INCLUDED_SERVICE_UUID_WITH_QUERY_RESULT; 981 send_gatt_included_service_uuid_request(gatt_client); |
982 return 1; | 982 return true; |
983 984 case P_W2_SEND_READ_CHARACTERISTIC_VALUE_QUERY: 985 gatt_client->gatt_client_state = P_W4_READ_CHARACTERISTIC_VALUE_RESULT; 986 send_gatt_read_characteristic_value_request(gatt_client); | 983 984 case P_W2_SEND_READ_CHARACTERISTIC_VALUE_QUERY: 985 gatt_client->gatt_client_state = P_W4_READ_CHARACTERISTIC_VALUE_RESULT; 986 send_gatt_read_characteristic_value_request(gatt_client); |
987 return 1; | 987 return true; |
988 989 case P_W2_SEND_READ_BLOB_QUERY: 990 gatt_client->gatt_client_state = P_W4_READ_BLOB_RESULT; 991 send_gatt_read_blob_request(gatt_client); | 988 989 case P_W2_SEND_READ_BLOB_QUERY: 990 gatt_client->gatt_client_state = P_W4_READ_BLOB_RESULT; 991 send_gatt_read_blob_request(gatt_client); |
992 return 1; | 992 return true; |
993 994 case P_W2_SEND_READ_BY_TYPE_REQUEST: 995 gatt_client->gatt_client_state = P_W4_READ_BY_TYPE_RESPONSE; 996 send_gatt_read_by_type_request(gatt_client); | 993 994 case P_W2_SEND_READ_BY_TYPE_REQUEST: 995 gatt_client->gatt_client_state = P_W4_READ_BY_TYPE_RESPONSE; 996 send_gatt_read_by_type_request(gatt_client); |
997 return 1; | 997 return true; |
998 999 case P_W2_SEND_READ_MULTIPLE_REQUEST: 1000 gatt_client->gatt_client_state = P_W4_READ_MULTIPLE_RESPONSE; 1001 send_gatt_read_multiple_request(gatt_client); | 998 999 case P_W2_SEND_READ_MULTIPLE_REQUEST: 1000 gatt_client->gatt_client_state = P_W4_READ_MULTIPLE_RESPONSE; 1001 send_gatt_read_multiple_request(gatt_client); |
1002 return 1; | 1002 return true; |
1003 1004 case P_W2_SEND_WRITE_CHARACTERISTIC_VALUE: 1005 gatt_client->gatt_client_state = P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT; 1006 send_gatt_write_attribute_value_request(gatt_client); | 1003 1004 case P_W2_SEND_WRITE_CHARACTERISTIC_VALUE: 1005 gatt_client->gatt_client_state = P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT; 1006 send_gatt_write_attribute_value_request(gatt_client); |
1007 return 1; | 1007 return true; |
1008 1009 case P_W2_PREPARE_WRITE: 1010 gatt_client->gatt_client_state = P_W4_PREPARE_WRITE_RESULT; 1011 send_gatt_prepare_write_request(gatt_client); | 1008 1009 case P_W2_PREPARE_WRITE: 1010 gatt_client->gatt_client_state = P_W4_PREPARE_WRITE_RESULT; 1011 send_gatt_prepare_write_request(gatt_client); |
1012 return 1; | 1012 return true; |
1013 1014 case P_W2_PREPARE_WRITE_SINGLE: 1015 gatt_client->gatt_client_state = P_W4_PREPARE_WRITE_SINGLE_RESULT; 1016 send_gatt_prepare_write_request(gatt_client); | 1013 1014 case P_W2_PREPARE_WRITE_SINGLE: 1015 gatt_client->gatt_client_state = P_W4_PREPARE_WRITE_SINGLE_RESULT; 1016 send_gatt_prepare_write_request(gatt_client); |
1017 return 1; | 1017 return true; |
1018 1019 case P_W2_PREPARE_RELIABLE_WRITE: 1020 gatt_client->gatt_client_state = P_W4_PREPARE_RELIABLE_WRITE_RESULT; 1021 send_gatt_prepare_write_request(gatt_client); | 1018 1019 case P_W2_PREPARE_RELIABLE_WRITE: 1020 gatt_client->gatt_client_state = P_W4_PREPARE_RELIABLE_WRITE_RESULT; 1021 send_gatt_prepare_write_request(gatt_client); |
1022 return 1; | 1022 return true; |
1023 1024 case P_W2_EXECUTE_PREPARED_WRITE: 1025 gatt_client->gatt_client_state = P_W4_EXECUTE_PREPARED_WRITE_RESULT; 1026 send_gatt_execute_write_request(gatt_client); | 1023 1024 case P_W2_EXECUTE_PREPARED_WRITE: 1025 gatt_client->gatt_client_state = P_W4_EXECUTE_PREPARED_WRITE_RESULT; 1026 send_gatt_execute_write_request(gatt_client); |
1027 return 1; | 1027 return true; |
1028 1029 case P_W2_CANCEL_PREPARED_WRITE: 1030 gatt_client->gatt_client_state = P_W4_CANCEL_PREPARED_WRITE_RESULT; 1031 send_gatt_cancel_prepared_write_request(gatt_client); | 1028 1029 case P_W2_CANCEL_PREPARED_WRITE: 1030 gatt_client->gatt_client_state = P_W4_CANCEL_PREPARED_WRITE_RESULT; 1031 send_gatt_cancel_prepared_write_request(gatt_client); |
1032 return 1; | 1032 return true; |
1033 1034 case P_W2_CANCEL_PREPARED_WRITE_DATA_MISMATCH: 1035 gatt_client->gatt_client_state = P_W4_CANCEL_PREPARED_WRITE_DATA_MISMATCH_RESULT; 1036 send_gatt_cancel_prepared_write_request(gatt_client); | 1033 1034 case P_W2_CANCEL_PREPARED_WRITE_DATA_MISMATCH: 1035 gatt_client->gatt_client_state = P_W4_CANCEL_PREPARED_WRITE_DATA_MISMATCH_RESULT; 1036 send_gatt_cancel_prepared_write_request(gatt_client); |
1037 return 1; | 1037 return true; |
1038 1039#ifdef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY 1040 case P_W2_SEND_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY: 1041 // use Find Information 1042 gatt_client->gatt_client_state = P_W4_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT; 1043 send_gatt_characteristic_descriptor_request(gatt_client); 1044#else 1045 case P_W2_SEND_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY: 1046 // Use Read By Type 1047 gatt_client->gatt_client_state = P_W4_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT; 1048 send_gatt_read_client_characteristic_configuration_request(gatt_client); 1049#endif | 1038 1039#ifdef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY 1040 case P_W2_SEND_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY: 1041 // use Find Information 1042 gatt_client->gatt_client_state = P_W4_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT; 1043 send_gatt_characteristic_descriptor_request(gatt_client); 1044#else 1045 case P_W2_SEND_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY: 1046 // Use Read By Type 1047 gatt_client->gatt_client_state = P_W4_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT; 1048 send_gatt_read_client_characteristic_configuration_request(gatt_client); 1049#endif |
1050 return 1; | 1050 return true; |
1051 1052 case P_W2_SEND_READ_CHARACTERISTIC_DESCRIPTOR_QUERY: 1053 gatt_client->gatt_client_state = P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT; 1054 send_gatt_read_characteristic_descriptor_request(gatt_client); | 1051 1052 case P_W2_SEND_READ_CHARACTERISTIC_DESCRIPTOR_QUERY: 1053 gatt_client->gatt_client_state = P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT; 1054 send_gatt_read_characteristic_descriptor_request(gatt_client); |
1055 return 1; | 1055 return true; |
1056 1057 case P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY: 1058 gatt_client->gatt_client_state = P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT; 1059 send_gatt_read_blob_request(gatt_client); | 1056 1057 case P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY: 1058 gatt_client->gatt_client_state = P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT; 1059 send_gatt_read_blob_request(gatt_client); |
1060 return 1; | 1060 return true; |
1061 1062 case P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR: 1063 gatt_client->gatt_client_state = P_W4_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT; 1064 send_gatt_write_attribute_value_request(gatt_client); | 1061 1062 case P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR: 1063 gatt_client->gatt_client_state = P_W4_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT; 1064 send_gatt_write_attribute_value_request(gatt_client); |
1065 return 1; | 1065 return true; |
1066 1067 case P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION: 1068 gatt_client->gatt_client_state = P_W4_CLIENT_CHARACTERISTIC_CONFIGURATION_RESULT; 1069 send_gatt_write_client_characteristic_configuration_request(gatt_client); | 1066 1067 case P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION: 1068 gatt_client->gatt_client_state = P_W4_CLIENT_CHARACTERISTIC_CONFIGURATION_RESULT; 1069 send_gatt_write_client_characteristic_configuration_request(gatt_client); |
1070 return 1; | 1070 return true; |
1071 1072 case P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR: 1073 gatt_client->gatt_client_state = P_W4_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT; 1074 send_gatt_prepare_write_request(gatt_client); | 1071 1072 case P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR: 1073 gatt_client->gatt_client_state = P_W4_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT; 1074 send_gatt_prepare_write_request(gatt_client); |
1075 return 1; | 1075 return true; |
1076 1077 case P_W2_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR: 1078 gatt_client->gatt_client_state = P_W4_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT; 1079 send_gatt_execute_write_request(gatt_client); | 1076 1077 case P_W2_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR: 1078 gatt_client->gatt_client_state = P_W4_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT; 1079 send_gatt_execute_write_request(gatt_client); |
1080 return 1; | 1080 return true; |
1081 1082#ifdef ENABLE_LE_SIGNED_WRITE 1083 case P_W4_IDENTITY_RESOLVING: 1084 log_info("P_W4_IDENTITY_RESOLVING - state %x", sm_identity_resolving_state(gatt_client->con_handle)); 1085 switch (sm_identity_resolving_state(gatt_client->con_handle)){ 1086 case IRK_LOOKUP_SUCCEEDED: 1087 gatt_client->le_device_index = sm_le_device_index(gatt_client->con_handle); 1088 gatt_client->gatt_client_state = P_W4_CMAC_READY; 1089 break; 1090 case IRK_LOOKUP_FAILED: 1091 gatt_client_handle_transaction_complete(gatt_client); 1092 emit_gatt_complete_event(gatt_client, ATT_ERROR_BONDING_INFORMATION_MISSING); | 1081 1082#ifdef ENABLE_LE_SIGNED_WRITE 1083 case P_W4_IDENTITY_RESOLVING: 1084 log_info("P_W4_IDENTITY_RESOLVING - state %x", sm_identity_resolving_state(gatt_client->con_handle)); 1085 switch (sm_identity_resolving_state(gatt_client->con_handle)){ 1086 case IRK_LOOKUP_SUCCEEDED: 1087 gatt_client->le_device_index = sm_le_device_index(gatt_client->con_handle); 1088 gatt_client->gatt_client_state = P_W4_CMAC_READY; 1089 break; 1090 case IRK_LOOKUP_FAILED: 1091 gatt_client_handle_transaction_complete(gatt_client); 1092 emit_gatt_complete_event(gatt_client, ATT_ERROR_BONDING_INFORMATION_MISSING); |
1093 return 0; | 1093 return false; |
1094 default: | 1094 default: |
1095 return 0; | 1095 return false; |
1096 } 1097 1098 /* Fall through */ 1099 1100 case P_W4_CMAC_READY: 1101 if (sm_cmac_ready()){ 1102 sm_key_t csrk; 1103 le_device_db_local_csrk_get(gatt_client->le_device_index, csrk); 1104 uint32_t sign_counter = le_device_db_local_counter_get(gatt_client->le_device_index); 1105 gatt_client->gatt_client_state = P_W4_CMAC_RESULT; 1106 sm_cmac_signed_write_start(csrk, ATT_SIGNED_WRITE_COMMAND, gatt_client->attribute_handle, gatt_client->attribute_length, gatt_client->attribute_value, sign_counter, att_signed_write_handle_cmac_result); 1107 } | 1096 } 1097 1098 /* Fall through */ 1099 1100 case P_W4_CMAC_READY: 1101 if (sm_cmac_ready()){ 1102 sm_key_t csrk; 1103 le_device_db_local_csrk_get(gatt_client->le_device_index, csrk); 1104 uint32_t sign_counter = le_device_db_local_counter_get(gatt_client->le_device_index); 1105 gatt_client->gatt_client_state = P_W4_CMAC_RESULT; 1106 sm_cmac_signed_write_start(csrk, ATT_SIGNED_WRITE_COMMAND, gatt_client->attribute_handle, gatt_client->attribute_length, gatt_client->attribute_value, sign_counter, att_signed_write_handle_cmac_result); 1107 } |
1108 return 0; | 1108 return false; |
1109 1110 case P_W2_SEND_SIGNED_WRITE: { 1111 gatt_client->gatt_client_state = P_W4_SEND_SINGED_WRITE_DONE; 1112 // bump local signing counter 1113 uint32_t sign_counter = le_device_db_local_counter_get(gatt_client->le_device_index); 1114 le_device_db_local_counter_set(gatt_client->le_device_index, sign_counter + 1); 1115 // send signed write command 1116 send_gatt_signed_write_request(gatt_client, sign_counter); 1117 // finally, notifiy client that write is complete 1118 gatt_client_handle_transaction_complete(gatt_client); 1119 emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS); | 1109 1110 case P_W2_SEND_SIGNED_WRITE: { 1111 gatt_client->gatt_client_state = P_W4_SEND_SINGED_WRITE_DONE; 1112 // bump local signing counter 1113 uint32_t sign_counter = le_device_db_local_counter_get(gatt_client->le_device_index); 1114 le_device_db_local_counter_set(gatt_client->le_device_index, sign_counter + 1); 1115 // send signed write command 1116 send_gatt_signed_write_request(gatt_client, sign_counter); 1117 // finally, notifiy client that write is complete 1118 gatt_client_handle_transaction_complete(gatt_client); 1119 emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS); |
1120 return 1; | 1120 return true; |
1121 } 1122#endif 1123 default: 1124 break; 1125 } 1126 1127 // requested can send snow? 1128 if (gatt_client->write_without_response_callback){ 1129 btstack_packet_handler_t packet_handler = gatt_client->write_without_response_callback; 1130 gatt_client->write_without_response_callback = NULL; 1131 uint8_t event[4]; 1132 event[0] = GATT_EVENT_CAN_WRITE_WITHOUT_RESPONSE; 1133 event[1] = sizeof(event) - 2u; 1134 little_endian_store_16(event, 2, gatt_client->con_handle); 1135 packet_handler(HCI_EVENT_PACKET, gatt_client->con_handle, event, sizeof(event)); | 1121 } 1122#endif 1123 default: 1124 break; 1125 } 1126 1127 // requested can send snow? 1128 if (gatt_client->write_without_response_callback){ 1129 btstack_packet_handler_t packet_handler = gatt_client->write_without_response_callback; 1130 gatt_client->write_without_response_callback = NULL; 1131 uint8_t event[4]; 1132 event[0] = GATT_EVENT_CAN_WRITE_WITHOUT_RESPONSE; 1133 event[1] = sizeof(event) - 2u; 1134 little_endian_store_16(event, 2, gatt_client->con_handle); 1135 packet_handler(HCI_EVENT_PACKET, gatt_client->con_handle, event, sizeof(event)); |
1136 return 1; // to trigger requeueing (even if higher layer didn't sent) | 1136 return true; // to trigger requeueing (even if higher layer didn't sent) |
1137 } 1138 | 1137 } 1138 |
1139 return 0; | 1139 return false; |
1140} 1141 1142static void gatt_client_run(void){ 1143 btstack_linked_item_t *it; 1144 for (it = (btstack_linked_item_t *) gatt_client_connections; it != NULL; it = it->next){ 1145 gatt_client_t * gatt_client = (gatt_client_t *) it; 1146 if (!att_dispatch_client_can_send_now(gatt_client->con_handle)) { 1147 att_dispatch_client_request_can_send_now_event(gatt_client->con_handle); 1148 return; 1149 } | 1140} 1141 1142static void gatt_client_run(void){ 1143 btstack_linked_item_t *it; 1144 for (it = (btstack_linked_item_t *) gatt_client_connections; it != NULL; it = it->next){ 1145 gatt_client_t * gatt_client = (gatt_client_t *) it; 1146 if (!att_dispatch_client_can_send_now(gatt_client->con_handle)) { 1147 att_dispatch_client_request_can_send_now_event(gatt_client->con_handle); 1148 return; 1149 } |
1150 int packet_sent = gatt_client_run_for_gatt_client(gatt_client); | 1150 bool packet_sent = gatt_client_run_for_gatt_client(gatt_client); |
1151 if (packet_sent){ 1152 // request new permission 1153 att_dispatch_client_request_can_send_now_event(gatt_client->con_handle); 1154 // requeue client for fairness and exit 1155 // note: iterator has become invalid 1156 btstack_linked_list_remove(&gatt_client_connections, (btstack_linked_item_t *) gatt_client); 1157 btstack_linked_list_add_tail(&gatt_client_connections, (btstack_linked_item_t *) gatt_client); 1158 return; --- 1134 unchanged lines hidden --- | 1151 if (packet_sent){ 1152 // request new permission 1153 att_dispatch_client_request_can_send_now_event(gatt_client->con_handle); 1154 // requeue client for fairness and exit 1155 // note: iterator has become invalid 1156 btstack_linked_list_remove(&gatt_client_connections, (btstack_linked_item_t *) gatt_client); 1157 btstack_linked_list_add_tail(&gatt_client_connections, (btstack_linked_item_t *) gatt_client); 1158 return; --- 1134 unchanged lines hidden --- |