xref: /btstack/port/arduino/examples/ANCS/ANCS.ino (revision 690999b0e56bbf6361211ab420f80bc01aa9aa03)
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