414 lines
12 KiB
C
414 lines
12 KiB
C
/********************************** (C) COPYRIGHT *******************************
|
|
* File Name : main.c
|
|
* Author : WCH
|
|
* Version : V1.1
|
|
* Date : 2020/08/06
|
|
* Description :
|
|
*********************************************************************************
|
|
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
|
* Attention: This software (modified or not) and binary are used for
|
|
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
|
*******************************************************************************/
|
|
|
|
/******************************************************************************/
|
|
#include <time_units.h>
|
|
#include "CONFIG.h"
|
|
#include "HAL.h"
|
|
#include "ancs.h"
|
|
#include "ancs_client.h"
|
|
#include "time_units.h"
|
|
|
|
|
|
static void bt_ancs_notification_source_handler(struct bt_ancs_client *ancs_c,
|
|
int err, const struct bt_ancs_evt_notif *notif);
|
|
static void bt_ancs_data_source_handler(struct bt_ancs_client *ancs_c,
|
|
const struct bt_ancs_attr_response *response);
|
|
static void bt_ancs_write_response_handler(struct bt_ancs_client *ancs_c,
|
|
uint8_t err);
|
|
|
|
__attribute__((aligned(4))) uint32_t MEM_BUF[BLE_MEMHEAP_SIZE / 4];
|
|
|
|
#if(defined(BLE_MAC)) && (BLE_MAC == TRUE)
|
|
const uint8_t MacAddr[6] = {0x84, 0xC2, 0xE4, 0x03, 0x02, 0x02};
|
|
#endif
|
|
|
|
#define ATTR_DATA_SIZE BT_ANCS_ATTR_DATA_MAX
|
|
|
|
#define KEY_REQ_NOTI_ATTR (1<<0)
|
|
#define KEY_REQ_APP_ATTR (1<<1)
|
|
#define KEY_POS_ACTION (1<<0)
|
|
#define KEY_NEG_ACTION (1<<0)
|
|
|
|
static struct bt_ancs_subscribe_cb subscribe = {
|
|
.data_source = bt_ancs_data_source_handler,
|
|
.notification_source = bt_ancs_notification_source_handler,
|
|
.write_response = bt_ancs_write_response_handler,
|
|
};
|
|
|
|
|
|
/* Local copy to keep track of the newest arriving notifications. */
|
|
static struct bt_ancs_evt_notif notification_latest;
|
|
/* Local copy of the newest notification attribute. */
|
|
static struct bt_ancs_attr notif_attr_latest;
|
|
/* Local copy of the newest app attribute. */
|
|
static struct bt_ancs_attr notif_attr_app_id_latest;
|
|
|
|
/* Buffers to store attribute data. */
|
|
static uint8_t attr_appid[ATTR_DATA_SIZE];
|
|
static uint8_t attr_title[ATTR_DATA_SIZE];
|
|
static uint8_t attr_subtitle[ATTR_DATA_SIZE];
|
|
static uint8_t attr_message[ATTR_DATA_SIZE];
|
|
static uint8_t attr_message_size[ATTR_DATA_SIZE];
|
|
static uint8_t attr_date[ATTR_DATA_SIZE];
|
|
static uint8_t attr_posaction[ATTR_DATA_SIZE];
|
|
static uint8_t attr_negaction[ATTR_DATA_SIZE];
|
|
static uint8_t attr_disp_name[ATTR_DATA_SIZE];
|
|
|
|
/* String literals for the iOS notification categories.
|
|
* Used then printing to UART.
|
|
*/
|
|
static const char *lit_catid[BT_ANCS_CATEGORY_ID_COUNT] = {
|
|
"Other",
|
|
"Incoming Call",
|
|
"Missed Call",
|
|
"Voice Mail",
|
|
"Social",
|
|
"Schedule",
|
|
"Email",
|
|
"News",
|
|
"Health And Fitness",
|
|
"Business And Finance",
|
|
"Location",
|
|
"Entertainment"
|
|
};
|
|
|
|
/* String literals for the iOS notification event types.
|
|
* Used then printing to UART.
|
|
*/
|
|
static const char *lit_eventid[BT_ANCS_EVT_ID_COUNT] = { "Added",
|
|
"Modified",
|
|
"Removed" };
|
|
|
|
/* String literals for the iOS notification attribute types.
|
|
* Used when printing to UART.
|
|
*/
|
|
static const char *lit_attrid[BT_ANCS_NOTIF_ATTR_COUNT] = {
|
|
"App Identifier",
|
|
"Title",
|
|
"Subtitle",
|
|
"Message",
|
|
"Message Size",
|
|
"Date",
|
|
"Positive Action Label",
|
|
"Negative Action Label"
|
|
};
|
|
|
|
static const char *lit_appid[BT_ANCS_APP_ATTR_COUNT] = { "Display Name" };
|
|
|
|
|
|
|
|
|
|
|
|
static void notif_print(struct bt_ancs_evt_notif *notif)
|
|
{
|
|
PRINT("\nNotification\n");
|
|
PRINT("Event: %s\n", lit_eventid[notif->evt_id]);
|
|
PRINT("Category ID: %s\n", lit_catid[notif->category_id]);
|
|
PRINT("Category Cnt:%u\n", (unsigned int)notif->category_count);
|
|
PRINT("UID: %u\n", (unsigned int)notif->notif_uid);
|
|
|
|
PRINT("Flags:\n");
|
|
if (notif->evt_flags.silent) {
|
|
PRINT(" Silent\n");
|
|
}
|
|
if (notif->evt_flags.important) {
|
|
PRINT(" Important\n");
|
|
}
|
|
if (notif->evt_flags.pre_existing) {
|
|
PRINT(" Pre-existing\n");
|
|
}
|
|
if (notif->evt_flags.positive_action) {
|
|
PRINT(" Positive Action\n");
|
|
}
|
|
if (notif->evt_flags.negative_action) {
|
|
PRINT(" Negative Action\n");
|
|
}
|
|
}
|
|
|
|
/**@brief Function for printing iOS notification attribute data.
|
|
*
|
|
* @param[in] attr Pointer to an iOS notification attribute.
|
|
*/
|
|
static void notif_attr_print(const struct bt_ancs_attr *attr)
|
|
{
|
|
if (attr->attr_len != 0) {
|
|
PRINT("%s: %s\n", lit_attrid[attr->attr_id],
|
|
(char *)attr->attr_data);
|
|
} else if (attr->attr_len == 0) {
|
|
PRINT("%s: (N/A)\n", lit_attrid[attr->attr_id]);
|
|
}
|
|
}
|
|
|
|
/**@brief Function for printing iOS notification attribute data.
|
|
*
|
|
* @param[in] attr Pointer to an iOS App attribute.
|
|
*/
|
|
static void app_attr_print(const struct bt_ancs_attr *attr)
|
|
{
|
|
if (attr->attr_len != 0) {
|
|
PRINT("%s: %s\n", lit_appid[attr->attr_id],
|
|
(char *)attr->attr_data);
|
|
} else if (attr->attr_len == 0) {
|
|
PRINT("%s: (N/A)\n", lit_appid[attr->attr_id]);
|
|
}
|
|
}
|
|
|
|
static int ancs_init(void)
|
|
{
|
|
int err;
|
|
|
|
err = bt_ancs_client_init(&ancs_c);
|
|
if (err) {
|
|
return err;
|
|
}
|
|
|
|
err = bt_ancs_register_attr(&ancs_c,
|
|
BT_ANCS_NOTIF_ATTR_ID_APP_IDENTIFIER,
|
|
attr_appid, ATTR_DATA_SIZE);
|
|
if (err) {
|
|
return err;
|
|
}
|
|
|
|
err = bt_ancs_register_app_attr(&ancs_c,
|
|
BT_ANCS_APP_ATTR_ID_DISPLAY_NAME,
|
|
attr_disp_name, sizeof(attr_disp_name));
|
|
if (err) {
|
|
return err;
|
|
}
|
|
|
|
err = bt_ancs_register_attr(&ancs_c,
|
|
BT_ANCS_NOTIF_ATTR_ID_TITLE,
|
|
attr_title, ATTR_DATA_SIZE);
|
|
if (err) {
|
|
return err;
|
|
}
|
|
|
|
err = bt_ancs_register_attr(&ancs_c,
|
|
BT_ANCS_NOTIF_ATTR_ID_MESSAGE,
|
|
attr_message, ATTR_DATA_SIZE);
|
|
if (err) {
|
|
return err;
|
|
}
|
|
|
|
err = bt_ancs_register_attr(&ancs_c,
|
|
BT_ANCS_NOTIF_ATTR_ID_SUBTITLE,
|
|
attr_subtitle, ATTR_DATA_SIZE);
|
|
if (err) {
|
|
return err;
|
|
}
|
|
|
|
err = bt_ancs_register_attr(&ancs_c,
|
|
BT_ANCS_NOTIF_ATTR_ID_MESSAGE_SIZE,
|
|
attr_message_size, ATTR_DATA_SIZE);
|
|
if (err) {
|
|
return err;
|
|
}
|
|
|
|
err = bt_ancs_register_attr(&ancs_c,
|
|
BT_ANCS_NOTIF_ATTR_ID_DATE,
|
|
attr_date, ATTR_DATA_SIZE);
|
|
if (err) {
|
|
return err;
|
|
}
|
|
|
|
err = bt_ancs_register_attr(&ancs_c,
|
|
BT_ANCS_NOTIF_ATTR_ID_POSITIVE_ACTION_LABEL,
|
|
attr_posaction, ATTR_DATA_SIZE);
|
|
if (err) {
|
|
return err;
|
|
}
|
|
|
|
err = bt_ancs_register_attr(&ancs_c,
|
|
BT_ANCS_NOTIF_ATTR_ID_NEGATIVE_ACTION_LABEL,
|
|
attr_negaction, ATTR_DATA_SIZE);
|
|
|
|
return err;
|
|
}
|
|
|
|
static void bt_ancs_notification_source_handler(struct bt_ancs_client *ancs_c,
|
|
int err, const struct bt_ancs_evt_notif *notif)
|
|
{
|
|
if (!err) {
|
|
notification_latest = *notif;
|
|
notif_print(¬ification_latest);
|
|
}
|
|
}
|
|
|
|
static void bt_ancs_data_source_handler(struct bt_ancs_client *ancs_c,
|
|
const struct bt_ancs_attr_response *response)
|
|
{
|
|
switch (response->command_id) {
|
|
case BT_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES:
|
|
notif_attr_latest = response->attr;
|
|
notif_attr_print(¬if_attr_latest);
|
|
if (response->attr.attr_id ==
|
|
BT_ANCS_NOTIF_ATTR_ID_APP_IDENTIFIER) {
|
|
notif_attr_app_id_latest = response->attr;
|
|
}
|
|
break;
|
|
|
|
case BT_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES:
|
|
app_attr_print(&response->attr);
|
|
break;
|
|
|
|
default:
|
|
/* No implementation needed. */
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void bt_ancs_write_response_handler(struct bt_ancs_client *ancs_c,
|
|
uint8_t err)
|
|
{
|
|
switch (err) {
|
|
case BT_ATT_ERR_ANCS_NP_UNKNOWN_COMMAND:
|
|
PRINT("Error: Command ID was not recognized by the Notification Provider.\n");
|
|
break;
|
|
|
|
case BT_ATT_ERR_ANCS_NP_INVALID_COMMAND:
|
|
PRINT("Error: Command failed to be parsed on the Notification Provider.\n");
|
|
break;
|
|
|
|
case BT_ATT_ERR_ANCS_NP_INVALID_PARAMETER:
|
|
PRINT("Error: Parameter does not refer to an existing object on the Notification Provider.\n");
|
|
break;
|
|
|
|
case BT_ATT_ERR_ANCS_NP_ACTION_FAILED:
|
|
PRINT("Error: Perform Notification Action Failed on the Notification Provider.\n");
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
struct key_state {
|
|
uint32_t timestamp_key1;
|
|
uint32_t timestamp_key2;
|
|
};
|
|
|
|
/**
|
|
* key1(PB22):
|
|
* single: request attributes for a notification.
|
|
* double: request attributes for a given app.
|
|
*
|
|
* key2(PB4):
|
|
* single: perform a positive action.
|
|
* double: perform a negative action.
|
|
*/
|
|
void button_changed(uint8_t keys)
|
|
{
|
|
int err;
|
|
static struct key_state k_s = {0};
|
|
|
|
if(keys & HAL_KEY_SW_1){
|
|
uint32_t current_time = get_current_time();
|
|
if(current_time - k_s.timestamp_key1 < 600){
|
|
if (notif_attr_app_id_latest.attr_id ==
|
|
BT_ANCS_NOTIF_ATTR_ID_APP_IDENTIFIER &&
|
|
notif_attr_app_id_latest.attr_len != 0) {
|
|
PRINT("Request for %s:\n",
|
|
notif_attr_app_id_latest.attr_data);
|
|
err = bt_ancs_request_app_attr(
|
|
&ancs_c, notif_attr_app_id_latest.attr_data,
|
|
notif_attr_app_id_latest.attr_len,
|
|
bt_ancs_write_response_handler);
|
|
if (err) {
|
|
PRINT("Failed requesting attributes for a given app (err: %d)\n",
|
|
err);
|
|
}
|
|
}
|
|
} else {
|
|
err = bt_ancs_request_attrs(&ancs_c, ¬ification_latest,
|
|
bt_ancs_write_response_handler);
|
|
if(err){
|
|
PRINT("Failed requesting attributes for a notification (err: %d)\n",
|
|
err);
|
|
}
|
|
}
|
|
k_s.timestamp_key1 = current_time;
|
|
}
|
|
|
|
if(keys & HAL_KEY_SW_2){
|
|
uint32_t current_time = get_current_time();
|
|
if(current_time - k_s.timestamp_key2 < 600){
|
|
PRINT("Performing Negative Action.\n");
|
|
err = bt_ancs_notification_action(
|
|
&ancs_c, notification_latest.notif_uid,
|
|
BT_ANCS_ACTION_ID_NEGATIVE,
|
|
bt_ancs_write_response_handler);
|
|
if (err) {
|
|
PRINT("Failed performing action (err: %d)\n",
|
|
err);
|
|
}
|
|
} else {
|
|
PRINT("Performing Positive Action.\n");
|
|
err = bt_ancs_notification_action(
|
|
&ancs_c, notification_latest.notif_uid,
|
|
BT_ANCS_ACTION_ID_POSITIVE,
|
|
bt_ancs_write_response_handler);
|
|
if (err) {
|
|
PRINT("Failed performing action (err: %d)\n",
|
|
err);
|
|
}
|
|
}
|
|
|
|
k_s.timestamp_key2 = current_time;
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn Main_Circulation
|
|
*
|
|
* @brief Main loop
|
|
*
|
|
* @return none
|
|
*/
|
|
__attribute__((section(".highcode")))
|
|
__attribute__((noinline))
|
|
void Main_Circulation(void)
|
|
{
|
|
while(1)
|
|
{
|
|
TMOS_SystemProcess();
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn main
|
|
*
|
|
* @brief Main function
|
|
*
|
|
* @return none
|
|
*/
|
|
int main(void)
|
|
{
|
|
Delay_Init();
|
|
#ifdef DEBUG
|
|
USART_Printf_Init( 115200 );
|
|
#endif
|
|
PRINT("start.%s\n",__TIME__);
|
|
PRINT("%s\n", VER_LIB);
|
|
WCHBLE_Init();
|
|
HAL_Init();
|
|
|
|
HalKeyConfig(button_changed);
|
|
ancs_init();
|
|
ancs_subscribe_cb_register(&subscribe);
|
|
GAPRole_PeripheralInit();
|
|
peripheral_ancs_client_init();
|
|
Main_Circulation();
|
|
}
|
|
|
|
/******************************** endfile @ main ******************************/
|