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.

notify characterstic length problem in cc2650

Other Parts Discussed in Thread: BLE-STACK

i am trying to creade a 20 byte long notify chracterstic using simple ble perepheral characterstic 4. I increased the length of the characterstic to 20 byte and did the required changes where they were needed. then i used btool to enable notification afterenabing the notification iis sent but i am only receiving 5 bytes on btool while i defined the length to 20 bytes what may be the problem

I really want to have 20 byte long notify characterstic

please help me regarding this problem

  • Can you show me the modification you made to the project?
  • in simplegattprofile.h
    #define SIMPLEPROFILE_CHAR4_LEN 20
    in simplegattprofile.c
    // Characteristic 4 UUID: 0xFFF4
    CONST uint8 simpleProfilechar4UUID[ATT_BT_UUID_SIZE] = { LO_UINT16(
    SIMPLEPROFILE_CHAR4_UUID), HI_UINT16(SIMPLEPROFILE_CHAR4_UUID) };
    then

    // Simple Profile Characteristic 4 Properties
    static uint8 simpleProfileChar4Props = GATT_PROP_READ | GATT_PROP_NOTIFY;

    // Characteristic 4 Value
    //static uint8 simpleProfileChar4 = 0;
    static uint8 simpleProfileChar4[SIMPLEPROFILE_CHAR4_LEN] = { 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0 };

    // Simple Profile Characteristic 4 Configuration Each client has its own
    // instantiation of the Client Characteristic Configuration. Reads of the
    // Client Characteristic Configuration only shows the configuration for
    // that client and writes only affect the configuration of that client.
    static gattCharCfg_t *simpleProfileChar4Config;

    // Simple Profile Characteristic 4 User Description
    static uint8 simpleProfileChar4UserDesp[17] = "my char 4";

    then in Profile Attributes - Table

    // Characteristic 4 Declaration
    { { ATT_BT_UUID_SIZE, characterUUID },
    GATT_PERMIT_READ, 0, &simpleProfileChar4Props },

    // Characteristic Value 4
    { { ATT_BT_UUID_SIZE, simpleProfilechar4UUID },
    GATT_PERMIT_READ, 0,simpleProfileChar4 },

    // Characteristic 4 configuration
    { { ATT_BT_UUID_SIZE, clientCharCfgUUID },
    GATT_PERMIT_READ | GATT_PERMIT_WRITE, 0,
    (uint8 *) &simpleProfileChar4Config },

    // Characteristic 4 User Description
    { { ATT_BT_UUID_SIZE, charUserDescUUID },
    GATT_PERMIT_READ, 0, simpleProfileChar4UserDesp },

    then in simple profile add service function

    // Allocate Client Characteristic Configuration table
    simpleProfileChar4Config = (gattCharCfg_t *) ICall_malloc(
    sizeof(gattCharCfg_t) * linkDBNumConns);
    if (simpleProfileChar4Config == NULL) {
    return ( bleMemAllocError);
    }

    GATTServApp_InitCharCfg( INVALID_CONNHANDLE, simpleProfileChar4Config);

    then in set parameters

    case SIMPLEPROFILE_CHAR4:
    if (len == SIMPLEPROFILE_CHAR4_LEN) {

    VOID memcpy(simpleProfileChar4, value, SIMPLEPROFILE_CHAR4_LEN);

    GATTServApp_ProcessCharCfg(simpleProfileChar4Config,simpleProfileChar4, FALSE, simpleProfileAttrTbl,GATT_NUM_ATTRS(simpleProfileAttrTbl),INVALID_TASK_ID, simpleProfile_ReadAttrCB);

    } else {
    ret = bleInvalidRange;
    }
    break;

    then in get parameters

    case SIMPLEPROFILE_CHAR4:
    VOID memcpy(value, simpleProfileChar4, SIMPLEPROFILE_CHAR4_LEN);
    break;

    then in read attribute

    case SIMPLEPROFILE_CHAR4_UUID:
    *pLen = SIMPLEPROFILE_CHAR4_LEN;
    VOID memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR4_LEN);

    then in simple ble perepheral.c in the init function i set the property
    SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, SIMPLEPROFILE_CHAR4_LEN,charValue4);

    now i can scan the characterstic in btool abd i enable the config characterstic by writing 01:00 into it
    then in timer function the following function is being called
    SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, SIMPLEPROFILE_CHAR4_LEN,charValue4);
    but in btool i am only receiving 5 bytes instead of 20 bytes

    charValue4 is also an array of 20 bytes

    what is the problem?
    i also tried different methods like i changed the property to notify and read
    but hwne i read in btool it still giving 5 bytes instead of 20 bytes
  • Did you take care of the following function?
    SimpleBLEPeripheral_performPeriodicTask
  • i meant SimpleBLEPeripheral_performPeriodicTask when i said timer function
    so yes i called this function
    SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, SIMPLEPROFILE_CHAR4_LEN,charValue4);
    so that it can sent a notification
    and yes i can receive a notification in btool on every SimpleBLEPeripheral_performPeriodicTask event but the data length is 5 bytes instead of 20 thats the problem
  • Can you try to set breakpoint and check what got passed into the function?
  • i already did and the whole array is being passed into the function
  • Hi Mohammad,

    GATTServApp_ProcessCharCfg is ultimately what will being calling the BLE-Stack API to send your notification. Since it appears that you are getting the array passed into your set_parameter function, can you debug into the GATTServApp_ProcessCharCfg to see what it returns? If successful it should call gattServApp_SendNotiInd and return a status, what is that value?
  • but the notification is receiving on btool the problem is that m only getting 5 bytes of the characteristic value while i have defined it 20 bytes in the code....and one more thing i also tried removing notify property and gave characteristic 4 read property and disable the notification property at that time it was just like another characteristic with read property and when i read its value in btool it was still giving 5 bytes only (keeping in mind that it was no more a notification characteristic) ........
  • Mohammad,

    Thanks for the update. However, if you are trying to send notifications, then it is best to test with notifications. Can you please try my suggestion above?
  • i will try ur suggestion too ...beside ur suggestion i have found another solution but couldnt find what the problem was....i created another characteristic with same properties of 20 bytes and it worked i did everything same as i did for characteristic 4 so with new characteristic m receiving 20 bytes but still couldnt get what the problem was well ill try ur suggestion and will update u on this so that anybody else couldnt face the same problem
  • Mohammad,

    Glad you have it working, but I believe you have missed one step for converting char4. I have been to send a 20B notification on char4 by following the general steps outlined you sent. Let me know the results of your debugging. Particularly you are interested in

    gattAttribute_t *pAttr;
    pAttr->len //MAKE SURE THIS IS 20B!
  • this is the debug screen shot for pattr

  • the status  is success its not the norify property problem i guess its something else

    because i created another characterstic with the same code and i am receiving 20 bytes on notifications

    but not on char4

  • Mohammad,

    The problem is that len is not 20B so the GATT server still thinks you are working with a 20B char. The best advice I can offer is that you should go through every reference to char 4 and change its size. Also, since char4 is now an array, there is some pointer housekeeping that needs to be taken care of. For example &char4 is not necessary anymore. Also make sure when initializing char4 in the SBP init function you are using a 20B value. I have verified that it is possible to extend of char 4 to 20B.

    If you still have issues please post your code (entire .c,.h files) as an attachment. Please do not copy and paste as it will be hard to read. You can do this using the rich formatting button and then clicking the paperclip 

  • ok i am uploading the files

    /**************************************************************************************************
     Filename:       simpleGATTprofile.c
     Revised:        $Date: 2015-07-20 11:31:07 -0700 (Mon, 20 Jul 2015) $
     Revision:       $Revision: 44370 $
    
     Description:    This file contains the Simple GATT profile sample GATT service
     profile for use with the BLE sample application.
    
     Copyright 2010 - 2015 Texas Instruments Incorporated. All rights reserved.
    
     IMPORTANT: Your use of this Software is limited to those specific rights
     granted under the terms of a software license agreement between the user
     who downloaded the software, his/her employer (which must be your employer)
     and Texas Instruments Incorporated (the "License").  You may not use this
     Software unless you agree to abide by the terms of the License. The License
     limits your use, and you acknowledge, that the Software may not be modified,
     copied or distributed unless embedded on a Texas Instruments microcontroller
     or used solely and exclusively in conjunction with a Texas Instruments radio
     frequency transceiver, which is integrated into your product.  Other than for
     the foregoing purpose, you may not use, reproduce, copy, prepare derivative
     works of, modify, distribute, perform, display or sell this Software and/or
     its documentation for any purpose.
    
     YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
     PROVIDED �AS IS� WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
     INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
     NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
     TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
     NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
     LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
     INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
     OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
     OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
     (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
    
     Should you have any questions regarding your right to use this Software,
     contact Texas Instruments Incorporated at www.TI.com.
     **************************************************************************************************/
    
    /*********************************************************************
     * 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 "simpleGATTprofile.h"
    #include "hal_mcu.h"
    
    /*********************************************************************
     * MACROS
     */
    
    /*********************************************************************
     * CONSTANTS
     */
    
    #define SERVAPP_NUM_ATTR_SUPPORTED        33
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    /*********************************************************************
     * GLOBAL VARIABLES (arrays to break uuid into two bytes and swap bytes)
     */
    // Simple GATT Profile Service UUID: 0xFFF0  //now 0x1523
    CONST uint8 simpleProfileServUUID[ATT_UUID_SIZE] = {
    		//LO_UINT16(SIMPLEPROFILE_SERV_UUID), HI_UINT16(SIMPLEPROFILE_SERV_UUID)
    		TI_BASE_UUID_128(SIMPLEPROFILE_SERV_UUID),  //shayan
    };
    
    // Characteristic 1 UUID: 0xFFF1  //now 0x1524
    CONST uint8 simpleProfilechar1UUID[ATT_UUID_SIZE] = {
    		//LO_UINT16(SIMPLEPROFILE_CHAR1_UUID), HI_UINT16(SIMPLEPROFILE_CHAR1_UUID)
    		TI_BASE_UUID_128(SIMPLEPROFILE_CHAR1_UUID), //shayan
    };
    
    // Characteristic 2 UUID: 0xFFF2
    CONST uint8 simpleProfilechar2UUID[ATT_BT_UUID_SIZE] = { LO_UINT16(
    		SIMPLEPROFILE_CHAR2_UUID), HI_UINT16(SIMPLEPROFILE_CHAR2_UUID) };
    
    // Characteristic 3 UUID: 0xFFF3 //now 0x0002
    CONST uint8 simpleProfilechar3UUID[ATT_UUID_SIZE] = {
    		TI_BASE_UUID_128(SIMPLEPROFILE_CHAR3_UUID), //shayan };
    };
    
    // Characteristic 4 UUID: 0xFFF4
    CONST uint8 simpleProfilechar4UUID[ATT_BT_UUID_SIZE] = { LO_UINT16(
    		SIMPLEPROFILE_CHAR4_UUID), HI_UINT16(SIMPLEPROFILE_CHAR4_UUID) };
    
    // Characteristic 5 UUID: 0xFFF5
    CONST uint8 simpleProfilechar5UUID[ATT_BT_UUID_SIZE] = { LO_UINT16(
    		SIMPLEPROFILE_CHAR5_UUID), HI_UINT16(SIMPLEPROFILE_CHAR5_UUID) };
    
    // Characteristic 6 UUID: 0xFFF6 //now 0x1526
    CONST uint8 simpleProfilechar6UUID[ATT_UUID_SIZE] = {
    		//LO_UINT16(SIMPLEPROFILE_CHAR6_UUID), HI_UINT16(SIMPLEPROFILE_CHAR6_UUID)
    		TI_BASE_UUID_128(SIMPLEPROFILE_CHAR6_UUID), //shayan
    };
    
    // Characteristic 7 UUID: 0xFFF7 //now 0x152A
    CONST uint8 simpleProfilechar7UUID[ATT_UUID_SIZE] = {
    		//LO_UINT16(SIMPLEPROFILE_CHAR7_UUID), HI_UINT16(SIMPLEPROFILE_CHAR7_UUID)
    		TI_BASE_UUID_128(SIMPLEPROFILE_CHAR7_UUID), //shayan
    };
    
    // Characteristic 8 UUID: 0xFFF8 // now 0x152C
    CONST uint8 simpleProfilechar8UUID[ATT_UUID_SIZE] = {
    		//LO_UINT16(SIMPLEPROFILE_CHAR8_UUID), HI_UINT16(SIMPLEPROFILE_CHAR8_UUID)
    		TI_BASE_UUID_128(SIMPLEPROFILE_CHAR8_UUID), //shayan
    };
    
    // Characteristic 9 UUID: 0xFFF9 //now 0x152D
    CONST uint8 simpleProfilechar9UUID[ATT_UUID_SIZE] = {
    		//LO_UINT16(SIMPLEPROFILE_CHAR9_UUID), HI_UINT16(SIMPLEPROFILE_CHAR9_UUID)
    		TI_BASE_UUID_128(SIMPLEPROFILE_CHAR9_UUID), //shayan
    
    };
    
    // Characteristic 10 UUID: //now 0x152E
    CONST uint8 simpleProfilechar10UUID[ATT_UUID_SIZE] = {
    		//LO_UINT16(SIMPLEPROFILE_CHAR9_UUID), HI_UINT16(SIMPLEPROFILE_CHAR9_UUID)
    		TI_BASE_UUID_128(SIMPLEPROFILE_CHAR10_UUID), //shayan
    
    };
    
    bool correctpass=FALSE;
    
    /*********************************************************************
     * EXTERNAL VARIABLES
     */
    
    /*********************************************************************
     * EXTERNAL FUNCTIONS
     */
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    
    static simpleProfileCBs_t *simpleProfile_AppCBs = NULL;
    
    /*********************************************************************
     * Profile Attributes - variables
     */
    
    // Simple Profile Service attribute
    static CONST gattAttrType_t simpleProfileService = { ATT_UUID_SIZE,
    		simpleProfileServUUID };
    
    /*
     // Simple Profile Characteristic 1 Properties
     static uint8 simpleProfileChar1Props = GATT_PROP_READ | GATT_PROP_WRITE;
    
     // Characteristic 1 Value
     static uint8 simpleProfileChar1 = 0;
    
     // Simple Profile Characteristic 1 User Description
     static uint8 simpleProfileChar1UserDesp[17] = "my char 1";
     */ //shayan
    // Simple Profile Characteristic 1 Properties
    static uint8 simpleProfileChar1Props = GATT_PROP_READ | GATT_PROP_WRITE;
    
    // Characteristic 1 Value
    static uint8 simpleProfileChar1[SIMPLEPROFILE_CHAR1_LEN] = { 0, 0, 0, 0, 0, 0,
    		0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    
    // Simple Profile Characteristic 1 User Description
    static uint8 simpleProfileChar1UserDesp[17] = "char 1 length 16";
    //shayan
    
    // Simple Profile Characteristic 2 Properties
    static uint8 simpleProfileChar2Props = GATT_PROP_READ;
    
    // Characteristic 2 Value
    static uint8 simpleProfileChar2 = 0;
    
    // Simple Profile Characteristic 2 User Description
    static uint8 simpleProfileChar2UserDesp[17] = "my char 2";
    
    // Simple Profile Characteristic 3 Properties
    static uint8 simpleProfileChar3Props = GATT_PROP_WRITE;
    
    // Characteristic 3 Value
    //static uint8 simpleProfileChar3 = 0;
    static uint8 simpleProfileChar3[SIMPLEPROFILE_CHAR3_LEN] = { 0, 0 };
    
    // Simple Profile Characteristic 3 User Description
    static uint8 simpleProfileChar3UserDesp[17] = "RX";
    
    // Simple Profile Characteristic 4 Properties
    static uint8 simpleProfileChar4Props = GATT_PROP_READ | GATT_PROP_NOTIFY;
    
    // Characteristic 4 Value
    //static uint8 simpleProfileChar4 = 0;
    static uint8 simpleProfileChar4[SIMPLEPROFILE_CHAR4_LEN] = { 0, 0, 0, 0, 0, 0,
    		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    
    // Simple Profile Characteristic 4 Configuration Each client has its own
    // instantiation of the Client Characteristic Configuration. Reads of the
    // Client Characteristic Configuration only shows the configuration for
    // that client and writes only affect the configuration of that client.
    static gattCharCfg_t *simpleProfileChar4Config;
    
    // Simple Profile Characteristic 4 User Description
    static uint8 simpleProfileChar4UserDesp[17] = "TX";
    
    // Simple Profile Characteristic 5 Properties
    static uint8 simpleProfileChar5Props = GATT_PROP_READ;
    
    // Characteristic 5 Value
    static uint8 simpleProfileChar5[SIMPLEPROFILE_CHAR5_LEN] = { 0, 0, 0, 0, 0 };
    
    // Simple Profile Characteristic 5 User Description
    static uint8 simpleProfileChar5UserDesp[17] = "Characteristic 5";
    
    
    //new characterstcs by shayan
    
    // Simple Profile Characteristic 6 Properties
    static uint8 simpleProfileChar6Props = GATT_PROP_READ | GATT_PROP_WRITE;
    
    // Characteristic 6 Value
    static uint8 simpleProfileChar6[SIMPLEPROFILE_CHAR6_LEN] = { 0, 0, 0, 0, 0, 0, 0, 0 };
    
    // Simple Profile Characteristic 6 User Description
    static uint8 simpleProfileChar6UserDesp[17] = "char 6 length 8";
    
    // Simple Profile Characteristic 7 Properties
    static uint8 simpleProfileChar7Props = GATT_PROP_READ | GATT_PROP_WRITE;
    
    // Characteristic 7 Value
    static uint8 simpleProfileChar7[SIMPLEPROFILE_CHAR7_LEN] = { 0, 0, 0, 0 };
    
    // Simple Profile Characteristic 7 User Description
    static uint8 simpleProfileChar7UserDesp[17] = "char 7 length 4";
    
    // Simple Profile Characteristic 8 Properties
    static uint8 simpleProfileChar8Props = GATT_PROP_READ | GATT_PROP_WRITE;
    
    // Characteristic 8 Value
    static uint8 simpleProfileChar8[SIMPLEPROFILE_CHAR8_LEN] = { 0, 0, 0, 0, 0, 0, 0 };
    
    // Simple Profile Characteristic 8 User Description
    static uint8 simpleProfileChar8UserDesp[17] = "char 8 length 7";
    
    // Simple Profile Characteristic 9 Properties
    static uint8 simpleProfileChar9Props = GATT_PROP_READ | GATT_PROP_WRITE;
    
    // Characteristic 9 Value
    static uint8 simpleProfileChar9[SIMPLEPROFILE_CHAR9_LEN] = { 0, 0 };
    
    // Simple Profile Characteristic 9 User Description
    static uint8 simpleProfileChar9UserDesp[17] = "char 9 length 2";
    
    // Simple Profile Characteristic 10 Properties
    static uint8 simpleProfileChar10Props = GATT_PROP_READ |GATT_PROP_NOTIFY;
    
    // Characteristic 10 Value
    static uint8 simpleProfileChar10[SIMPLEPROFILE_CHAR10_LEN] = { 0, 0, 0, 0, 0, 0,
    		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    
    static gattCharCfg_t *simpleProfileChar10Config;
    // Simple Profile Characteristic 10 User Description
    static uint8 simpleProfileChar10UserDesp[17] = "TX";
    
    bStatus_t status;
    //new characterstics by shayan
    
    /*********************************************************************
     * Profile Attributes - Table
     */
    
    static gattAttribute_t simpleProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] = {
    // Simple Profile Service
    		{ { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
    		GATT_PERMIT_READ, /* permissions */
    		0, /* handle */
    		(uint8 *) &simpleProfileService /* pValue */
    		},
    
    		// Characteristic 1 Declaration
    		{ { ATT_BT_UUID_SIZE, characterUUID },
    		GATT_PERMIT_READ, 0, &simpleProfileChar1Props },
    
    		// Characteristic Value 1
    		{ { ATT_UUID_SIZE, simpleProfilechar1UUID },
    		GATT_PERMIT_READ | GATT_PERMIT_WRITE, 0, simpleProfileChar1 },
    
    		// Characteristic 1 User Description
    		{ { ATT_BT_UUID_SIZE, charUserDescUUID },
    		GATT_PERMIT_READ, 0, simpleProfileChar1UserDesp },
    
    		// Characteristic 2 Declaration
    		{ { ATT_BT_UUID_SIZE, characterUUID },
    		GATT_PERMIT_READ, 0, &simpleProfileChar2Props },
    
    		// Characteristic Value 2
    		{ { ATT_BT_UUID_SIZE, simpleProfilechar2UUID },
    		GATT_PERMIT_READ, 0, &simpleProfileChar2 },
    
    		// Characteristic 2 User Description
    		{ { ATT_BT_UUID_SIZE, charUserDescUUID },
    		GATT_PERMIT_READ, 0, simpleProfileChar2UserDesp },
    
    		// Characteristic 3 Declaration
    		{ { ATT_BT_UUID_SIZE, characterUUID },
    		GATT_PERMIT_READ, 0, &simpleProfileChar3Props },
    
    		// Characteristic Value 3
    		{ { ATT_UUID_SIZE, simpleProfilechar3UUID },
    		GATT_PERMIT_WRITE, 0, simpleProfileChar3 },
    
    		// Characteristic 3 User Description
    		{ { ATT_BT_UUID_SIZE, charUserDescUUID },
    		GATT_PERMIT_READ, 0, simpleProfileChar3UserDesp },
    
    		// Characteristic 4 Declaration
    		{ { ATT_BT_UUID_SIZE, characterUUID },
    		GATT_PERMIT_READ, 0, &simpleProfileChar4Props },
    
    		// Characteristic Value 4
    		{ { ATT_BT_UUID_SIZE, simpleProfilechar4UUID },
    		GATT_PERMIT_READ, 0,simpleProfileChar4 },
    
    		// Characteristic 4 configuration
    		{ { ATT_BT_UUID_SIZE, clientCharCfgUUID },
    		GATT_PERMIT_READ | GATT_PERMIT_WRITE, 0,
    				(uint8 *) &simpleProfileChar4Config },
    
    		// Characteristic 4 User Description
    		{ { ATT_BT_UUID_SIZE, charUserDescUUID },
    		GATT_PERMIT_READ, 0, simpleProfileChar4UserDesp },
    
    		// Characteristic 5 Declaration
    		{ { ATT_BT_UUID_SIZE, characterUUID },
    		GATT_PERMIT_READ, 0, &simpleProfileChar5Props },
    
    		// Characteristic Value 5
    		{ { ATT_BT_UUID_SIZE, simpleProfilechar5UUID },
    		GATT_PERMIT_AUTHEN_READ, 0, simpleProfileChar5 },
    
    		// Characteristic 5 User Description
    		{ { ATT_BT_UUID_SIZE, charUserDescUUID },
    		GATT_PERMIT_READ, 0, simpleProfileChar5UserDesp },
    
    		//shayan work
    		// Characteristic 6 Declaration
    				{ { ATT_BT_UUID_SIZE, characterUUID },
    				GATT_PERMIT_READ, 0, &simpleProfileChar6Props },
    
    				// Characteristic Value 6
    				{ { ATT_UUID_SIZE, simpleProfilechar6UUID },
    				GATT_PERMIT_READ | GATT_PERMIT_WRITE, 0, simpleProfileChar6 },
    
    				// Characteristic 6 User Description
    				{ { ATT_BT_UUID_SIZE, charUserDescUUID },
    				GATT_PERMIT_READ, 0, simpleProfileChar6UserDesp },
    
    				// Characteristic 7 Declaration
    						{ { ATT_BT_UUID_SIZE, characterUUID },
    						GATT_PERMIT_READ, 0, &simpleProfileChar7Props },
    
    						// Characteristic Value 7
    						{ { ATT_UUID_SIZE, simpleProfilechar7UUID },
    						GATT_PERMIT_READ | GATT_PERMIT_WRITE, 0, simpleProfileChar7 },
    
    						// Characteristic 7 User Description
    						{ { ATT_BT_UUID_SIZE, charUserDescUUID },
    						GATT_PERMIT_READ, 0, simpleProfileChar7UserDesp },
    
    						// Characteristic 8 Declaration
    								{ { ATT_BT_UUID_SIZE, characterUUID },
    								GATT_PERMIT_READ, 0, &simpleProfileChar8Props },
    
    								// Characteristic Value 8
    								{ { ATT_UUID_SIZE, simpleProfilechar8UUID },
    								GATT_PERMIT_READ | GATT_PERMIT_WRITE, 0, simpleProfileChar8 },
    
    								// Characteristic 8 User Description
    								{ { ATT_BT_UUID_SIZE, charUserDescUUID },
    								GATT_PERMIT_READ, 0, simpleProfileChar8UserDesp },
    
    								// Characteristic 9 Declaration
    										{ { ATT_BT_UUID_SIZE, characterUUID },
    										GATT_PERMIT_READ, 0, &simpleProfileChar9Props },
    
    										// Characteristic Value 9
    										{ { ATT_UUID_SIZE, simpleProfilechar9UUID },
    										GATT_PERMIT_READ | GATT_PERMIT_WRITE, 0, simpleProfileChar9 },
    
    										// Characteristic 9 User Description
    										{ { ATT_BT_UUID_SIZE, charUserDescUUID },
    										GATT_PERMIT_READ, 0, simpleProfileChar9UserDesp },
    
    										// Characteristic 10 Declaration
    										{ { ATT_BT_UUID_SIZE, characterUUID },
    										GATT_PERMIT_READ, 0, &simpleProfileChar10Props },
    
    										// Characteristic Value 10
    										{ { ATT_UUID_SIZE, simpleProfilechar10UUID },
    										GATT_PERMIT_READ, 0, simpleProfileChar10 },
    
    										// Characteristic 10 configuration
    										{ { ATT_BT_UUID_SIZE, clientCharCfgUUID },
    										GATT_PERMIT_READ | GATT_PERMIT_WRITE, 0,
    												(uint8 *) &simpleProfileChar10Config },
    
    										// Characteristic 10 User Description
    										{ { ATT_BT_UUID_SIZE, charUserDescUUID },
    										GATT_PERMIT_READ, 0, simpleProfileChar10UserDesp },};
    		//shayan work
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    static bStatus_t simpleProfile_ReadAttrCB(uint16_t connHandle,
    		gattAttribute_t *pAttr, uint8_t *pValue, uint16_t *pLen,
    		uint16_t offset, uint16_t maxLen, uint8_t method);
    static bStatus_t simpleProfile_WriteAttrCB(uint16_t connHandle,
    		gattAttribute_t *pAttr, uint8_t *pValue, uint16_t len, uint16_t offset,
    		uint8_t method);
    
    /*********************************************************************
     * PROFILE CALLBACKS
     */
    // Simple Profile Service Callbacks
    CONST gattServiceCBs_t simpleProfileCBs = { simpleProfile_ReadAttrCB, // Read callback function pointer
    		simpleProfile_WriteAttrCB, // Write callback function pointer
    		NULL                       // Authorization callback function pointer
    		};
    
    /*********************************************************************
     * PUBLIC FUNCTIONS
     */
    
    /*********************************************************************
     * @fn      SimpleProfile_AddService
     *
     * @brief   Initializes the Simple Profile service by registering
     *          GATT attributes with the GATT server.
     *
     * @param   services - services to add. This is a bit map and can
     *                     contain more than one service.
     *
     * @return  Success or Failure
     */
    bStatus_t SimpleProfile_AddService(uint32 services) {
    	uint8 status;
    
    	// Allocate Client Characteristic Configuration table
    	simpleProfileChar4Config = (gattCharCfg_t *) ICall_malloc(
    			sizeof(gattCharCfg_t) * linkDBNumConns);
    	if (simpleProfileChar4Config == NULL) {
    		return ( bleMemAllocError);
    	}
    	//shayan
    	// Allocate Client Characteristic Configuration table
    	simpleProfileChar10Config = (gattCharCfg_t *) ICall_malloc(
    			sizeof(gattCharCfg_t) * linkDBNumConns);
    	if (simpleProfileChar10Config == NULL) {
    		return ( bleMemAllocError);
    	}
    
    
    	// Initialize Client Characteristic Configuration attributes
    	GATTServApp_InitCharCfg( INVALID_CONNHANDLE, simpleProfileChar4Config);
    
    	GATTServApp_InitCharCfg( INVALID_CONNHANDLE, simpleProfileChar10Config); //shayan
    
    	if (services & SIMPLEPROFILE_SERVICE) {
    		// Register GATT attribute list and CBs with GATT Server App
    		status = GATTServApp_RegisterService(simpleProfileAttrTbl,
    				GATT_NUM_ATTRS(simpleProfileAttrTbl),
    				GATT_MAX_ENCRYPT_KEY_SIZE, &simpleProfileCBs);
    	} else {
    		status = SUCCESS;
    	}
    
    	return (status);
    }
    
    /*********************************************************************
     * @fn      SimpleProfile_RegisterAppCBs
     *
     * @brief   Registers the application callback function. Only call 
     *          this function once.
     *
     * @param   callbacks - pointer to application callbacks.
     *
     * @return  SUCCESS or bleAlreadyInRequestedMode
     */
    bStatus_t SimpleProfile_RegisterAppCBs(simpleProfileCBs_t *appCallbacks) {
    	if (appCallbacks) {
    		simpleProfile_AppCBs = appCallbacks;
    
    		return ( SUCCESS);
    	} else {
    		return ( bleAlreadyInRequestedMode);
    	}
    }
    
    /*********************************************************************
     * @fn      SimpleProfile_SetParameter
     *
     * @brief   Set a Simple Profile parameter.
     *
     * @param   param - Profile parameter ID
     * @param   len - length of data to write
     * @param   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).
     *
     * @return  bStatus_t
     */
    bStatus_t SimpleProfile_SetParameter(uint8 param, uint8 len, void *value) {
    	bStatus_t ret = SUCCESS;
    	switch (param) {
    	case SIMPLEPROFILE_CHAR1:
    
    		if (len == SIMPLEPROFILE_CHAR1_LEN) {
    			VOID memcpy(simpleProfileChar1, value, SIMPLEPROFILE_CHAR1_LEN);
    		} else {
    			ret = bleInvalidRange;
    		}
    
    		break;
    
    	case SIMPLEPROFILE_CHAR2:
    		if (len == sizeof(uint8)) {
    			simpleProfileChar2 = *((uint8*) value);
    		} else {
    			ret = bleInvalidRange;
    		}
    		break;
    
    	case SIMPLEPROFILE_CHAR3:
    		if (len == SIMPLEPROFILE_CHAR3_LEN) {
    			//simpleProfileChar3 = *((uint8*) value);
    			VOID memcpy(simpleProfileChar3, value, SIMPLEPROFILE_CHAR3_LEN);
    		} else {
    			ret = bleInvalidRange;
    		}
    		break;
    
    	case SIMPLEPROFILE_CHAR4:
    		if (len == SIMPLEPROFILE_CHAR4_LEN) {
    			//simpleProfileChar4 = *((uint8*) value);
    			VOID memcpy(simpleProfileChar4, value, SIMPLEPROFILE_CHAR4_LEN);
    			// See if Notification has been enabled
    			//GATTServApp_ProcessCharCfg(simpleProfileChar4Config,
    				//	&simpleProfileChar4, FALSE, simpleProfileAttrTbl,
    				//	GATT_NUM_ATTRS(simpleProfileAttrTbl),
    				//	INVALID_TASK_ID, simpleProfile_ReadAttrCB);
    			 status = GATTServApp_ProcessCharCfg(simpleProfileChar4Config,simpleProfileChar4, FALSE, simpleProfileAttrTbl,GATT_NUM_ATTRS(simpleProfileAttrTbl),INVALID_TASK_ID, simpleProfile_ReadAttrCB);
    
    		} else {
    			ret = bleInvalidRange;
    		}
    		break;
    
    	case SIMPLEPROFILE_CHAR5:
    		if (len == SIMPLEPROFILE_CHAR5_LEN) {
    			VOID memcpy(simpleProfileChar5, value, SIMPLEPROFILE_CHAR5_LEN);
    		} else {
    			ret = bleInvalidRange;
    		}
    		break;
    		//shayan work
    	case SIMPLEPROFILE_CHAR6:
    		if (len == SIMPLEPROFILE_CHAR6_LEN) {
    				VOID memcpy(simpleProfileChar6, value, SIMPLEPROFILE_CHAR6_LEN);
    			} else {
    				ret = bleInvalidRange;
    			}
    		break;
    
    	case SIMPLEPROFILE_CHAR7:
    		if (len == SIMPLEPROFILE_CHAR7_LEN) {
    				VOID memcpy(simpleProfileChar7, value, SIMPLEPROFILE_CHAR7_LEN);
    			} else {
    				ret = bleInvalidRange;
    			}
    		break;
    
    	case SIMPLEPROFILE_CHAR8:
    		if (len == SIMPLEPROFILE_CHAR8_LEN) {
    				VOID memcpy(simpleProfileChar8, value, SIMPLEPROFILE_CHAR8_LEN);
    			} else {
    				ret = bleInvalidRange;
    			}
    		break;
    
    	case SIMPLEPROFILE_CHAR9:
    		if (len == SIMPLEPROFILE_CHAR9_LEN) {
    				VOID memcpy(simpleProfileChar9, value, SIMPLEPROFILE_CHAR9_LEN);
    			} else {
    				ret = bleInvalidRange;
    			}
    		break;
    
    	case SIMPLEPROFILE_CHAR10:
    			if (len == SIMPLEPROFILE_CHAR10_LEN) {
    					VOID memcpy(simpleProfileChar10, value, SIMPLEPROFILE_CHAR10_LEN);
    
    					GATTServApp_ProcessCharCfg(simpleProfileChar10Config,simpleProfileChar10, FALSE, simpleProfileAttrTbl,GATT_NUM_ATTRS(simpleProfileAttrTbl),INVALID_TASK_ID, simpleProfile_ReadAttrCB);
    
    				} else {
    					ret = bleInvalidRange;
    				}
    			break;
    		//shayan work
    
    	default:
    		ret = INVALIDPARAMETER;
    		break;
    	}
    
    	return (ret);
    }
    
    /*********************************************************************
     * @fn      SimpleProfile_GetParameter
     *
     * @brief   Get a Simple Profile parameter.
     *
     * @param   param - Profile parameter ID
     * @param   value - pointer to data to put.  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).
     *
     * @return  bStatus_t
     */
    bStatus_t SimpleProfile_GetParameter(uint8 param, void *value) {
    	bStatus_t ret = SUCCESS;
    	switch (param) {
    	case SIMPLEPROFILE_CHAR1:
    		// *((uint8*)value) = simpleProfileChar1;
    		VOID memcpy(value, simpleProfileChar1, SIMPLEPROFILE_CHAR1_LEN);
    		break;
    
    	case SIMPLEPROFILE_CHAR2:
    		*((uint8*) value) = simpleProfileChar2;
    		break;
    
    	case SIMPLEPROFILE_CHAR3:
    		//*((uint8*) value) = simpleProfileChar3;
    		VOID memcpy(value, simpleProfileChar3, SIMPLEPROFILE_CHAR3_LEN);
    		break;
    
    	case SIMPLEPROFILE_CHAR4:
    		//*((uint8*) value) = simpleProfileChar4;
    		VOID memcpy(value, simpleProfileChar4, SIMPLEPROFILE_CHAR4_LEN);
    		break;
    
    	case SIMPLEPROFILE_CHAR5:
    		VOID memcpy(value, simpleProfileChar5, SIMPLEPROFILE_CHAR5_LEN);
    		break;
    
    		//shayan work
    	case SIMPLEPROFILE_CHAR6:
    		VOID memcpy(value, simpleProfileChar6, SIMPLEPROFILE_CHAR6_LEN);
    		break;
    
    	case SIMPLEPROFILE_CHAR7:
    		VOID memcpy(value, simpleProfileChar7, SIMPLEPROFILE_CHAR7_LEN);
    		break;
    
    	case SIMPLEPROFILE_CHAR8:
    		VOID memcpy(value, simpleProfileChar8, SIMPLEPROFILE_CHAR8_LEN);
    		break;
    
    	case SIMPLEPROFILE_CHAR9:
    		VOID memcpy(value, simpleProfileChar9, SIMPLEPROFILE_CHAR9_LEN);
    		break;
    
    	case SIMPLEPROFILE_CHAR10:
    			VOID memcpy(value, simpleProfileChar10, SIMPLEPROFILE_CHAR10_LEN);
    			break;
    		//shayan work
    
    	default:
    		ret = INVALIDPARAMETER;
    		break;
    	}
    
    	return (ret);
    }
    
    /*********************************************************************
     * @fn          simpleProfile_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 simpleProfile_ReadAttrCB(uint16_t connHandle,
    		gattAttribute_t *pAttr, uint8_t *pValue, uint16_t *pLen,
    		uint16_t offset, uint16_t maxLen, uint8_t method) {
    	bStatus_t status = SUCCESS;
    
    	// If attribute permissions require authorization to read, return error
    	if (gattPermitAuthorRead(pAttr->permissions)) {
    		// Insufficient authorization
    		return ( ATT_ERR_INSUFFICIENT_AUTHOR);
    	}
    
    	// Make sure it's not a blob operation (no attributes in the profile are long)
    	if (offset > 0) {
    		return ( ATT_ERR_ATTR_NOT_LONG);
    	}
    
    	if (pAttr->type.len == ATT_BT_UUID_SIZE || pAttr->type.len == ATT_UUID_SIZE) {
    		// 16-bit UUID
    		//uint16 uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
    		uint16 uuid;
    		if (pAttr->type.len == ATT_BT_UUID_SIZE )
    		  {
    		    // 16-bit UUID direct
    			 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
    		  }
    		  else if (pAttr->type.len == ATT_UUID_SIZE)
    		  {
    		    // 16-bit UUID extracted bytes 12 and 13
    			  uuid = BUILD_UINT16( pAttr->type.uuid[12], pAttr->type.uuid[13]);
    		  }
    
    
    		 switch (uuid) {
    		// No need for "GATT_SERVICE_UUID" or "GATT_CLIENT_CHAR_CFG_UUID" cases;
    		// gattserverapp handles those reads
    		// characteristics 1 and 2 have read permissions
    		// characteritisc 3 does not have read permissions; therefore it is not
    		//   included here
    		// characteristic 4 does not have read permissions, but because it
    		//   can be sent as a notification, it is included here
    		case SIMPLEPROFILE_CHAR1_UUID:
    			*pLen = SIMPLEPROFILE_CHAR1_LEN;
    			VOID memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR1_LEN);
    			break;
    		case SIMPLEPROFILE_CHAR2_UUID:
    
    			*pLen = 1;
    			pValue[0] = *pAttr->pValue;
    			break;
    
    		case SIMPLEPROFILE_CHAR4_UUID:
    			*pLen = SIMPLEPROFILE_CHAR4_LEN;
    			VOID memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR4_LEN);
    
    		case SIMPLEPROFILE_CHAR5_UUID:
    			*pLen = SIMPLEPROFILE_CHAR5_LEN;
    			VOID memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR5_LEN);
    			break;
    
    			//shayan work
    		case SIMPLEPROFILE_CHAR6_UUID:
    			*pLen = SIMPLEPROFILE_CHAR6_LEN;
    			VOID memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR6_LEN);
    			break;
    
    		case SIMPLEPROFILE_CHAR7_UUID:
    			*pLen = SIMPLEPROFILE_CHAR7_LEN;
    			VOID memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR7_LEN);
    			break;
    
    		case SIMPLEPROFILE_CHAR8_UUID:
    			*pLen = SIMPLEPROFILE_CHAR8_LEN;
    			VOID memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR8_LEN);
    			break;
    
    		case SIMPLEPROFILE_CHAR9_UUID:
    			*pLen = SIMPLEPROFILE_CHAR9_LEN;
    			VOID memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR9_LEN);
    			break;
    
    		case SIMPLEPROFILE_CHAR10_UUID:
    			*pLen = SIMPLEPROFILE_CHAR10_LEN;
    			VOID memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR10_LEN);
    			break;
    			//shayan work
    
    		default:
    			// Should never get here! (characteristics 3 and 4 do not have read permissions)
    			*pLen = 0;
    			status = ATT_ERR_ATTR_NOT_FOUND;
    			break;
    		}
    	} else {
    		// 128-bit UUID
    		*pLen = 0;
    		status = ATT_ERR_INVALID_HANDLE;
    	}
    
    	return (status);
    }
    
    /*********************************************************************
     * @fn      simpleProfile_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 simpleProfile_WriteAttrCB(uint16_t connHandle,
    		gattAttribute_t *pAttr, uint8_t *pValue, uint16_t len, uint16_t offset,
    		uint8_t method) {
    	bStatus_t status = SUCCESS;
    	uint8 notifyApp = 0xFF;
    
    	// If attribute permissions require authorization to write, return error
    	if (gattPermitAuthorWrite(pAttr->permissions)) {
    		// Insufficient authorization
    		return ( ATT_ERR_INSUFFICIENT_AUTHOR);
    	}
    
    	if (pAttr->type.len == ATT_BT_UUID_SIZE || pAttr->type.len == ATT_UUID_SIZE) {
    		// 16-bit UUID
    		//uint16 uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
    		uint16 uuid;
    		if (pAttr->type.len == ATT_BT_UUID_SIZE )
    		  {
    		    // 16-bit UUID direct
    			 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
    		  }
    		  else if (pAttr->type.len == ATT_UUID_SIZE)
    		  {
    		    // 16-bit UUID extracted bytes 12 and 13
    			  uuid = BUILD_UINT16( pAttr->type.uuid[12], pAttr->type.uuid[13]);
    		  }
    
    		switch (uuid) {
    
    		case SIMPLEPROFILE_CHAR1_UUID:
    			//shayan
    			//Validate the value
    			// Make sure it's not a blob oper
    			if (offset == 0) {
    				if (len != SIMPLEPROFILE_CHAR1_LEN) {
    					status = ATT_ERR_INVALID_VALUE_SIZE;
    				}
    			} else {
    				status = ATT_ERR_ATTR_NOT_LONG;
    			}
    			if (status == SUCCESS && correctpass) {
    		    memcpy(simpleProfileChar1, pValue, SIMPLEPROFILE_CHAR1_LEN);
    		    notifyApp = SIMPLEPROFILE_CHAR1;
    			}
    			else{HAL_SYSTEM_RESET();}
    			break;
    			//shayan
    
    		case SIMPLEPROFILE_CHAR3_UUID:
    
    			//Validate the value
    			// Make sure it's not a blob oper
    			if (offset == 0) {
    				if (len != SIMPLEPROFILE_CHAR3_LEN) {
    					status = ATT_ERR_INVALID_VALUE_SIZE;
    				}
    			} else {
    				status = ATT_ERR_ATTR_NOT_LONG;
    			}
    
    			if (status == SUCCESS) {
    		    memcpy(simpleProfileChar3, pValue, SIMPLEPROFILE_CHAR3_LEN);
    		    notifyApp = SIMPLEPROFILE_CHAR3;
    			}
    
    			break;
    
    			//Write the value
    			/*
    			if (status == SUCCESS) {
    				uint8 *pCurValue = (uint8 *) pAttr->pValue;
    				*pCurValue = pValue[0];
    
    				if (pAttr->pValue == &simpleProfileChar1) {
    					notifyApp = SIMPLEPROFILE_CHAR1;
    				} else {
    					notifyApp = SIMPLEPROFILE_CHAR3;
    				}
    			}
    	*/
    		//	break;
    
    		case GATT_CLIENT_CHAR_CFG_UUID:
    			status = GATTServApp_ProcessCCCWriteReq(connHandle, pAttr, pValue,
    					len, offset, GATT_CLIENT_CFG_NOTIFY);
    			break;
    
    			//shayan work
    		case SIMPLEPROFILE_CHAR6_UUID:
    			//Validate the value
    			// Make sure it's not a blob oper
    			if (offset == 0) {
    				if (len != SIMPLEPROFILE_CHAR6_LEN) {
    					status = ATT_ERR_INVALID_VALUE_SIZE;
    				}
    			} else {
    				status = ATT_ERR_ATTR_NOT_LONG;
    			}
    			if (status == SUCCESS && correctpass) {
    		    memcpy(simpleProfileChar6, pValue, SIMPLEPROFILE_CHAR6_LEN);
    		    notifyApp = SIMPLEPROFILE_CHAR6;
    			}
    			else{HAL_SYSTEM_RESET();}
    			break;
    
    		case SIMPLEPROFILE_CHAR7_UUID:
    			//Validate the value
    			// Make sure it's not a blob oper
    			if (offset == 0) {
    				if (len != SIMPLEPROFILE_CHAR7_LEN) {
    					status = ATT_ERR_INVALID_VALUE_SIZE;
    				}
    			} else {
    				status = ATT_ERR_ATTR_NOT_LONG;
    			}
    			if (status == SUCCESS) {
    		    memcpy(simpleProfileChar7, pValue, SIMPLEPROFILE_CHAR7_LEN);
    		    if(simpleProfileChar7[0]==0x29 && simpleProfileChar7[1]==0x56 && simpleProfileChar7[2]==0x81 && simpleProfileChar7[3]==0x74)
    		    {
    		    	correctpass=TRUE;
    		    }
    		    else
    		    {HAL_SYSTEM_RESET();}
    
    		    notifyApp = SIMPLEPROFILE_CHAR7;
    			}
    			break;
    
    		case SIMPLEPROFILE_CHAR8_UUID:
    			//Validate the value
    			// Make sure it's not a blob oper
    			if (offset == 0) {
    				if (len != SIMPLEPROFILE_CHAR8_LEN) {
    					status = ATT_ERR_INVALID_VALUE_SIZE;
    				}
    			} else {
    				status = ATT_ERR_ATTR_NOT_LONG;
    			}
    			if (status == SUCCESS &&correctpass) {
    		    memcpy(simpleProfileChar8, pValue, SIMPLEPROFILE_CHAR8_LEN);
    		    notifyApp = SIMPLEPROFILE_CHAR8;
    			}
    			else{HAL_SYSTEM_RESET();}
    			break;
    
    		case SIMPLEPROFILE_CHAR9_UUID:
    			//Validate the value
    			// Make sure it's not a blob oper
    			if (offset == 0) {
    				if (len != SIMPLEPROFILE_CHAR9_LEN) {
    					status = ATT_ERR_INVALID_VALUE_SIZE;
    				}
    			} else {
    				status = ATT_ERR_ATTR_NOT_LONG;
    			}
    			if (status == SUCCESS &&correctpass) {
    		    memcpy(simpleProfileChar9, pValue, SIMPLEPROFILE_CHAR9_LEN);
    		    notifyApp = SIMPLEPROFILE_CHAR9;
    			}
    			else{HAL_SYSTEM_RESET();}
    			break;
    
    		//not writeable//case SIMPLEPROFILE_CHAR10_UUID:
    			//shayan work
    
    		default:
    			// Should never get here! (characteristics 2 and 4 do not have write permissions)
    			status = ATT_ERR_ATTR_NOT_FOUND;
    			break;
    		}
    	} else {
    		// 128-bit UUID
    		status = ATT_ERR_INVALID_HANDLE;
    	}
    
    	// If a characteristic value changed then callback function to notify application of change
    	if ((notifyApp != 0xFF) && simpleProfile_AppCBs
    			&& simpleProfile_AppCBs->pfnSimpleProfileChange) {
    		simpleProfile_AppCBs->pfnSimpleProfileChange(notifyApp);
    	}
    
    	return (status);
    }
    
    /*********************************************************************
     *********************************************************************/
    
    simpleGATTprofile.h

  • /**************************************************************************************************
     Filename:       simpleGATTprofile.c
     Revised:        $Date: 2015-07-20 11:31:07 -0700 (Mon, 20 Jul 2015) $
     Revision:       $Revision: 44370 $
    
     Description:    This file contains the Simple GATT profile sample GATT service
     profile for use with the BLE sample application.
    
     Copyright 2010 - 2015 Texas Instruments Incorporated. All rights reserved.
    
     IMPORTANT: Your use of this Software is limited to those specific rights
     granted under the terms of a software license agreement between the user
     who downloaded the software, his/her employer (which must be your employer)
     and Texas Instruments Incorporated (the "License").  You may not use this
     Software unless you agree to abide by the terms of the License. The License
     limits your use, and you acknowledge, that the Software may not be modified,
     copied or distributed unless embedded on a Texas Instruments microcontroller
     or used solely and exclusively in conjunction with a Texas Instruments radio
     frequency transceiver, which is integrated into your product.  Other than for
     the foregoing purpose, you may not use, reproduce, copy, prepare derivative
     works of, modify, distribute, perform, display or sell this Software and/or
     its documentation for any purpose.
    
     YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
     PROVIDED �AS IS� WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
     INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
     NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
     TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
     NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
     LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
     INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
     OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
     OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
     (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
    
     Should you have any questions regarding your right to use this Software,
     contact Texas Instruments Incorporated at www.TI.com.
     **************************************************************************************************/
    
    /*********************************************************************
     * 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 "simpleGATTprofile.h"
    #include "hal_mcu.h"
    
    /*********************************************************************
     * MACROS
     */
    
    /*********************************************************************
     * CONSTANTS
     */
    
    #define SERVAPP_NUM_ATTR_SUPPORTED        33
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    /*********************************************************************
     * GLOBAL VARIABLES (arrays to break uuid into two bytes and swap bytes)
     */
    // Simple GATT Profile Service UUID: 0xFFF0  //now 0x1523
    CONST uint8 simpleProfileServUUID[ATT_UUID_SIZE] = {
    		//LO_UINT16(SIMPLEPROFILE_SERV_UUID), HI_UINT16(SIMPLEPROFILE_SERV_UUID)
    		TI_BASE_UUID_128(SIMPLEPROFILE_SERV_UUID),  //shayan
    };
    
    // Characteristic 1 UUID: 0xFFF1  //now 0x1524
    CONST uint8 simpleProfilechar1UUID[ATT_UUID_SIZE] = {
    		//LO_UINT16(SIMPLEPROFILE_CHAR1_UUID), HI_UINT16(SIMPLEPROFILE_CHAR1_UUID)
    		TI_BASE_UUID_128(SIMPLEPROFILE_CHAR1_UUID), //shayan
    };
    
    // Characteristic 2 UUID: 0xFFF2
    CONST uint8 simpleProfilechar2UUID[ATT_BT_UUID_SIZE] = { LO_UINT16(
    		SIMPLEPROFILE_CHAR2_UUID), HI_UINT16(SIMPLEPROFILE_CHAR2_UUID) };
    
    // Characteristic 3 UUID: 0xFFF3 //now 0x0002
    CONST uint8 simpleProfilechar3UUID[ATT_UUID_SIZE] = {
    		TI_BASE_UUID_128(SIMPLEPROFILE_CHAR3_UUID), //shayan };
    };
    
    // Characteristic 4 UUID: 0xFFF4
    CONST uint8 simpleProfilechar4UUID[ATT_BT_UUID_SIZE] = { LO_UINT16(
    		SIMPLEPROFILE_CHAR4_UUID), HI_UINT16(SIMPLEPROFILE_CHAR4_UUID) };
    
    // Characteristic 5 UUID: 0xFFF5
    CONST uint8 simpleProfilechar5UUID[ATT_BT_UUID_SIZE] = { LO_UINT16(
    		SIMPLEPROFILE_CHAR5_UUID), HI_UINT16(SIMPLEPROFILE_CHAR5_UUID) };
    
    // Characteristic 6 UUID: 0xFFF6 //now 0x1526
    CONST uint8 simpleProfilechar6UUID[ATT_UUID_SIZE] = {
    		//LO_UINT16(SIMPLEPROFILE_CHAR6_UUID), HI_UINT16(SIMPLEPROFILE_CHAR6_UUID)
    		TI_BASE_UUID_128(SIMPLEPROFILE_CHAR6_UUID), //shayan
    };
    
    // Characteristic 7 UUID: 0xFFF7 //now 0x152A
    CONST uint8 simpleProfilechar7UUID[ATT_UUID_SIZE] = {
    		//LO_UINT16(SIMPLEPROFILE_CHAR7_UUID), HI_UINT16(SIMPLEPROFILE_CHAR7_UUID)
    		TI_BASE_UUID_128(SIMPLEPROFILE_CHAR7_UUID), //shayan
    };
    
    // Characteristic 8 UUID: 0xFFF8 // now 0x152C
    CONST uint8 simpleProfilechar8UUID[ATT_UUID_SIZE] = {
    		//LO_UINT16(SIMPLEPROFILE_CHAR8_UUID), HI_UINT16(SIMPLEPROFILE_CHAR8_UUID)
    		TI_BASE_UUID_128(SIMPLEPROFILE_CHAR8_UUID), //shayan
    };
    
    // Characteristic 9 UUID: 0xFFF9 //now 0x152D
    CONST uint8 simpleProfilechar9UUID[ATT_UUID_SIZE] = {
    		//LO_UINT16(SIMPLEPROFILE_CHAR9_UUID), HI_UINT16(SIMPLEPROFILE_CHAR9_UUID)
    		TI_BASE_UUID_128(SIMPLEPROFILE_CHAR9_UUID), //shayan
    
    };
    
    // Characteristic 10 UUID: //now 0x152E
    CONST uint8 simpleProfilechar10UUID[ATT_UUID_SIZE] = {
    		//LO_UINT16(SIMPLEPROFILE_CHAR9_UUID), HI_UINT16(SIMPLEPROFILE_CHAR9_UUID)
    		TI_BASE_UUID_128(SIMPLEPROFILE_CHAR10_UUID), //shayan
    
    };
    
    bool correctpass=FALSE;
    
    /*********************************************************************
     * EXTERNAL VARIABLES
     */
    
    /*********************************************************************
     * EXTERNAL FUNCTIONS
     */
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    
    static simpleProfileCBs_t *simpleProfile_AppCBs = NULL;
    
    /*********************************************************************
     * Profile Attributes - variables
     */
    
    // Simple Profile Service attribute
    static CONST gattAttrType_t simpleProfileService = { ATT_UUID_SIZE,
    		simpleProfileServUUID };
    
    /*
     // Simple Profile Characteristic 1 Properties
     static uint8 simpleProfileChar1Props = GATT_PROP_READ | GATT_PROP_WRITE;
    
     // Characteristic 1 Value
     static uint8 simpleProfileChar1 = 0;
    
     // Simple Profile Characteristic 1 User Description
     static uint8 simpleProfileChar1UserDesp[17] = "my char 1";
     */ //shayan
    // Simple Profile Characteristic 1 Properties
    static uint8 simpleProfileChar1Props = GATT_PROP_READ | GATT_PROP_WRITE;
    
    // Characteristic 1 Value
    static uint8 simpleProfileChar1[SIMPLEPROFILE_CHAR1_LEN] = { 0, 0, 0, 0, 0, 0,
    		0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    
    // Simple Profile Characteristic 1 User Description
    static uint8 simpleProfileChar1UserDesp[17] = "char 1 length 16";
    //shayan
    
    // Simple Profile Characteristic 2 Properties
    static uint8 simpleProfileChar2Props = GATT_PROP_READ;
    
    // Characteristic 2 Value
    static uint8 simpleProfileChar2 = 0;
    
    // Simple Profile Characteristic 2 User Description
    static uint8 simpleProfileChar2UserDesp[17] = "my char 2";
    
    // Simple Profile Characteristic 3 Properties
    static uint8 simpleProfileChar3Props = GATT_PROP_WRITE;
    
    // Characteristic 3 Value
    //static uint8 simpleProfileChar3 = 0;
    static uint8 simpleProfileChar3[SIMPLEPROFILE_CHAR3_LEN] = { 0, 0 };
    
    // Simple Profile Characteristic 3 User Description
    static uint8 simpleProfileChar3UserDesp[17] = "RX";
    
    // Simple Profile Characteristic 4 Properties
    static uint8 simpleProfileChar4Props = GATT_PROP_READ | GATT_PROP_NOTIFY;
    
    // Characteristic 4 Value
    //static uint8 simpleProfileChar4 = 0;
    static uint8 simpleProfileChar4[SIMPLEPROFILE_CHAR4_LEN] = { 0, 0, 0, 0, 0, 0,
    		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    
    // Simple Profile Characteristic 4 Configuration Each client has its own
    // instantiation of the Client Characteristic Configuration. Reads of the
    // Client Characteristic Configuration only shows the configuration for
    // that client and writes only affect the configuration of that client.
    static gattCharCfg_t *simpleProfileChar4Config;
    
    // Simple Profile Characteristic 4 User Description
    static uint8 simpleProfileChar4UserDesp[17] = "TX";
    
    // Simple Profile Characteristic 5 Properties
    static uint8 simpleProfileChar5Props = GATT_PROP_READ;
    
    // Characteristic 5 Value
    static uint8 simpleProfileChar5[SIMPLEPROFILE_CHAR5_LEN] = { 0, 0, 0, 0, 0 };
    
    // Simple Profile Characteristic 5 User Description
    static uint8 simpleProfileChar5UserDesp[17] = "Characteristic 5";
    
    
    //new characterstcs by shayan
    
    // Simple Profile Characteristic 6 Properties
    static uint8 simpleProfileChar6Props = GATT_PROP_READ | GATT_PROP_WRITE;
    
    // Characteristic 6 Value
    static uint8 simpleProfileChar6[SIMPLEPROFILE_CHAR6_LEN] = { 0, 0, 0, 0, 0, 0, 0, 0 };
    
    // Simple Profile Characteristic 6 User Description
    static uint8 simpleProfileChar6UserDesp[17] = "char 6 length 8";
    
    // Simple Profile Characteristic 7 Properties
    static uint8 simpleProfileChar7Props = GATT_PROP_READ | GATT_PROP_WRITE;
    
    // Characteristic 7 Value
    static uint8 simpleProfileChar7[SIMPLEPROFILE_CHAR7_LEN] = { 0, 0, 0, 0 };
    
    // Simple Profile Characteristic 7 User Description
    static uint8 simpleProfileChar7UserDesp[17] = "char 7 length 4";
    
    // Simple Profile Characteristic 8 Properties
    static uint8 simpleProfileChar8Props = GATT_PROP_READ | GATT_PROP_WRITE;
    
    // Characteristic 8 Value
    static uint8 simpleProfileChar8[SIMPLEPROFILE_CHAR8_LEN] = { 0, 0, 0, 0, 0, 0, 0 };
    
    // Simple Profile Characteristic 8 User Description
    static uint8 simpleProfileChar8UserDesp[17] = "char 8 length 7";
    
    // Simple Profile Characteristic 9 Properties
    static uint8 simpleProfileChar9Props = GATT_PROP_READ | GATT_PROP_WRITE;
    
    // Characteristic 9 Value
    static uint8 simpleProfileChar9[SIMPLEPROFILE_CHAR9_LEN] = { 0, 0 };
    
    // Simple Profile Characteristic 9 User Description
    static uint8 simpleProfileChar9UserDesp[17] = "char 9 length 2";
    
    // Simple Profile Characteristic 10 Properties
    static uint8 simpleProfileChar10Props = GATT_PROP_READ |GATT_PROP_NOTIFY;
    
    // Characteristic 10 Value
    static uint8 simpleProfileChar10[SIMPLEPROFILE_CHAR10_LEN] = { 0, 0, 0, 0, 0, 0,
    		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    
    static gattCharCfg_t *simpleProfileChar10Config;
    // Simple Profile Characteristic 10 User Description
    static uint8 simpleProfileChar10UserDesp[17] = "TX";
    
    bStatus_t status;
    //new characterstics by shayan
    
    /*********************************************************************
     * Profile Attributes - Table
     */
    
    static gattAttribute_t simpleProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] = {
    // Simple Profile Service
    		{ { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
    		GATT_PERMIT_READ, /* permissions */
    		0, /* handle */
    		(uint8 *) &simpleProfileService /* pValue */
    		},
    
    		// Characteristic 1 Declaration
    		{ { ATT_BT_UUID_SIZE, characterUUID },
    		GATT_PERMIT_READ, 0, &simpleProfileChar1Props },
    
    		// Characteristic Value 1
    		{ { ATT_UUID_SIZE, simpleProfilechar1UUID },
    		GATT_PERMIT_READ | GATT_PERMIT_WRITE, 0, simpleProfileChar1 },
    
    		// Characteristic 1 User Description
    		{ { ATT_BT_UUID_SIZE, charUserDescUUID },
    		GATT_PERMIT_READ, 0, simpleProfileChar1UserDesp },
    
    		// Characteristic 2 Declaration
    		{ { ATT_BT_UUID_SIZE, characterUUID },
    		GATT_PERMIT_READ, 0, &simpleProfileChar2Props },
    
    		// Characteristic Value 2
    		{ { ATT_BT_UUID_SIZE, simpleProfilechar2UUID },
    		GATT_PERMIT_READ, 0, &simpleProfileChar2 },
    
    		// Characteristic 2 User Description
    		{ { ATT_BT_UUID_SIZE, charUserDescUUID },
    		GATT_PERMIT_READ, 0, simpleProfileChar2UserDesp },
    
    		// Characteristic 3 Declaration
    		{ { ATT_BT_UUID_SIZE, characterUUID },
    		GATT_PERMIT_READ, 0, &simpleProfileChar3Props },
    
    		// Characteristic Value 3
    		{ { ATT_UUID_SIZE, simpleProfilechar3UUID },
    		GATT_PERMIT_WRITE, 0, simpleProfileChar3 },
    
    		// Characteristic 3 User Description
    		{ { ATT_BT_UUID_SIZE, charUserDescUUID },
    		GATT_PERMIT_READ, 0, simpleProfileChar3UserDesp },
    
    		// Characteristic 4 Declaration
    		{ { ATT_BT_UUID_SIZE, characterUUID },
    		GATT_PERMIT_READ, 0, &simpleProfileChar4Props },
    
    		// Characteristic Value 4
    		{ { ATT_BT_UUID_SIZE, simpleProfilechar4UUID },
    		GATT_PERMIT_READ, 0,simpleProfileChar4 },
    
    		// Characteristic 4 configuration
    		{ { ATT_BT_UUID_SIZE, clientCharCfgUUID },
    		GATT_PERMIT_READ | GATT_PERMIT_WRITE, 0,
    				(uint8 *) &simpleProfileChar4Config },
    
    		// Characteristic 4 User Description
    		{ { ATT_BT_UUID_SIZE, charUserDescUUID },
    		GATT_PERMIT_READ, 0, simpleProfileChar4UserDesp },
    
    		// Characteristic 5 Declaration
    		{ { ATT_BT_UUID_SIZE, characterUUID },
    		GATT_PERMIT_READ, 0, &simpleProfileChar5Props },
    
    		// Characteristic Value 5
    		{ { ATT_BT_UUID_SIZE, simpleProfilechar5UUID },
    		GATT_PERMIT_AUTHEN_READ, 0, simpleProfileChar5 },
    
    		// Characteristic 5 User Description
    		{ { ATT_BT_UUID_SIZE, charUserDescUUID },
    		GATT_PERMIT_READ, 0, simpleProfileChar5UserDesp },
    
    		//shayan work
    		// Characteristic 6 Declaration
    				{ { ATT_BT_UUID_SIZE, characterUUID },
    				GATT_PERMIT_READ, 0, &simpleProfileChar6Props },
    
    				// Characteristic Value 6
    				{ { ATT_UUID_SIZE, simpleProfilechar6UUID },
    				GATT_PERMIT_READ | GATT_PERMIT_WRITE, 0, simpleProfileChar6 },
    
    				// Characteristic 6 User Description
    				{ { ATT_BT_UUID_SIZE, charUserDescUUID },
    				GATT_PERMIT_READ, 0, simpleProfileChar6UserDesp },
    
    				// Characteristic 7 Declaration
    						{ { ATT_BT_UUID_SIZE, characterUUID },
    						GATT_PERMIT_READ, 0, &simpleProfileChar7Props },
    
    						// Characteristic Value 7
    						{ { ATT_UUID_SIZE, simpleProfilechar7UUID },
    						GATT_PERMIT_READ | GATT_PERMIT_WRITE, 0, simpleProfileChar7 },
    
    						// Characteristic 7 User Description
    						{ { ATT_BT_UUID_SIZE, charUserDescUUID },
    						GATT_PERMIT_READ, 0, simpleProfileChar7UserDesp },
    
    						// Characteristic 8 Declaration
    								{ { ATT_BT_UUID_SIZE, characterUUID },
    								GATT_PERMIT_READ, 0, &simpleProfileChar8Props },
    
    								// Characteristic Value 8
    								{ { ATT_UUID_SIZE, simpleProfilechar8UUID },
    								GATT_PERMIT_READ | GATT_PERMIT_WRITE, 0, simpleProfileChar8 },
    
    								// Characteristic 8 User Description
    								{ { ATT_BT_UUID_SIZE, charUserDescUUID },
    								GATT_PERMIT_READ, 0, simpleProfileChar8UserDesp },
    
    								// Characteristic 9 Declaration
    										{ { ATT_BT_UUID_SIZE, characterUUID },
    										GATT_PERMIT_READ, 0, &simpleProfileChar9Props },
    
    										// Characteristic Value 9
    										{ { ATT_UUID_SIZE, simpleProfilechar9UUID },
    										GATT_PERMIT_READ | GATT_PERMIT_WRITE, 0, simpleProfileChar9 },
    
    										// Characteristic 9 User Description
    										{ { ATT_BT_UUID_SIZE, charUserDescUUID },
    										GATT_PERMIT_READ, 0, simpleProfileChar9UserDesp },
    
    										// Characteristic 10 Declaration
    										{ { ATT_BT_UUID_SIZE, characterUUID },
    										GATT_PERMIT_READ, 0, &simpleProfileChar10Props },
    
    										// Characteristic Value 10
    										{ { ATT_UUID_SIZE, simpleProfilechar10UUID },
    										GATT_PERMIT_READ, 0, simpleProfileChar10 },
    
    										// Characteristic 10 configuration
    										{ { ATT_BT_UUID_SIZE, clientCharCfgUUID },
    										GATT_PERMIT_READ | GATT_PERMIT_WRITE, 0,
    												(uint8 *) &simpleProfileChar10Config },
    
    										// Characteristic 10 User Description
    										{ { ATT_BT_UUID_SIZE, charUserDescUUID },
    										GATT_PERMIT_READ, 0, simpleProfileChar10UserDesp },};
    		//shayan work
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    static bStatus_t simpleProfile_ReadAttrCB(uint16_t connHandle,
    		gattAttribute_t *pAttr, uint8_t *pValue, uint16_t *pLen,
    		uint16_t offset, uint16_t maxLen, uint8_t method);
    static bStatus_t simpleProfile_WriteAttrCB(uint16_t connHandle,
    		gattAttribute_t *pAttr, uint8_t *pValue, uint16_t len, uint16_t offset,
    		uint8_t method);
    
    /*********************************************************************
     * PROFILE CALLBACKS
     */
    // Simple Profile Service Callbacks
    CONST gattServiceCBs_t simpleProfileCBs = { simpleProfile_ReadAttrCB, // Read callback function pointer
    		simpleProfile_WriteAttrCB, // Write callback function pointer
    		NULL                       // Authorization callback function pointer
    		};
    
    /*********************************************************************
     * PUBLIC FUNCTIONS
     */
    
    /*********************************************************************
     * @fn      SimpleProfile_AddService
     *
     * @brief   Initializes the Simple Profile service by registering
     *          GATT attributes with the GATT server.
     *
     * @param   services - services to add. This is a bit map and can
     *                     contain more than one service.
     *
     * @return  Success or Failure
     */
    bStatus_t SimpleProfile_AddService(uint32 services) {
    	uint8 status;
    
    	// Allocate Client Characteristic Configuration table
    	simpleProfileChar4Config = (gattCharCfg_t *) ICall_malloc(
    			sizeof(gattCharCfg_t) * linkDBNumConns);
    	if (simpleProfileChar4Config == NULL) {
    		return ( bleMemAllocError);
    	}
    	//shayan
    	// Allocate Client Characteristic Configuration table
    	simpleProfileChar10Config = (gattCharCfg_t *) ICall_malloc(
    			sizeof(gattCharCfg_t) * linkDBNumConns);
    	if (simpleProfileChar10Config == NULL) {
    		return ( bleMemAllocError);
    	}
    
    
    	// Initialize Client Characteristic Configuration attributes
    	GATTServApp_InitCharCfg( INVALID_CONNHANDLE, simpleProfileChar4Config);
    
    	GATTServApp_InitCharCfg( INVALID_CONNHANDLE, simpleProfileChar10Config); //shayan
    
    	if (services & SIMPLEPROFILE_SERVICE) {
    		// Register GATT attribute list and CBs with GATT Server App
    		status = GATTServApp_RegisterService(simpleProfileAttrTbl,
    				GATT_NUM_ATTRS(simpleProfileAttrTbl),
    				GATT_MAX_ENCRYPT_KEY_SIZE, &simpleProfileCBs);
    	} else {
    		status = SUCCESS;
    	}
    
    	return (status);
    }
    
    /*********************************************************************
     * @fn      SimpleProfile_RegisterAppCBs
     *
     * @brief   Registers the application callback function. Only call 
     *          this function once.
     *
     * @param   callbacks - pointer to application callbacks.
     *
     * @return  SUCCESS or bleAlreadyInRequestedMode
     */
    bStatus_t SimpleProfile_RegisterAppCBs(simpleProfileCBs_t *appCallbacks) {
    	if (appCallbacks) {
    		simpleProfile_AppCBs = appCallbacks;
    
    		return ( SUCCESS);
    	} else {
    		return ( bleAlreadyInRequestedMode);
    	}
    }
    
    /*********************************************************************
     * @fn      SimpleProfile_SetParameter
     *
     * @brief   Set a Simple Profile parameter.
     *
     * @param   param - Profile parameter ID
     * @param   len - length of data to write
     * @param   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).
     *
     * @return  bStatus_t
     */
    bStatus_t SimpleProfile_SetParameter(uint8 param, uint8 len, void *value) {
    	bStatus_t ret = SUCCESS;
    	switch (param) {
    	case SIMPLEPROFILE_CHAR1:
    
    		if (len == SIMPLEPROFILE_CHAR1_LEN) {
    			VOID memcpy(simpleProfileChar1, value, SIMPLEPROFILE_CHAR1_LEN);
    		} else {
    			ret = bleInvalidRange;
    		}
    
    		break;
    
    	case SIMPLEPROFILE_CHAR2:
    		if (len == sizeof(uint8)) {
    			simpleProfileChar2 = *((uint8*) value);
    		} else {
    			ret = bleInvalidRange;
    		}
    		break;
    
    	case SIMPLEPROFILE_CHAR3:
    		if (len == SIMPLEPROFILE_CHAR3_LEN) {
    			//simpleProfileChar3 = *((uint8*) value);
    			VOID memcpy(simpleProfileChar3, value, SIMPLEPROFILE_CHAR3_LEN);
    		} else {
    			ret = bleInvalidRange;
    		}
    		break;
    
    	case SIMPLEPROFILE_CHAR4:
    		if (len == SIMPLEPROFILE_CHAR4_LEN) {
    			//simpleProfileChar4 = *((uint8*) value);
    			VOID memcpy(simpleProfileChar4, value, SIMPLEPROFILE_CHAR4_LEN);
    			// See if Notification has been enabled
    			//GATTServApp_ProcessCharCfg(simpleProfileChar4Config,
    				//	&simpleProfileChar4, FALSE, simpleProfileAttrTbl,
    				//	GATT_NUM_ATTRS(simpleProfileAttrTbl),
    				//	INVALID_TASK_ID, simpleProfile_ReadAttrCB);
    			 status = GATTServApp_ProcessCharCfg(simpleProfileChar4Config,simpleProfileChar4, FALSE, simpleProfileAttrTbl,GATT_NUM_ATTRS(simpleProfileAttrTbl),INVALID_TASK_ID, simpleProfile_ReadAttrCB);
    
    		} else {
    			ret = bleInvalidRange;
    		}
    		break;
    
    	case SIMPLEPROFILE_CHAR5:
    		if (len == SIMPLEPROFILE_CHAR5_LEN) {
    			VOID memcpy(simpleProfileChar5, value, SIMPLEPROFILE_CHAR5_LEN);
    		} else {
    			ret = bleInvalidRange;
    		}
    		break;
    		//shayan work
    	case SIMPLEPROFILE_CHAR6:
    		if (len == SIMPLEPROFILE_CHAR6_LEN) {
    				VOID memcpy(simpleProfileChar6, value, SIMPLEPROFILE_CHAR6_LEN);
    			} else {
    				ret = bleInvalidRange;
    			}
    		break;
    
    	case SIMPLEPROFILE_CHAR7:
    		if (len == SIMPLEPROFILE_CHAR7_LEN) {
    				VOID memcpy(simpleProfileChar7, value, SIMPLEPROFILE_CHAR7_LEN);
    			} else {
    				ret = bleInvalidRange;
    			}
    		break;
    
    	case SIMPLEPROFILE_CHAR8:
    		if (len == SIMPLEPROFILE_CHAR8_LEN) {
    				VOID memcpy(simpleProfileChar8, value, SIMPLEPROFILE_CHAR8_LEN);
    			} else {
    				ret = bleInvalidRange;
    			}
    		break;
    
    	case SIMPLEPROFILE_CHAR9:
    		if (len == SIMPLEPROFILE_CHAR9_LEN) {
    				VOID memcpy(simpleProfileChar9, value, SIMPLEPROFILE_CHAR9_LEN);
    			} else {
    				ret = bleInvalidRange;
    			}
    		break;
    
    	case SIMPLEPROFILE_CHAR10:
    			if (len == SIMPLEPROFILE_CHAR10_LEN) {
    					VOID memcpy(simpleProfileChar10, value, SIMPLEPROFILE_CHAR10_LEN);
    
    					GATTServApp_ProcessCharCfg(simpleProfileChar10Config,simpleProfileChar10, FALSE, simpleProfileAttrTbl,GATT_NUM_ATTRS(simpleProfileAttrTbl),INVALID_TASK_ID, simpleProfile_ReadAttrCB);
    
    				} else {
    					ret = bleInvalidRange;
    				}
    			break;
    		//shayan work
    
    	default:
    		ret = INVALIDPARAMETER;
    		break;
    	}
    
    	return (ret);
    }
    
    /*********************************************************************
     * @fn      SimpleProfile_GetParameter
     *
     * @brief   Get a Simple Profile parameter.
     *
     * @param   param - Profile parameter ID
     * @param   value - pointer to data to put.  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).
     *
     * @return  bStatus_t
     */
    bStatus_t SimpleProfile_GetParameter(uint8 param, void *value) {
    	bStatus_t ret = SUCCESS;
    	switch (param) {
    	case SIMPLEPROFILE_CHAR1:
    		// *((uint8*)value) = simpleProfileChar1;
    		VOID memcpy(value, simpleProfileChar1, SIMPLEPROFILE_CHAR1_LEN);
    		break;
    
    	case SIMPLEPROFILE_CHAR2:
    		*((uint8*) value) = simpleProfileChar2;
    		break;
    
    	case SIMPLEPROFILE_CHAR3:
    		//*((uint8*) value) = simpleProfileChar3;
    		VOID memcpy(value, simpleProfileChar3, SIMPLEPROFILE_CHAR3_LEN);
    		break;
    
    	case SIMPLEPROFILE_CHAR4:
    		//*((uint8*) value) = simpleProfileChar4;
    		VOID memcpy(value, simpleProfileChar4, SIMPLEPROFILE_CHAR4_LEN);
    		break;
    
    	case SIMPLEPROFILE_CHAR5:
    		VOID memcpy(value, simpleProfileChar5, SIMPLEPROFILE_CHAR5_LEN);
    		break;
    
    		//shayan work
    	case SIMPLEPROFILE_CHAR6:
    		VOID memcpy(value, simpleProfileChar6, SIMPLEPROFILE_CHAR6_LEN);
    		break;
    
    	case SIMPLEPROFILE_CHAR7:
    		VOID memcpy(value, simpleProfileChar7, SIMPLEPROFILE_CHAR7_LEN);
    		break;
    
    	case SIMPLEPROFILE_CHAR8:
    		VOID memcpy(value, simpleProfileChar8, SIMPLEPROFILE_CHAR8_LEN);
    		break;
    
    	case SIMPLEPROFILE_CHAR9:
    		VOID memcpy(value, simpleProfileChar9, SIMPLEPROFILE_CHAR9_LEN);
    		break;
    
    	case SIMPLEPROFILE_CHAR10:
    			VOID memcpy(value, simpleProfileChar10, SIMPLEPROFILE_CHAR10_LEN);
    			break;
    		//shayan work
    
    	default:
    		ret = INVALIDPARAMETER;
    		break;
    	}
    
    	return (ret);
    }
    
    /*********************************************************************
     * @fn          simpleProfile_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 simpleProfile_ReadAttrCB(uint16_t connHandle,
    		gattAttribute_t *pAttr, uint8_t *pValue, uint16_t *pLen,
    		uint16_t offset, uint16_t maxLen, uint8_t method) {
    	bStatus_t status = SUCCESS;
    
    	// If attribute permissions require authorization to read, return error
    	if (gattPermitAuthorRead(pAttr->permissions)) {
    		// Insufficient authorization
    		return ( ATT_ERR_INSUFFICIENT_AUTHOR);
    	}
    
    	// Make sure it's not a blob operation (no attributes in the profile are long)
    	if (offset > 0) {
    		return ( ATT_ERR_ATTR_NOT_LONG);
    	}
    
    	if (pAttr->type.len == ATT_BT_UUID_SIZE || pAttr->type.len == ATT_UUID_SIZE) {
    		// 16-bit UUID
    		//uint16 uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
    		uint16 uuid;
    		if (pAttr->type.len == ATT_BT_UUID_SIZE )
    		  {
    		    // 16-bit UUID direct
    			 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
    		  }
    		  else if (pAttr->type.len == ATT_UUID_SIZE)
    		  {
    		    // 16-bit UUID extracted bytes 12 and 13
    			  uuid = BUILD_UINT16( pAttr->type.uuid[12], pAttr->type.uuid[13]);
    		  }
    
    
    		 switch (uuid) {
    		// No need for "GATT_SERVICE_UUID" or "GATT_CLIENT_CHAR_CFG_UUID" cases;
    		// gattserverapp handles those reads
    		// characteristics 1 and 2 have read permissions
    		// characteritisc 3 does not have read permissions; therefore it is not
    		//   included here
    		// characteristic 4 does not have read permissions, but because it
    		//   can be sent as a notification, it is included here
    		case SIMPLEPROFILE_CHAR1_UUID:
    			*pLen = SIMPLEPROFILE_CHAR1_LEN;
    			VOID memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR1_LEN);
    			break;
    		case SIMPLEPROFILE_CHAR2_UUID:
    
    			*pLen = 1;
    			pValue[0] = *pAttr->pValue;
    			break;
    
    		case SIMPLEPROFILE_CHAR4_UUID:
    			*pLen = SIMPLEPROFILE_CHAR4_LEN;
    			VOID memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR4_LEN);
    
    		case SIMPLEPROFILE_CHAR5_UUID:
    			*pLen = SIMPLEPROFILE_CHAR5_LEN;
    			VOID memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR5_LEN);
    			break;
    
    			//shayan work
    		case SIMPLEPROFILE_CHAR6_UUID:
    			*pLen = SIMPLEPROFILE_CHAR6_LEN;
    			VOID memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR6_LEN);
    			break;
    
    		case SIMPLEPROFILE_CHAR7_UUID:
    			*pLen = SIMPLEPROFILE_CHAR7_LEN;
    			VOID memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR7_LEN);
    			break;
    
    		case SIMPLEPROFILE_CHAR8_UUID:
    			*pLen = SIMPLEPROFILE_CHAR8_LEN;
    			VOID memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR8_LEN);
    			break;
    
    		case SIMPLEPROFILE_CHAR9_UUID:
    			*pLen = SIMPLEPROFILE_CHAR9_LEN;
    			VOID memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR9_LEN);
    			break;
    
    		case SIMPLEPROFILE_CHAR10_UUID:
    			*pLen = SIMPLEPROFILE_CHAR10_LEN;
    			VOID memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR10_LEN);
    			break;
    			//shayan work
    
    		default:
    			// Should never get here! (characteristics 3 and 4 do not have read permissions)
    			*pLen = 0;
    			status = ATT_ERR_ATTR_NOT_FOUND;
    			break;
    		}
    	} else {
    		// 128-bit UUID
    		*pLen = 0;
    		status = ATT_ERR_INVALID_HANDLE;
    	}
    
    	return (status);
    }
    
    /*********************************************************************
     * @fn      simpleProfile_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 simpleProfile_WriteAttrCB(uint16_t connHandle,
    		gattAttribute_t *pAttr, uint8_t *pValue, uint16_t len, uint16_t offset,
    		uint8_t method) {
    	bStatus_t status = SUCCESS;
    	uint8 notifyApp = 0xFF;
    
    	// If attribute permissions require authorization to write, return error
    	if (gattPermitAuthorWrite(pAttr->permissions)) {
    		// Insufficient authorization
    		return ( ATT_ERR_INSUFFICIENT_AUTHOR);
    	}
    
    	if (pAttr->type.len == ATT_BT_UUID_SIZE || pAttr->type.len == ATT_UUID_SIZE) {
    		// 16-bit UUID
    		//uint16 uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
    		uint16 uuid;
    		if (pAttr->type.len == ATT_BT_UUID_SIZE )
    		  {
    		    // 16-bit UUID direct
    			 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
    		  }
    		  else if (pAttr->type.len == ATT_UUID_SIZE)
    		  {
    		    // 16-bit UUID extracted bytes 12 and 13
    			  uuid = BUILD_UINT16( pAttr->type.uuid[12], pAttr->type.uuid[13]);
    		  }
    
    		switch (uuid) {
    
    		case SIMPLEPROFILE_CHAR1_UUID:
    			//shayan
    			//Validate the value
    			// Make sure it's not a blob oper
    			if (offset == 0) {
    				if (len != SIMPLEPROFILE_CHAR1_LEN) {
    					status = ATT_ERR_INVALID_VALUE_SIZE;
    				}
    			} else {
    				status = ATT_ERR_ATTR_NOT_LONG;
    			}
    			if (status == SUCCESS && correctpass) {
    		    memcpy(simpleProfileChar1, pValue, SIMPLEPROFILE_CHAR1_LEN);
    		    notifyApp = SIMPLEPROFILE_CHAR1;
    			}
    			else{HAL_SYSTEM_RESET();}
    			break;
    			//shayan
    
    		case SIMPLEPROFILE_CHAR3_UUID:
    
    			//Validate the value
    			// Make sure it's not a blob oper
    			if (offset == 0) {
    				if (len != SIMPLEPROFILE_CHAR3_LEN) {
    					status = ATT_ERR_INVALID_VALUE_SIZE;
    				}
    			} else {
    				status = ATT_ERR_ATTR_NOT_LONG;
    			}
    
    			if (status == SUCCESS) {
    		    memcpy(simpleProfileChar3, pValue, SIMPLEPROFILE_CHAR3_LEN);
    		    notifyApp = SIMPLEPROFILE_CHAR3;
    			}
    
    			break;
    
    			//Write the value
    			/*
    			if (status == SUCCESS) {
    				uint8 *pCurValue = (uint8 *) pAttr->pValue;
    				*pCurValue = pValue[0];
    
    				if (pAttr->pValue == &simpleProfileChar1) {
    					notifyApp = SIMPLEPROFILE_CHAR1;
    				} else {
    					notifyApp = SIMPLEPROFILE_CHAR3;
    				}
    			}
    	*/
    		//	break;
    
    		case GATT_CLIENT_CHAR_CFG_UUID:
    			status = GATTServApp_ProcessCCCWriteReq(connHandle, pAttr, pValue,
    					len, offset, GATT_CLIENT_CFG_NOTIFY);
    			break;
    
    			//shayan work
    		case SIMPLEPROFILE_CHAR6_UUID:
    			//Validate the value
    			// Make sure it's not a blob oper
    			if (offset == 0) {
    				if (len != SIMPLEPROFILE_CHAR6_LEN) {
    					status = ATT_ERR_INVALID_VALUE_SIZE;
    				}
    			} else {
    				status = ATT_ERR_ATTR_NOT_LONG;
    			}
    			if (status == SUCCESS && correctpass) {
    		    memcpy(simpleProfileChar6, pValue, SIMPLEPROFILE_CHAR6_LEN);
    		    notifyApp = SIMPLEPROFILE_CHAR6;
    			}
    			else{HAL_SYSTEM_RESET();}
    			break;
    
    		case SIMPLEPROFILE_CHAR7_UUID:
    			//Validate the value
    			// Make sure it's not a blob oper
    			if (offset == 0) {
    				if (len != SIMPLEPROFILE_CHAR7_LEN) {
    					status = ATT_ERR_INVALID_VALUE_SIZE;
    				}
    			} else {
    				status = ATT_ERR_ATTR_NOT_LONG;
    			}
    			if (status == SUCCESS) {
    		    memcpy(simpleProfileChar7, pValue, SIMPLEPROFILE_CHAR7_LEN);
    		    if(simpleProfileChar7[0]==0x29 && simpleProfileChar7[1]==0x56 && simpleProfileChar7[2]==0x81 && simpleProfileChar7[3]==0x74)
    		    {
    		    	correctpass=TRUE;
    		    }
    		    else
    		    {HAL_SYSTEM_RESET();}
    
    		    notifyApp = SIMPLEPROFILE_CHAR7;
    			}
    			break;
    
    		case SIMPLEPROFILE_CHAR8_UUID:
    			//Validate the value
    			// Make sure it's not a blob oper
    			if (offset == 0) {
    				if (len != SIMPLEPROFILE_CHAR8_LEN) {
    					status = ATT_ERR_INVALID_VALUE_SIZE;
    				}
    			} else {
    				status = ATT_ERR_ATTR_NOT_LONG;
    			}
    			if (status == SUCCESS &&correctpass) {
    		    memcpy(simpleProfileChar8, pValue, SIMPLEPROFILE_CHAR8_LEN);
    		    notifyApp = SIMPLEPROFILE_CHAR8;
    			}
    			else{HAL_SYSTEM_RESET();}
    			break;
    
    		case SIMPLEPROFILE_CHAR9_UUID:
    			//Validate the value
    			// Make sure it's not a blob oper
    			if (offset == 0) {
    				if (len != SIMPLEPROFILE_CHAR9_LEN) {
    					status = ATT_ERR_INVALID_VALUE_SIZE;
    				}
    			} else {
    				status = ATT_ERR_ATTR_NOT_LONG;
    			}
    			if (status == SUCCESS &&correctpass) {
    		    memcpy(simpleProfileChar9, pValue, SIMPLEPROFILE_CHAR9_LEN);
    		    notifyApp = SIMPLEPROFILE_CHAR9;
    			}
    			else{HAL_SYSTEM_RESET();}
    			break;
    
    		//not writeable//case SIMPLEPROFILE_CHAR10_UUID:
    			//shayan work
    
    		default:
    			// Should never get here! (characteristics 2 and 4 do not have write permissions)
    			status = ATT_ERR_ATTR_NOT_FOUND;
    			break;
    		}
    	} else {
    		// 128-bit UUID
    		status = ATT_ERR_INVALID_HANDLE;
    	}
    
    	// If a characteristic value changed then callback function to notify application of change
    	if ((notifyApp != 0xFF) && simpleProfile_AppCBs
    			&& simpleProfile_AppCBs->pfnSimpleProfileChange) {
    		simpleProfile_AppCBs->pfnSimpleProfileChange(notifyApp);
    	}
    
    	return (status);
    }
    
    /*********************************************************************
     *********************************************************************/
    

  • Hi there,

    I have almost the same problem as mohammad,

    I'm able to transfer up to 90 bytes in a single characteristics, but following examples I'm trying to convert this characteristic into notifiable one but characteristic is not notifying. I'm using a custom android app (api 23 with requestMTU handling). So if I read characteristic I can read entire 90 bytes, but I'm not get notifications from this characteristics. Apparently, when my characteristics are single byte or upto 13 bytes(the maximum tested before 90 bytes) it notify as required, but no longer works with 90 bytes characteristics. Can you provide me any hint to debug or solve this issue???? Thank you. 

  • Hi Mohammad,

    In my test, Simple_peripheral can notify 20 bytes to BTools

    /******************************************************************************
    
     @file  simple_gatt_profile.c
    
     @brief This file contains the Simple GATT profile sample GATT service profile
            for use with the BLE sample application.
    
     Group: WCS, BTS
     Target Device: CC2650, CC2640, CC1350
    
     ******************************************************************************
     
     Copyright (c) 2010-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.
    
     ******************************************************************************
     Release Name: ble_sdk_2_02_00_31
     Release Date: 2016-06-16 18:57:29
     *****************************************************************************/
    
    /*********************************************************************
     * 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 "simple_gatt_profile.h"
    
    /*********************************************************************
     * MACROS
     */
    
    /*********************************************************************
     * CONSTANTS
     */
    
    #define SERVAPP_NUM_ATTR_SUPPORTED        17
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    /*********************************************************************
     * GLOBAL VARIABLES
     */
    // Simple GATT Profile Service UUID: 0xFFF0
    CONST uint8 simpleProfileServUUID[ATT_BT_UUID_SIZE] =
    { 
      LO_UINT16(SIMPLEPROFILE_SERV_UUID), HI_UINT16(SIMPLEPROFILE_SERV_UUID)
    };
    
    // Characteristic 1 UUID: 0xFFF1
    CONST uint8 simpleProfilechar1UUID[ATT_BT_UUID_SIZE] =
    { 
      LO_UINT16(SIMPLEPROFILE_CHAR1_UUID), HI_UINT16(SIMPLEPROFILE_CHAR1_UUID)
    };
    
    // Characteristic 2 UUID: 0xFFF2
    CONST uint8 simpleProfilechar2UUID[ATT_BT_UUID_SIZE] =
    { 
      LO_UINT16(SIMPLEPROFILE_CHAR2_UUID), HI_UINT16(SIMPLEPROFILE_CHAR2_UUID)
    };
    
    // Characteristic 3 UUID: 0xFFF3
    CONST uint8 simpleProfilechar3UUID[ATT_BT_UUID_SIZE] =
    { 
      LO_UINT16(SIMPLEPROFILE_CHAR3_UUID), HI_UINT16(SIMPLEPROFILE_CHAR3_UUID)
    };
    
    // Characteristic 4 UUID: 0xFFF4
    CONST uint8 simpleProfilechar4UUID[ATT_BT_UUID_SIZE] =
    { 
      LO_UINT16(SIMPLEPROFILE_CHAR4_UUID), HI_UINT16(SIMPLEPROFILE_CHAR4_UUID)
    };
    
    // Characteristic 5 UUID: 0xFFF5
    CONST uint8 simpleProfilechar5UUID[ATT_BT_UUID_SIZE] =
    { 
      LO_UINT16(SIMPLEPROFILE_CHAR5_UUID), HI_UINT16(SIMPLEPROFILE_CHAR5_UUID)
    };
    
    /*********************************************************************
     * EXTERNAL VARIABLES
     */
    
    /*********************************************************************
     * EXTERNAL FUNCTIONS
     */
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    
    static simpleProfileCBs_t *simpleProfile_AppCBs = NULL;
    
    /*********************************************************************
     * Profile Attributes - variables
     */
    
    // Simple Profile Service attribute
    static CONST gattAttrType_t simpleProfileService = { ATT_BT_UUID_SIZE, simpleProfileServUUID };
    
    
    // Simple Profile Characteristic 1 Properties
    static uint8 simpleProfileChar1Props = GATT_PROP_READ | GATT_PROP_WRITE;
    
    // Characteristic 1 Value
    static uint8 simpleProfileChar1 = 0;
    
    // Simple Profile Characteristic 1 User Description
    static uint8 simpleProfileChar1UserDesp[17] = "Characteristic 1";
    
    
    // Simple Profile Characteristic 2 Properties
    static uint8 simpleProfileChar2Props = GATT_PROP_READ;
    
    // Characteristic 2 Value
    static uint8 simpleProfileChar2 = 0;
    
    // Simple Profile Characteristic 2 User Description
    static uint8 simpleProfileChar2UserDesp[17] = "Characteristic 2";
    
    
    // Simple Profile Characteristic 3 Properties
    static uint8 simpleProfileChar3Props = GATT_PROP_WRITE;
    
    // Characteristic 3 Value
    static uint8 simpleProfileChar3 = 0;
    
    // Simple Profile Characteristic 3 User Description
    static uint8 simpleProfileChar3UserDesp[17] = "Characteristic 3";
    
    
    // Simple Profile Characteristic 4 Properties
    static uint8 simpleProfileChar4Props = GATT_PROP_NOTIFY;
    
    // Characteristic 4 Value
    static uint8 simpleProfileChar4[SIMPLEPROFILE_CHAR4_LEN] = {0};
    
    // Simple Profile Characteristic 4 Configuration Each client has its own
    // instantiation of the Client Characteristic Configuration. Reads of the
    // Client Characteristic Configuration only shows the configuration for
    // that client and writes only affect the configuration of that client.
    static gattCharCfg_t *simpleProfileChar4Config;
                                            
    // Simple Profile Characteristic 4 User Description
    static uint8 simpleProfileChar4UserDesp[17] = "Characteristic 4";
    
    
    // Simple Profile Characteristic 5 Properties
    static uint8 simpleProfileChar5Props = GATT_PROP_READ;
    
    // Characteristic 5 Value
    static uint8 simpleProfileChar5[SIMPLEPROFILE_CHAR5_LEN] = { 0, 0, 0, 0, 0 };
    
    // Simple Profile Characteristic 5 User Description
    static uint8 simpleProfileChar5UserDesp[17] = "Characteristic 5";
    
    /*********************************************************************
     * Profile Attributes - Table
     */
    
    static gattAttribute_t simpleProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] = 
    {
      // Simple Profile Service
      { 
        { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
        GATT_PERMIT_READ,                         /* permissions */
        0,                                        /* handle */
        (uint8 *)&simpleProfileService            /* pValue */
      },
    
        // Characteristic 1 Declaration
        { 
          { ATT_BT_UUID_SIZE, characterUUID },
          GATT_PERMIT_READ, 
          0,
          &simpleProfileChar1Props 
        },
    
          // Characteristic Value 1
          { 
            { ATT_BT_UUID_SIZE, simpleProfilechar1UUID },
            GATT_PERMIT_READ | GATT_PERMIT_WRITE, 
            0, 
            &simpleProfileChar1 
          },
    
          // Characteristic 1 User Description
          { 
            { ATT_BT_UUID_SIZE, charUserDescUUID },
            GATT_PERMIT_READ, 
            0, 
            simpleProfileChar1UserDesp 
          },      
    
        // Characteristic 2 Declaration
        { 
          { ATT_BT_UUID_SIZE, characterUUID },
          GATT_PERMIT_READ, 
          0,
          &simpleProfileChar2Props 
        },
    
          // Characteristic Value 2
          { 
            { ATT_BT_UUID_SIZE, simpleProfilechar2UUID },
            GATT_PERMIT_READ, 
            0, 
            &simpleProfileChar2 
          },
    
          // Characteristic 2 User Description
          { 
            { ATT_BT_UUID_SIZE, charUserDescUUID },
            GATT_PERMIT_READ, 
            0, 
            simpleProfileChar2UserDesp 
          },           
          
        // Characteristic 3 Declaration
        { 
          { ATT_BT_UUID_SIZE, characterUUID },
          GATT_PERMIT_READ, 
          0,
          &simpleProfileChar3Props 
        },
    
          // Characteristic Value 3
          { 
            { ATT_BT_UUID_SIZE, simpleProfilechar3UUID },
            GATT_PERMIT_WRITE, 
            0, 
            &simpleProfileChar3 
          },
    
          // Characteristic 3 User Description
          { 
            { ATT_BT_UUID_SIZE, charUserDescUUID },
            GATT_PERMIT_READ, 
            0, 
            simpleProfileChar3UserDesp 
          },
    
        // Characteristic 4 Declaration
        { 
          { ATT_BT_UUID_SIZE, characterUUID },
          GATT_PERMIT_READ, 
          0,
          &simpleProfileChar4Props 
        },
    
          // Characteristic Value 4
          { 
            { ATT_BT_UUID_SIZE, simpleProfilechar4UUID },
            0, 
            0, 
            simpleProfileChar4 
          },
    
          // Characteristic 4 configuration
          { 
            { ATT_BT_UUID_SIZE, clientCharCfgUUID },
            GATT_PERMIT_READ | GATT_PERMIT_WRITE, 
            0, 
            (uint8 *)&simpleProfileChar4Config 
          },
          
          // Characteristic 4 User Description
          { 
            { ATT_BT_UUID_SIZE, charUserDescUUID },
            GATT_PERMIT_READ, 
            0, 
            simpleProfileChar4UserDesp 
          },
          
        // Characteristic 5 Declaration
        { 
          { ATT_BT_UUID_SIZE, characterUUID },
          GATT_PERMIT_READ, 
          0,
          &simpleProfileChar5Props 
        },
    
          // Characteristic Value 5
          { 
            { ATT_BT_UUID_SIZE, simpleProfilechar5UUID },
            GATT_PERMIT_AUTHEN_READ, 
            0, 
            simpleProfileChar5 
          },
    
          // Characteristic 5 User Description
          { 
            { ATT_BT_UUID_SIZE, charUserDescUUID },
            GATT_PERMIT_READ, 
            0, 
            simpleProfileChar5UserDesp 
          },
    };
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    static bStatus_t simpleProfile_ReadAttrCB(uint16_t connHandle,
                                              gattAttribute_t *pAttr, 
                                              uint8_t *pValue, uint16_t *pLen,
                                              uint16_t offset, uint16_t maxLen,
                                              uint8_t method);
    static bStatus_t simpleProfile_WriteAttrCB(uint16_t connHandle,
                                               gattAttribute_t *pAttr,
                                               uint8_t *pValue, uint16_t len,
                                               uint16_t offset, uint8_t method);
    
    /*********************************************************************
     * PROFILE CALLBACKS
     */
    
    // Simple Profile Service Callbacks
    // Note: When an operation on a characteristic requires authorization and 
    // pfnAuthorizeAttrCB is not defined for that characteristic's service, the 
    // Stack will report a status of ATT_ERR_UNLIKELY to the client.  When an 
    // operation on a characteristic requires authorization the Stack will call 
    // pfnAuthorizeAttrCB to check a client's authorization prior to calling
    // pfnReadAttrCB or pfnWriteAttrCB, so no checks for authorization need to be 
    // made within these functions.
    CONST gattServiceCBs_t simpleProfileCBs =
    {
      simpleProfile_ReadAttrCB,  // Read callback function pointer
      simpleProfile_WriteAttrCB, // Write callback function pointer
      NULL                       // Authorization callback function pointer
    };
    
    /*********************************************************************
     * PUBLIC FUNCTIONS
     */
    
    /*********************************************************************
     * @fn      SimpleProfile_AddService
     *
     * @brief   Initializes the Simple Profile service by registering
     *          GATT attributes with the GATT server.
     *
     * @param   services - services to add. This is a bit map and can
     *                     contain more than one service.
     *
     * @return  Success or Failure
     */
    bStatus_t SimpleProfile_AddService( uint32 services )
    {
      uint8 status;
    
      // Allocate Client Characteristic Configuration table
      simpleProfileChar4Config = (gattCharCfg_t *)ICall_malloc( sizeof(gattCharCfg_t) *
                                                                linkDBNumConns );
      if ( simpleProfileChar4Config == NULL )
      {     
        return ( bleMemAllocError );
      }
      
      // Initialize Client Characteristic Configuration attributes
      GATTServApp_InitCharCfg( INVALID_CONNHANDLE, simpleProfileChar4Config );
      
      if ( services & SIMPLEPROFILE_SERVICE )
      {
        // Register GATT attribute list and CBs with GATT Server App
        status = GATTServApp_RegisterService( simpleProfileAttrTbl, 
                                              GATT_NUM_ATTRS( simpleProfileAttrTbl ),
                                              GATT_MAX_ENCRYPT_KEY_SIZE,
                                              &simpleProfileCBs );
      }
      else
      {
        status = SUCCESS;
      }
    
      return ( status );
    }
    
    /*********************************************************************
     * @fn      SimpleProfile_RegisterAppCBs
     *
     * @brief   Registers the application callback function. Only call 
     *          this function once.
     *
     * @param   callbacks - pointer to application callbacks.
     *
     * @return  SUCCESS or bleAlreadyInRequestedMode
     */
    bStatus_t SimpleProfile_RegisterAppCBs( simpleProfileCBs_t *appCallbacks )
    {
      if ( appCallbacks )
      {
        simpleProfile_AppCBs = appCallbacks;
        
        return ( SUCCESS );
      }
      else
      {
        return ( bleAlreadyInRequestedMode );
      }
    }
    
    /*********************************************************************
     * @fn      SimpleProfile_SetParameter
     *
     * @brief   Set a Simple Profile parameter.
     *
     * @param   param - Profile parameter ID
     * @param   len - length of data to write
     * @param   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).
     *
     * @return  bStatus_t
     */
    bStatus_t SimpleProfile_SetParameter( uint8 param, uint8 len, void *value )
    {
      bStatus_t ret = SUCCESS;
      switch ( param )
      {
        case SIMPLEPROFILE_CHAR1:
          if ( len == sizeof ( uint8 ) ) 
          {
            simpleProfileChar1 = *((uint8*)value);
          }
          else
          {
            ret = bleInvalidRange;
          }
          break;
    
        case SIMPLEPROFILE_CHAR2:
          if ( len == sizeof ( uint8 ) ) 
          {
            simpleProfileChar2 = *((uint8*)value);
          }
          else
          {
            ret = bleInvalidRange;
          }
          break;
    
        case SIMPLEPROFILE_CHAR3:
          if ( len == sizeof ( uint8 ) ) 
          {
            simpleProfileChar3 = *((uint8*)value);
          }
          else
          {
            ret = bleInvalidRange;
          }
          break;
    
        case SIMPLEPROFILE_CHAR4:
          if ( len == SIMPLEPROFILE_CHAR4_LEN ) 
          {
            VOID memcpy( simpleProfileChar4, value, SIMPLEPROFILE_CHAR4_LEN );
            
            // See if Notification has been enabled
            GATTServApp_ProcessCharCfg( simpleProfileChar4Config, simpleProfileChar4, FALSE,
                                        simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ),
                                        INVALID_TASK_ID, simpleProfile_ReadAttrCB );
          }
          else
          {
            ret = bleInvalidRange;
          }
          break;
    
        case SIMPLEPROFILE_CHAR5:
          if ( len == SIMPLEPROFILE_CHAR5_LEN ) 
          {
            VOID memcpy( simpleProfileChar5, value, SIMPLEPROFILE_CHAR5_LEN );
          }
          else
          {
            ret = bleInvalidRange;
          }
          break;
          
        default:
          ret = INVALIDPARAMETER;
          break;
      }
      
      return ( ret );
    }
    
    /*********************************************************************
     * @fn      SimpleProfile_GetParameter
     *
     * @brief   Get a Simple Profile parameter.
     *
     * @param   param - Profile parameter ID
     * @param   value - pointer to data to put.  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).
     *
     * @return  bStatus_t
     */
    bStatus_t SimpleProfile_GetParameter( uint8 param, void *value )
    {
      bStatus_t ret = SUCCESS;
      switch ( param )
      {
        case SIMPLEPROFILE_CHAR1:
          *((uint8*)value) = simpleProfileChar1;
          break;
    
        case SIMPLEPROFILE_CHAR2:
          *((uint8*)value) = simpleProfileChar2;
          break;      
    
        case SIMPLEPROFILE_CHAR3:
          *((uint8*)value) = simpleProfileChar3;
          break;  
    
        case SIMPLEPROFILE_CHAR4:
          //*((uint8*)value) = simpleProfileChar4;
          break;
    
        case SIMPLEPROFILE_CHAR5:
          VOID memcpy( value, simpleProfileChar5, SIMPLEPROFILE_CHAR5_LEN );
          break;      
          
        default:
          ret = INVALIDPARAMETER;
          break;
      }
      
      return ( ret );
    }
    
    /*********************************************************************
     * @fn          simpleProfile_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 simpleProfile_ReadAttrCB(uint16_t connHandle,
                                              gattAttribute_t *pAttr,
                                              uint8_t *pValue, uint16_t *pLen,
                                              uint16_t offset, uint16_t maxLen,
                                              uint8_t method)
    {
      bStatus_t status = SUCCESS;
      
      // Make sure it's not a blob operation (no attributes in the profile are long)
      if ( offset > 0 )
      {
        return ( ATT_ERR_ATTR_NOT_LONG );
      }
     
      if ( pAttr->type.len == ATT_BT_UUID_SIZE )
      {
        // 16-bit UUID
        uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
        switch ( uuid )
        {
          // No need for "GATT_SERVICE_UUID" or "GATT_CLIENT_CHAR_CFG_UUID" cases;
          // gattserverapp handles those reads
    
          // characteristics 1 and 2 have read permissions
          // characteritisc 3 does not have read permissions; therefore it is not
          //   included here
          // characteristic 4 does not have read permissions, but because it
          //   can be sent as a notification, it is included here
          case SIMPLEPROFILE_CHAR1_UUID:
          case SIMPLEPROFILE_CHAR2_UUID:
          //case SIMPLEPROFILE_CHAR4_UUID:
            *pLen = 1;
            pValue[0] = *pAttr->pValue;
            break;
          case SIMPLEPROFILE_CHAR4_UUID:
            *pLen = SIMPLEPROFILE_CHAR4_LEN;
            VOID memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR4_LEN );
            break;
          case SIMPLEPROFILE_CHAR5_UUID:
            *pLen = SIMPLEPROFILE_CHAR5_LEN;
            VOID memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR5_LEN );
            break;
            
          default:
            // Should never get here! (characteristics 3 and 4 do not have read permissions)
            *pLen = 0;
            status = ATT_ERR_ATTR_NOT_FOUND;
            break;
        }
      }
      else
      {
        // 128-bit UUID
        *pLen = 0;
        status = ATT_ERR_INVALID_HANDLE;
      }
    
      return ( status );
    }
    
    /*********************************************************************
     * @fn      simpleProfile_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 simpleProfile_WriteAttrCB(uint16_t connHandle,
                                               gattAttribute_t *pAttr,
                                               uint8_t *pValue, uint16_t len,
                                               uint16_t offset, uint8_t method)
    {
      bStatus_t status = SUCCESS;
      uint8 notifyApp = 0xFF;
      
      if ( pAttr->type.len == ATT_BT_UUID_SIZE )
      {
        // 16-bit UUID
        uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
        switch ( uuid )
        {
          case SIMPLEPROFILE_CHAR1_UUID:
          case SIMPLEPROFILE_CHAR3_UUID:
    
            //Validate the value
            // Make sure it's not a blob oper
            if ( offset == 0 )
            {
              if ( len != 1 )
              {
                status = ATT_ERR_INVALID_VALUE_SIZE;
              }
            }
            else
            {
              status = ATT_ERR_ATTR_NOT_LONG;
            }
            
            //Write the value
            if ( status == SUCCESS )
            {
              uint8 *pCurValue = (uint8 *)pAttr->pValue;        
              *pCurValue = pValue[0];
    
              if( pAttr->pValue == &simpleProfileChar1 )
              {
                notifyApp = SIMPLEPROFILE_CHAR1;        
              }
              else
              {
                notifyApp = SIMPLEPROFILE_CHAR3;           
              }
            }
                 
            break;
    
          case GATT_CLIENT_CHAR_CFG_UUID:
            status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,
                                                     offset, GATT_CLIENT_CFG_NOTIFY );
            break;
            
          default:
            // Should never get here! (characteristics 2 and 4 do not have write permissions)
            status = ATT_ERR_ATTR_NOT_FOUND;
            break;
        }
      }
      else
      {
        // 128-bit UUID
        status = ATT_ERR_INVALID_HANDLE;
      }
    
      // If a characteristic value changed then callback function to notify application of change
      if ( (notifyApp != 0xFF ) && simpleProfile_AppCBs && simpleProfile_AppCBs->pfnSimpleProfileChange )
      {
        simpleProfile_AppCBs->pfnSimpleProfileChange( notifyApp );  
      }
      
      return ( status );
    }
    
    /*********************************************************************
    *********************************************************************/
    

    simple_gatt_profile.h

  • Hi Erick,
    If you want to transfer more than 20 bytes, you need divide data into 20 bytes or use bluetooth 4.2
  • The problem was solved a long time ago

    I wonder you are replying after 4 months lolx

    well the problem was with the stock notify character given in simple ble peripheral

    i was modifying its length but i was only receiving the 4 or 5 bytes

    so i created another notify character with 20 bytes length and it worked.