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.

CCS/CC2640R2F: Value not received during write operation of BLE service

Part Number: CC2640R2F
Other Parts Discussed in Thread: BLE-STACK, , CC2640

Tool/software: Code Composer Studio

I have created one BLE service to write the data to microcontroller using service generator. following is the code for callback :

static void user_Led_ServiceValueChangeCB(uint8_t paramID)
{
// See Led_Service.h to compare paramID with characteristic value attribute.
// Called in Stack Task context, so can't do processing here.

// Send message to application message queue about received data.
uint16_t readLen=0; // How much to read via service API

switch (paramID)
{
case LED_SERVICE_LED_CONTROL:
readLen = LED_SERVICE_LED_CONTROL_LEN;
break;
}

app_msg_t *pMsg = ICall_malloc( sizeof(app_msg_t) + sizeof(server_char_write_t) + readLen );

// Allocate memory for the message.
// Note: The message doesn't have to contain the data itself, as that's stored in
// a variable in the service. However, to prevent data loss if a new value is received
// before GetParameter is called, we call GetParameter now.
server_char_write_t *pWrite = ICall_malloc(sizeof(server_char_write_t) + readLen);

if (pWrite != NULL)
{
//pMsg->type = appMsgType;
// server_char_write_t *pWrite = (server_char_write_t *)pMsg->pdu;
pWrite->svcUUID = LED_SERVICE_SERV_UUID;
pWrite->dataLen = readLen;
pWrite->paramID = paramID;
// memcpy(pWrite->data, pValue, readLen);
// Get the data from the service API.
// Note: Fixed length is used here, but changing the GetParameter signature is not
// a problem, in case variable length is needed.
// Note: It could be just as well to send dataLen and a pointer to the received data directly to this callback, avoiding GetParameter alltogether.
Led_Service_GetParameter( paramID, pWrite->data );

// Enqueue the message using pointer to queue node element.
Queue_enqueue(hServiceMsgQ, &pWrite->_elem);
// Let application know there's a message
Event_post(syncEvent, PRZ_APP_MSG_EVT);
}
}


void user_Led_Service_ValueChangeDispatchHandler(server_char_write_t *pWrite)
{
//*a=pWrite->data;
switch (pWrite->paramID)
{
case LED_SERVICE_LED_CONTROL:
// Do something useful with pWrite->data here
// -------------------------
GPIO_write(Board_GPIO_LED1, Board_GPIO_LED_ON);
// Do something useful with pWrite->data here
// -------------------------
if (pWrite->data == "00")
{
// PIN_setOutputValue(ledPinHandle, Board_RLED, 0);
GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_OFF);
}
else if (pWrite->data == "01" )
{
GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);
// PIN_setOutputValue(ledPinHandle, Board_RLED, 1);
}
break;

default:
return;
}

}

following is the code for writeattributecallback defined in Led_Service.c

static bStatus_t Led_Service_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
uint8 *pValue, uint16 len, uint16 offset,
uint8 method )
{
bStatus_t status = SUCCESS;
uint8_t paramID = 0xFF;

// See if request is regarding a Client Characterisic Configuration
if ( ! memcmp(pAttr->type.uuid, clientCharCfgUUID, pAttr->type.len) )
{
// Allow only notifications.
status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,
offset, GATT_CLIENT_CFG_NOTIFY);
}
// See if request is regarding the Led_Control Characteristic Value
else if ( ! memcmp(pAttr->type.uuid, Led_Service_Led_ControlUUID, pAttr->type.len) )
{
if ( offset + len > LED_SERVICE_LED_CONTROL_LEN )
{
status = ATT_ERR_INVALID_OFFSET;
}
else
{
// Copy pValue into the variable we point to from the attribute table.
memcpy(pAttr->pValue + offset, pValue, len);

// Only notify application if entire expected value is written
if ( offset + len == LED_SERVICE_LED_CONTROL_LEN)
paramID = LED_SERVICE_LED_CONTROL;
}
}
else
{
// If we get here, that means you've forgotten to add an if clause for a
// characteristic value attribute in the attribute table that has WRITE permissions.
status = ATT_ERR_ATTR_NOT_FOUND;
}

// Let the application know something changed (if it did) by using the
// callback it registered earlier (if it did).
if (paramID != 0xFF)
if ( pAppCBs && pAppCBs->pfnChangeCb )
pAppCBs->pfnChangeCb( paramID ); // Call app function from stack task context.

return status;
}

no value is received in pWrite->data what can be the error in this.

Please help me with this.

Urgently Required.

Cheers,

Smriti

 

  • Hello Smriti,

    Did you confirm with a sniffer that the write operation was sent by the client to the correct server handle?

    Best wishes
  • Hi JXS,

    Can you please explain what do you exactly mean.

    Smriti
  • Please look into this as this is urgently required.
  • Hi JXS,

    I have implemented the code given in resource explorer to generate services and it is not working. How can TI service generator provide us with wrong codes to implement which don't work when implemented. This is something TI should look into. This is really disturbing that the online tool provided in simplelink academy generates wrong code.
    Please help me with what changes should i make in my generated code.

    Smriti
  • Hi JXS,

    Please help me with this as this is the only thing remaining and because of this my entire project is at hold.

    Smriti
  • Hi Smriti,

    It's probably something as simple as changing the include files in your service code. Since you didn't provide the SDK/component that you are using, I can't be certain. Here's the porting guide for BLE-Stack v3.1.0 (SDK 1.40):
    software-dl.ti.com/.../blestack3.00.01-to-blestack3.01.00.html

    Note step three.

    Best wishes
  • Hi JXS,

    I am using simplelink_cc2640r2_sdk_1_35_00_33. I generated and included my service code from service generator given in the following link
    dev.ti.com/.../
    i have also shared my code above.

    Cheers,
    smriti
  • I don't have to migrate my ble stack
  • Hi JXS,

    I provided you with the details kindly see to it. This is urgently required.

    Smriti
  • Hi smriti,

    Just use the Project Zero for TI CC2640R2F. It has led service.

    github.com/.../ble_examples-3.0

    github.com/.../blestack

    - kel
  • Hi Kel,

    I have seen this example and tried to implement it in my code but it did not work.

    Smriti
  • Hi smriti,

    I have used the led service and button service to Simple Peripheral from SDK v1.40 and it worked.

    What exactly do you want your program to do?

    - kel
  • Markel Robregado said:
    Hi smriti,

    I have used the led service and button service to Simple Peripheral from SDK v1.40 and it worked.

    What exactly do you want your program to do?

    - kel

    Hi KEL,

    I want to control my LED from my phone using 0(off) and 1(on).  I made one led service to do this task. I implemented this service with the code provided by service generator in resource explorer. I am attaching files please see to it.

    led_service.c
    /*
     * led_service.c
     *
     *  Created on: 18-Sep-2017
     *      Author: smriti asthana
     */
    /**********************************************************************************************
     * Filename:       Led_Service.c
     *
     * Description:    This file contains the implementation of the service.
     *
     * Copyright (c) 2015-2017, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     *************************************************************************************************/
    
    
    /*********************************************************************
     * INCLUDES
     */
    #include <string.h>
    
    #include "bcomdef.h"
    #include "OSAL.h"
    #include "linkdb.h"
    #include "att.h"
    #include "gatt.h"
    #include "gatt_uuid.h"
    #include "gattservapp.h"
    #include "gapbondmgr.h"
    
    #include "Led_Service.h"
    
    #ifdef ICALL_LITE
    #  include "icall_ble_api.h" // Use ifdef to be compatible with older stack versions
    #endif
    
    /*********************************************************************
     * MACROS
     */
    
    /*********************************************************************
     * CONSTANTS
     */
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    /*********************************************************************
    * GLOBAL VARIABLES
    */
    
    // Led_Service Service UUID
    CONST uint8_t Led_ServiceUUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(LED_SERVICE_SERV_UUID), HI_UINT16(LED_SERVICE_SERV_UUID)
    };
    
    // Led_Control UUID
    CONST uint8_t Led_Service_Led_ControlUUID[ATT_UUID_SIZE] =
    {
      TI_BASE_UUID_128(LED_SERVICE_LED_CONTROL_UUID)
    };
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    
    static Led_ServiceCBs_t *pAppCBs = NULL;
    
    /*********************************************************************
    * Profile Attributes - variables
    */
    
    // Service declaration
    static CONST gattAttrType_t Led_ServiceDecl = { ATT_BT_UUID_SIZE, Led_ServiceUUID };
    
    // Characteristic "Led_Control" Properties (for declaration)
    static uint8_t Led_Service_Led_ControlProps = GATT_PROP_WRITE;
    
    // Characteristic "Led_Control" Value variable
    static uint8_t Led_Service_Led_ControlVal[LED_SERVICE_LED_CONTROL_LEN] = {0};
    
    /*********************************************************************
    * Profile Attributes - Table
    */
    
    static gattAttribute_t Led_ServiceAttrTbl[] =
    {
      // Led_Service Service Declaration
      {
        { ATT_BT_UUID_SIZE, primaryServiceUUID },
        GATT_PERMIT_READ,
        0,
        (uint8_t *)&Led_ServiceDecl
      },
        // Led_Control Characteristic Declaration
        {
          { ATT_BT_UUID_SIZE, characterUUID },
          GATT_PERMIT_READ,
          0,
          &Led_Service_Led_ControlProps
        },
          // Led_Control Characteristic Value
          {
            { ATT_UUID_SIZE, Led_Service_Led_ControlUUID },
            GATT_PERMIT_READ | GATT_PERMIT_WRITE,
            0,
            Led_Service_Led_ControlVal
          },
    };
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    static bStatus_t Led_Service_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
                                               uint8 *pValue, uint16 *pLen, uint16 offset,
                                               uint16 maxLen, uint8 method );
    static bStatus_t Led_Service_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
                                                uint8 *pValue, uint16 len, uint16 offset,
                                                uint8 method );
    
    /*********************************************************************
     * PROFILE CALLBACKS
     */
    // Simple Profile Service Callbacks
    CONST gattServiceCBs_t Led_ServiceCBs =
    {
      Led_Service_ReadAttrCB,  // Read callback function pointer
      Led_Service_WriteAttrCB, // Write callback function pointer
      NULL                       // Authorization callback function pointer
    };
    
    /*********************************************************************
    * PUBLIC FUNCTIONS
    */
    
    /*
     * Led_Service_AddService- Initializes the Led_Service service by registering
     *          GATT attributes with the GATT server.
     *
     */
    bStatus_t Led_Service_AddService( void )
    {
      uint8_t status;
    
      // Register GATT attribute list and CBs with GATT Server App
      status = GATTServApp_RegisterService( Led_ServiceAttrTbl,
                                            GATT_NUM_ATTRS( Led_ServiceAttrTbl ),
                                            GATT_MAX_ENCRYPT_KEY_SIZE,
                                            &Led_ServiceCBs );
    
      return ( status );
    }
    
    /*
     * Led_Service_RegisterAppCBs - Registers the application callback function.
     *                    Only call this function once.
     *
     *    appCallbacks - pointer to application callbacks.
     */
    bStatus_t Led_Service_RegisterAppCBs( Led_ServiceCBs_t *appCallbacks )
    {
      if ( appCallbacks )
      {
        pAppCBs = appCallbacks;
    
        return ( SUCCESS );
      }
      else
      {
        return ( bleAlreadyInRequestedMode );
      }
    }
    
    /*
     * Led_Service_SetParameter - Set a Led_Service parameter.
     *
     *    param - Profile parameter ID
     *    len - length of data to right
     *    value - pointer to data to write.  This is dependent on
     *          the parameter ID and WILL be cast to the appropriate
     *          data type (example: data type of uint16 will be cast to
     *          uint16 pointer).
     */
    bStatus_t Led_Service_SetParameter( uint8 param, uint8 len, void *value )
    {
      bStatus_t ret = SUCCESS;
      switch ( param )
      {
        case LED_SERVICE_LED_CONTROL:
          if ( len == LED_SERVICE_LED_CONTROL_LEN )
          {
            memcpy(Led_Service_Led_ControlVal, value, len);
          }
          else
          {
            ret = bleInvalidRange;
          }
          break;
    
        default:
          ret = INVALIDPARAMETER;
          break;
      }
      return ret;
    }
    
    
    /*
     * Led_Service_GetParameter - Get a Led_Service parameter.
     *
     *    param - Profile parameter ID
     *    value - pointer to data to write.  This is dependent on
     *          the parameter ID and WILL be cast to the appropriate
     *          data type (example: data type of uint16 will be cast to
     *          uint16 pointer).
     */
    bStatus_t Led_Service_GetParameter( uint8 param, void *value )
    {
      bStatus_t ret = SUCCESS;
      switch ( param )
      {
        case LED_SERVICE_LED_CONTROL:
          memcpy(value, Led_Service_Led_ControlVal, LED_SERVICE_LED_CONTROL_LEN);
          break;
    
        default:
          ret = INVALIDPARAMETER;
          break;
      }
      return ret;
    }
    
    
    /*********************************************************************
     * @fn          Led_Service_ReadAttrCB
     *
     * @brief       Read an attribute.
     *
     * @param       connHandle - connection message was received on
     * @param       pAttr - pointer to attribute
     * @param       pValue - pointer to data to be read
     * @param       pLen - length of data to be read
     * @param       offset - offset of the first octet to be read
     * @param       maxLen - maximum length of data to be read
     * @param       method - type of read message
     *
     * @return      SUCCESS, blePending or Failure
     */
    static bStatus_t Led_Service_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
                                           uint8 *pValue, uint16 *pLen, uint16 offset,
                                           uint16 maxLen, uint8 method )
    {
      bStatus_t status = SUCCESS;
    
      // See if request is regarding the Led_Control Characteristic Value
    if ( ! memcmp(pAttr->type.uuid, Led_Service_Led_ControlUUID, pAttr->type.len) )
      {
        if ( offset > LED_SERVICE_LED_CONTROL_LEN )  // Prevent malicious ATT ReadBlob offsets.
        {
          status = ATT_ERR_INVALID_OFFSET;
        }
        else
        {
          *pLen = MIN(maxLen, LED_SERVICE_LED_CONTROL_LEN - offset);  // Transmit as much as possible
          memcpy(pValue, pAttr->pValue + offset, *pLen);
        }
      }
      else
      {
        // If we get here, that means you've forgotten to add an if clause for a
        // characteristic value attribute in the attribute table that has READ permissions.
        *pLen = 0;
        status = ATT_ERR_ATTR_NOT_FOUND;
      }
    
      return status;
    }
    
    
    /*********************************************************************
     * @fn      Led_Service_WriteAttrCB
     *
     * @brief   Validate attribute data prior to a write operation
     *
     * @param   connHandle - connection message was received on
     * @param   pAttr - pointer to attribute
     * @param   pValue - pointer to data to be written
     * @param   len - length of data
     * @param   offset - offset of the first octet to be written
     * @param   method - type of write message
     *
     * @return  SUCCESS, blePending or Failure
     */
    static bStatus_t Led_Service_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
                                            uint8 *pValue, uint16 len, uint16 offset,
                                            uint8 method )
    {
      bStatus_t status  = SUCCESS;
      uint8_t   paramID = 0xFF;
    
      // See if request is regarding a Client Characterisic Configuration
      if ( ! memcmp(pAttr->type.uuid, clientCharCfgUUID, pAttr->type.len) )
      {
        // Allow only notifications.
        status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,
                                                 offset, GATT_CLIENT_CFG_NOTIFY);
      }
      // See if request is regarding the Led_Control Characteristic Value
      else if ( ! memcmp(pAttr->type.uuid, Led_Service_Led_ControlUUID, pAttr->type.len) )
      {
        if ( offset + len > LED_SERVICE_LED_CONTROL_LEN )
        {
          status = ATT_ERR_INVALID_OFFSET;
        }
        else
        {
          // Copy pValue into the variable we point to from the attribute table.
          memcpy(pAttr->pValue + offset, pValue, len);
    
          // Only notify application if entire expected value is written
          if ( offset + len == LED_SERVICE_LED_CONTROL_LEN)
            paramID = LED_SERVICE_LED_CONTROL;
        }
      }
      else
      {
        // If we get here, that means you've forgotten to add an if clause for a
        // characteristic value attribute in the attribute table that has WRITE permissions.
        status = ATT_ERR_ATTR_NOT_FOUND;
      }
    
      // Let the application know something changed (if it did) by using the
      // callback it registered earlier (if it did).
      if (paramID != 0xFF)
        if ( pAppCBs && pAppCBs->pfnChangeCb )
          pAppCBs->pfnChangeCb( paramID ); // Call app function from stack task context.
    
      return status;
    }
    
    
    
    

    led_service.h

    implementation_file.c
    /*
     * implementation_file.c
     *
     *  Created on: 18-Sep-2017
     *      Author: smriti asthana
     */
    
    /**********************************************************************************************
     * Filename:       appsnippets.c
     *
     * Description:    This file contains snippets needed to utilize the generated services.
     *
     * Copyright (c) 2015-2017, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     *************************************************************************************************/
    
    //...
    #include <ti/sysbios/knl/Event.h>
    #include <ti/sysbios/knl/Queue.h>
    
    //...
    #include "Led_Service.h"
    
    //...
    
    // Event handle globally used to post events to the application thread
    static ICall_SyncHandle syncEvent; // Already present in sample applications.
    
    // Queue object used for service messages.
    static Queue_Struct serviceMsgQ;
    static Queue_Handle hServiceMsgQ;
    
    // Struct for messages from a service
    typedef struct
    {
      Queue_Elem _elem;
      uint16_t svcUUID;
      uint16_t dataLen;
      uint8_t  paramID;
      uint8_t  data[]; // Flexible array member, extended to malloc - sizeof(.)
    } server_char_write_t;
    
    //...
    
    // Declaration of service callback handlers
    static void user_Led_ServiceValueChangeCB(uint8_t paramID); // Callback from the service.
    static void user_Led_Service_ValueChangeDispatchHandler(server_char_write_t *pWrite); // Local handler called from the Task context of this task.
    
    // Service callback function implementation
    // Led_Service callback handler. The type Led_ServiceCBs_t is defined in Led_Service.h
    static Led_ServiceCBs_t user_Led_ServiceCBs =
    {
      user_Led_ServiceValueChangeCB // Characteristic value change callback handler
    };
    
    
    // taskFxn_init(..)
    // {
      // Initialize queue for service messages.
      // Note: Used to transfer control to application thread
      Queue_construct(&serviceMsgQ, NULL);
      hServiceMsgQ = Queue_handle(&serviceMsgQ);
    
      Led_Service_AddService();
      Led_Service_RegisterAppCBs(&user_Led_ServiceCBs);
    
      // Placeholder variable for characteristic intialization
      uint8_t someVal[20] = {0};
    
      // Initalization of characteristics in Led_Service that are readable.
    
    //}
    
    
    // taskFxn(..)
    // {
    //   for (;;) {
    //     ... events = Event_pend(...)   // Wait for event
    //
          while (!Queue_empty(hServiceMsgQ))
          {
            server_char_write_t *pWrite = Queue_dequeue(hServiceMsgQ);
    
            switch(pWrite->svcUUID)
            {
              case LED_SERVICE_SERV_UUID:
                user_Led_Service_ValueChangeDispatchHandler(pWrite);
                break;
            }
    
            // Free the message received from the service callback.
            ICall_free(pWrite);
          }
    
    //      }
    //   }
    // }
    
    
    void user_Led_Service_ValueChangeDispatchHandler(server_char_write_t *pWrite)
    {
      switch (pWrite->paramID)
      {
            case LED_SERVICE_LED_CONTROL:
          // Do something useful with pWrite->data here
          // -------------------------
          break;
          }
    
    }
    
    
    static void user_Led_ServiceValueChangeCB(uint8_t paramID)
    {
      // See Led_Service.h to compare paramID with characteristic value attribute.
      // Called in Stack Task context, so can't do processing here.
    
      // Send message to application message queue about received data.
      uint16_t readLen = 0; // How much to read via service API
    
      switch (paramID)
      {
        case LED_SERVICE_LED_CONTROL:
          readLen = LED_SERVICE_LED_CONTROL_LEN;
          break;
      }
    
      // Allocate memory for the message.
      // Note: The message doesn't have to contain the data itself, as that's stored in
      //       a variable in the service. However, to prevent data loss if a new value is received
      //       before GetParameter is called, we call GetParameter now.
      server_char_write_t *pWrite = ICall_malloc(sizeof(server_char_write_t) + readLen);
    
      if (pWrite != NULL)
      {
        pWrite->svcUUID = LED_SERVICE_SERV_UUID;
        pWrite->dataLen = readLen;
        pWrite->paramID = paramID;
        // Get the data from the service API.
        // Note: Fixed length is used here, but changing the GetParameter signature is not
        //       a problem, in case variable length is needed.
        // Note: It could be just as well to send dataLen and a pointer to the received data directly to this callback, avoiding GetParameter alltogether.
        Led_Service_GetParameter( paramID, pWrite->data );
    
        // Enqueue the message using pointer to queue node element.
        Queue_enqueue(hServiceMsgQ, &pWrite->_elem);
        // Let application know there's a message
        Event_post(syncEvent, PRZ_APP_MSG_EVT);
      }
    }
    
    
    
    

    Kindly look into this.  Urgently required.

    Smriti 

  • Hello Smriti ,

    You are using the service generator which is generating code for SDK 1.40. However, you are trying to use the auto-generated code in an earlier SDK 1.35. Since we don't offer a 'backporting' guide, I suggest making sure the include files match the SDK 1.35 (you can review an existing service.c example) or, as KEL suggests, use SDK 1.40.

    Best wishes
  • Hi JXS,

    I am have used SDK1.40 only not 1.35 still it's not working. please can you tell where is the code generated by service generator wrong.

    Smriti
  • Hi JXS,

    i am stuck in my project because of this. i can't find what is the mistake in the code please review it and help me.

    Smriti
  • Hi Kel,

    I provided you with the board files and i'm using SDK version 1.40 . please go through it nf tell me where is the mistake in the file. this is urgently required.

    Smriti
  • Hi JXS,

    I provided you with board files. please go through it and let me know where is the error, if you did't then atleast let me know that you didn't. this would be very useful for me.

    Smriti
  • Hi Smriti,

    I would suggest you start by downloading the Project Zero project as Kel suggested, running that and seeing how it works. It can be found here:
    Project Zero SimpleLink CC2640R2 SDK v1.40

    That example contains a service that does what you're trying to accomplish, once you see that working and figure out how it works you can take what you need from that project and port it to the project you are currently working on.

    Hope that helps,
    Gerardo

  • HI Gerardo,

    I already saw project zero and run it on my launchpad. it was running fine then i copied the part of code i needed and it didn't work then. then i decided to use service generator but the code is not working. i am very much troubled because of this so please help me.

    Smriti
  • Hi Gerardo,

    i have attached my service file also in previous messages please go through it and help me with this.

    Smriti
  • Which part of the code did you originally copy from project zero?

    I can skim through the code you have provided to see if anything stands out as being wrong, but it's probably going to be better for me to understand what you've done so far.

    Thanks,
    Gerardo

  • I see that you have only included the generated application implementation file and not the one with your changes added to it, could you also add that so I can make sure you're not missing something there.

    Thanks,
    Gerardo
  • Hi Gerardo,

    Thanks, I am uploading my simple peripheral.c file and my led service files also please go through them and inform me where is the mistake.

    8132.simple_peripheral.c
    /******************************************************************************
    
     @file  simple_peripheral.c
    
     @brief This file contains the Simple BLE Peripheral sample application for use
            with the CC2640 Bluetooth Low Energy Protocol Stack.
    
     Group: CMCU, SCS
     Target Device: CC2640R2
    
     ******************************************************************************
     
     Copyright (c) 2013-2017, Texas Instruments Incorporated
     All rights reserved.
    
     Redistribution and use in source and binary forms, with or without
     modification, are permitted provided that the following conditions
     are met:
    
     *  Redistributions of source code must retain the above copyright
        notice, this list of conditions and the following disclaimer.
    
     *  Redistributions in binary form must reproduce the above copyright
        notice, this list of conditions and the following disclaimer in the
        documentation and/or other materials provided with the distribution.
    
     *  Neither the name of Texas Instruments Incorporated nor the names of
        its contributors may be used to endorse or promote products derived
        from this software without specific prior written permission.
    
     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    
     ******************************************************************************
     Release Name: simplelink_cc2640r2_sdk_1_30_00_25
     Release Date: 2017-03-02 20:08:31
     *****************************************************************************/
    
    /*********************************************************************
     * INCLUDES
     */
    #include <string.h>
    
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Event.h>
    #include <ti/sysbios/knl/Queue.h>
    #include <ti/sysbios/knl/Semaphore.h>
    #include <ti/drivers/rf/RF.h>
    #include <ti/drivers/GPIO.h>
    //#include <ti/drivers/pin/PINCC26xx.h>
    
    
    #if defined(FEATURE_OAD) || defined(IMAGE_INVALIDATE)
    #include "oad_target.h"
    #include "oad.h"
    #endif //FEATURE_OAD || IMAGE_INVALIDATE
    #include "peripheral.h"
    #include "gapbondmgr.h"
    
    #include "bcomdef.h"
    #include "osal_snv.h"
    #include "icall_apimsg.h"
    #include "hci_tl.h"
    #include "gatt.h"
    #include "linkdb.h"
    #include "gapgattserver.h"
    #include "gattservapp.h"
    #include "devinfoservice.h"
    #include "simple_gatt_profile.h"
    #include "ll_common.h"
    #include "util.h"
    /***** temperature sensor libraries******/
    #include "adc.h"
    #include "temp_sensor.h"
    #include <ti/drivers/ADC.h>
    /***********Led Service Libraries**********/
    #include "led_service.h"
    
    /********timer libraries*********/
    #include "timer.h"
    
    
    #ifdef USE_RCOSC
    #include "rcosc_calibration.h"
    #endif //USE_RCOSC
    
    #ifdef USE_CORE_SDK
      #include <ti/display/Display.h>
    #else // !USE_CORE_SDK
      #include <ti/mw/display/Display.h>
    #endif // USE_CORE_SDK
    #include "board_key.h"
    
    #include "board.h"
    
    #include "simple_peripheral.h"
    
    #if defined( USE_FPGA ) || defined( DEBUG_SW_TRACE )
    #include <driverlib/ioc.h>
    #endif // USE_FPGA | DEBUG_SW_TRACE
    
    #include "icall_api.h"
    /*********************************************************************
     * CONSTANTS
     */
    static ICall_Semaphore sem;
    
    // Advertising interval when device is discoverable (units of 625us, 160=100ms)
    #define DEFAULT_ADVERTISING_INTERVAL          160
    
    // Limited discoverable mode advertises for 30.72s, and then stops
    // General discoverable mode advertises indefinitely
    #define DEFAULT_DISCOVERABLE_MODE             GAP_ADTYPE_FLAGS_GENERAL
    
    #ifndef FEATURE_OAD
    // Minimum connection interval (units of 1.25ms, 80=100ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MIN_CONN_INTERVAL     80
    
    // Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MAX_CONN_INTERVAL     1600
    #else //!FEATURE_OAD
    // Minimum connection interval (units of 1.25ms, 8=10ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MIN_CONN_INTERVAL     8
    
    // Maximum connection interval (units of 1.25ms, 8=10ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MAX_CONN_INTERVAL     8
    #endif // FEATURE_OAD
    
    // Slave latency to use if automatic parameter update request is enabled
    #define DEFAULT_DESIRED_SLAVE_LATENCY         0
    
    // Supervision timeout value (units of 10ms, 1000=10s) if automatic parameter
    // update request is enabled
    #define DEFAULT_DESIRED_CONN_TIMEOUT          1000
    
    // Whether to enable automatic parameter update request when a connection is
    // formed
    #define DEFAULT_ENABLE_UPDATE_REQUEST         GAPROLE_LINK_PARAM_UPDATE_WAIT_REMOTE_PARAMS
    
    // Connection Pause Peripheral time value (in seconds)
    #define DEFAULT_CONN_PAUSE_PERIPHERAL         6
    
    // How often to perform periodic event (in msec)
    #define SBP_PERIODIC_EVT_PERIOD               5000
    
    // Application specific event ID for HCI Connection Event End Events
    #define SBP_HCI_CONN_EVT_END_EVT              0x0001
    
    // Type of Display to open
    #if !defined(Display_DISABLE_ALL)
      #ifdef USE_CORE_SDK
        #if defined(BOARD_DISPLAY_USE_LCD) && (BOARD_DISPLAY_USE_LCD!=0)
          #define SBP_DISPLAY_TYPE Display_Type_LCD
        #elif defined (BOARD_DISPLAY_USE_UART) && (BOARD_DISPLAY_USE_UART!=0)
          #define SBP_DISPLAY_TYPE Display_Type_UART
        #else // !BOARD_DISPLAY_USE_LCD && !BOARD_DISPLAY_USE_UART
          #define SBP_DISPLAY_TYPE 0 // Option not supported
        #endif // BOARD_DISPLAY_USE_LCD && BOARD_DISPLAY_USE_UART
      #else // !USE_CORE_SDK
        #if !defined(BOARD_DISPLAY_EXCLUDE_LCD)
          #define SBP_DISPLAY_TYPE Display_Type_LCD
        #elif !defined (BOARD_DISPLAY_EXCLUDE_UART)
          #define SBP_DISPLAY_TYPE Display_Type_UART
        #else // BOARD_DISPLAY_EXCLUDE_LCD && BOARD_DISPLAY_EXCLUDE_UART
          #define SBP_DISPLAY_TYPE 0 // Option not supported
        #endif // !BOARD_DISPLAY_EXCLUDE_LCD || !BOARD_DISPLAY_EXCLUDE_UART
      #endif // USE_CORE_SDK
    #else // BOARD_DISPLAY_USE_LCD && BOARD_DISPLAY_USE_UART
      #define SBP_DISPLAY_TYPE 0 // No Display
    #endif // Display_DISABLE_ALL
    
    #ifdef FEATURE_OAD
    // The size of an OAD packet.
    #define OAD_PACKET_SIZE                       ((OAD_BLOCK_SIZE) + 2)
    #endif // FEATURE_OAD
    
    // Task configuration
    #define SBP_TASK_PRIORITY                     1
    
    #ifndef SBP_TASK_STACK_SIZE
    #define SBP_TASK_STACK_SIZE                   644
    #endif
    
    #define SBP_STATE_CHANGE_EVT                  0x0001
    #define SBP_CHAR_CHANGE_EVT                   0x0002
    
    // Internal Events for RTOS application
    #define SBP_ICALL_EVT                         ICALL_MSG_EVENT_ID // Event_Id_31
    #define SBP_QUEUE_EVT                         UTIL_QUEUE_EVENT_ID // Event_Id_30
    #define SBP_PERIODIC_EVT                      Event_Id_00
    
    #ifdef FEATURE_OAD
    #define SBP_QUEUE_PING_EVT                    Event_Id_01
    
    #define SBP_ALL_EVENTS                        (SBP_ICALL_EVT        | \
                                                   SBP_QUEUE_EVT        | \
                                                   SBP_PERIODIC_EVT     | \
                                                   SBP_QUEUE_PING_EVT)
    #else
    #define SBP_ALL_EVENTS                        (SBP_ICALL_EVT        | \
                                                   SBP_QUEUE_EVT        | \
                                                   SBP_PERIODIC_EVT)
    #endif /* FEATURE_OAD */
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    // App event passed from profiles.
    typedef struct
    {
      appEvtHdr_t hdr;  // event header.
    } sbpEvt_t;
    
    
    /*********************************************************************
     * GLOBAL VARIABLES
     */
    
    // Display Interface
    Display_Handle dispHandle = NULL;
    
    
    
    /*****struct for message from a service**********/
    typedef struct
    {
      Queue_Elem _elem;
      uint16_t svcUUID;
      uint16_t dataLen;
      uint8_t  paramID;
      uint8_t  data[]; // Flexible array member, extended to malloc - sizeof(.)
    } server_char_write_t;
    
    
    uint8_t a[10]= "0";
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    //******service queue****************//
    static Queue_Struct serviceMsgQ;
    static Queue_Handle hServiceMsgQ;
    
    // Entity ID globally used to check for source and/or destination of messages
    static ICall_EntityID selfEntity;
    
    // Event globally used to post local events and pend on system and
    // local events.
    static ICall_SyncHandle syncEvent;
    
    // Clock instances for internal periodic events.
    static Clock_Struct periodicClock;
    
    // Queue object used for app messages
    static Queue_Struct appMsg;
    static Queue_Handle appMsgQueue;
    
    
    #if defined(FEATURE_OAD)
    // Event data from OAD profile.
    static Queue_Struct oadQ;
    static Queue_Handle hOadQ;
    #endif //FEATURE_OAD
    
    // Task configuration
    Task_Struct sbpTask;
    Char sbpTaskStack[SBP_TASK_STACK_SIZE];
    
    // Profile state and parameters
    //static gaprole_States_t gapProfileState = GAPROLE_INIT;
    
    // GAP - SCAN RSP data (max size = 31 bytes)
    static uint8_t scanRspData[] =
    {
      // complete name
      0x14,   // length of this data
      GAP_ADTYPE_LOCAL_NAME_COMPLETE,
      'H',
      'e',
      'a',
      't',
      'i',
      'n',
      'g',
      'P',
      'a',
      't',
      'c',
      'h',
     /* 'i',
      'p',
      'h',
      'e',
      'r',
      'a',
      'l',*/
    
      // connection interval range
      0x05,   // length of this data
      GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
      LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),   // 100ms
      HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
      LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),   // 1s
      HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),
    
      // Tx power level
      0x02,   // length of this data
      GAP_ADTYPE_POWER_LEVEL,
      0       // 0dBm
    };
    
    // GAP - Advertisement data (max size = 31 bytes, though this is
    // best kept short to conserve power while advertisting)
    static uint8_t advertData[] =
    {
      // Flags; this sets the device to use limited discoverable
      // mode (advertises for 30 seconds at a time) instead of general
      // discoverable mode (advertises indefinitely)
      0x02,   // length of this data
      GAP_ADTYPE_FLAGS,
      DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
    
      // service UUID, to notify central devices what services are included
      // in this peripheral
    #if !defined(FEATURE_OAD) || defined(FEATURE_OAD_ONCHIP)
      0x03,   // length of this data
    #else //OAD for external flash
      0x05,  // lenght of this data
    #endif //FEATURE_OAD
      GAP_ADTYPE_16BIT_MORE,      // some of the UUID's, but not all
    #ifdef FEATURE_OAD
      LO_UINT16(OAD_SERVICE_UUID),
      HI_UINT16(OAD_SERVICE_UUID),
    #endif //FEATURE_OAD
    #ifndef FEATURE_OAD_ONCHIP
      LO_UINT16(SIMPLEPROFILE_SERV_UUID),
      HI_UINT16(SIMPLEPROFILE_SERV_UUID)
    #endif //FEATURE_OAD_ONCHIP
    };
    
    /*******set Led Pin handle*******/
    
    //static PIN_Handle ledPinHandle;
    //static PIN_State ledPinState;
    /*
     * Initial LED pin configuration table
     *   - LEDs Board_LED0 & Board_LED1 are off.
     */
    /*PIN_Config ledPinTable[] = {
      Board_RLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
        PIN_TERMINATE
    };
    */
    
    
    
    
    // GAP GATT Attributes
    static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "Heating Patch";
    
    // Globals used for ATT Response retransmission
    static gattMsgEvent_t *pAttRsp = NULL;
    static uint8_t rspTxRetry = 0;
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    static void SimpleBLEPeripheral_init( void );
    static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1);
    
    static uint8_t SimpleBLEPeripheral_processStackMsg(ICall_Hdr *pMsg);
    static uint8_t SimpleBLEPeripheral_processGATTMsg(gattMsgEvent_t *pMsg);
    static void SimpleBLEPeripheral_processAppMsg(sbpEvt_t *pMsg);
    static void SimpleBLEPeripheral_processStateChangeEvt(gaprole_States_t newState);
    static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID);
    static void SimpleBLEPeripheral_performPeriodicTask(void);
    static void SimpleBLEPeripheral_clockHandler(UArg arg);
    
    static void SimpleBLEPeripheral_sendAttRsp(void);
    static void SimpleBLEPeripheral_freeAttRsp(uint8_t status);
    
    static void SimpleBLEPeripheral_stateChangeCB(gaprole_States_t newState);
    #ifndef FEATURE_OAD_ONCHIP
    static void SimpleBLEPeripheral_charValueChangeCB(uint8_t paramID);
    #endif //!FEATURE_OAD_ONCHIP
    static void SimpleBLEPeripheral_enqueueMsg(uint8_t event, uint8_t state);
    
    /******* Temperature Service callback handlers*********/
    //static void user_Temperature_SensorValueChangeCB(uint8_t paramID); // Callback from the service.
    //static void user_Temperature_Sensor_ValueChangeDispatchHandler(server_char_write_t *pWrite);
    
    /*********LED service callack handlers*******/
    static void user_Led_ServiceValueChangeCB(uint8_t paramID); // Callback from the service.
    static void user_Led_Service_ValueChangeDispatchHandler(server_char_write_t *pWrite); // Local handler called from the Task context of this task.
    
    //static char *Util_convertArrayToHexString(uint8_t const *src, uint8_t src_len, uint8_t *dst, uint8_t dst_len);
    
    #ifdef FEATURE_OAD
    void SimpleBLEPeripheral_processOadWriteCB(uint8_t event, uint16_t connHandle,uint8_t *pData);
    #endif //FEATURE_OAD
    
    
    
    
    /************* Temperature Sensor Callback implementation*************/
    /*
    static Temperature_SensorCBs_t user_Temperature_SensorCBs =
    {
      user_Temperature_SensorValueChangeCB // Characteristic value change callback handler
    };
    */
    
    /*******Led service Callback implementation****/
    
    static Led_ServiceCBs_t user_Led_ServiceCBs =
    {
      user_Led_ServiceValueChangeCB // (function call) Characteristic value change callback handler
    };
    
    
    /*********************************************************************
     * EXTERN FUNCTIONS
     */
    extern void AssertHandler(uint8 assertCause, uint8 assertSubcause);
    
    /*********************************************************************
     * PROFILE CALLBACKS
     */
    
    // GAP Role Callbacks
    static gapRolesCBs_t SimpleBLEPeripheral_gapRoleCBs =
    {
      SimpleBLEPeripheral_stateChangeCB     // Profile State Change Callbacks
    };
    
    // GAP Bond Manager Callbacks
    static gapBondCBs_t simpleBLEPeripheral_BondMgrCBs =
    {
      NULL, // Passcode callback (not used by application)
      NULL  // Pairing / Bonding state Callback (not used by application)
    };
    
    // Simple GATT Profile Callbacks
    //#ifndef FEATURE_OAD_ONCHIP
    static simpleProfileCBs_t SimpleBLEPeripheral_simpleProfileCBs =
    {
      SimpleBLEPeripheral_charValueChangeCB // Characteristic value change callback
    };
    //#endif //!FEATURE_OAD_ONCHIP
    
    #ifdef FEATURE_OAD
    static oadTargetCBs_t simpleBLEPeripheral_oadCBs =
    {
      SimpleBLEPeripheral_processOadWriteCB // Write Callback.
    };
    #endif //FEATURE_OAD
    
    /*********************************************************************
     * PUBLIC FUNCTIONS
     */
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_createTask
     *
     * @brief   Task creation function for the Simple BLE Peripheral.
     *
     * @param   None.
     *
     * @return  None.
     */
    void SimpleBLEPeripheral_createTask(void)
    {
      Task_Params taskParams;
    
      // Configure task
      Task_Params_init(&taskParams);
      taskParams.stack = sbpTaskStack;
      taskParams.stackSize = SBP_TASK_STACK_SIZE;
      taskParams.priority = SBP_TASK_PRIORITY;
    
      Task_construct(&sbpTask, SimpleBLEPeripheral_taskFxn, &taskParams, NULL);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_init
     *
     * @brief   Called during initialization and contains application
     *          specific initialization (ie. hardware initialization/setup,
     *          table initialization, power up notification, etc), and
     *          profile initialization/setup.
     *
     * @param   None.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_init(void)
    {
         adctemp();
       //taskFxn();
    
    
      // ******************************************************************
      // N0 STACK API CALLS CAN OCCUR BEFORE THIS CALL TO ICall_registerApp
      // ******************************************************************
      // Register the current thread as an ICall dispatcher application
      // so that the application can send and receive messages.
    
        ICall_registerApp(&selfEntity, &syncEvent);
    
     //  dispHandle = Display_open(Display_Type_UART, NULL);
    
    
        /************ initialize queue for service message********/
    
      Queue_construct(&serviceMsgQ, NULL);
       hServiceMsgQ = Queue_handle(&serviceMsgQ);
    
    
    
    /****************hardware initialization for led****************/
    //  ledPinHandle = PIN_open(&ledPinState, ledPinTable);
      //  if(!ledPinHandle) {
        //  Task_exit();
        //}
    
    
    
    #ifdef USE_RCOSC
      RCOSC_enableCalibration();
    #endif // USE_RCOSC
    
    #if defined( USE_FPGA )
      // configure RF Core SMI Data Link
      IOCPortConfigureSet(IOID_12, IOC_PORT_RFC_GPO0, IOC_STD_OUTPUT);
      IOCPortConfigureSet(IOID_11, IOC_PORT_RFC_GPI0, IOC_STD_INPUT);
    
      // configure RF Core SMI Command Link
      IOCPortConfigureSet(IOID_10, IOC_IOCFG0_PORT_ID_RFC_SMI_CL_OUT, IOC_STD_OUTPUT);
      IOCPortConfigureSet(IOID_9, IOC_IOCFG0_PORT_ID_RFC_SMI_CL_IN, IOC_STD_INPUT);
    
      // configure RF Core tracer IO
      IOCPortConfigureSet(IOID_8, IOC_PORT_RFC_TRC, IOC_STD_OUTPUT);
    #else // !USE_FPGA
      #if defined( DEBUG_SW_TRACE )
        // configure RF Core tracer IO
        IOCPortConfigureSet(IOID_8, IOC_PORT_RFC_TRC, IOC_STD_OUTPUT | IOC_CURRENT_4MA | IOC_SLEW_ENABLE);
      #endif // DEBUG_SW_TRACE
    #endif // USE_FPGA
    
      // Create an RTOS queue for message from profile to be sent to app.
      appMsgQueue = Util_constructQueue(&appMsg);
    
      // Create one-shot clocks for internal periodic events.
      Util_constructClock(&periodicClock, SimpleBLEPeripheral_clockHandler,
                          SBP_PERIODIC_EVT_PERIOD, 0, false, SBP_PERIODIC_EVT);
    
      dispHandle = Display_open(SBP_DISPLAY_TYPE, NULL);
    
      // Setup the GAP
      GAP_SetParamValue(TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL);
    
      // Setup the GAP Peripheral Role Profile
      {
        // For all hardware platforms, device starts advertising upon initialization
        uint8_t initialAdvertEnable = TRUE;
    
        // By setting this to zero, the device will go into the waiting state after
        // being discoverable for 30.72 second, and will not being advertising again
        // until the enabler is set back to TRUE
        uint16_t advertOffTime = 0;
    
        uint8_t enableUpdateRequest = DEFAULT_ENABLE_UPDATE_REQUEST;
        uint16_t desiredMinInterval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
        uint16_t desiredMaxInterval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
        uint16_t desiredSlaveLatency = DEFAULT_DESIRED_SLAVE_LATENCY;
        uint16_t desiredConnTimeout = DEFAULT_DESIRED_CONN_TIMEOUT;
    
        // Set the GAP Role Parameters
        GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                             &initialAdvertEnable);
        GAPRole_SetParameter(GAPROLE_ADVERT_OFF_TIME, sizeof(uint16_t),
                             &advertOffTime);
    
        GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData),
                             scanRspData);
        GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
    
        GAPRole_SetParameter(GAPROLE_PARAM_UPDATE_ENABLE, sizeof(uint8_t),
                             &enableUpdateRequest);
        GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16_t),
                             &desiredMinInterval);
        GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16_t),
                             &desiredMaxInterval);
        GAPRole_SetParameter(GAPROLE_SLAVE_LATENCY, sizeof(uint16_t),
                             &desiredSlaveLatency);
        GAPRole_SetParameter(GAPROLE_TIMEOUT_MULTIPLIER, sizeof(uint16_t),
                             &desiredConnTimeout);
      }
    
      // Set the GAP Characteristics
      GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);
    
      // Set advertising interval
      {
        uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL;
    
        GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MIN, advInt);
        GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MAX, advInt);
        GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MIN, advInt);
        GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MAX, advInt);
      }
    
      // Setup the GAP Bond Manager
      {
        uint32_t passkey = 0; // passkey "000000"
        uint8_t pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
        uint8_t mitm = TRUE;
        uint8_t ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
        uint8_t bonding = TRUE;
    
        GAPBondMgr_SetParameter(GAPBOND_DEFAULT_PASSCODE, sizeof(uint32_t),
                                &passkey);
        GAPBondMgr_SetParameter(GAPBOND_PAIRING_MODE, sizeof(uint8_t), &pairMode);
        GAPBondMgr_SetParameter(GAPBOND_MITM_PROTECTION, sizeof(uint8_t), &mitm);
        GAPBondMgr_SetParameter(GAPBOND_IO_CAPABILITIES, sizeof(uint8_t), &ioCap);
        GAPBondMgr_SetParameter(GAPBOND_BONDING_ENABLED, sizeof(uint8_t), &bonding);
      }
    
       // Initialize GATT attributes
      GGS_AddService(GATT_ALL_SERVICES);           // GAP
    
      GATTServApp_AddService(GATT_ALL_SERVICES);   // GATT attributes
    
       DevInfo_AddService();                        // Device Information Service
    
      //add  service
    
     Temperature_Sensor_AddService();
     Led_Service_AddService();
    
     //************************ Register for service callback.****************************//
    
     //Temperature_Sensor_RegisterAppCBs(&user_Temperature_SensorCBs );
     Led_Service_RegisterAppCBs(&user_Led_ServiceCBs);
    
    
    //if(flag == True) {
    
    //    flag= False;
    //Temperature_Sensor_SetParameter(TEMPERATURE_SENSOR_TEMPERATURE_MEASUREMENT, TEMPERATURE_SENSOR_TEMPERATURE_MEASUREMENT_LEN, &temp );
    Led_Service_SetParameter(LED_SERVICE_LED_CONTROL, LED_SERVICE_LED_CONTROL_LEN, a );
    //}
    
    #ifndef FEATURE_OAD_ONCHIP
      SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile
    #endif //!FEATURE_OAD_ONCHIP
    
    #ifdef FEATURE_OAD
      VOID OAD_addService();                 // OAD Profile
      OAD_register((oadTargetCBs_t *)&simpleBLEPeripheral_oadCBs);
      hOadQ = Util_constructQueue(&oadQ);
    #endif //FEATURE_OAD
    
    #ifdef IMAGE_INVALIDATE
      Reset_addService();
    #endif //IMAGE_INVALIDATE
    
    
    #ifndef FEATURE_OAD_ONCHIP
      // Setup the SimpleProfile Characteristic Values
      {
        uint8_t charValue1 = 1;
        uint8_t charValue2 = 2;
        uint8_t charValue3 = 3;
        uint8_t charValue4 = 4;
        uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN] = { 1, 2, 3, 4, 5 };
    
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1, sizeof(uint8_t),
                                   &charValue1);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, sizeof(uint8_t),
                                   &charValue2);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR3, sizeof(uint8_t),
                                   &charValue3);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, sizeof(uint8_t),
                                   &charValue4);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN,
                                   charValue5);
      }
    
      // Register callback with SimpleGATTprofile
      SimpleProfile_RegisterAppCBs(&SimpleBLEPeripheral_simpleProfileCBs);
    #endif //!FEATURE_OAD_ONCHIP
    
      // Start the Device
      VOID GAPRole_StartDevice(&SimpleBLEPeripheral_gapRoleCBs);
    
      // Start Bond Manager
      VOID GAPBondMgr_Register(&simpleBLEPeripheral_BondMgrCBs);
    
      // Register with GAP for HCI/Host messages
      GAP_RegisterForMsgs(selfEntity);
    
      // Register for GATT local events and ATT Responses pending for transmission
      GATT_RegisterForMsgs(selfEntity);
    
      //This should be included only if 4.2 length extension feature is enable....
      //HCI_LE_ReadMaxDataLenCmd();
    
    #if !defined (USE_LL_CONN_PARAM_UPDATE)
      // Get the currently set local supported LE features
      // The HCI will generate an HCI event that will get received in the main
      // loop
      HCI_LE_ReadLocalSupportedFeaturesCmd();
    #endif // !defined (USE_LL_CONN_PARAM_UPDATE)
    
    #if defined FEATURE_OAD
    #if defined (HAL_IMAGE_A)
      Display_print0(dispHandle, 0, 0, "BLE Peripheral A");
    #else
      Display_print0(dispHandle, 0, 0, "BLE Peripheral B");
    #endif // HAL_IMAGE_A
    #else
      Display_print0(dispHandle, 0, 0, "BLE Peripheral");
    #endif // FEATURE_OAD
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_taskFxn
     *
     * @brief   Application task entry point for the Simple BLE Peripheral.
     *
     * @param   a0, a1 - not used.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1)
    {
      // Initialize application
    
    
      SimpleBLEPeripheral_init();
    
      // Application main loop
      for (;;)
      {
    
        uint32_t events;
    
        // Waits for an event to be posted associated with the calling thread.
        // Note that an event associated with a thread is posted when a
        // message is queued to the message receive queue of the thread
    
    
        //************** Temperature Service Task  ***********//
        /*while (!Queue_empty(hServiceMsgQ))
             {
               server_char_write_t *pWrite = Queue_dequeue(hServiceMsgQ);
    
               switch(pWrite->svcUUID)
               {
                 case TEMPERATURE_SENSOR_SERV_UUID:
                   user_Temperature_Sensor_ValueChangeDispatchHandler(pWrite);
                   break;
    
               }
    
               // Free the message received from the service callback.
               ICall_free(pWrite);
             }
    */
    
    
        events = Event_pend(syncEvent, Event_Id_NONE, SBP_ALL_EVENTS, ICALL_TIMEOUT_FOREVER);
        if (events)
        {
          ICall_EntityID dest;
          ICall_ServiceEnum src;
          ICall_HciExtEvt *pMsg = NULL;
    
          if (ICall_fetchServiceMsg(&src, &dest,
                                    (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
          {
            uint8 safeToDealloc = TRUE;
    
            if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
            {
              ICall_Stack_Event *pEvt = (ICall_Stack_Event *)pMsg;
    
              // Check for BLE stack events first
              if (pEvt->signature == 0xffff)
              {
                if (pEvt->event_flag & SBP_HCI_CONN_EVT_END_EVT)
                {
                  // Try to retransmit pending ATT Response (if any)
                  SimpleBLEPeripheral_sendAttRsp();
                }
              }
              else
              {
                // Process inter-task message
                safeToDealloc = SimpleBLEPeripheral_processStackMsg((ICall_Hdr *)pMsg);
              }
            }
    
            if (pMsg && safeToDealloc)
            {
              ICall_freeMsg(pMsg);
            }
          }
    
          // If RTOS queue is not empty, process app message.
          if (events & SBP_QUEUE_EVT)
          {
            while (!Queue_empty(appMsgQueue))
            {
              sbpEvt_t *pMsg = (sbpEvt_t *)Util_dequeueMsg(appMsgQueue);
              if (pMsg)
              {
                // Process message.
                SimpleBLEPeripheral_processAppMsg(pMsg);
    
                // Free the space from the message.
                ICall_free(pMsg);
              }
            }
          }
    
          if (events & SBP_PERIODIC_EVT)
          {
            Util_startClock(&periodicClock);
    
            // Perform periodic application task
            SimpleBLEPeripheral_performPeriodicTask();
          }
    
    
    
    #ifdef FEATURE_OAD
          if (events & SBP_QUEUE_PING_EVT)
          {
            while (!Queue_empty(hOadQ))
            {
              oadTargetWrite_t *oadWriteEvt = Queue_get(hOadQ);
    
              // Identify new image.
              if (oadWriteEvt->event == OAD_WRITE_IDENTIFY_REQ)
              {
                OAD_imgIdentifyWrite(oadWriteEvt->connHandle, oadWriteEvt->pData);
              }
              // Write a next block request.
              else if (oadWriteEvt->event == OAD_WRITE_BLOCK_REQ)
              {
                OAD_imgBlockWrite(oadWriteEvt->connHandle, oadWriteEvt->pData);
              }
    
              // Free buffer.
              ICall_free(oadWriteEvt);
            }
          }
    #endif //FEATURE_OAD
    
    
        //*************led service task***********//
               while (!Queue_empty(hServiceMsgQ))
                    {
                      server_char_write_t *pWrite = Queue_dequeue(hServiceMsgQ);
    
                      switch(pWrite->svcUUID)
                      {
                        case LED_SERVICE_SERV_UUID:
                          user_Led_Service_ValueChangeDispatchHandler(pWrite);
                          break;
                      }
    
                      // Free the message received from the service callback.
                      ICall_free(pWrite);
                    }
        }
      }
    
    }
    
    
    /******* temperauture write value******////////
    
    /*void user_Temperature_Sensor_ValueChangeDispatchHandler(server_char_write_t *pWrite)
    {
      switch (pWrite->paramID)
      {
            case TEMPERATURE_SENSOR_TEMPERATURE_MEASUREMENT:
          // Do something useful with pWrite->data here
    
          break;
          }
    
    }
    */
    
      /*********************************************************************
     * @fn      SimpleBLEPeripheral_processStackMsg
     *
     * @brief   Process an incoming stack message.
     *
     * @param   pMsg - message to process
     *
     * @return  TRUE if safe to deallocate incoming message, FALSE otherwise.
     */
    static uint8_t SimpleBLEPeripheral_processStackMsg(ICall_Hdr *pMsg)
    {
      uint8_t safeToDealloc = TRUE;
    
      switch (pMsg->event)
      {
        case GATT_MSG_EVENT:
          // Process GATT message
          safeToDealloc = SimpleBLEPeripheral_processGATTMsg((gattMsgEvent_t *)pMsg);
          break;
    
        case HCI_GAP_EVENT_EVENT:
          {
    
            // Process HCI message
            switch(pMsg->status)
            {
              case HCI_COMMAND_COMPLETE_EVENT_CODE:
                // Process HCI Command Complete Event
                {
    
    #if !defined (USE_LL_CONN_PARAM_UPDATE)
                  // This code will disable the use of the LL_CONNECTION_PARAM_REQ
                  // control procedure (for connection parameter updates, the 
                  // L2CAP Connection Parameter Update procedure will be used 
                  // instead). To re-enable the LL_CONNECTION_PARAM_REQ control
                  // procedures, define the symbol USE_LL_CONN_PARAM_UPDATE                
                  
                  // Parse Command Complete Event for opcode and status
                  hciEvt_CmdComplete_t* command_complete = (hciEvt_CmdComplete_t*) pMsg;
                  uint8_t   pktStatus = command_complete->pReturnParam[0]; 
                  
                  //find which command this command complete is for
                  switch (command_complete->cmdOpcode)
                  {
                    case HCI_LE_READ_LOCAL_SUPPORTED_FEATURES:
                      {
                        if (pktStatus == SUCCESS)
                        {
                          uint8_t featSet[8];
                          
                          // get current feature set from received event (bits 1-9 of
                          // the returned data
                          memcpy( featSet, &command_complete->pReturnParam[1], 8 );                          
                          
                          // Clear bit 1 of byte 0 of feature set to disable LL
                          // Connection Parameter Updates
                          CLR_FEATURE_FLAG( featSet[0], LL_FEATURE_CONN_PARAMS_REQ );
                            
                          // Update controller with modified features
                          HCI_EXT_SetLocalSupportedFeaturesCmd( featSet );
                        }
                      }
                      break;
                    
                    default:
                      //do nothing
                      break;
                  }   
    #endif // !defined (USE_LL_CONN_PARAM_UPDATE)
                  
                }
                break;
    
              case HCI_BLE_HARDWARE_ERROR_EVENT_CODE:
                AssertHandler(HAL_ASSERT_CAUSE_HARDWARE_ERROR,0);
                break;
    
              default:
                break;
            }
          }
          break;
    
          default:
            // do nothing
            break;
    
        }
      
      return (safeToDealloc);
    }
    
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processGATTMsg
     *
     * @brief   Process GATT messages and events.
     *
     * @return  TRUE if safe to deallocate incoming message, FALSE otherwise.
     */
    static uint8_t SimpleBLEPeripheral_processGATTMsg(gattMsgEvent_t *pMsg)
    {
      // See if GATT server was unable to transmit an ATT response
      if (pMsg->hdr.status == blePending)
      {
        // No HCI buffer was available. Let's try to retransmit the response
        // on the next connection event.
        if (HCI_EXT_ConnEventNoticeCmd(pMsg->connHandle, selfEntity,
                                       SBP_HCI_CONN_EVT_END_EVT) == SUCCESS)
        {
          // First free any pending response
          SimpleBLEPeripheral_freeAttRsp(FAILURE);
    
          // Hold on to the response message for retransmission
          pAttRsp = pMsg;
    
          // Don't free the response message yet
          return (FALSE);
        }
      }
      else if (pMsg->method == ATT_FLOW_CTRL_VIOLATED_EVENT)
      {
        // ATT request-response or indication-confirmation flow control is
        // violated. All subsequent ATT requests or indications will be dropped.
        // The app is informed in case it wants to drop the connection.
    
        // Display the opcode of the message that caused the violation.
        Display_print1(dispHandle, 5, 0, "FC Violated: %d", pMsg->msg.flowCtrlEvt.opcode);
      }
      else if (pMsg->method == ATT_MTU_UPDATED_EVENT)
      {
        // MTU size updated
        Display_print1(dispHandle, 5, 0, "MTU Size: %d", pMsg->msg.mtuEvt.MTU);
      }
    
      // Free message payload. Needed only for ATT Protocol messages
      GATT_bm_free(&pMsg->msg, pMsg->method);
    
      // It's safe to free the incoming message
      return (TRUE);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_sendAttRsp
     *
     * @brief   Send a pending ATT response message.
     *
     * @param   none
     *
     * @return  none
     */
    static void SimpleBLEPeripheral_sendAttRsp(void)
    {
      // See if there's a pending ATT Response to be transmitted
      if (pAttRsp != NULL)
      {
        uint8_t status;
    
        // Increment retransmission count
        rspTxRetry++;
    
        // Try to retransmit ATT response till either we're successful or
        // the ATT Client times out (after 30s) and drops the connection.
        status = GATT_SendRsp(pAttRsp->connHandle, pAttRsp->method, &(pAttRsp->msg));
        if ((status != blePending) && (status != MSG_BUFFER_NOT_AVAIL))
        {
          // Disable connection event end notice
          HCI_EXT_ConnEventNoticeCmd(pAttRsp->connHandle, selfEntity, 0);
    
          // We're done with the response message
          SimpleBLEPeripheral_freeAttRsp(status);
        }
        else
        {
          // Continue retrying
          Display_print1(dispHandle, 5, 0, "Rsp send retry: %d", rspTxRetry);
        }
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_freeAttRsp
     *
     * @brief   Free ATT response message.
     *
     * @param   status - response transmit status
     *
     * @return  none
     */
    static void SimpleBLEPeripheral_freeAttRsp(uint8_t status)
    {
      // See if there's a pending ATT response message
      if (pAttRsp != NULL)
      {
        // See if the response was sent out successfully
        if (status == SUCCESS)
        {
          Display_print1(dispHandle, 5, 0, "Rsp sent retry: %d", rspTxRetry);
        }
        else
        {
          // Free response payload
          GATT_bm_free(&pAttRsp->msg, pAttRsp->method);
    
          Display_print1(dispHandle, 5, 0, "Rsp retry failed: %d", rspTxRetry);
        }
    
        // Free response message
        ICall_freeMsg(pAttRsp);
    
        // Reset our globals
        pAttRsp = NULL;
        rspTxRetry = 0;
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processAppMsg
     *
     * @brief   Process an incoming callback from a profile.
     *
     * @param   pMsg - message to process
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processAppMsg(sbpEvt_t *pMsg)
    {
      switch (pMsg->hdr.event)
      {
        case SBP_STATE_CHANGE_EVT:
          SimpleBLEPeripheral_processStateChangeEvt((gaprole_States_t)pMsg->
                                                    hdr.state);
          break;
    
        case SBP_CHAR_CHANGE_EVT:
          SimpleBLEPeripheral_processCharValueChangeEvt(pMsg->hdr.state);
          break;
    
        default:
          // Do nothing.
          break;
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_stateChangeCB
     *
     * @brief   Callback from GAP Role indicating a role state change.
     *
     * @param   newState - new state
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_stateChangeCB(gaprole_States_t newState)
    {
      SimpleBLEPeripheral_enqueueMsg(SBP_STATE_CHANGE_EVT, newState);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processStateChangeEvt
     *
     * @brief   Process a pending GAP Role state change event.
     *
     * @param   newState - new state
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processStateChangeEvt(gaprole_States_t newState)
    {
    #ifdef PLUS_BROADCASTER
      static bool firstConnFlag = false;
    #endif // PLUS_BROADCASTER
    
      switch ( newState )
      {
        case GAPROLE_STARTED:
          {
            uint8_t ownAddress[B_ADDR_LEN];
            uint8_t systemId[DEVINFO_SYSTEM_ID_LEN];
    
            GAPRole_GetParameter(GAPROLE_BD_ADDR, ownAddress);
    
            // use 6 bytes of device address for 8 bytes of system ID value
            systemId[0] = ownAddress[0];
            systemId[1] = ownAddress[1];
            systemId[2] = ownAddress[2];
    
            // set middle bytes to zero
            systemId[4] = 0x00;
            systemId[3] = 0x00;
    
            // shift three bytes up
            systemId[7] = ownAddress[5];
            systemId[6] = ownAddress[4];
            systemId[5] = ownAddress[3];
    
            DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, systemId);
    
            // Display device address
            Display_print0(dispHandle, 1, 0, Util_convertBdAddr2Str(ownAddress));
            Display_print0(dispHandle, 2, 0, "Initialized");
          }
          break;
    
        case GAPROLE_ADVERTISING:
          Display_print0(dispHandle, 2, 0, "Advertising");
          break;
    
    #ifdef PLUS_BROADCASTER
        /* After a connection is dropped a device in PLUS_BROADCASTER will continue
         * sending non-connectable advertisements and shall sending this change of
         * state to the application.  These are then disabled here so that sending
         * connectable advertisements can resume.
         */
        case GAPROLE_ADVERTISING_NONCONN:
          {
            uint8_t advertEnabled = FALSE;
    
            // Disable non-connectable advertising.
            GAPRole_SetParameter(GAPROLE_ADV_NONCONN_ENABLED, sizeof(uint8_t),
                               &advertEnabled);
    
            advertEnabled = TRUE;
    
            // Enabled connectable advertising.
            GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                                 &advertEnabled);
    
            // Reset flag for next connection.
            firstConnFlag = false;
    
            SimpleBLEPeripheral_freeAttRsp(bleNotConnected);
          }
          break;
    #endif //PLUS_BROADCASTER
    
        case GAPROLE_CONNECTED:
          {
            linkDBInfo_t linkInfo;
            uint8_t numActive = 0;
    
            Util_startClock(&periodicClock);
    
            numActive = linkDB_NumActive();
    
            // Use numActive to determine the connection handle of the last
            // connection
            if ( linkDB_GetInfo( numActive - 1, &linkInfo ) == SUCCESS )
            {
              Display_print1(dispHandle, 2, 0, "Num Conns: %d", (uint16_t)numActive);
              Display_print0(dispHandle, 3, 0, Util_convertBdAddr2Str(linkInfo.addr));
            }
            else
            {
              uint8_t peerAddress[B_ADDR_LEN];
    
              GAPRole_GetParameter(GAPROLE_CONN_BD_ADDR, peerAddress);
    
              Display_print0(dispHandle, 2, 0, "Connected");
              Display_print0(dispHandle, 3, 0, Util_convertBdAddr2Str(peerAddress));
            }
    
            #ifdef PLUS_BROADCASTER
              // Only turn advertising on for this state when we first connect
              // otherwise, when we go from connected_advertising back to this state
              // we will be turning advertising back on.
              if (firstConnFlag == false)
              {
                uint8_t advertEnabled = FALSE; // Turn on Advertising
    
                // Disable connectable advertising.
                GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                                     &advertEnabled);
    
                // Set to true for non-connectabel advertising.
                advertEnabled = TRUE;
    
                // Enable non-connectable advertising.
                GAPRole_SetParameter(GAPROLE_ADV_NONCONN_ENABLED, sizeof(uint8_t),
                                     &advertEnabled);
                firstConnFlag = true;
              }
            #endif // PLUS_BROADCASTER
          }
          break;
    
        case GAPROLE_CONNECTED_ADV:
          Display_print0(dispHandle, 2, 0, "Connected Advertising");
          break;
    
        case GAPROLE_WAITING:
          Util_stopClock(&periodicClock);
          SimpleBLEPeripheral_freeAttRsp(bleNotConnected);
    
          Display_print0(dispHandle, 2, 0, "Disconnected");
    
          // Clear remaining lines
          Display_clearLines(dispHandle, 3, 5);
          break;
    
        case GAPROLE_WAITING_AFTER_TIMEOUT:
          SimpleBLEPeripheral_freeAttRsp(bleNotConnected);
    
          Display_print0(dispHandle, 2, 0, "Timed Out");
    
          // Clear remaining lines
          Display_clearLines(dispHandle, 3, 5);
    
          #ifdef PLUS_BROADCASTER
            // Reset flag for next connection.
            firstConnFlag = false;
          #endif //#ifdef (PLUS_BROADCASTER)
          break;
    
        case GAPROLE_ERROR:
          Display_print0(dispHandle, 2, 0, "Error");
          break;
    
        default:
          Display_clearLine(dispHandle, 2);
          break;
      }
    
      // Update the state
      //gapProfileState = newState;
    }
    
    //#ifndef FEATURE_OAD_ONCHIP
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_charValueChangeCB
     *
     * @brief   Callback from Simple Profile indicating a characteristic
     *          value change.
     *
     * @param   paramID - parameter ID of the value that was changed.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_charValueChangeCB(uint8_t paramID)
    {
      SimpleBLEPeripheral_enqueueMsg(SBP_CHAR_CHANGE_EVT, paramID);
    }
    //#endif //!FEATURE_OAD_ONCHIP
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processCharValueChangeEvt
     *
     * @brief   Process a pending Simple Profile characteristic value change
     *          event.
     *
     * @param   paramID - parameter ID of the value that was changed.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID)
    {
    //#ifndef FEATURE_OAD_ONCHIP
      uint8_t newValue;
    
      switch(paramID)
      {
        case SIMPLEPROFILE_CHAR1:
          SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR1, &newValue);
    
          Display_print1(dispHandle, 4, 0, "Char 1: %d", (uint16_t)newValue);
          break;
    
        case SIMPLEPROFILE_CHAR3:
          SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR3, &newValue);
    
          Display_print1(dispHandle, 4, 0, "Char 3: %d", (uint16_t)newValue);
          break;
    
        default:
          // should not reach here!
          break;
      }
    //#endif //!FEATURE_OAD_ONCHIP
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_performPeriodicTask
     *
     * @brief   Perform a periodic application task. This function gets called
     *          every five seconds (SBP_PERIODIC_EVT_PERIOD). In this example,
     *          the value of the third characteristic in the SimpleGATTProfile
     *          service is retrieved from the profile, and then copied into the
     *          value of the the fourth characteristic.
     *
     * @param   None.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_performPeriodicTask(void)
    {
    //#ifndef FEATURE_OAD_ONCHIP
      uint8_t valueToCopy;
    
      // Call to retrieve the value of the third characteristic in the profile
      if (SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR3, &valueToCopy) == SUCCESS)
      {
        // Call to set that value of the fourth characteristic in the profile.
        // Note that if notifications of the fourth characteristic have been
        // enabled by a GATT client device, then a notification will be sent
        // every time this function is called.
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, sizeof(uint8_t),
                                   &valueToCopy);
      //  adctemp();
        Temperature_Sensor_SetParameter(TEMPERATURE_SENSOR_TEMPERATURE_MEASUREMENT, TEMPERATURE_SENSOR_TEMPERATURE_MEASUREMENT_LEN, &temp );
      }
    //#endif //!FEATURE_OAD_ONCHIP
    }
    
    
    #ifdef FEATURE_OAD
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processOadWriteCB
     *
     * @brief   Process a write request to the OAD profile.
     *
     * @param   event      - event type:
     *                       OAD_WRITE_IDENTIFY_REQ
     *                       OAD_WRITE_BLOCK_REQ
     * @param   connHandle - the connection Handle this request is from.
     * @param   pData      - pointer to data for processing and/or storing.
     *
     * @return  None.
     */
    void SimpleBLEPeripheral_processOadWriteCB(uint8_t event, uint16_t connHandle,
                                               uint8_t *pData)
    {
      oadTargetWrite_t *oadWriteEvt = ICall_malloc( sizeof(oadTargetWrite_t) + \
                                                 sizeof(uint8_t) * OAD_PACKET_SIZE);
    
      if ( oadWriteEvt != NULL )
      {
        oadWriteEvt->event = event;
        oadWriteEvt->connHandle = connHandle;
    
        oadWriteEvt->pData = (uint8_t *)(&oadWriteEvt->pData + 1);
        memcpy(oadWriteEvt->pData, pData, OAD_PACKET_SIZE);
    
        Queue_put(hOadQ, (Queue_Elem *)oadWriteEvt);
    
        // Post the application's event.  For OAD, no event flag is used.
        Event_post(syncEvent, SBP_QUEUE_PING_EVT);
      }
      else
      {
        // Fail silently.
      }
    }
    #endif //FEATURE_OAD
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_clockHandler
     *
     * @brief   Handler function for clock timeouts.
     *
     * @param   arg - event type
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_clockHandler(UArg arg)
    {
      // Wake up the application.
      Event_post(syncEvent, arg);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_enqueueMsg
     *
     * @brief   Creates a message and puts the message in RTOS queue.
     *
     * @param   event - message event.
     * @param   state - message state.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_enqueueMsg(uint8_t event, uint8_t state)
    {
      sbpEvt_t *pMsg;
    
      // Create dynamic pointer to message.
      if ((pMsg = ICall_malloc(sizeof(sbpEvt_t))))
      {
        pMsg->hdr.event = event;
        pMsg->hdr.state = state;
    
        // Enqueue the message.
        Util_enqueueMsg(appMsgQueue, syncEvent, (uint8*)pMsg);
      }
    }
    //********* LED service write value*******///
    
    void user_Led_Service_ValueChangeDispatchHandler(server_char_write_t *pWrite)
    {
       // static uint8_t pretty_data_holder[16]; // 5 bytes as hex string "AA:BB:CC:DD:EE"
     //   Util_convertArrayToHexString(pWrite->data, pWrite->dataLen, pretty_data_holder, sizeof(pretty_data_holder));
    
    
        GPIO_write(Board_GPIO_LED1, Board_GPIO_LED_ON);
      switch (pWrite->paramID)
      {
             case LED_SERVICE_LED_CONTROL:
    
           // Do something useful with pWrite->data here
          // -------------------------
          // PIN_setOutputValue(ledPinHandle, Board_RLED, pWrite->data[0]);
               if (pWrite->data == "00")
              {
                // PIN_setOutputValue(ledPinHandle, Board_RLED, 0);
                  GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_OFF);
            }
            else if (pWrite->data == "01")
            {
               GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);
              // PIN_setOutputValue(ledPinHandle, Board_RLED, 1);
    
            }
             break;
    
    }
    
    }
    
    //////////////********************************************////////////////////////////
    /*
    static void user_Temperature_SensorValueChangeCB(uint8_t paramID)
    {
      // See Temperature_Sensor.h to compare paramID with characteristic value attribute.
      // Called in Stack Task context, so can't do processing here.
    
      // Send message to application message queue about received data.
      uint16_t readLen = 0; // How much to read via service API
    
      switch (paramID)
      {
        case TEMPERATURE_SENSOR_TEMPERATURE_MEASUREMENT:
          readLen = TEMPERATURE_SENSOR_TEMPERATURE_MEASUREMENT_LEN;
          break;
      }
    
      // Allocate memory for the message.
      // Note: The message doesn't have to contain the data itself, as that's stored in
      //       a variable in the service. However, to prevent data loss if a new value is received
      //       before GetParameter is called, we call GetParameter now.
      server_char_write_t *pWrite = ICall_malloc(sizeof(server_char_write_t) + readLen);
    
      if (pWrite != NULL)
      {
        pWrite->svcUUID = TEMPERATURE_SENSOR_SERV_UUID;
        pWrite->dataLen = readLen;
        pWrite->paramID = paramID;
        // Get the data from the service API.
        // Note: Fixed length is used here, but changing the GetParameter signature is not
        //       a problem, in case variable length is needed.
        // Note: It could be just as well to send dataLen and a pointer to the received data directly to this callback, avoiding GetParameter alltogether.
        Temperature_Sensor_GetParameter( paramID, pWrite->data );
    
        // Enqueue the message using pointer to queue node element.
        Queue_enqueue(hServiceMsgQ, &pWrite->_elem);
        // Let application know there's a message
        Semaphore_post(sem);
      }
    }*/
    /////////////////////////*************************************************/////////////////////////////////
    
    static void user_Led_ServiceValueChangeCB(uint8_t paramID)
    {
      // See Led_Service.h to compare paramID with characteristic value attribute.
      // Called in Stack Task context, so can't do processing here.
    
      // Send message to application message queue about received data.
      uint16_t readLen = 0; // How much to read via service API
    
      switch (paramID)
      {
        case LED_SERVICE_LED_CONTROL:
          readLen = LED_SERVICE_LED_CONTROL_LEN;
          break;
      }
    
      // Allocate memory for the message.
      // Note: The message doesn't have to contain the data itself, as that's stored in
      //       a variable in the service. However, to prevent data loss if a new value is received
      //       before GetParameter is called, we call GetParameter now.
      server_char_write_t *pWrite = ICall_malloc(sizeof(server_char_write_t) + readLen);
    
      if (pWrite != NULL)
      {
        pWrite->svcUUID = LED_SERVICE_SERV_UUID;
        pWrite->dataLen = readLen;
        pWrite->paramID = paramID;
        // Get the data from the service API.
        // Note: Fixed length is used here, but changing the GetParameter signature is not
        //       a problem, in case variable length is needed.
        // Note: It could be just as well to send dataLen and a pointer to the received data directly to this callback, avoiding GetParameter alltogether.
        Led_Service_GetParameter( paramID, pWrite->data );
    
        // Enqueue the message using pointer to queue node element.
        Queue_enqueue(hServiceMsgQ, &pWrite->_elem);
        // Let application know there's a message
        Semaphore_post(sem);
      }
    }
    
    
    /*
     * @brief   Convert {0x01, 0x02} to "01:02"
     *
     * @param   src - source byte-array
     * @param   src_len - length of array
     * @param   dst - destination string-array
     * @param   dst_len - length of array
     *
     * @return  array as string
     */
    /*static char *Util_convertArrayToHexString(uint8_t const *src, uint8_t src_len, uint8_t *dst, uint8_t dst_len)
    {
      char        hex[] = "0123456789ABCDEF";
      uint8_t     *pStr = dst;
      uint8_t     avail = dst_len-1;
    
      memset(dst, 0, avail);
    
      while (src_len && avail > 3)
      {
        if (avail < dst_len-1) { *pStr++ = ':'; avail -= 1; };
        *pStr++ = hex[*src >> 4];
        *pStr++ = hex[*src++ & 0x0F];
        avail -= 2;
        src_len--;
      }
    
      if (src_len && avail)
        *pStr++ = ':'; // Indicate not all data fit on line.
    
      return (char *)dst;
    }
    */
    /*********************************************************************
    *********************************************************************/
    

    2746.led_service.c
    /**********************************************************************************************
     * Filename:       Led_Service.c
     *
     * Description:    This file contains the implementation of the service.
     *
     * Copyright (c) 2015-2016, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     *************************************************************************************************/
    
    
    /*********************************************************************
     * INCLUDES
     */
    #include <string.h>
    
    #include "bcomdef.h"
    #include "OSAL.h"
    #include "linkdb.h"
    #include "att.h"
    #include "gatt.h"
    #include "gatt_uuid.h"
    #include "gattservapp.h"
    #include "gapbondmgr.h"
    
    #include "led_service.h"
    
    #ifdef ICALL_LITE
    #  include "icall_ble_api.h" // Only exists for 3.x stack version, so use ifdef.
    #endif
    
    /*********************************************************************
     * MACROS
     */
    
    /*********************************************************************
     * CONSTANTS
     */
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    /*********************************************************************
    * GLOBAL VARIABLES
    */
    
    // Led_Service Service UUID
    CONST uint8_t Led_ServiceUUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(LED_SERVICE_SERV_UUID), HI_UINT16(LED_SERVICE_SERV_UUID)
    };
    
    // Led_Control UUID
    CONST uint8_t Led_Service_Led_ControlUUID[ATT_UUID_SIZE] =
    {
      TI_BASE_UUID_128(LED_SERVICE_LED_CONTROL_UUID)
    };
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    
    static Led_ServiceCBs_t *pAppCBs = NULL;
    
    /*********************************************************************
    * Profile Attributes - variables
    */
    
    // Service declaration
    static CONST gattAttrType_t Led_ServiceDecl = { ATT_BT_UUID_SIZE, Led_ServiceUUID };
    
    // Characteristic "Led_Control" Properties (for declaration)
    static uint8_t Led_Service_Led_ControlProps = GATT_PROP_READ | GATT_PROP_WRITE;
    
    // Characteristic "Led_Control" Value variable
    static uint8_t Led_Service_Led_ControlVal[LED_SERVICE_LED_CONTROL_LEN] = {0};
    
    /*********************************************************************
    * Profile Attributes - Table
    */
    
    static gattAttribute_t Led_ServiceAttrTbl[] =
    {
      // Led_Service Service Declaration
      {
        { ATT_BT_UUID_SIZE, primaryServiceUUID },
        GATT_PERMIT_READ,
        0,
        (uint8_t *)&Led_ServiceDecl
      },
        // Led_Control Characteristic Declaration
        {
          { ATT_BT_UUID_SIZE, characterUUID },
          GATT_PERMIT_READ,
          0,
          &Led_Service_Led_ControlProps
        },
          // Led_Control Characteristic Value
          {
            { ATT_UUID_SIZE, Led_Service_Led_ControlUUID },
            GATT_PERMIT_READ | GATT_PERMIT_WRITE,
            0,
            Led_Service_Led_ControlVal
          },
    };
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    static bStatus_t Led_Service_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
                                               uint8 *pValue, uint16 *pLen, uint16 offset,
                                               uint16 maxLen, uint8 method );
    static bStatus_t Led_Service_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
                                                uint8 *pValue, uint16 len, uint16 offset,
                                                uint8 method );
    
    /*********************************************************************
     * PROFILE CALLBACKS
     */
    // Simple Profile Service Callbacks
    CONST gattServiceCBs_t Led_ServiceCBs =
    {
      Led_Service_ReadAttrCB,  // Read callback function pointer
      Led_Service_WriteAttrCB, // Write callback function pointer
      NULL                       // Authorization callback function pointer
    };
    
    /*********************************************************************
    * PUBLIC FUNCTIONS
    */
    
    /*
     * Led_Service_AddService- Initializes the Led_Service service by registering
     *          GATT attributes with the GATT server.
     *
     */
    bStatus_t Led_Service_AddService( void )
    {
      uint8_t status;
    
      // Register GATT attribute list and CBs with GATT Server App
      status = GATTServApp_RegisterService( Led_ServiceAttrTbl,
                                            GATT_NUM_ATTRS( Led_ServiceAttrTbl ),
                                            GATT_MAX_ENCRYPT_KEY_SIZE,
                                            &Led_ServiceCBs );
    
      return ( status );
    }
    
    /*
     * Led_Service_RegisterAppCBs - Registers the application callback function.
     *                    Only call this function once.
     *
     *    appCallbacks - pointer to application callbacks.
     */
    bStatus_t Led_Service_RegisterAppCBs( Led_ServiceCBs_t *appCallbacks )
    {
      if ( appCallbacks )
      {
        pAppCBs = appCallbacks;
    
        return ( SUCCESS );
      }
      else
      {
        return ( bleAlreadyInRequestedMode );
      }
    }
    
    /*
     * Led_Service_SetParameter - Set a Led_Service parameter.
     *
     *    param - Profile parameter ID
     *    len - length of data to right
     *    value - pointer to data to write.  This is dependent on
     *          the parameter ID and WILL be cast to the appropriate
     *          data type (example: data type of uint16 will be cast to
     *          uint16 pointer).
     */
    bStatus_t Led_Service_SetParameter( uint8 param, uint8 len, void *value )
    {
      bStatus_t ret = SUCCESS;
      switch ( param )
      {
        case LED_SERVICE_LED_CONTROL:
          if ( len == LED_SERVICE_LED_CONTROL_LEN )
          {
            memcpy(Led_Service_Led_ControlVal, value, len);
          }
          else
          {
            ret = bleInvalidRange;
          }
          break;
    
        default:
          ret = INVALIDPARAMETER;
          break;
      }
      return ret;
    }
    
    
    /*
     * Led_Service_GetParameter - Get a Led_Service parameter.
     *
     *    param - Profile parameter ID
     *    value - pointer to data to write.  This is dependent on
     *          the parameter ID and WILL be cast to the appropriate
     *          data type (example: data type of uint16 will be cast to
     *          uint16 pointer).
     */
    bStatus_t Led_Service_GetParameter( uint8 param, void *value )
    {
      bStatus_t ret = SUCCESS;
      switch ( param )
      {
        case LED_SERVICE_LED_CONTROL:
          memcpy(value, Led_Service_Led_ControlVal, LED_SERVICE_LED_CONTROL_LEN);
          break;
    
        default:
          ret = INVALIDPARAMETER;
          break;
      }
      return ret;
    }
    
    
    /*********************************************************************
     * @fn          Led_Service_ReadAttrCB
     *
     * @brief       Read an attribute.
     *
     * @param       connHandle - connection message was received on
     * @param       pAttr - pointer to attribute
     * @param       pValue - pointer to data to be read
     * @param       pLen - length of data to be read
     * @param       offset - offset of the first octet to be read
     * @param       maxLen - maximum length of data to be read
     * @param       method - type of read message
     *
     * @return      SUCCESS, blePending or Failure
     */
    static bStatus_t Led_Service_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
                                           uint8 *pValue, uint16 *pLen, uint16 offset,
                                           uint16 maxLen, uint8 method )
    {
      bStatus_t status = SUCCESS;
    
      // See if request is regarding the Led_Control Characteristic Value
    if ( ! memcmp(pAttr->type.uuid, Led_Service_Led_ControlUUID, pAttr->type.len) )
      {
        if ( offset > LED_SERVICE_LED_CONTROL_LEN )  // Prevent malicious ATT ReadBlob offsets.
        {
          status = ATT_ERR_INVALID_OFFSET;
        }
        else
        {
          *pLen = MIN(maxLen, LED_SERVICE_LED_CONTROL_LEN - offset);  // Transmit as much as possible
          memcpy(pValue, pAttr->pValue + offset, *pLen);
        }
      }
      else
      {
        // If we get here, that means you've forgotten to add an if clause for a
        // characteristic value attribute in the attribute table that has READ permissions.
        *pLen = 0;
        status = ATT_ERR_ATTR_NOT_FOUND;
      }
    
      return status;
    }
    
    
    /*********************************************************************
     * @fn      Led_Service_WriteAttrCB
     *
     * @brief   Validate attribute data prior to a write operation
     *
     * @param   connHandle - connection message was received on
     * @param   pAttr - pointer to attribute
     * @param   pValue - pointer to data to be written
     * @param   len - length of data
     * @param   offset - offset of the first octet to be written
     * @param   method - type of write message
     *
     * @return  SUCCESS, blePending or Failure
     */
    static bStatus_t Led_Service_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
                                            uint8 *pValue, uint16 len, uint16 offset,
                                            uint8 method )
    {
      bStatus_t status  = SUCCESS;
      uint8_t   paramID = 0xFF;
    
      // See if request is regarding a Client Characterisic Configuration
      if ( ! memcmp(pAttr->type.uuid, clientCharCfgUUID, pAttr->type.len) )
      {
        // Allow only notifications.
        status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,
                                                 offset, GATT_CLIENT_CFG_NOTIFY);
      }
      // See if request is regarding the Led_Control Characteristic Value
      else if ( ! memcmp(pAttr->type.uuid, Led_Service_Led_ControlUUID, pAttr->type.len) )
      {
        if ( offset + len > LED_SERVICE_LED_CONTROL_LEN )
        {
          status = ATT_ERR_INVALID_OFFSET;
        }
        else
        {
          // Copy pValue into the variable we point to from the attribute table.
          memcpy(pAttr->pValue + offset, pValue, len);
    
          // Only notify application if entire expected value is written
          if ( offset + len == LED_SERVICE_LED_CONTROL_LEN)
            paramID = LED_SERVICE_LED_CONTROL;
        }
      }
      else
      {
        // If we get here, that means you've forgotten to add an if clause for a
        // characteristic value attribute in the attribute table that has WRITE permissions.
        status = ATT_ERR_ATTR_NOT_FOUND;
      }
    
      // Let the application know something changed (if it did) by using the
      // callback it registered earlier (if it did).
      if (paramID != 0xFF)
        if ( pAppCBs && pAppCBs->pfnChangeCb )
          pAppCBs->pfnChangeCb( paramID ); // Call app function from stack task context.
    
      return status;
    }
    

    5460.led_service.h

    Cheers,

    Smriti

  • Hi Smriti,

    It looks like you're using pWrite->data incorrectly, you are using the address of the data[] member of the struct instead of using the value stored inside of it, you should be doing something like:

    if (pWrite->data[0] == 0)
    {
      // PIN_setOutputValue(ledPinHandle, Board_RLED, 0);
      GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_OFF);
    }
    else if (pWrite->data[0] == 1)
    {
      GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);
      // PIN_setOutputValue(ledPinHandle, Board_RLED, 1);
    }

    Also since you're using this only to control an LED there's no reason your Led control characteristic should be 5 bytes in length, 1 byte would be more than enough, this will help keep thing cleaner. You are also using a 10 byte array to initialize the value of that same characteristic, this should be modified to match the length of the characteristic.

    Thanks,
    Gerardo

  • Hi Gerardo,

    I made that change to my code still it is not working. and it is showing me one warming 

    Cheers,

    Smriti

  • What should i do now?
  • Hi Smriti,

    The warning itself is showing you what is wrong, your value in pWrite->data[0] is of type uint8_t and you're trying to compare it to a string, you need to compare it to another  uint8_t so it should look like:

    if (pWrite->data[0] == 0)

    Thanks,
    Gerardo

  • Hi Gerardo,

    uint8_t is a char type data. I made changes as you suggested me still it's not working. I am not able to understand what exactly is problem in my code

    Smriti

  • == "0" is not correct. == 0 is.

    You have implemented Gerardo's solution incorrectly and are comparing different data types. (0 is an uint8_t, "0" is a char).

    In general you seem to be struggling with both HW and SW in your project development. Maybe you are starting off at a too complex level? Have you considered taking a few university classes on electronics and embedded SW development? That might give you a better foundation for developing BLE applications.

    Cheers,
    Fredrik
  • Hi Fredrik,

    Thanks for your advice but I am working on software only hardware was designed by my colleague, i implemented gerardo's changes but still it didn't work. I have attached my files previously if you could go through it and tell me where else the mistake is because i used the code provided by TI service generator and it's not working.

    Smriti
  • Hi gerardo,

    I made the change you told me to but the code didn't work. please look into this it's quite urgent.

    Smriti
  • Hi,

    I did this it didn't work.

    Smriti
  • Hi Smriti,

    Set a breakpoint at 

    if (pWrite->data[0] == 0)

    and add a watch expression to check what the value of pWrite->data[0] is when it hits the breakpoint.

    Thanks,
    Gerardo

  • Hi gerardo,

    I did this and no value is received in pwrtite->data[0].

    Smriti
  • What do you mean by no value? Is it just showing garbage on pwrtite->data[0]?

    Gerardo
  • it is showing 0. i am sending values but it is showing me zero constantly
  • Hi Gersrdo,

    Also i would like to tell you that earlier i was using CC2640r2f MCU it didn't work then also. and now i am using CC2640 MCU it's not working now also.

    Smriti
  • The problem is you're just reading the last value written into the Led_Service_Led_ControlVal variable and using that to control the LED, but you are never updating this value when a write comes. So you're essentially just using the value you set there initially always and never changing it. Your service also doesn't transmit the new write value to your application callback so you're not using this at all. You need to modify your application callback to also transmit the new write value and make sure that once in there you are using this value instead of reading that variable to control the LED, and also ensure the variable is updated.

    Once again I suggest you look at project0 to get a better idea of how this should be done. All of this is being done in that example.

    Thanks,
    Gerardo
  • Thanks for your suggestion but i have resolved my issue. there was some other problem in value change callback. the value was always received in pWrite->data. but there is an extra function provided in callback which is not required which was causing problem.

    Smriti