nrf51822 ---ancs(2)

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” 的设备,会出现配对界面,如下:

nrf51822 ---ancs(2)_第1张图片

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

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

4.打电话测试:

  nrf51822 ---ancs(2)_第2张图片

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

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);
  
}

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

好了。打电话测试:

nrf51822 ---ancs(2)_第3张图片

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

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.当连接的时候跳出配对框

nrf51822 ---ancs(2)_第4张图片

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

#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);

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







你可能感兴趣的:(nrf51822 ---ancs(2))