nrf51822 ---ancs(2)

来源:互联网 发布:linux查看文件大小m 编辑:程序博客网 时间:2024/06/11 20:42

1.目的

    ancs接收ios信息

2.分析

  上面一章已经介绍了基本的信息,现在来实战吧。

3.平台:

协议栈版本:SDK8.0.0

编译软件:keil 5.14    

Apple APP:lightblue(手机工具)

硬件平台:nrf51822最小系统

例子:SDK 10.0.0\SDK10.0\examples\ble_peripheral\ble_app_ancs_c\pca10028\s110\arm4

4.步骤

  a.把固件烧入到开发板里面

  b.打开了蓝牙,打开lightblue 连接名字为 “ANCS” 的设备,会出现配对界面,如下:


3。点击配对,就好了。这个时候ancs功能已经打开了,推出lightblue。

  注意:如果不点击配对,则ancs失效。ancs必须配对才能有效

4.打电话测试:

  

电话来了。电话断开都会产生事件。

4.这个时候要怎么获得,电话号码等属性呢。

在"ANCS(1)"(请查看上面一章内容) 中我们知道,需要通过

 3、Data Source:

   UUID 22EAC6E9-24D6-4BB5-BE44-B36ACE7C7BFB(notifiable)

   数据源,用于提供详细数据,在控制信息写入后通过此characteristic返回;

 

来获得数据源。

官方的开发板子上面一个案件,可以获取数据源。 如下:BSP_EVENT_KEY_1

 注意:官方例子只能获得最后一次事件的数据属性

       可以在程序里面保存UID来获取多次数据属性

static void bsp_event_handler(bsp_event_t event){    uint32_t err_code;    switch (event)    {        case BSP_EVENT_SLEEP:            sleep_mode_enter();            break;        case BSP_EVENT_DISCONNECT:            err_code = sd_ble_gap_disconnect(m_conn_handle,                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);            if (err_code != NRF_ERROR_INVALID_STATE)            {                APP_ERROR_CHECK(err_code);            }            break;        case BSP_EVENT_WHITELIST_OFF:            err_code = ble_advertising_restart_without_whitelist();            if (err_code != NRF_ERROR_INVALID_STATE)            {                APP_ERROR_CHECK(err_code);            }            break;        case BSP_EVENT_KEY_1:            err_code = ble_ancs_c_request_attrs(&m_notification_latest);            APP_ERROR_CHECK(err_code);            break;        default:            break;    }}
我自己的板子上面没有怎么办呢?在如下添加 ble_ancs_c_request_attrs(&m_notification_latest);

static void notif_print(ble_ancs_c_evt_notif_t * p_notif){    printf("\n\rNotification\n\r");    printf("Event:       %s\n", lit_eventid[p_notif->evt_id]);    printf("Category ID: %s\n", lit_catid[p_notif->category_id]);    printf("Category Cnt:%u\n", (unsigned int) p_notif->category_count);    printf("UID:         %u\n\r", (unsigned int) p_notif->notif_uid);    printf("Flags:\n\r");    if(p_notif->evt_flags.silent == 1)    {        printf(" Silent\n\r");    }    if(p_notif->evt_flags.important == 1)    {        printf(" Important\n\r");    }    if(p_notif->evt_flags.pre_existing == 1)    {        printf(" Pre-existing\n\r");    } if(p_notif->evt_flags.positive_action == 1)    {        printf(" Positive Action\n\r");    }    if(p_notif->evt_flags.negative_action == 1)    {        printf(" Positive Action\n\r");    } ble_ancs_c_request_attrs(&m_notification_latest);  }

这样每次有事件都可以获得 数据属性。

好了。打电话测试:


上面,电话号码 和 时间 都出现了。。。

4.刚才在修改代码的时候,是不是出现,下载进去后程序一直复位,

原因是设备这边清掉了绑定信息,而手机没有清掉 ,出现了 0x08错误。导致跳到了

__WEAK void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name){    // On assert, the system can only recover with a reset.#ifndef DEBUG    NVIC_SystemReset();#else

复位了。

解决办法。1.手机忽略此设备

5.ios和设备连上后。复位设备,是不是有出现了复位。。也是0x08错误

  这个是因为,复位的时候以上的绑定信息,全部软件擦出了。

static void buttons_leds_init(bool * p_erase_bonds){    bsp_event_t startup_event;    uint32_t err_code = bsp_init(BSP_INIT_LED | BSP_INIT_BUTTONS,                                 APP_TIMER_TICKS(100, APP_TIMER_PRESCALER),                                 bsp_event_handler);    APP_ERROR_CHECK(err_code);    err_code = bsp_btn_ble_init(NULL, &startup_event);    APP_ERROR_CHECK(err_code);    *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA);}

 *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA);

擦出全部绑定信息。

把词句屏蔽 ,

static void buttons_leds_init(bool * p_erase_bonds){    bsp_event_t startup_event;    uint32_t err_code = bsp_init(BSP_INIT_LED | BSP_INIT_BUTTONS,                                 APP_TIMER_TICKS(100, APP_TIMER_PRESCALER),                                 bsp_event_handler);    APP_ERROR_CHECK(err_code);    err_code = bsp_btn_ble_init(NULL, &startup_event);    APP_ERROR_CHECK(err_code);  //  *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA);}
bool     erase_bonds = 0;

这样就不会擦出信息了。

ret_code_t dm_init(dm_init_param_t const * const p_init_param){    pstorage_module_param_t param;    pstorage_handle_t       block_handle;    ret_code_t              err_code;    uint32_t                index;    DM_LOG("[DM]: >> dm_init.\r\n");    NULL_PARAM_CHECK(p_init_param);    SDK_MUTEX_INIT(m_dm_mutex);    DM_MUTEX_LOCK();    for (index = 0; index < DEVICE_MANAGER_MAX_APPLICATIONS; index++)    {        application_instance_init(index);    }    for (index = 0; index < DEVICE_MANAGER_MAX_CONNECTIONS; index++)    {        connection_instance_init(index);    } memset(m_gatts_table, 0, sizeof(m_gatts_table));    //Initialization of all device instances.    for (index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)    {        peer_instance_init(index);        m_irk_index_table[index] = DM_INVALID_ID;    }    //All context with respect to a particular device is stored contiguously.    param.block_size  = ALL_CONTEXT_SIZE;    param.block_count = DEVICE_MANAGER_MAX_BONDS;    param.cb          = dm_pstorage_cb_handler;    err_code = pstorage_register(¶m, &m_storage_handle);    if (err_code == NRF_SUCCESS)    {        m_module_initialized = true;        printf("p_init_param->clear_persistent_data=%d\r\n",p_init_param->clear_persistent_data);        if (p_init_param->clear_persistent_data == false)        {            DM_LOG("[DM]: Storage handle 0x%08X.\r\n", m_storage_handle.block_id);            //Copy bonded peer device address and IRK to RAM table.            //Bonded devices are stored in range (0,DEVICE_MANAGER_MAX_BONDS-1). The remaining            //range is for active connections that may or may not be bonded.            for (index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)            {                err_code = pstorage_block_identifier_get(&m_storage_handle, index, &block_handle);                //Issue read request if you successfully get the block identifier.                if (err_code == NRF_SUCCESS)                {                    DM_TRC("[DM]:[0x%02X]: Block handle 0x%08X.\r\n", index, block_handle.block_id);                    err_code = pstorage_load((uint8_t *)&m_peer_table[index],                                             &block_handle,                                             sizeof(peer_id_t),                                             0);                    if (err_code != NRF_SUCCESS)                    {                        // In case a peer device could not be loaded successfully, rest of the                        // initialization procedure are skipped and an error is sent to the                        // application.                        DM_ERR(                            "[DM]: Failed to load peer device %08X from storage, reason %08X.\r\n",                            index,                            err_code);                        m_module_initialized = false;                        break;                    }                  else                    {//   printf("\r\nBLE ANCS\r\n");                        DM_TRC("[DM]:[DI 0x%02X]: Device type 0x%02X.\r\n",                               index,                               m_peer_table[index].peer_id.id_addr_info.addr_type);                        DM_TRC("[DM]: Device Addr 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X.\r\n",                               m_peer_table[index].peer_id.id_addr_info.addr[0],                               m_peer_table[index].peer_id.id_addr_info.addr[1],                               m_peer_table[index].peer_id.id_addr_info.addr[2],                               m_peer_table[index].peer_id.id_addr_info.addr[3],                               m_peer_table[index].peer_id.id_addr_info.addr[4],                               m_peer_table[index].peer_id.id_addr_info.addr[5]);                    }                }                else                {                   //In case a peer device could not be loaded successfully, rest of the                    //initialization procedure are skipped and an error is sent to the application.                    DM_LOG("[DM]: Failed to get block handle for instance %08X, reason %08X.\r\n",                           index,                           err_code);                    m_module_initialized = false;                    break;                }            }        }        else        {            err_code = pstorage_clear(&m_storage_handle, (param.block_size * param.block_count));            DM_ERR("[DM]: Successfully requested clear of persistent data.\r\n");        }    } else    {        DM_ERR("[DM]: Failed to register with storage module, reason 0x%08X.\r\n", err_code);    }    DM_MUTEX_UNLOCK();    DM_TRC("[DM]: << dm_init.\r\n");    return err_code;}

上面代码可以看到 if (p_init_param->clear_persistent_data == false)的时候,

     执行:pstorage_load()即读出绑定信息

  else 

    pstorage_clear()擦出

 
p_init_param->clear_persistent_data 这个即是:p_erase_bonds 的值


有网友遇到:事件到了100的时候,就不会增加了。就是假如收到了100条信息 可以显示内容,到了101条就不显示了。(原因不详知道的告诉下,谢谢)

6.当light连上ancs并配对后,长时间不通信会自动断开

   抛出的错误类型为:#define BLE_HCI_DIFFERENT_TRANSACTION_COLLISION        0x2A       /**< Different Transaction Collision. */

 解决办法:每隔一段时间发送一个 无效数据 给手机。。。

  7.当连接的时候跳出配对框


当点击取消的时候,系统会复位,因为在于,系统抛出了

#define BLE_GAP_SEC_STATUS_PASSKEY_ENTRY_FAILED   0x81  /**< Passkey entry failed (user cancelled or other). */

看如下代码:

static uint32_t device_manager_evt_handler(dm_handle_t const * p_handle,                                           dm_event_t const  * p_evt,                                           ret_code_t          event_result){    uint32_t err_code;    APP_ERROR_CHECK(event_result);  //检查event    ble_ancs_c_on_device_manager_evt(&m_ancs_c, p_handle, p_evt);    switch (p_evt->event_id)    {        case DM_EVT_CONNECTION:            m_peer_handle = (*p_handle);            err_code      = app_timer_start(m_sec_req_timer_id, SECURITY_REQUEST_DELAY, NULL);            APP_ERROR_CHECK(err_code);            break;        case DM_EVT_LINK_SECURED:            err_code = ble_db_discovery_start(&m_ble_db_discovery,                                              p_evt->event_param.p_gap_param->conn_handle);            APP_ERROR_CHECK(err_code);            break;         default:            break;    }    return NRF_SUCCESS;}
APP_ERROR_CHECK(event_result);

会导致复位。这点要注意。可以把这个给屏蔽掉。。







0 0
原创粉丝点击