This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[ CC2540] ANCS on iphone , how to receive detail of message notification

Other Parts Discussed in Thread: CC2541, CC2540

in timeapp sample 

in ANCS section , how can i subscribe both Notification Source and Data Source  and obtain their callback ?
(https://developer.apple.com/library/ios/documentation/CoreBluetooth/Reference/AppleNotificationCenterServiceSpecification/Specification/Specification.html) 

Brief description: 

9FBF [notify characteristic ] - Notification Source
22EA[notify characteristic ] - Data Source
69D1 [write] - control point 


msg receive ->  9FBF notify with message ID, write command with message ID to 69D1, 22EA will callback the info of that msg

do it means i can get CCCD from both 9FBF , 22EA ?
 and i can start notify both by writing  a value of 0x0001 to the client characteristic configuration descriptor (CCCD). ?
( http://www.deyisupport.com/question_answer/wireless_connectivity/f/45/p/18256/61800.aspx )

i tried to search for CCCD , only can find CCCD in 0x9FBF,
so 0x22EA never  receive callback even i write value to 0x69D1
 

with reference to "timeapp_discover.c"

is the callback of both notify  arrive at  TimeAppDiscAlertNtf ?

  • I am doing proof of concept of ANCS on iphone , my objective is not only get notification when message / miss call arrive iphone, but also want the detail of those message

    how can i at the same time initialize 2 different notification characteristics and where can i got those callback ?

    with reference to http://mbientlab.com/blog/ancs-on-ti2541-in-an-afternoon/

    ANCS on iphone have following 3 characteristics

    9FBF [notify characteristic ] - Notification Source
    22EA[notify characteristic ] - Data Source
    69D1 [write] - control point 

    https://developer.apple.com/library/ios/documentation/CoreBluetooth/Reference/AppleNotificationCenterServiceSpecification/Specification/Specification.html

    brief description : 
    1. when message arrive , 0x0FBF will receive notifcation callback , together with notification ID
    2. using the notification id + attribute wanted, write command string to 0x69D1
    3. if succeed , 0x22EA will receive a notification callback , together with the details of attributed wanted  ( e.g. sender , title , app id ... ) 

    i am stuck on 3. because i can't receive notification of 0x22EA
    i succeed on initialized notification 0x0FBF, by getting CCCD handler and write 0x0001 to it 
    but i can't find CCCD of 0x22EA or its handler , so i can't init the notification 

  • Hello J J,

    I stumbled on this last week but since I only have the iPad, I didn't dig to deeply into it.  The article does seem to provide everything including code.  Maybe it can help you.

    http://mbientlab.com/blog/ancs-on-ti2541-in-an-afternoon/

    Thanks,

  • Hi greenja:

    As i mentioned before , i already come across the link you stated,
    i has no problem of getting the message notification 

    but i can't further get the content of the message , which is send back to another notify characteristic ( there are 2 unique notification in this service i have to listen , one is message notifcation, another is content callback )

    it is essential because notification from facebook,line,imessage are all grouped by "social" category in message notification, i need to find exact app from

    Jeff

  • Hi Jeff, 

    I am also working with mbientlab  sample, but you have gotten further than me. I can't receive the notifications like you have.

    Could you share your source code based on mbientlab. It would be very appreciated.

    Thanks 

    Daniel

  • Self Answer to my question, 

    My assumption is right after several experiment

    The Data Notify need to be activated using same method as Message Notification Source Characteristics,

    The Callback containing the message details will also arrived at 

    timeAppProcessGattMsg( gattMsgEvent_t *pMsg ) on timeapp.c

  • hi Daniel , 

    dont forget to clear the previous pairup on iphone , wrong pairup will fail the notification 

    You need to manually activated the 0x9FBF, 

    As demo in timeapp_discovery.c

    You need to find out the handler of notification source ( 0x9FBF )
    Then find out the CCCD handler of notification source 
    Do a characteristic write to CCCD, write a value of 0x0001, then the 0x9FBF notification will be activated

  • Hi jeff jeff!

    Why are your uuid?
    I use such uuid :
    #define ANCS_NOTIF_CHAR_UUID    0x1DBD
    #define ANCS_CONTROL_CHAR_UUID  0xD9D9
    #define ANCS_DATA_CHAR_UUID     0x7BFB

     
    and CCCD UUID for NOTIF and DATA is
    GATT_CLIENT_CHAR_CFG_UUID == 0x2902 // Client Characteristic Configuration
    for CONTROL
    GATT_CHAR_EXT_PROPS_UUID == 0x2900 // Characteristic Extended Properties
     
    that is for CONTROL
              for ( i = 0; i < pMsg->msg.findInfoRsp.numInfo; i++ )
              {
                if ( (pMsg->msg.findInfoRsp.info.btPair[i].uuid[0] ==
                      LO_UINT16(GATT_CHAR_EXT_PROPS_UUID)) &&
                     (pMsg->msg.findInfoRsp.info.btPair[i].uuid[1] ==
                      HI_UINT16(GATT_CHAR_EXT_PROPS_UUID)) )
                {
                  // CCCD found
                  glassesHdlCache[HDL_ANCS_CTRL_CCCD] =
                    pMsg->msg.findInfoRsp.info.btPair[i].handle;    
                  break;
                }
              }

    but when the message comes from ANCS and I try to write in the Control Point, then an error is returned to me ATT_ERR_WRITE_NOT_PERMITTED 0x03 / /! <Attribute cannot be written
     
    I do so, is that correct?
     
          attWriteReq_t req;             
          req.handle = glassesHdlCache[HDL_ANCS_CTRL_CCCD];
          req.len = 6;
          req.value[0] = 0; // CommandIDGetNotificationAttributes
          req.value[1] = pMsg->msg.handleValueNoti.value[4];       
          req.value[2] = pMsg->msg.handleValueNoti.value[5];       
          req.value[3] = pMsg->msg.handleValueNoti.value[6];       
          req.value[4] = pMsg->msg.handleValueNoti.value[7];     
          req.value[5] = 0; //  NotificationAttributeIDAppIdentifier
          req.sig = 0;
          req.cmd = 0;           
          
          GATT_WriteCharValue( glassesConnHandle, &req, glasses_TaskID );   
          

     
    wanted to ask you whether you want to activate the Control Point and Data Source record 0x0001 or like it on another?

    I'm very sorry for my English translated. I would be very grateful for your response!
  • hi  ,

    sorry , i made some mistake, your ANCS are correct

    you seems mixed up "write characteristic" with "notifiy characteristic activation"


    CCCD handler is used for notify subscription (0x1DBD) , if you need normal "write" characteristics for control point, you just need characteristic  handler (0xD9D9) , you may reference to Ti CentralBLE Sample or google it  
    ( hints : search for  glassesHdlCache[START_ANCS_CTRL_CCCD] in your sourcecode, its very close to your answer ) 

    Please also ensure: 

    1. you need to enable bonding ( pairup )

    2. you need to clear last pair record on iphone everytime you write the new firmware to chipset

  • hi jeff

    switch ( uuid )
    {
    case ANCS_NTF_SOURCE_CHAR_UUID:
    timeAppHdlCache[HDL_ANCS_NTF_SOURCE_START] = handle;
    timeAppEndHdlIdx = HDL_ANCS_NTF_SOURCE_END;
    break;
    case ANCS_DATA_SOURCE_CHAR_UUID:
    timeAppHdlCache[HDL_ANCS_DATA_SOURCE_START] = handle;
    timeAppEndHdlIdx = HDL_ANCS_DATA_SOURCE_END;
    break;
    case ANCS_CTL_POINT_CHAR_UUID:
    timeAppHdlCache[HDL_ANCS_CTL_POINT_CTRL] = handle;
    break;
    default:
    break;
    }

    if ( pMsg->msg.handleValueNoti.handle == 15 )
    {
    attWriteReq_t writeReq;

    writeReq.len = 4;

    writeReq.value[0] = pMsg->msg.handleValueNoti.value[4];
    writeReq.value[1] = pMsg->msg.handleValueNoti.value[5];
    writeReq.value[2] = pMsg->msg.handleValueNoti.value[6];
    writeReq.value[3] = pMsg->msg.handleValueNoti.value[7];

    writeReq.sig = 0;
    writeReq.cmd = 1;
    writeReq.handle = 12;
    GATT_WriteNoRsp( timeAppConnHandle, &writeReq );
    }

  • Well, you changed it? Wrong way? Can talk about it?

  • wei lu said:

    if ( pMsg->msg.handleValueNoti.handle == 15 )

    why do you listen at handle 15? is it fixed?

    wei lu said:

    writeReq.len = 4;

    writeReq.value[0] = pMsg->msg.handleValueNoti.value[4];
    writeReq.value[1] = pMsg->msg.handleValueNoti.value[5];
    writeReq.value[2] = pMsg->msg.handleValueNoti.value[6];
    writeReq.value[3] = pMsg->msg.handleValueNoti.value[7];

    writeReq.sig = 0;
    writeReq.cmd = 1;
    writeReq.handle = 12;

    ANCS C.P command is not in this format.
    where is your attribute id?
    also, cmd should be 0.
    at the end, why do you fix handle at 12 again?

    wei lu said:

    GATT_WriteNoRsp( timeAppConnHandle, &writeReq );

    in spec., control point is "write with response".

  • kirill poznyak said:

    attWriteReq_t req; req.handle = glassesHdlCache[HDL_ANCS_CTRL_CCCD];



    you should not write to CCCD, the UUID you have to write is "control point".

    I failed at receiving "10 12 0 FB 7B 7C CE 6A B3 44 BE B5 4B D6 24 E9 C6 EA 22" via

    data source handle, it looks wrong, but I don't know why...

  • sorry Kuo, I have poor English。

    Direct access ANCS_CTL_POINT_CHAR_UUID

                // If UUID is of interest, store handle
                switch ( uuid )
                {
                  case ANCS_NTF_SOURCE_CHAR_UUID:
                    timeAppHdlCache[HDL_ANCS_NTF_SOURCE_START] = handle;
                    timeAppEndHdlIdx = HDL_ANCS_NTF_SOURCE_END;
                    break;
                  case ANCS_DATA_SOURCE_CHAR_UUID:
                    timeAppHdlCache[HDL_ANCS_DATA_SOURCE_START] = handle;
                    timeAppEndHdlIdx = HDL_ANCS_DATA_SOURCE_END;
                    break;
                  case ANCS_CTL_POINT_CHAR_UUID:
                    timeAppHdlCache[HDL_ANCS_CTL_POINT_CTRL] = handle;
                    break;
                  default:
                    break;
                }
    
    void timeAppIndGattMsg( gattMsgEvent_t *pMsg )
    {
      unsigned char i = 0;
      if ( pMsg->msg.handleValueNoti.handle == timeAppHdlCache[HDL_ANCS_NTF_SOURCE_START] )
      {
          attWriteReq_t writeReq;
          
          writeReq.len = 10;
          writeReq.value[0] = 0;
          writeReq.value[1] = pMsg->msg.handleValueNoti.value[4];
          writeReq.value[2] = pMsg->msg.handleValueNoti.value[5];
          writeReq.value[3] = pMsg->msg.handleValueNoti.value[6];
          writeReq.value[4] = pMsg->msg.handleValueNoti.value[7];
          writeReq.value[5] = 0;
          writeReq.value[6] = 1;
          writeReq.value[7] = 0xff;
          writeReq.value[8] = 0xff;
          writeReq.value[9] = 5;
          writeReq.sig = 0;
          writeReq.cmd = 0;
          writeReq.handle = timeAppHdlCache[HDL_ANCS_CTL_POINT_CTRL];
          GATT_WriteCharValue( timeAppConnHandle, &writeReq, timeAppTaskId);
      }
      
      else if ( pMsg->msg.handleValueNoti.handle == timeAppHdlCache[HDL_ANCS_DATA_SOURCE_START] )   
      {
         //data source notification,I did not receive notify
      }
    }
    

  • wei lu said:

    sorry Kuo, I have poor English。

    if ( pMsg->msg.handleValueNoti.handle == timeAppHdlCache[HDL_ANCS_DATA_SOURCE_START] ) { //data source notification,I did not receive notify } }

    never mind, English is not my tongue, too. I come from TW.
    by the way, I had the same progress as you right now.

    in spec., data source is written as "notifiable", so I am confused if this is as same as "notification source",
    or I just send a "GATT_ReadCharValue".

    in my way, I uses "osal_start_timerEx( timeAppTaskId, START_FRED_EVT, 0);" to register an event. It was
    called when "ATT_WRITE_RSP" is received. This event will trigger the "GATT_ReadCharValue".

    In this way, I can read messages from data source characteristic, but the return value is wrong.

    I tried to set "data source" notifiable, but it failed.

    hope anyone may give me a further instruction....

  • problem is solved. set nofi for data source.

  • I have still not been resolved, I do not know how it is. You can provide point a further instruction ...

  • Thank Kuo,

    problem is solved...I can receive telephone number, the data source notification is work.

  • wei lu said:

    Thank Kuo,

    problem is solved...I can receive telephone number, the data source notification is work.

    cool, may I know if the incoming call number is achieved from "get noti attribute" or
    "get APP attribute"? I can only receive a string "incoming call", a "get APP attribute"
    is required I think.

    b.t.w, call me "Yang", not "Kuo". (smile)

  • wei lu said:



    I know this, so you use 3: IDMessage? (I was told so)

  •       writeReq.len = 15;
          writeReq.value[0] = 0;
          writeReq.value[1] = pMsg->msg.handleValueNoti.value[4];
          writeReq.value[2] = pMsg->msg.handleValueNoti.value[5];
          writeReq.value[3] = pMsg->msg.handleValueNoti.value[6];
          writeReq.value[4] = pMsg->msg.handleValueNoti.value[7];
          writeReq.value[5] = 0x01;       //Title
          writeReq.value[6] = 0xff;
          writeReq.value[7] = 0Xff;
          writeReq.value[8] = 0X02;       //Subtitle
          writeReq.value[9] = 0Xff;
          writeReq.value[10] = 0Xff;
          writeReq.value[11] = 0X03;      //Message
          writeReq.value[12] = 0Xff;
          writeReq.value[13] = 0Xff;
          writeReq.value[14] = 0X05;      //Date

  • wei lu said:
          writeReq.len = 15;
          writeReq.value[0] = 0;
          writeReq.value[1] = pMsg->msg.handleValueNoti.value[4];
          writeReq.value[2] = pMsg->msg.handleValueNoti.value[5];
          writeReq.value[3] = pMsg->msg.handleValueNoti.value[6];
          writeReq.value[4] = pMsg->msg.handleValueNoti.value[7];
          writeReq.value[5] = 0x01;       //Title
          writeReq.value[6] = 0xff;
          writeReq.value[7] = 0Xff;
          writeReq.value[8] = 0X02;       //Subtitle
          writeReq.value[9] = 0Xff;
          writeReq.value[10] = 0Xff;
          writeReq.value[11] = 0X03;      //Message
          writeReq.value[12] = 0Xff;
          writeReq.value[13] = 0Xff;
          writeReq.value[14] = 0X05;      //Date



    which one is the phone number...?
    0x02 is the alias (contact person info), I cannot get number directly...

    so I wonder if "get APP attribute" is necessary.

    thanks for reply.

  • If the telephone number is recorded in the phone, it will display the name but not telephone number . You can use the strangers telephone , it shows telephone  number.

  • wei lu said:

    If the telephone number is recorded in the phone, it will display the name but not telephone number . You can use the strangers telephone , it shows telephone  number.

    Yes, I found it, too. bravo bro, we both conquer this solution now.

  • Hi All,

           i'm working on ANCS client application using TI timeapp sample project and i did changes in the timeapp_discovery.c file according to following link

     http://mbientlab.com/blog/ancs-on-ti2541-in-an-afternoon/

    I connected the client device(keyfob) with iphone 4s using pairing process and it was successfully paired with iphone, after that client device discovered the ANCS using timeAppDiscStart() function.

    i got timeApp_ProcessOSALMsg() callback for enabling notifications and after that i am not getting any notifications for text messages.

    please help me to resolve this issue.

    thanks

    prabakaran

  • Hi wei,

    I have changed my code accordingly as you mentioned above.Do you have any idea how to process each category in timeApp_ProcessOsaLMsg(). I am able to blink the led on the keyfob when i receive a mail or message. Now i have to recognise each category and display on the LCD.Do you have any idea how to do it?

  • Hi

    I have changed my code accordingly as you mentioned above.Do you have any idea how to process each category in timeApp_ProcessOsaLMsg(). I am able to blink the led on the keyfob when i receive a mail or message. Now i have to recognise each category and display on the LCD.Do you have any idea how to do it?

    The following code snippet where i am able to blink an LED on keyfob .

    switch ( pMsg->event )
    {
    case KEY_CHANGE:
    timeApp_HandleKeys( ((keyChange_t *)pMsg)->state, ((keyChange_t *)pMsg)->keys );
    break;

    case GATT_MSG_EVENT:
    count++;
    if(count==1)
    {
    P1_0=1;
    P1_1=0;
    }
    if(count==2)
    {
    count=0;
    P1_0=0;
    P1_1=1;
    }
    timeAppProcessGattMsg( (gattMsgEvent_t *) pMsg );
    break;

    default:
    break;
    }
    }

    Can anybody tell me how to process each category seperately here?

  • Don,

    I haven't really followed the correspondence above.  I assume you have used the timeApp example and are able to subscribe to the ANCS services correctly?  If so, then when you receive a value notification you need to parse the value.  If you look at the ANCS documentation from apple, the third bit indicates what caused the notification.  See below...  If you are using the code above, be carful to make sure it is a value notification and it's from the handle of the notification source.

    uint8 *p = pMsg->msg.handleValueNoti.value;
          if (p[0] == 0){
            if (p[2] == 4){ //Social
              HalLedSet( HAL_LED_1 , HAL_LED_MODE_ON ); // Keyfob LED1 On
            }
            if (p[2] == 6){ //Eamil
              HalLedSet( HAL_LED_2 , HAL_LED_MODE_ON ); // Keyfob LED2 On
            }
             if (p[2] == 1){ //Phone
              HalLedSet( HAL_LED_2  , HAL_LED_MODE_OFF ); // Keyfob LED 1 and 2 off
              HalLedSet( HAL_LED_1 , HAL_LED_MODE_OFF );
            }

  • Hi,

    I can get the notification alert from the Iphone, but still I am still not able to get the data. Is it possible for you to share details of your source code to get the data from data source?

  • Are you able to get data source notification into work?

  • Not really... I am still having trouble enabling the data source. I can see the handle in the list. After that I enable the data source and still don't see data after notification.

  • Hi,

    I am working on ANCS on cc2541 for a while.Recently i  was able to put all the sources to work.But with the latest IOS 8 i am not able to get the data source working, allthough i am able to get basic notifications.Can anybody tell what changes i have to make with the TimeApp discovery so that the data source works with IOS 8

    Regards

    Don

  • HI wei lu

       1. can you tell me  what is the HDL_ANCS_DATA_SOURCE_EN value  or    it define

       2 . where call the timeAppIndGattMsg() functione;

  • Hi lu:

          do you have finish ANCS in CC2540?

          i have a question about the  define   ATT_UUID_SIZE,

          why does it define as 16bit

          was it  128bit ?