This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

registering to listen ble_ancs_c events

Hi.

I'm trying to get Apple notifications to nrf52. And specifically to listen both regular ANS (for android) and ANCS (for iOS) events depending what sort of phone is connected.

I've used the regular ANS example as base (and that side works) as the ANCS example seems to be the "apple device"/peripheral side of the implementation.

So I'll try to add the listeners for the ANCS events in my init function. However the app crashes right after the ANCS initialization is called. I checked the ble_ancs_c.c and the parameters should be OK.

What is the correct way to register for these events? Have I misunderstood the ANCS example wrong and it just doesn't behave same way as regular ANS (wherethe phone advertises the ans service and characteristics)? I mean why would the ANCS notification receiver add the service to its supported services in advertisement init? Or is this some peculiarity of ANCS?

And the ble_ancs_c_attr_add is also needed for adding the main service and attributes when using in peripheral mode (like normally the iPhone acts)?

EDIT: Apparently the system runs out of memory. I get NRF_ERROR_NO_MEM when assigning the control point service UUID in ble_ancs_c_init. err_code = sd_ble_uuid_vs_add(&ble_ancs_cp_base_uuid128, &p_ancs->service.control_point_char.uuid.type);

My memory config is same as in the ANS example. So is this really out of memory or is this matter of configuration. I mean there isn't any extra data structures added (tracing must be taking some), just included the ANCS initializations to mix. My code snipplets:

int main(void) {
    uint32_t err_code;
    bool erase_bonds;

   // Initialize.
   err_code = NRF_LOG_INIT();
   APP_ERROR_CHECK(err_code);
   NRF_LOG_PRINTF("\r\n[MAIN] ********************START***************\n\r");
   timers_init();
   buttons_leds_init(&erase_bonds);
   ble_stack_init();
   peer_manager_init(erase_bonds);
   if (erase_bonds == true) {
      NRF_LOG_DEBUG("Bonds erased!\n\r");
   }
   db_discovery_init();
   gap_params_init();
   advertising_init();
   conn_params_init();
   standard_alert_notification_init();
   apple_alert_notification_init(); <========problem function

   // Start execution.
   advertising_start();

   // Enter main loop.
   for (;;) {
       power_manage();
   }
}

The init itself:

/**@brief Function for initialization of the Alert Notification Service Client.
*/
void apple_alert_notification_init() {
   uint32_t         err_code;
   ble_ancs_c_init_t ancs_init_obj;

   NRF_LOG_PRINTF("[APPLE] apple notif init\n\r");
   memset(&ancs_init_obj, 0, sizeof(ancs_init_obj));

   ancs_init_obj.evt_handler         = on_ancs_c_evt;
   ancs_init_obj.error_handler       = alert_notification_error_handler;

   err_code = ble_ancs_c_init(&m_ancs_c, &ancs_init_obj);
   if (err_code != NRF_SUCCESS) {
       NRF_LOG_PRINTF("[APPLE] init fail\n\r");
   }
   APP_ERROR_CHECK(err_code);

}

As general comment, it wouldn't really hurt to put littlebit more explanation to examples what they are supposed to do. It's totally fantastic that you guys do this sort of examples, and especially the support here is first class. But little better descriptions in the examples would save a lot of time supporting here in the forum.

Related