18caefee3SMatthias Ringwald#include <BTstack.h> 28caefee3SMatthias Ringwald#include <stdio.h> 33edc84c5SMatthias Ringwald#include "ble/att_server.h" 43edc84c5SMatthias Ringwald#include "ble/gatt_client.h" 5*690999b0SMatthias Ringwald#include "ble/gatt-service/ancs_client.h" 63edc84c5SMatthias Ringwald#include "ble/sm.h" 7*690999b0SMatthias Ringwald#include "btstack_event.h" 88caefee3SMatthias Ringwald#include <SPI.h> 98caefee3SMatthias Ringwald 108caefee3SMatthias Ringwald/* 118caefee3SMatthias Ringwald * EXAMPLE_START(ANCS): ANCS Client 128caefee3SMatthias Ringwald */ 138caefee3SMatthias Ringwald 148caefee3SMatthias Ringwald/* 158caefee3SMatthias Ringwald * @section Advertisement 168caefee3SMatthias Ringwald * @text An ANCS Client needs to include the ANCS UUID in its advertisement to 178caefee3SMatthias Ringwald * get recognized by iOS 188caefee3SMatthias Ringwald */ 198caefee3SMatthias Ringwald 208caefee3SMatthias Ringwald/* LISTING_START(ANCSAdvertisement): ANCS Advertisement */ 218caefee3SMatthias Ringwaldconst uint8_t adv_data[] = { 228caefee3SMatthias Ringwald // Flags general discoverable 238caefee3SMatthias Ringwald 0x02, 0x01, 0x02, 248caefee3SMatthias Ringwald // Name 258caefee3SMatthias Ringwald 0x05, 0x09, 'A', 'N', 'C', 'S', 268caefee3SMatthias Ringwald // Service Solicitation, 128-bit UUIDs - ANCS (little endian) 278caefee3SMatthias Ringwald 0x11,0x15,0xD0,0x00,0x2D,0x12,0x1E,0x4B,0x0F,0xA4,0x99,0x4E,0xCE,0xB5,0x31,0xF4,0x05,0x79 288caefee3SMatthias Ringwald}; 298caefee3SMatthias Ringwald/* LISTING_END(ANCSAdvertisement): ANCS Advertisement */ 308caefee3SMatthias Ringwald 318caefee3SMatthias Ringwald/* 328caefee3SMatthias Ringwald * @section Setup 338caefee3SMatthias Ringwald * 348caefee3SMatthias Ringwald * @text In the setup, the LE Security Manager is configured to accept pairing requests. 358caefee3SMatthias Ringwald * Then, the ANCS Client library is initialized and and ancs_callback registered. 368caefee3SMatthias Ringwald * Finally, the Advertisement data is set and Advertisements are started. 378caefee3SMatthias Ringwald */ 388caefee3SMatthias Ringwald 398caefee3SMatthias Ringwald/* LISTING_START(ANCSSetup): ANCS Setup */ 408caefee3SMatthias Ringwaldvoid setup(void){ 418caefee3SMatthias Ringwald 428caefee3SMatthias Ringwald Serial.begin(9600); 438caefee3SMatthias Ringwald Serial.println("BTstack ANCS Client starting up..."); 448caefee3SMatthias Ringwald 458caefee3SMatthias Ringwald // startup BTstack and configure log_info/log_error 468caefee3SMatthias Ringwald BTstack.setup(); 478caefee3SMatthias Ringwald 488caefee3SMatthias Ringwald sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_ONLY); 498caefee3SMatthias Ringwald sm_set_authentication_requirements( SM_AUTHREQ_BONDING ); 508caefee3SMatthias Ringwald 518caefee3SMatthias Ringwald // setup ANCS Client 528caefee3SMatthias Ringwald ancs_client_init(); 538caefee3SMatthias Ringwald ancs_client_register_callback(&ancs_callback); 548caefee3SMatthias Ringwald 558caefee3SMatthias Ringwald // enable advertisements 568caefee3SMatthias Ringwald BTstack.setAdvData(sizeof(adv_data), adv_data); 578caefee3SMatthias Ringwald BTstack.startAdvertising(); 588caefee3SMatthias Ringwald} 598caefee3SMatthias Ringwald/* LISTING_END(ANCSSetup): ANCS Setup */ 608caefee3SMatthias Ringwald 618caefee3SMatthias Ringwaldvoid loop(void){ 628caefee3SMatthias Ringwald BTstack.loop(); 638caefee3SMatthias Ringwald} 648caefee3SMatthias Ringwald 658caefee3SMatthias Ringwald/* 668caefee3SMatthias Ringwald * @section ANCS Callback 678caefee3SMatthias Ringwald * @text In the ANCS Callback, connect and disconnect events are received. 688caefee3SMatthias Ringwald * For actual notifications, ancs_client_attribute_name_for_id allows to 698caefee3SMatthias Ringwald * look up the name. To get the notification body, e.g., the actual message, 708caefee3SMatthias Ringwald * the GATT Client needs to be used direclty. 718caefee3SMatthias Ringwald */ 728caefee3SMatthias Ringwald 73a4815874SMatthias Ringwald 748caefee3SMatthias Ringwald/* LISTING_START(ANCSCallback): ANCS Callback */ 75591e5551SMatthias Ringwaldvoid ancs_callback(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 768caefee3SMatthias Ringwald const char * attribute_name; 770e2df43fSMatthias Ringwald if (hci_event_packet_get_type(packet) != HCI_EVENT_ANCS_META) return; 78*690999b0SMatthias Ringwald switch (hci_event_ancs_meta_get_subevent_code(packet)){ 79e10ce426SMatthias Ringwald case ANCS_SUBEVENT_CLIENT_CONNECTED: 808caefee3SMatthias Ringwald Serial.println("ANCS Client: Connected"); 818caefee3SMatthias Ringwald break; 82e10ce426SMatthias Ringwald case ANCS_SUBEVENT_CLIENT_DISCONNECTED: 838caefee3SMatthias Ringwald Serial.println("ANCS Client: Disconnected"); 848caefee3SMatthias Ringwald break; 85e10ce426SMatthias Ringwald case ANCS_SUBEVENT_CLIENT_NOTIFICATION: 86e10ce426SMatthias Ringwald attribute_name = ancs_client_attribute_name_for_id(ancs_subevent_client_notification_get_attribute_id(packet)); 878caefee3SMatthias Ringwald if (!attribute_name) break; 888caefee3SMatthias Ringwald Serial.print("Notification: "); 898caefee3SMatthias Ringwald Serial.print(attribute_name); 908caefee3SMatthias Ringwald Serial.print(" - "); 91e10ce426SMatthias Ringwald Serial.println(ancs_subevent_client_notification_get_text(packet)); 928caefee3SMatthias Ringwald break; 938caefee3SMatthias Ringwald default: 948caefee3SMatthias Ringwald break; 958caefee3SMatthias Ringwald } 968caefee3SMatthias Ringwald} 978caefee3SMatthias Ringwald/* LISTING_END(ANCSCallback): ANCS Callback */ 988caefee3SMatthias Ringwald 99