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