A POC Code of doing ANCS with nrf51822-mKit. See README.txt for details.

Dependencies:   BLE_API mbed nRF51822

A sample code implementing ANCS client accessory with nRF51822-mKit. This is just a proof that this thing is indeed doable.

The code itself is complete mess. I'm not planing to furnish this, as the purpose (make sure it is doable) was achieved.

The next step possible step is (no timeline) 1. Implementing Gatt Client API in BLE API (forking?) 2. Do ANCS with that.

Please see README.txt for details.

debug.cpp

Committer:
devsar
Date:
2014-06-03
Revision:
0:1f985a7c0a8b

File content as of revision 0:1f985a7c0a8b:


// Set error string based on error number for
// convinience debugging purpose.
// See: API Reference>S110>SofDevice Global Error Codes
#include <stdint.h>
#include <stdio.h>

#include "nRF51822n.h"

#define MAX_BUFFER 100
char m_error_string[MAX_BUFFER];
char m_event_string[MAX_BUFFER];
char m_nrfevent_string[MAX_BUFFER];
char m_ancs_string[MAX_BUFFER];


char *get_error_unknown(uint32_t error_num) {
    snprintf(m_error_string, MAX_BUFFER, "Unknown");
    return m_error_string;
}

// Global error base.
char *get_error_global(uint32_t error_num) {
    if(error_num == NRF_ERROR_BASE_NUM + 0){
        snprintf(m_error_string, MAX_BUFFER, "Successful command. ");
    } else if(error_num == NRF_ERROR_BASE_NUM + 1){
        snprintf(m_error_string, MAX_BUFFER, "SVC handler is missing. ");
    } else if(error_num == NRF_ERROR_BASE_NUM + 2){
        snprintf(m_error_string, MAX_BUFFER, "SoftDevice has not been enabled. ");
    } else if(error_num == NRF_ERROR_BASE_NUM + 3){
        snprintf(m_error_string, MAX_BUFFER, "Internal Error. ");
    } else if(error_num == NRF_ERROR_BASE_NUM + 4){
        snprintf(m_error_string, MAX_BUFFER, "No Memory for operation. ");
    } else if(error_num == NRF_ERROR_BASE_NUM + 5){
        snprintf(m_error_string, MAX_BUFFER, "Not found. ");
    } else if(error_num == NRF_ERROR_BASE_NUM + 6){
        snprintf(m_error_string, MAX_BUFFER, "Not supported. ");
    } else if(error_num == NRF_ERROR_BASE_NUM + 7){
        snprintf(m_error_string, MAX_BUFFER, "Invalid Parameter. ");
    } else if(error_num == NRF_ERROR_BASE_NUM + 8){
        snprintf(m_error_string, MAX_BUFFER, "Invalid state, operation disallowed in this state. ");
    } else if(error_num == NRF_ERROR_BASE_NUM + 9){
        snprintf(m_error_string, MAX_BUFFER, "Invalid Length. ");
    } else if(error_num == NRF_ERROR_BASE_NUM + 10){
        snprintf(m_error_string, MAX_BUFFER, "Invalid Flags. ");
    } else if(error_num == NRF_ERROR_BASE_NUM + 11){
        snprintf(m_error_string, MAX_BUFFER, "Invalid Data. ");
    } else if(error_num == NRF_ERROR_BASE_NUM + 12){
        snprintf(m_error_string, MAX_BUFFER, "Data size exceeds limit. ");
    } else if(error_num == NRF_ERROR_BASE_NUM + 13){
        snprintf(m_error_string, MAX_BUFFER, "Operation timed out. ");
    } else if(error_num == NRF_ERROR_BASE_NUM + 14){
        snprintf(m_error_string, MAX_BUFFER, "Null Pointer. ");
    } else if(error_num == NRF_ERROR_BASE_NUM + 15){
        snprintf(m_error_string, MAX_BUFFER, "Forbidden Operation. ");
    } else if(error_num == NRF_ERROR_BASE_NUM + 16){
        snprintf(m_error_string, MAX_BUFFER, "Bad Memory Address. ");
    } else if(error_num == NRF_ERROR_BASE_NUM + 17){
        snprintf(m_error_string, MAX_BUFFER, "Busy. ");        
    } else {
        return get_error_unknown(error_num);
    }
    return m_error_string;
}

// SDM error base.
char *get_error_sdm(uint32_t error_num) {
    if(error_num == NRF_ERROR_SDM_BASE_NUM + 0){
        snprintf(m_error_string, MAX_BUFFER, "Unknown lfclk source. ");
    } else if(error_num == NRF_ERROR_SDM_BASE_NUM + 1){
        snprintf(m_error_string, MAX_BUFFER, "Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts) ");
    } else if(error_num == NRF_ERROR_SDM_BASE_NUM + 2){
        snprintf(m_error_string, MAX_BUFFER, "Incorrect CLENR0 (can be caused by erronous SoftDevice flashing) ");
    } else {
        return get_error_unknown(error_num);
    }    
    return m_error_string;
}

// SoC error base.
char *get_error_soc(uint32_t error_num) {
    if(error_num == NRF_ERROR_SOC_BASE_NUM + 0){
        snprintf(m_error_string, MAX_BUFFER, "Mutex already taken. ");        
    } else if(error_num == NRF_ERROR_SOC_BASE_NUM + 1){
        snprintf(m_error_string, MAX_BUFFER, "NVIC interrupt not available. ");        
    } else if(error_num == NRF_ERROR_SOC_BASE_NUM + 2){
        snprintf(m_error_string, MAX_BUFFER, "NVIC interrupt priority not allowed. ");        
    } else if(error_num == NRF_ERROR_SOC_BASE_NUM + 3){
        snprintf(m_error_string, MAX_BUFFER, "NVIC should not return. ");        
    } else if(error_num == NRF_ERROR_SOC_BASE_NUM + 4){
        snprintf(m_error_string, MAX_BUFFER, "Power mode unknown. ");        
    } else if(error_num == NRF_ERROR_SOC_BASE_NUM + 5){
        snprintf(m_error_string, MAX_BUFFER, "Power POF threshold unknown. ");        
    } else if(error_num == NRF_ERROR_SOC_BASE_NUM + 6){
        snprintf(m_error_string, MAX_BUFFER, "Power off should not return. ");        
    } else if(error_num == NRF_ERROR_SOC_BASE_NUM + 7){
        snprintf(m_error_string, MAX_BUFFER, "RAND not enough values. ");        
    } else if(error_num == NRF_ERROR_SOC_BASE_NUM + 8){
        snprintf(m_error_string, MAX_BUFFER, "Invalid PPI Channel. ");        
    } else if(error_num == NRF_ERROR_SOC_BASE_NUM + 9){
        snprintf(m_error_string, MAX_BUFFER, "Invalid PPI Group. ");        
    } else {
        return get_error_unknown(error_num);
    }
    return m_error_string;
}

// STK error base.
char *get_error_stk(uint32_t error_num) {
    snprintf(m_error_string, MAX_BUFFER, "stk error.");
    return m_error_string;
}

char *error2string(uint32_t error_num) {
    
    if(error_num<NRF_ERROR_SDM_BASE_NUM) {
        return get_error_global(error_num);
    } else if(error_num<NRF_ERROR_SDM_BASE_NUM) {
        return get_error_sdm(error_num);
    } else if(error_num<NRF_ERROR_SOC_BASE_NUM) {
        return get_error_soc(error_num);
    } else if(error_num<NRF_ERROR_STK_BASE_NUM) {
        return get_error_stk(error_num);
    } else {
        return get_error_unknown(error_num);
    }
     
}

char *event2string(ble_evt_t * p_ble_evt) {
    switch (p_ble_evt->header.evt_id) { 
        // GAP
        case BLE_GAP_EVT_CONNECTED:
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GAP_EVT_CONNECTED", "Connection established.");
            break;
        case BLE_GAP_EVT_DISCONNECTED :
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GAP_EVT_DISCONNECTED ", "Disconnected from peer.");
            break;
        case BLE_GAP_EVT_CONN_PARAM_UPDATE:
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GAP_EVT_CONN_PARAM_UPDATE", "Connection Parameters updated.");
            break;
        case BLE_GAP_EVT_SEC_PARAMS_REQUEST :
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GAP_EVT_SEC_PARAMS_REQUEST ", "Request to provide security parameters.");
            break;
        case BLE_GAP_EVT_SEC_INFO_REQUEST :
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GAP_EVT_SEC_INFO_REQUEST ", "Request to provide security information.");
            break;
        case BLE_GAP_EVT_PASSKEY_DISPLAY:
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GAP_EVT_PASSKEY_DISPLAY", "Request to display a passkey to the user.");
            break;
        case BLE_GAP_EVT_AUTH_KEY_REQUEST:
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GAP_EVT_AUTH_KEY_REQUEST", "Request to provide an authentication key.");
            break;
        case BLE_GAP_EVT_AUTH_STATUS :
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GAP_EVT_AUTH_STATUS ", "Authentication procedure completed with status.");
            break;
        case BLE_GAP_EVT_CONN_SEC_UPDATE:
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GAP_EVT_CONN_SEC_UPDATE ", "Connection security updated.");
            break;
        case BLE_GAP_EVT_TIMEOUT :
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GAP_EVT_TIMEOUT ", "Timeout expired.");
            break;
        case BLE_GAP_EVT_RSSI_CHANGED :
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GAP_EVT_RSSI_CHANGED ", "Signal strength measurement report.");
            break;
        // GATTC
        case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP  :
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP ", "Primary Service Discovery Response event.");
            break;
        case BLE_GATTC_EVT_REL_DISC_RSP  :
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GATTC_EVT_REL_DISC_RSP ", "Relationship Discovery Response event.");
            break;
        case BLE_GATTC_EVT_CHAR_DISC_RSP  :
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GATTC_EVT_CHAR_DISC_RSP ", "Characteristic Discovery Response event.");
            break;
        case BLE_GATTC_EVT_DESC_DISC_RSP  :
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GATTC_EVT_DESC_DISC_RSP ", "Descriptor Discovery Response event.");
            break;
        case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP :
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP", "Read By UUID Response event.");
            break;
        case BLE_GATTC_EVT_READ_RSP  :
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GATTC_EVT_READ_RSP ", "Read Response event.");
            break;
        case BLE_GATTC_EVT_CHAR_VALS_READ_RSP  :
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GATTC_EVT_CHAR_VALS_READ_RSP ", "Read multiple Response event.");
            break;
        case BLE_GATTC_EVT_WRITE_RSP  :
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GATTC_EVT_WRITE_RSP", "Write Response event.");
            break;
        case BLE_GATTC_EVT_HVX  :
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GATTC_EVT_HVX ", "Handle Value Notification or Indication event.");
            break;
        case BLE_GATTC_EVT_TIMEOUT  :
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GATTC_EVT_TIMEOUT ", "Timeout event.");
            break;
        // GATTS
        case BLE_GATTS_EVT_WRITE  :
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GATTS_EVT_WRITE ", "Write operation performed.");
            break;
        case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST  :
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST ", "Read/Write Authorization request.");
            break;
        case BLE_GATTS_EVT_SYS_ATTR_MISSING  :
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GATTS_EVT_SYS_ATTR_MISSING ", "A persistent system attribute access is pending, awaiting a sd_ble_gatts_sys_attr_set().");
            break;
        case BLE_GATTS_EVT_HVC  :
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GATTS_EVT_HVC ", "Handle Value Confirmation.");
            break;
        case BLE_GATTS_EVT_SC_CONFIRM  :
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GATTS_EVT_SC_CONFIRM ", "Service Changed Confirmation.");
            break;
        case BLE_GATTS_EVT_TIMEOUT  :
            snprintf(m_event_string, MAX_BUFFER, "%s (%s)", "BLE_GATTS_EVT_TIMEOUT ", "Timeout.");
            break;
        //
        default:
            snprintf(m_event_string, MAX_BUFFER, "Event: Unknown (%d)", p_ble_evt->header.evt_id);
            break;
    }        

    return m_event_string;    
}


char *nrfevent2string(uint32_t evt_id) {
    switch (evt_id) { 
//        case NRF_EVT_HFCLKSTARTED   :
//            snprintf(m_nrfevent_string, MAX_BUFFER, "%s (%s)", "NRF_EVT_HFCLKSTARTED", "Event indicating that the HFCLK has started.");
//            break;
//        case NRF_EVT_POWER_FAILURE_WARNING   :
//            snprintf(m_nrfevent_string, MAX_BUFFER, "%s (%s)", "NRF_EVT_POWER_FAILURE_WARNING", "Event indicating that a power failure warning has occurred.");
//            break;
//        case NRF_EVT_FLASH_OPERATION_SUCCESS   :
//            snprintf(m_nrfevent_string, MAX_BUFFER, "%s (%s)", "NRF_EVT_FLASH_OPERATION_SUCCESS", "Event indicating that the ongoing flash operation has completed successfully.");
//            break;
//        case NRF_EVT_FLASH_OPERATION_ERROR  :
//            snprintf(m_nrfevent_string, MAX_BUFFER, "%s (%s)", "NRF_EVT_FLASH_OPERATION_ERROR", "Event indicating that the ongoing flash operation has timed out with an error.");
//            break;
//        case NRF_EVT_HFCLKSTARTED   :
//            snprintf(m_nrfevent_string, MAX_BUFFER, "%s (%s)", "NRF_EVT_HFCLKSTARTED ", "Event indicating that the HFCLK has started.");
//            break;
//        case NRF_EVT_POWER_FAILURE_WARNING  :
//            snprintf(m_nrfevent_string, MAX_BUFFER, "%s (%s)", "NRF_EVT_POWER_FAILURE_WARNING", "Event indicating that a power failure warning has occurred.");
//            break;
//        case NRF_EVT_FLASH_OPERATION_SUCCESS  :
//            snprintf(m_nrfevent_string, MAX_BUFFER, "%s (%s)", "NRF_EVT_FLASH_OPERATION_SUCCESS", "Event indicating that the ongoing flash operation has completed successfully.");
//            break;
//        case NRF_EVT_FLASH_OPERATION_ERROR   :
//            snprintf(m_nrfevent_string, MAX_BUFFER, "%s (%s)", "NRF_EVT_FLASH_OPERATION_ERROR ", "Event indicating that the ongoing flash operation has timed out with an error.");
//            break;
        default:
            snprintf(m_nrfevent_string, MAX_BUFFER, "Event: Unknown (%d)", evt_id);
            break;
    }        

    return m_nrfevent_string;
}

char *eventid2string(uint8_t d) {
    switch (d) {   
        case 0 :
            snprintf(m_ancs_string, MAX_BUFFER, "%s", "Notification Added");
            break;
        case 1 :
            snprintf(m_ancs_string, MAX_BUFFER, "%s", "Notification Modified");
            break;
        case 2 :
            snprintf(m_ancs_string, MAX_BUFFER, "%s", "Notification Removed");
            break;            
        default:
            snprintf(m_ancs_string, MAX_BUFFER, "Reserved (%d)", d);
            break;
    }        

    return m_ancs_string;
}

char *eventflags2string(uint8_t d) {
    snprintf(m_ancs_string, MAX_BUFFER, "(no flags)");
    if(d & 3) {
        snprintf(m_ancs_string, MAX_BUFFER, "%s", "Silent & Important");
    } else if(d & 1) {
        snprintf(m_ancs_string, MAX_BUFFER, "%s", "Silent");
    } else if(d & 2) {
        snprintf(m_ancs_string, MAX_BUFFER, "%s", "Important");
    }

    return m_ancs_string;
}

char *categoryid2string(uint8_t d) {
    switch (d) {   
        case 0 :
            snprintf(m_ancs_string, MAX_BUFFER, "%s", "Other");
            break;
        case 1 :
            snprintf(m_ancs_string, MAX_BUFFER, "%s", "Incomming Call");
            break;
        case 2 :
            snprintf(m_ancs_string, MAX_BUFFER, "%s", "Missed Call");
            break;            
        case 3 :
            snprintf(m_ancs_string, MAX_BUFFER, "%s", "Voice Mail");
            break;
        case 4 :
            snprintf(m_ancs_string, MAX_BUFFER, "%s", "Social");
            break;
        case 5 :
            snprintf(m_ancs_string, MAX_BUFFER, "%s", "Schedule");
            break;            
        case 6 :
            snprintf(m_ancs_string, MAX_BUFFER, "%s", "Email");
            break;
        case 7 :
            snprintf(m_ancs_string, MAX_BUFFER, "%s", "News");
            break;
        case 8 :
            snprintf(m_ancs_string, MAX_BUFFER, "%s", "Health And Fitness");
            break;            
        case 9 :
            snprintf(m_ancs_string, MAX_BUFFER, "%s", "Business And Finance");
            break;
        case 10 :
            snprintf(m_ancs_string, MAX_BUFFER, "%s", "Location"); // iBeacon?
            break;
        case 11 :
            snprintf(m_ancs_string, MAX_BUFFER, "%s", "Entertainment");
            break;            
        default:
            snprintf(m_ancs_string, MAX_BUFFER, "Reserved (%d)", d);
            break;
    }        

    return m_ancs_string;
}