gatt_client.c (d1e1a57fd30595f9308bed33297460ce1472a62e) | gatt_client.c (f4b33574b8b8a983cf5ba955722d7d498d69564f) |
---|---|
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 --- 52 unchanged lines hidden (view full) --- 61#include "hci_cmd.h" 62#include "hci_dump.h" 63#include "l2cap.h" 64 65static btstack_linked_list_t gatt_client_connections; 66static btstack_linked_list_t gatt_client_value_listeners; 67static btstack_packet_callback_registration_t hci_event_callback_registration; 68 | 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 --- 52 unchanged lines hidden (view full) --- 61#include "hci_cmd.h" 62#include "hci_dump.h" 63#include "l2cap.h" 64 65static btstack_linked_list_t gatt_client_connections; 66static btstack_linked_list_t gatt_client_value_listeners; 67static btstack_packet_callback_registration_t hci_event_callback_registration; 68 |
69#ifdef ENABLE_GATT_CLIENT_PAIRING 70static btstack_packet_callback_registration_t sm_event_callback_registration; 71#endif 72 |
|
69static uint8_t mtu_exchange_enabled; 70 71static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size); | 73static uint8_t mtu_exchange_enabled; 74 75static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size); |
72static void gatt_client_hci_event_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); | 76static void gatt_client_event_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); |
73static void gatt_client_report_error_if_pending(gatt_client_t *peripheral, uint8_t error_code); 74 75#ifdef ENABLE_LE_SIGNED_WRITE 76static void att_signed_write_handle_cmac_result(uint8_t hash[8]); 77#endif 78 79static uint16_t peripheral_mtu(gatt_client_t *peripheral){ 80 if (peripheral->mtu > l2cap_max_le_mtu()){ 81 log_error("Peripheral mtu is not initialized"); 82 return l2cap_max_le_mtu(); 83 } 84 return peripheral->mtu; 85} 86 87void gatt_client_init(void){ 88 gatt_client_connections = NULL; 89 mtu_exchange_enabled = 1; | 77static void gatt_client_report_error_if_pending(gatt_client_t *peripheral, uint8_t error_code); 78 79#ifdef ENABLE_LE_SIGNED_WRITE 80static void att_signed_write_handle_cmac_result(uint8_t hash[8]); 81#endif 82 83static uint16_t peripheral_mtu(gatt_client_t *peripheral){ 84 if (peripheral->mtu > l2cap_max_le_mtu()){ 85 log_error("Peripheral mtu is not initialized"); 86 return l2cap_max_le_mtu(); 87 } 88 return peripheral->mtu; 89} 90 91void gatt_client_init(void){ 92 gatt_client_connections = NULL; 93 mtu_exchange_enabled = 1; |
94 |
|
90 // regsister for HCI Events | 95 // regsister for HCI Events |
91 hci_event_callback_registration.callback = &gatt_client_hci_event_packet_handler; | 96 hci_event_callback_registration.callback = &gatt_client_event_packet_handler; |
92 hci_add_event_handler(&hci_event_callback_registration); 93 | 97 hci_add_event_handler(&hci_event_callback_registration); 98 |
99#ifdef ENABLE_GATT_CLIENT_PAIRING 100 // register for SM Events 101 sm_event_callback_registration.callback = &gatt_client_event_packet_handler; 102 sm_add_event_handler(&sm_event_callback_registration); 103#endif 104 |
|
94 // and ATT Client PDUs 95 att_dispatch_register_client(gatt_client_att_packet_handler); 96} 97 98static gatt_client_t * gatt_client_for_timer(btstack_timer_source_t * ts){ 99 btstack_linked_list_iterator_t it; 100 btstack_linked_list_iterator_init(&it, &gatt_client_connections); 101 while (btstack_linked_list_iterator_has_next(&it)){ --- 718 unchanged lines hidden (view full) --- 820 821// returns 1 if packet was sent 822static int gatt_client_run_for_peripheral( gatt_client_t * peripheral){ 823 // log_info("- handle_peripheral_list, mtu state %u, client state %u", peripheral->mtu_state, peripheral->gatt_client_state); 824 825 // wait until re-encryption as central is complete 826 if (gap_reconnect_security_setup_active(peripheral->con_handle)) return 0; 827 | 105 // and ATT Client PDUs 106 att_dispatch_register_client(gatt_client_att_packet_handler); 107} 108 109static gatt_client_t * gatt_client_for_timer(btstack_timer_source_t * ts){ 110 btstack_linked_list_iterator_t it; 111 btstack_linked_list_iterator_init(&it, &gatt_client_connections); 112 while (btstack_linked_list_iterator_has_next(&it)){ --- 718 unchanged lines hidden (view full) --- 831 832// returns 1 if packet was sent 833static int gatt_client_run_for_peripheral( gatt_client_t * peripheral){ 834 // log_info("- handle_peripheral_list, mtu state %u, client state %u", peripheral->mtu_state, peripheral->gatt_client_state); 835 836 // wait until re-encryption as central is complete 837 if (gap_reconnect_security_setup_active(peripheral->con_handle)) return 0; 838 |
839#ifdef ENABLE_GATT_CLIENT_PAIRING 840 // wait until pairing complete 841 if (peripheral->wait_for_pairing_complete) return 0; 842#endif 843 |
|
828 switch (peripheral->mtu_state) { 829 case SEND_MTU_EXCHANGE: 830 peripheral->mtu_state = SENT_MTU_EXCHANGE; 831 att_exchange_mtu_request(peripheral->con_handle); 832 return 1; 833 case SENT_MTU_EXCHANGE: 834 return 0; 835 default: --- 211 unchanged lines hidden (view full) --- 1047} 1048 1049static void gatt_client_report_error_if_pending(gatt_client_t *peripheral, uint8_t error_code) { 1050 if (is_ready(peripheral)) return; 1051 gatt_client_handle_transaction_complete(peripheral); 1052 emit_gatt_complete_event(peripheral, error_code); 1053} 1054 | 844 switch (peripheral->mtu_state) { 845 case SEND_MTU_EXCHANGE: 846 peripheral->mtu_state = SENT_MTU_EXCHANGE; 847 att_exchange_mtu_request(peripheral->con_handle); 848 return 1; 849 case SENT_MTU_EXCHANGE: 850 return 0; 851 default: --- 211 unchanged lines hidden (view full) --- 1063} 1064 1065static void gatt_client_report_error_if_pending(gatt_client_t *peripheral, uint8_t error_code) { 1066 if (is_ready(peripheral)) return; 1067 gatt_client_handle_transaction_complete(peripheral); 1068 emit_gatt_complete_event(peripheral, error_code); 1069} 1070 |
1055static void gatt_client_hci_event_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ | 1071static void gatt_client_event_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ |
1056 UNUSED(channel); // ok: handling own l2cap events 1057 UNUSED(size); // ok: there is no channel 1058 1059 if (packet_type != HCI_EVENT_PACKET) return; 1060 | 1072 UNUSED(channel); // ok: handling own l2cap events 1073 UNUSED(size); // ok: there is no channel 1074 1075 if (packet_type != HCI_EVENT_PACKET) return; 1076 |
1077 hci_con_handle_t con_handle; 1078 gatt_client_t * peripheral; |
|
1061 switch (hci_event_packet_get_type(packet)) { 1062 case HCI_EVENT_DISCONNECTION_COMPLETE: | 1079 switch (hci_event_packet_get_type(packet)) { 1080 case HCI_EVENT_DISCONNECTION_COMPLETE: |
1063 { | |
1064 log_info("GATT Client: HCI_EVENT_DISCONNECTION_COMPLETE"); | 1081 log_info("GATT Client: HCI_EVENT_DISCONNECTION_COMPLETE"); |
1065 hci_con_handle_t con_handle = little_endian_read_16(packet,3); 1066 gatt_client_t * peripheral = get_gatt_client_context_for_handle(con_handle); | 1082 con_handle = little_endian_read_16(packet,3); 1083 peripheral = get_gatt_client_context_for_handle(con_handle); |
1067 if (!peripheral) break; 1068 gatt_client_report_error_if_pending(peripheral, ATT_ERROR_HCI_DISCONNECT_RECEIVED); 1069 1070 btstack_linked_list_remove(&gatt_client_connections, (btstack_linked_item_t *) peripheral); 1071 btstack_memory_gatt_client_free(peripheral); 1072 break; | 1084 if (!peripheral) break; 1085 gatt_client_report_error_if_pending(peripheral, ATT_ERROR_HCI_DISCONNECT_RECEIVED); 1086 1087 btstack_linked_list_remove(&gatt_client_connections, (btstack_linked_item_t *) peripheral); 1088 btstack_memory_gatt_client_free(peripheral); 1089 break; |
1073 } | 1090 1091#ifdef ENABLE_GATT_CLIENT_PAIRING 1092 // Pairing complete (with/without bonding=storing of pairing information) 1093 case SM_EVENT_PAIRING_COMPLETE: 1094 con_handle = sm_event_pairing_complete_get_handle(packet); 1095 peripheral = get_gatt_client_context_for_handle(con_handle); 1096 if (!peripheral) break; 1097 1098 if (peripheral->wait_for_pairing_complete){ 1099 peripheral->wait_for_pairing_complete = 0; 1100 if (sm_event_pairing_complete_get_status(packet)){ 1101 log_info("pairing failed, report previous error 0x%x", peripheral->pending_error_code); 1102 gatt_client_handle_transaction_complete(peripheral); 1103 emit_gatt_complete_event(peripheral, peripheral->pending_error_code); 1104 } else { 1105 log_info("pairing success, retry operation"); 1106 } 1107 } 1108 break; 1109#endif 1110 |
1074 default: 1075 break; 1076 } 1077 1078 gatt_client_run(); 1079} 1080 1081static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){ --- 314 unchanged lines hidden (view full) --- 1396 } 1397 break; 1398 default: 1399 gatt_client_report_error_if_pending(peripheral, packet[4]); 1400 break; 1401 } 1402 break; 1403 } | 1111 default: 1112 break; 1113 } 1114 1115 gatt_client_run(); 1116} 1117 1118static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){ --- 314 unchanged lines hidden (view full) --- 1433 } 1434 break; 1435 default: 1436 gatt_client_report_error_if_pending(peripheral, packet[4]); 1437 break; 1438 } 1439 break; 1440 } |
1404 default: | 1441 1442#ifdef ENABLE_GATT_CLIENT_PAIRING 1443 1444 case ATT_ERROR_INSUFFICIENT_AUTHENTICATION: 1445 case ATT_ERROR_INSUFFICIENT_ENCRYPTION_KEY_SIZE: 1446 case ATT_ERROR_INSUFFICIENT_ENCRYPTION: 1447 // security too low 1448 if (peripheral->security_counter > 0) { 1449 gatt_client_report_error_if_pending(peripheral, packet[4]); 1450 break; 1451 } 1452 // start security 1453 peripheral->security_counter++; 1454 1455 // setup action 1456 int retry = 1; 1457 switch (peripheral->gatt_client_state){ 1458 case P_W4_READ_CHARACTERISTIC_VALUE_RESULT: 1459 peripheral->gatt_client_state = P_W2_SEND_READ_CHARACTERISTIC_VALUE_QUERY ; 1460 break; 1461 case P_W4_READ_BLOB_RESULT: 1462 peripheral->gatt_client_state = P_W2_SEND_READ_BLOB_QUERY; 1463 break; 1464 case P_W4_READ_BY_TYPE_RESPONSE: 1465 peripheral->gatt_client_state = P_W2_SEND_READ_BY_TYPE_REQUEST; 1466 break; 1467 case P_W4_READ_MULTIPLE_RESPONSE: 1468 peripheral->gatt_client_state = P_W2_SEND_READ_MULTIPLE_REQUEST; 1469 break; 1470 case P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT: 1471 peripheral->gatt_client_state = P_W2_SEND_WRITE_CHARACTERISTIC_VALUE; 1472 break; 1473 case P_W4_PREPARE_WRITE_RESULT: 1474 peripheral->gatt_client_state = P_W2_PREPARE_WRITE; 1475 break; 1476 case P_W4_PREPARE_WRITE_SINGLE_RESULT: 1477 peripheral->gatt_client_state = P_W2_PREPARE_WRITE_SINGLE; 1478 break; 1479 case P_W4_PREPARE_RELIABLE_WRITE_RESULT: 1480 peripheral->gatt_client_state = P_W2_PREPARE_RELIABLE_WRITE; 1481 break; 1482 case P_W4_EXECUTE_PREPARED_WRITE_RESULT: 1483 peripheral->gatt_client_state = P_W2_EXECUTE_PREPARED_WRITE; 1484 break; 1485 case P_W4_CANCEL_PREPARED_WRITE_RESULT: 1486 peripheral->gatt_client_state = P_W2_CANCEL_PREPARED_WRITE; 1487 break; 1488 case P_W4_CANCEL_PREPARED_WRITE_DATA_MISMATCH_RESULT: 1489 peripheral->gatt_client_state = P_W2_CANCEL_PREPARED_WRITE_DATA_MISMATCH; 1490 break; 1491 case P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT: 1492 peripheral->gatt_client_state = P_W2_SEND_READ_CHARACTERISTIC_DESCRIPTOR_QUERY; 1493 break; 1494 case P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT: 1495 peripheral->gatt_client_state = P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY; 1496 break; 1497 case P_W4_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT: 1498 peripheral->gatt_client_state = P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR; 1499 break; 1500 case P_W4_CLIENT_CHARACTERISTIC_CONFIGURATION_RESULT: 1501 peripheral->gatt_client_state = P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION; 1502 break; 1503 case P_W4_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT: 1504 peripheral->gatt_client_state = P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR; 1505 break; 1506 case P_W4_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT: 1507 peripheral->gatt_client_state = P_W2_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR; 1508 break; 1509#ifdef ENABLE_LE_SIGNED_WRITE 1510 case P_W4_SEND_SINGED_WRITE_DONE: 1511 peripheral->gatt_client_state = P_W2_SEND_SIGNED_WRITE; 1512 break; 1513#endif 1514 default: 1515 log_info("retry not supported for state %x", peripheral->gatt_client_state); 1516 retry = 0; 1517 break; 1518 } 1519 1520 if (!retry) { 1521 gatt_client_report_error_if_pending(peripheral, packet[4]); 1522 break; 1523 } 1524 1525 log_info("security error, start pairing"); 1526 1527 // requrest pairing 1528 peripheral->wait_for_pairing_complete = 1; 1529 peripheral->pending_error_code = packet[4]; 1530 sm_request_pairing(peripheral->con_handle); 1531 break; 1532#endif 1533 1534 // nothing we can do about that 1535 case ATT_ERROR_INSUFFICIENT_AUTHORIZATION: 1536 default: |
1405 gatt_client_report_error_if_pending(peripheral, packet[4]); 1406 break; 1407 } 1408 break; 1409 1410 default: 1411 log_info("ATT Handler, unhandled response type 0x%02x", packet[0]); 1412 break; --- 542 unchanged lines hidden --- | 1537 gatt_client_report_error_if_pending(peripheral, packet[4]); 1538 break; 1539 } 1540 break; 1541 1542 default: 1543 log_info("ATT Handler, unhandled response type 0x%02x", packet[0]); 1544 break; --- 542 unchanged lines hidden --- |