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 ---