|
| 1 | +#include <BTstack.h> |
| 2 | +#include <stdio.h> |
| 3 | +#include "ble/att_server.h" |
| 4 | +#include "ble/gatt_client.h" |
| 5 | +#include "ble/gatt-service/ancs_client.h" |
| 6 | +#include "ble/sm.h" |
| 7 | +#include "btstack_event.h" |
| 8 | +#include <SPI.h> |
| 9 | + |
| 10 | +/* |
| 11 | + EXAMPLE_START(ANCS): ANCS Client |
| 12 | +*/ |
| 13 | + |
| 14 | +/* |
| 15 | + @section Advertisement |
| 16 | + @text An ANCS Client needs to include the ANCS UUID in its advertisement to |
| 17 | + get recognized by iOS |
| 18 | +*/ |
| 19 | + |
| 20 | +/* LISTING_START(ANCSAdvertisement): ANCS Advertisement */ |
| 21 | +const uint8_t adv_data[] = { |
| 22 | + // Flags general discoverable |
| 23 | + 0x02, 0x01, 0x02, |
| 24 | + // Name |
| 25 | + 0x05, 0x09, 'A', 'N', 'C', 'S', |
| 26 | + // Service Solicitation, 128-bit UUIDs - ANCS (little endian) |
| 27 | + 0x11, 0x15, 0xD0, 0x00, 0x2D, 0x12, 0x1E, 0x4B, 0x0F, 0xA4, 0x99, 0x4E, 0xCE, 0xB5, 0x31, 0xF4, 0x05, 0x79 |
| 28 | +}; |
| 29 | +/* LISTING_END(ANCSAdvertisement): ANCS Advertisement */ |
| 30 | + |
| 31 | +/* |
| 32 | + @section Setup |
| 33 | +
|
| 34 | + @text In the setup, the LE Security Manager is configured to accept pairing requests. |
| 35 | + Then, the ANCS Client library is initialized and and ancs_callback registered. |
| 36 | + Finally, the Advertisement data is set and Advertisements are started. |
| 37 | +*/ |
| 38 | + |
| 39 | +/* LISTING_START(ANCSSetup): ANCS Setup */ |
| 40 | +void setup(void) { |
| 41 | + |
| 42 | + Serial.begin(9600); |
| 43 | + Serial.println("BTstack ANCS Client starting up..."); |
| 44 | + |
| 45 | + // startup BTstack and configure log_info/log_error |
| 46 | + BTstack.setup(); |
| 47 | + |
| 48 | + sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_ONLY); |
| 49 | + sm_set_authentication_requirements(SM_AUTHREQ_BONDING); |
| 50 | + |
| 51 | + // setup ANCS Client |
| 52 | + ancs_client_init(); |
| 53 | + ancs_client_register_callback(&ancs_callback); |
| 54 | + |
| 55 | + // enable advertisements |
| 56 | + BTstack.setAdvData(sizeof(adv_data), adv_data); |
| 57 | + BTstack.startAdvertising(); |
| 58 | +} |
| 59 | +/* LISTING_END(ANCSSetup): ANCS Setup */ |
| 60 | + |
| 61 | +void loop(void) { |
| 62 | + BTstack.loop(); |
| 63 | +} |
| 64 | + |
| 65 | +/* |
| 66 | + @section ANCS Callback |
| 67 | + @text In the ANCS Callback, connect and disconnect events are received. |
| 68 | + For actual notifications, ancs_client_attribute_name_for_id allows to |
| 69 | + look up the name. To get the notification body, e.g., the actual message, |
| 70 | + the GATT Client needs to be used directly. |
| 71 | +*/ |
| 72 | + |
| 73 | + |
| 74 | +/* LISTING_START(ANCSCallback): ANCS Callback */ |
| 75 | +void ancs_callback(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) { |
| 76 | + (void) packet_type; |
| 77 | + (void) channel; |
| 78 | + (void) size; |
| 79 | + const char * attribute_name; |
| 80 | + if (hci_event_packet_get_type(packet) != HCI_EVENT_ANCS_META) { |
| 81 | + return; |
| 82 | + } |
| 83 | + switch (hci_event_ancs_meta_get_subevent_code(packet)) { |
| 84 | + case ANCS_SUBEVENT_CLIENT_CONNECTED: |
| 85 | + Serial.println("ANCS Client: Connected"); |
| 86 | + break; |
| 87 | + case ANCS_SUBEVENT_CLIENT_DISCONNECTED: |
| 88 | + Serial.println("ANCS Client: Disconnected"); |
| 89 | + break; |
| 90 | + case ANCS_SUBEVENT_CLIENT_NOTIFICATION: |
| 91 | + attribute_name = ancs_client_attribute_name_for_id(ancs_subevent_client_notification_get_attribute_id(packet)); |
| 92 | + if (!attribute_name) { |
| 93 | + break; |
| 94 | + } |
| 95 | + Serial.print("Notification: "); |
| 96 | + Serial.print(attribute_name); |
| 97 | + Serial.print(" - "); |
| 98 | + Serial.println(ancs_subevent_client_notification_get_text(packet)); |
| 99 | + break; |
| 100 | + default: |
| 101 | + break; |
| 102 | + } |
| 103 | +} |
| 104 | +/* LISTING_END(ANCSCallback): ANCS Callback */ |
| 105 | + |
0 commit comments