/**
  * @brief  Used internal, to send write request to peer server's V5 Control Point Characteristic.
  * @param  ctl_pnt_ptr: pointer of control point data to write.
  * @retval TRUE--send request to upper stack success.
  *         FALSE--send request to upper stack failed.
  */
static bool SimpBleClient_CtlPntWrite( uint8_t *ctl_pnt_ptr )
{
    TWriteReq writeReq;
    bool hdl_valid = FALSE;
    DBG_BUFFER(MODULE_PROFILE, LEVEL_INFO, "SimpBleClient_CtlPntWrite", 0);

    if(SimpHdlCache[HDL_SIMBLE_V5_CTL_PNT])
    {
        writeReq.wHandle = SimpHdlCache[HDL_SIMBLE_V5_CTL_PNT];
        writeReq.wType = blueAPI_GATTWriteTypeRequest;
        writeReq.wLength = 3;
        writeReq.pData = ctl_pnt_ptr;
        hdl_valid = TRUE;
    }

    if(hdl_valid)
    {
        if(clientAPI_AttribWrite( SimpClient_ClientID, &writeReq ) == ProfileResult_Success)
        {
            return TRUE;
        }
    }
    
    DBG_BUFFER(MODULE_PROFILE, LEVEL_WARN, "SimpBleClient_CtlPntWrite: Request fail! Please check!", 0);
    return FALSE;
}
/**
  * @brief  Used by application, to enable or disable the indication of peer server's V5 Control Point Characteristic.
  * @param  command: 0--disable the indication, 1--enable the indication.
  * @retval TRUE--send request to upper stack success.
  *         FALSE--send request to upper stack failed.
  */
bool SimpBleClient_V5CtlPntIndicateCmd( bool command )
{
    TWriteReq writeReq;
    uint16_t wCCCDBits;
    bool hdl_valid = FALSE;

    DBG_BUFFER(MODULE_PROFILE, LEVEL_INFO, "SimpBleClient_V5CtlPntIndicateCmd: command = %d", 1, command);

    wCCCDBits = command ? 2 : 0;

    if(SimpHdlCache[HDL_SIMBLE_V5_CTL_PNT_CCCD])
    {
        writeReq.wHandle = SimpHdlCache[HDL_SIMBLE_V5_CTL_PNT_CCCD];
        writeReq.wType = blueAPI_GATTWriteTypeRequest;
        writeReq.wLength = sizeof(uint16_t);
        writeReq.pData = (uint8_t *)&wCCCDBits;
        hdl_valid = TRUE;
    }

    if(hdl_valid)
    {
        if(clientAPI_AttribWrite( SimpClient_ClientID, &writeReq ) == ProfileResult_Success)
        {
            return TRUE;
        }
    }
    
    DBG_BUFFER(MODULE_PROFILE, LEVEL_WARN, "SimpBleClient_V5CtlPntIndicateCmd: Request fail! Please check!", 0);
    return FALSE;
}
Esempio n. 3
0
/**
 * @brief handle blueAPI_Event_GATTCCCDInfo.
 *
 * @param pGATTCCCDInfo      upstream message from upper stack.
 * @return release buffer or not.
 * @retval TRUE 1
 * @retval FALSE 0
*/
bool profileHandle_GATTCCCDInfo(PBlueAPI_GATTCCCDInfo pGATTCCCDInfo )
{
    PGATTDService pService;

    pService = profileServiceFind(pGATTCCCDInfo->serviceHandle );

#ifdef PROFILE_DEBUG
    DBG_BUFFER(MODULE_PROFILE, LEVEL_INFO, "<-- profileHandle_GATTCCCDInfo:  count=%d ServiceID=%d",
               2, pGATTCCCDInfo->count, pService->ServiceIDx);
#endif

    if ( (pService != (PGATTDService)NULL))
    {
        int        i;
        uint16_t   wAttribIndex, wCCCBits;
        uint16_t * pWord;

        pWord = (uint16_t *)&pGATTCCCDInfo->data[pGATTCCCDInfo->gap];
        for ( i = 0; i < pGATTCCCDInfo->count; i++ )
        {
            wAttribIndex = *(pWord++);
            wCCCBits     = *(pWord++);
#ifdef PROFILE_DEBUG
            DBG_BUFFER(MODULE_PROFILE, LEVEL_INFO, "attribIndex=%d, cccBits=0x%04x",
                       2, wAttribIndex, wCCCBits);
#endif
            profileUpdateCCCDInfo((uint8_t)pService->ServiceIDx, wAttribIndex, wCCCBits);

        }
    }

    return ( true );
}
/**
  * @brief  Used by application, to send write request to peer server's V2 Write Characteristic.
  * @param  v2_write_val: data to write.
  * @retval TRUE--send request to upper stack success.
  *         FALSE--send request to upper stack failed.
  */
bool SimpBleClient_WriteV2WriteChar(uint8_t v2_write_val)
{
    TWriteReq writeReq;
    bool hdl_valid = FALSE;
    DBG_BUFFER(MODULE_PROFILE, LEVEL_INFO, "SimpBleClient_WriteV2WriteChar", 0);

    if(SimpHdlCache[HDL_SIMBLE_V2_WRITE])
    {
        writeReq.wHandle = SimpHdlCache[HDL_SIMBLE_V2_WRITE];
        writeReq.wType = blueAPI_GATTWriteTypeRequest;
        writeReq.wLength = sizeof(v2_write_val);
        writeReq.pData = &v2_write_val;
        hdl_valid = TRUE;
    }

    if(hdl_valid)
    {
        if(clientAPI_AttribWrite( SimpClient_ClientID, &writeReq ) == ProfileResult_Success)
        {
            return TRUE;
        }
    }
    
    DBG_BUFFER(MODULE_PROFILE, LEVEL_WARN, "SimpBleClient_WriteV2WriteChar: Request fail! Please check!", 0);
    return FALSE;
}
Esempio n. 5
0
/**
 * @brief handle blueAPI_Event_GATTAttributeUpdateRsp.
 *
 * @param pGATTAttributeUpdateRsp        upstream message from upper stack.
 * @return release buffer or not.
 * @retval TRUE 1
 * @retval FALSE 0
*/
bool profileHandle_GATTAttributeUpdateRsp(
    PBlueAPI_GATTAttributeUpdateRsp pGATTAttributeUpdateRsp )
{
    bool  Error = false;
#ifdef PROFILE_DEBUG
    DBG_BUFFER(MODULE_PROFILE, LEVEL_INFO, "<-- GATTAttributeUpdateRsp cause = 0x%x subcause = 0x%x ", 2,
               pGATTAttributeUpdateRsp->cause, pGATTAttributeUpdateRsp->subCause);
#endif
    gProfileData.wDsCredits++ ;
    if ( pGATTAttributeUpdateRsp->cause == blueAPI_CauseSuccess )
    {
        profileDataTxComplete(gProfileData.wDsCredits);

    }
    else  if ( pGATTAttributeUpdateRsp->subCause == GATT_ERR_OUT_OF_RESOURCE )
    {
        Error = true;
    }
    else  if ( (pGATTAttributeUpdateRsp->subCause == GATT_ERR_NOTIF_IND_CFG) &&
               (pGATTAttributeUpdateRsp->count > 0)
             )
    {
        /* list of BDs that configured the CCCD for notifications/indications */
        /* is appended */
        PBlueAPI_GATTAttributeUpdateListElement  pElement;
        int   i;
        DBG_BUFFER(MODULE_PROFILE, LEVEL_ERROR, "GATTAttributeUpdateRsp GATT_ERR_NOTIF_IND_CFG.", 0);
        DBG_BUFFER(MODULE_PROFILE, LEVEL_ERROR, "GATTAttributeUpdateRsp GATT_ERR_NOTIF_IND_CFG.", 0);

        pElement = (PBlueAPI_GATTAttributeUpdateListElement)(pGATTAttributeUpdateRsp->list + pGATTAttributeUpdateRsp->gap);
        for ( i = 0; i < pGATTAttributeUpdateRsp->count ; i++ )
        {
            pElement++;
        }
    }
    if (pGATTAttributeUpdateRsp->subCause == GATT_ERR_NOTIF_IND_CFG)
    {
        DBG_BUFFER(MODULE_PROFILE, LEVEL_ERROR, "Check GATT_ERR_NOTIF_IND_CFG.AttribIndex", 1, pGATTAttributeUpdateRsp->attribIndex);
    }
    if ( Error )
    {
        DBG_BUFFER(MODULE_PROFILE, LEVEL_ERROR, "GATTAttributeUpdateRsp Error %d.", 1, Error);
    }
    else
    {
        /* some services need to do some post update (sequence) processing (RACP ..): */
        /*
        if ( (pGATTData->iUpdateCnt == pGATTData->iUpdateConfirmed) ||
             (pGATTAttributeUpdateRsp->cause != blueAPI_CauseSuccess)
           )
        {
          gattdServiceUpdateCallback( pGATTData,
                pGATTAttributeUpdateRsp->subCause, pGATTAttributeUpdateRsp->attribIndex );
        }
        */
    }

    return ( true );
}
Esempio n. 6
0
/*
 * si4713_send_command - sends a command to si4713 and waits its response
 * @sdev: si4713_device structure for the device we are communicating
 * @command: command id
 * @args: command arguments we are sending (up to 7)
 * @argn: actual size of @args
 * @response: buffer to place the expected response from the device (up to 15)
 * @respn: actual size of @response
 * @usecs: amount of time to wait before reading the response (in usecs)
 */
static int si4713_send_command(struct si4713_device *sdev, const u8 command,
				const u8 args[], const int argn,
				u8 response[], const int respn, const int usecs)
{
	struct i2c_client *client = v4l2_get_subdevdata(&sdev->sd);
	unsigned long until_jiffies;
	u8 data1[MAX_ARGS + 1];
	int err;

	if (!client->adapter)
		return -ENODEV;

	/* First send the command and its arguments */
	data1[0] = command;
	memcpy(data1 + 1, args, argn);
	DBG_BUFFER(&sdev->sd, "Parameters", data1, argn + 1);

	err = i2c_master_send(client, data1, argn + 1);
	if (err != argn + 1) {
		v4l2_err(&sdev->sd, "Error while sending command 0x%02x\n",
			command);
		return err < 0 ? err : -EIO;
	}

	until_jiffies = jiffies + usecs_to_jiffies(usecs) + 1;

	/* Wait response from interrupt */
	if (client->irq) {
		if (!wait_for_completion_timeout(&sdev->work,
				usecs_to_jiffies(usecs) + 1))
			v4l2_warn(&sdev->sd,
				"(%s) Device took too much time to answer.\n",
				__func__);
	}

	do {
		err = i2c_master_recv(client, response, respn);
		if (err != respn) {
			v4l2_err(&sdev->sd,
				"Error %d while reading response for command 0x%02x\n",
				err, command);
			return err < 0 ? err : -EIO;
		}

		DBG_BUFFER(&sdev->sd, "Response", response, respn);
		if (!check_command_failed(response[0]))
			return 0;

		if (client->irq)
			return -EBUSY;
		if (usecs <= 1000)
			usleep_range(usecs, 1000);
		else
			usleep_range(1000, 2000);
	} while (time_is_after_jiffies(until_jiffies));

	return -EBUSY;
}
/**
  * @brief  Used by application, read data from server by using handles.
  * @param  readCharType: one of characteristic that has the readable property.
  * @retval TRUE--send request to upper stack success.
  *         FALSE--send request to upper stack failed.
  */
bool SimpBleClient_ReadByHandle( TSimpClientReadType readCharType )
{
    TReadHandleReq readHandle;
    bool hdl_valid = FALSE;

    DBG_BUFFER(MODULE_PROFILE, LEVEL_INFO, "SimpBleClient_ReadByHandle: charType = %d", 1, readCharType);
    
    switch(readCharType)
    {
        case SIMP_READ_REQ_V1_READ:
            if(SimpHdlCache[HDL_SIMBLE_V1_READ])
            {
                readHandle.wHandle = SimpHdlCache[HDL_SIMBLE_V1_READ];
                hdl_valid = TRUE;
            }
            break;
        case SIMP_READ_REQ_V3_NOTIFY_NOTIF_BIT:
            if(SimpHdlCache[HDL_SIMBLE_V3_NOTIFY_CCCD])
            {
                readHandle.wHandle = SimpHdlCache[HDL_SIMBLE_V3_NOTIFY_CCCD];
                hdl_valid = TRUE;
            }
            break;
        case SIMP_READ_REQ_V4_INDICATE_IND_BIT:
            if(SimpHdlCache[HDL_SIMBLE_V4_INDICATE_CCCD])
            {
                readHandle.wHandle = SimpHdlCache[HDL_SIMBLE_V4_INDICATE_CCCD];
                hdl_valid = TRUE;
            }
            break;
        case SIMP_READ_REQ_V5_CTL_PNT_IND_BIT:
            if(SimpHdlCache[HDL_SIMBLE_V5_CTL_PNT_CCCD])
            {
                readHandle.wHandle = SimpHdlCache[HDL_SIMBLE_V5_CTL_PNT_CCCD];
                hdl_valid = TRUE;
            }
            break;
        default:
            return FALSE;
    }
            
    if(hdl_valid)
    {
        if(clientAPI_AttribRead(SimpClient_ClientID, readHandle) == ProfileResult_Success)
        {
            return TRUE;
        }
    }
    
    DBG_BUFFER(MODULE_PROFILE, LEVEL_WARN, "SimpBleClient_ReadByHandle: Request fail! Please check!", 0);
    return FALSE;
}
//#ifdef CONFIG_DLPS_EN
BOOL DLPS_CheckTestUpperTask()
{
    if (g_pGattTest->bEnterDlps == true)
    {
    	DBG_BUFFER(MODULE_APP, LEVEL_INFO, "DLPS_CheckTestUpperTask true\n\n", 0);
        return true;
    }
    else
    {
    	DBG_BUFFER(MODULE_APP, LEVEL_INFO, "DLPS_CheckTestUpperTask flase\n\n", 0);
        return false;
    }
}
Esempio n. 9
0
/**
 * @brief handle blueAPI_Event_GATTAttributeUpdateStatusInd.
 *
 * @param pGATTAttributeUpdateStatusInd      upstream message from upper stack.
 * @return release buffer or not.
 * @retval TRUE 1
 * @retval FALSE 0
*/
bool profileHandle_GATTAttributeUpdateStatusInd(
    PBlueAPI_GATTAttributeUpdateStatusInd pGATTAttributeUpdateStatusInd )
{
    PGATTDService  pService;
    
#ifdef PROFILE_DEBUG
    DBG_BUFFER(MODULE_PROFILE, LEVEL_INFO, "<-- profileHandle_GATTAttributeUpdateStatusInd subCause=0x%x",
               1, pGATTAttributeUpdateStatusInd->subCause);
#endif

    pService = profileServiceFind( pGATTAttributeUpdateStatusInd->serviceHandle );
    
    //notify service
    if(gattSrvInfo[pService->ServiceIDx].cbInfo.pfnUpdateStatusCB)
    {
        gattSrvInfo[pService->ServiceIDx].cbInfo.pfnUpdateStatusCB(
            pService->ServiceIDx, pGATTAttributeUpdateStatusInd->attribIndex);
    }
    
    if ( blueAPI_GATTAttributeUpdateStatusConf(
                pGATTAttributeUpdateStatusInd->serviceHandle,
                pGATTAttributeUpdateStatusInd->requestHandle,
                pGATTAttributeUpdateStatusInd->attribIndex
            )
       )
    {
#ifdef PROFILE_DEBUG    
        DBG_BUFFER(MODULE_PROFILE, LEVEL_INFO, "<-- --> GATTAttributeUpdateStatusConf", 0);
#endif
    }

    /* check if update sequence should be continued */
    gProfileData.wDsCredits++ ;
    if ( pGATTAttributeUpdateStatusInd->cause == blueAPI_CauseSuccess )
    {
        profileDataTxComplete(gProfileData.wDsCredits);
    }
    else
    {
        //gSrvSequnceCtrl.iUpdateCnt = 0;
    }

    /* Modified for RSC CSC Procedure Already In Progress */
    /* some services need to do some post update (sequence) processing (RSC, CSC): */
    /*  if ( gSrvSequnceCtrl.iUpdateCnt == 0 )
      {
          DBG_BUFFER(MODULE_PROFILE, LEVEL_INFO, "--> gattdServiceUpdateCallback() executed.", 0);
      }
    */
    return ( true );
}
Esempio n. 10
0
/**
  * @brief  handle blueAPI_Event_GATTDiscoveryRsp.
  * @param  pGATTDiscoveryRsp: message from upper stack.
  * @retval TRUE: need to release buffer.
  *         FALSE: no need to release buffer.
  */
static bool profileHandle_GATTDiscoveryRsp(PBlueAPI_GATTDiscoveryRsp pGATTDiscoveryRsp)
{
#ifdef ANCS_DEBUG
    DBG_BUFFER(MODULE_PROFILE,LEVEL_INFO,"profileHandle_GATTDiscoveryRsp: subCause=0x%x",1,pGATTDiscoveryRsp->subCause);
#endif
    return( true );
}
Esempio n. 11
0
/**
 * @brief handle blueAPI_Event_GATTServiceRegisterRsp.
 *
 * @param pGATTServiceRegisterRsp        upstream message from upper stack.
 * @return release buffer or not.
 * @retval TRUE 1
 * @retval FALSE 0
*/
bool profileHandle_GATTServiceRegisterRsp(
    PBlueAPI_GATTServiceRegisterRsp pGATTServiceRegisterRsp )
{
#ifdef PROFILE_DEBUG
    DBG_BUFFER(MODULE_PROFILE, LEVEL_INFO, "profileHandle_GATTServiceRegisterRsp cause = 0x%x", 1,
               pGATTServiceRegisterRsp->cause);
#endif
    if ( pGATTServiceRegisterRsp->cause == blueAPI_CauseSuccess )
    {
        gattSrvInfo[gProfileData.iServiceCountIndex].Service.pServiceHandle =
            pGATTServiceRegisterRsp->serviceHandle;

        gProfileData.iServiceCountIndex++;
        if ( gProfileData.iServiceCountIndex == gServicesCount )
        {
            // service Register complete, send this to APP.lilly
            profileSrvStartCompleteEvt(0);
            peripheral_Handle_ServiceRegisterCompleteEvt();
        }
        else
        {
            /* register next service */
            profileServiceRegister();
        }
    }
    else
    {
        gattSrvInfo[gProfileData.iServiceCountIndex].Service.Used           = false;
        gattSrvInfo[gProfileData.iServiceCountIndex].Service.pServiceHandle = NULL;
    }

    return ( true );
}
static void dualmode_HandleBtGapEncryptStateChangeEvt(uint8_t new_state)
{
    switch (new_state)
    {
    case GAPBOND_ENCRYPT_STATE_ENABLED:
        DBG_BUFFER(MODULE_APP, LEVEL_INFO, "GAPBOND_ENCRYPT_STATE_ENABLED", 0);
        break;

    case GAPBOND_ENCRYPT_STATE_DISABLED:
        DBG_BUFFER(MODULE_APP, LEVEL_INFO, "GAPBOND_ENCRYPT_STATE_DISABLED", 0);
        break;

    default:
        break;
    }
}
Esempio n. 13
0
/**
 * @brief read characteristic data from service.
 *
 * @param ServiceId          ServiceID of characteristic data.
 * @param iAttribIndex          Attribute index of getting characteristic data.
 * @param iOffset                Used for Blob Read.
 * @param piLength            length of getting characteristic data.
 * @param ppValue            data got from service.
 * @return Profile procedure result
*/
TProfileResult  SimpBleServiceAttrReadCb( uint8_t ServiceId, uint16_t iAttribIndex, uint16_t iOffset, uint16_t * piLength, uint8_t **ppValue )
{
    TProfileResult  wCause  = ProfileResult_Success;

    switch ( iAttribIndex )
    {
    default:
        DBG_BUFFER(MODULE_PROFILE, LEVEL_ERROR, "<-- SimpBleServiceAttrReadCb, Attr not found, index=%d",
                   1, iAttribIndex);
        wCause  = ProfileResult_AttrNotFound;
        break;
    case SIMPLE_BLE_SERVICE_CHAR_V1_READ_INDEX:
        {
            TSIMP_CALLBACK_DATA callback_data;
            callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
            callback_data.msg_data.read_value_index = SIMP_READ_V1;
            pfnSimpBleServiceCB(ServiceId, (void*)&callback_data);            
            *ppValue    = &simpleCharReadValue;
            *piLength = sizeof(simpleCharReadValue);
        }
        break;
    }

    return ( wCause );
}
Esempio n. 14
0
/**
  * @brief  Set service related data from application.
  *
  * @param[in] param_type            parameter type to set: @ref BAS_Application_Parameters
  * @param[in] length                value length to be set.
  * @param[in] value_ptr             value to set.
  * @return parameter set result.
  * @retval 0 FALSE
  * @retval 1 TRUE
  */
bool BAS_SetParameter( uint8_t param_type, uint8_t length, uint8_t *value_ptr )
{
    bool ret = TRUE;

    switch (param_type)
    {
    default:
        {
            ret = FALSE;
            DBG_BUFFER(MODULE_PROFILE, LEVEL_INFO, "BAS_SetParameter failed\n", 0 );
        }
        break;

    case BAS_PARAM_BATTERY_LEVEL:
        {
            if (length != sizeof(uint8_t))
            {
                ret = FALSE;
            }
            else
            {
                gBatteryLevel = value_ptr[0];
            }
        }
        break;
    }

    return ret;
}
Esempio n. 15
0
/**
  * @brief  Called by profile client layer, when write request complete.
  * @param  reqResult: write request send success or not.
  * @retval ProfileResult_Success--procedure OK.
  *         other--procedure exception.
  */
static TProfileResult SimpBleClientWriteResultCb( TClientRequestResult reqResult )
{
    TAppResult appResult = AppResult_Success;
    TSimpClientCB_Data cb_data;
    cb_data.cb_type = SIMP_CLIENT_CB_TYPE_WRITE_RESULT;

    DBG_BUFFER(MODULE_PROFILE, LEVEL_INFO, "SimpBleClientWriteResultCb: result = %d", 1, reqResult);

    /* If write req success, branch to fetch value and send to application. */
    if(reqResult == CLIENT_REQ_SUCCESS)
    {
        cb_data.cb_content.write_result = SIMP_WRITE_RESULT_SUCCESS;
    }
    /* Read req fail, inform application. */
    else
    {
        cb_data.cb_content.write_result = SIMP_WRITE_RESULT_FAIL;
    }
    /* Inform application the write result. */
    if(pfnSimpClientAppCB)
    {
        appResult = (*pfnSimpClientAppCB)(SimpClient_ClientID, &cb_data);
    }

    return (clientAPI_GetProfileResult(appResult));
}
Esempio n. 16
0
/**
 * @brief write Long characteristic data from service.
 *
 * @param ServiceID          ServiceID to be written.
 * @param iAttribIndex          Attribute index of characteristic.
 * @param wLength            length of value to be written.
 * @param pValue            value to be written.
 * @return Profile procedure result
*/
TProfileResult SimpBleServiceAttrPreWriteCb(uint8_t ServiceId, uint16_t iAttribIndex, uint16_t wLength, uint8_t * pValue, TGATTDWriteIndPostProc * pWriteIndPostProc)
{
    TSIMP_CALLBACK_DATA callback_data;
    TProfileResult  wCause = ProfileResult_Success;
    if (SIMPLE_BLE_SERVICE_CHAR_V6_WRITE_INDEX == iAttribIndex)
    {
        /* Make sure written value size is valid. */
        if ( (wLength > sizeof(uint8_t)) || (pValue == NULL) )
        {
            wCause  = ProfileResult_InvalidValueSize;
        }
        else
        {
            /* Notify Application. */
            callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
			callback_data.msg_data.pre_write.opcode = SIMP_PRE_WRITE_V6;
			callback_data.msg_data.pre_write.pValue = pValue;
			callback_data.msg_data.pre_write.Len = wLength;
            
            if (pfnSimpBleServiceCB)
            {
                pfnSimpBleServiceCB(ServiceId, (void*)&callback_data);
            }
        }
    }
    else
    {
        DBG_BUFFER(MODULE_PROFILE, LEVEL_ERROR, "--> SimpBleServiceAttrPreWriteCb Error  iAttribIndex = 0x%x wLength=%d",
                   2,
                   iAttribIndex,
                   wLength);
        wCause = ProfileResult_AttrNotFound;
    }
    return wCause;
}
Esempio n. 17
0
/**
 * @brief  handle control point write (request).
 *
 * @param serviceID
 * @param write_length      write request data length.
 * @param value_ptr         pointer to write request data.
 * @return none
 * @retval  void
*/
static void  SimpBleService_CtlPntHandleReq( uint8_t serviceID, uint16_t write_length, uint8_t * value_ptr )
{
    BOOL opcode_supp = TRUE;

    memcpy( simpleCharCtlPntValue, value_ptr, write_length );
    DBG_BUFFER(MODULE_PROFILE, LEVEL_INFO, "SimpBleService_CtlPntHandleReq: OpCode=0x%x", 1,
               simpleCharCtlPntValue[0] );

    switch ( simpleCharCtlPntValue[0] )
    {
    default:
        opcode_supp = FALSE;
        break;
    case SIMPLE_CP_OPCODE_SET_CHAR_INDICATE_VAL:
        SimpBleService_CtlPntSetIndVal(serviceID);
        break;
    case SIMPLE_CP_OPCODE_SET_CHAR_NOTIFY_VAL:
        SimpBleService_CtlPntSetNotVal(serviceID);
        break;
    }

    if (!opcode_supp)
    {
        /* Send indication to client when request opcode not supported. */
        SimpBleService_V5Indicate(serviceID, simpleCharCtlPntValue[0], SIMPLE_CP_RSPCODE_OPCODE_UNSUPPORT);
    }
}
Esempio n. 18
0
bool App_SetConfig(PAppA2dpCallback AppA2dpCallback)
{
	TA2dpResult result;
	TA2dpSetCapabilities local_Caps;
	local_Caps.localEndPointId = A2DP_STREAM_SEID_SRC;
	local_Caps.role = AVDTP_ROLE_INT | AVDTP_ROLE_SRC;
	local_Caps.mediaType = AVDTP_MEDIA_TYPE_AUDIO;
	local_Caps.endPointType = AVDTP_TSEP_SRC;

	local_Caps.Capabilities.samplingFrequency = A2DP_FREQU44100 | A2DP_FREQU48000;
	local_Caps.Capabilities.channelMode = A2DP_MODESTEREO | A2DP_MODEJOINT;
	local_Caps.Capabilities.blockNumber = A2DP_BLOCKS4 | A2DP_BLOCKS8 | A2DP_BLOCKS12 | A2DP_BLOCKS16;
	local_Caps.Capabilities.subbandNumber = A2DP_SUBBANDS4 | A2DP_SUBBANDS8;
	local_Caps.Capabilities.allocMethod = A2DP_ALLOCSNR | A2DP_ALLOCLOUDNESS;
	local_Caps.Capabilities.minBitpool = A2DP_MIN_BITPOOL;
	local_Caps.Capabilities.maxBitpool = A2DP_MAX_BITPOOL;
	result == a2dp_InitConfiguration(local_Caps,AppA2dpCallback);
	if(result == A2DP_NO_RESOURCE)
	{	
		DBG_BUFFER(MODULE_APP, LEVEL_INFO, "allocate memory is fail \r\n",0);
		return FALSE;
	}

	local_Caps.localEndPointId = A2DP_STREAM_SEID_SNK1;
	local_Caps.role = AVDTP_ROLE_ACP | AVDTP_ROLE_SNK;
	local_Caps.mediaType = AVDTP_MEDIA_TYPE_AUDIO;
	local_Caps.endPointType = AVDTP_TSEP_SNK;

	local_Caps.Capabilities.samplingFrequency = A2DP_FREQU16000 | A2DP_FREQU32000 | A2DP_FREQU44100 | A2DP_FREQU48000;
	local_Caps.Capabilities.channelMode = A2DP_MODEMOMO | A2DP_MODEDUAL | A2DP_MODESTEREO | A2DP_MODEJOINT;
	local_Caps.Capabilities.blockNumber = A2DP_BLOCKS4 | A2DP_BLOCKS8 | A2DP_BLOCKS12 | A2DP_BLOCKS16;
	local_Caps.Capabilities.subbandNumber = A2DP_SUBBANDS4 | A2DP_SUBBANDS8;
	local_Caps.Capabilities.allocMethod = A2DP_ALLOCSNR | A2DP_ALLOCLOUDNESS;
	local_Caps.Capabilities.minBitpool = A2DP_MIN_BITPOOL;
	local_Caps.Capabilities.maxBitpool = A2DP_MAX_BITPOOL;
	result == a2dp_InitConfiguration(local_Caps,AppA2dpCallback);
	if(result == A2DP_NO_RESOURCE)
	{	
		DBG_BUFFER(MODULE_APP, LEVEL_INFO, "allocate memory is fail \r\n",0);
		return FALSE;
	}
	/*local_Caps.localEndPointId = A2DP_STREAM_SEID_SNK2;
	a2dp_InitConfiguration(localCaps,AppA2dpCallback);*/	
	DBG_BUFFER(MODULE_APP, LEVEL_INFO, "success set endpoint \r\n",0);
	return TRUE;

}
Esempio n. 19
0
/**
  * @brief  add Simple BLE client to application.
  * @param  appCB: pointer of app callback function to handle specific client module data.
  * @retval Client ID of the specific client module.
  */
TClientID SimpBle_AddClient( pfnSpecificClientAppCB_t appCB )
{
    TClientID simp_client_id;
    if ( FALSE == clientAPI_RegisterSpecClientCB( &simp_client_id, SimpHdlCache, &SimpBleClientCBs ) )
    {
        simp_client_id = AppProcessGeneralClientMsgID;
        DBG_BUFFER(MODULE_PROFILE, LEVEL_ERROR, "SimpBle_AddClient Fail !!!", 0);
        return simp_client_id;
    }
    SimpClient_ClientID = simp_client_id;
    DBG_BUFFER(MODULE_PROFILE, LEVEL_INFO, "SimpBle_AddClient: client ID = %d", 1, SimpClient_ClientID);

    /* register callback for profile to inform application that some events happened. */
    pfnSimpClientAppCB = appCB;
    
    return simp_client_id;
}
void TestProfileInit(void)
{
    uint16_t length = 0;
    void *pbuffer = NULL;

    length = legacy_SDPRecordLength("< I<UU> I<<U><UB>> I<U> I<III> I<<UI>> IS II >",
                            SDP_ATTR_SERVICECLASSIDLIST, UUID_HANDSFREE, UUID_GENERICAUDIO,
                            SDP_ATTR_PROTOCOLDESCRIPTORLIST,UUID_L2CAP, UUID_RFCOMM, 0x03,
                            SDP_ATTR_BROWSEGROUPLIST, UUID_PUBLIC_BROWSE_GROUP,
                            SDP_ATTR_LANGUAGEBASEATTRIBUTEIDLIST,SDP_LANGUAGE_ENGLISH, SDP_CHARCODE_UTF8, SDP_BASE_LANG_OFFSET,
                            SDP_ATTR_BLUETOOTHPROFILEDESCRIPTORLIST, UUID_HANDSFREE, 0x0107,
                            SDP_ATTR_SERVICENAME + SDP_BASE_LANG_OFFSET, "hfp",
                            SDP_ATTR_SUPPORTEDFEATURES, 0x03ff
                            );

    DBG_BUFFER(MODULE_APP, LEVEL_INFO, "TestProfileInit: SDP buffer length cal is %d", 1, length);

    if (length)
    {
        pbuffer = osMemoryAllocate(RAM_TYPE_DATA_ON, length);
        length = legacy_SDPCreateDes(pbuffer,
                                "< I<UU> I<<U><UB>> I<U> I<III> I<<UI>> IS II >",
                                SDP_ATTR_SERVICECLASSIDLIST, UUID_HANDSFREE, UUID_GENERICAUDIO,
                                SDP_ATTR_PROTOCOLDESCRIPTORLIST,UUID_L2CAP, UUID_RFCOMM, 0x03,
                                SDP_ATTR_BROWSEGROUPLIST, UUID_PUBLIC_BROWSE_GROUP,
                                SDP_ATTR_LANGUAGEBASEATTRIBUTEIDLIST,SDP_LANGUAGE_ENGLISH, SDP_CHARCODE_UTF8, SDP_BASE_LANG_OFFSET,
                                SDP_ATTR_BLUETOOTHPROFILEDESCRIPTORLIST, UUID_HANDSFREE, 0x0107,
                                SDP_ATTR_SERVICENAME + SDP_BASE_LANG_OFFSET, "hfp",
                                SDP_ATTR_SUPPORTEDFEATURES, 0x03ff
                                );

        DBG_BUFFER(MODULE_APP, LEVEL_INFO, "TestProfileInit: SDP buffer length is %d", 1, length);

        if (length)
        {
            legacy_AddSDPRecord(pbuffer, length);
        }
        else
        {
            osMemoryFree(pbuffer);
        }
    }


}
Esempio n. 21
0
void stNvramTest()
{
    int temp_data[8] = {0};
    int full_0_data[8] = {0};
    int full_1_data[8] = {1,1,1,1,1,1,1,1};
    int i;
    int errno;
    errno = stNvramRead((void *)temp_data,8);
    if(temp_data[0] > 0)
    {
        stNvramDelay();
        DBG_BUFFER(MODULE_APP, LEVEL_INFO, ">> TEST_INFO   Data stored in test page >0: <<\r\n>>> TEST_INFO", 0);
        for(i = 0; i < 8; i++)
            DBG_BUFFER( MODULE_APP, LEVEL_INFO,"   %d",1, temp_data[i]);
        DBG_BUFFER( MODULE_APP, LEVEL_INFO,"<<\r\n>>> TEST_INFO   Store data to test page 2. <<\r\n>",0);
        //memcpy((void *)&temp_data,(void *)&test_full_0_data,sizeof(test_data_struct));
        errno = stNvramWrite((void *)full_0_data,8);
    }
    else
    {
        stNvramDelay();
        DBG_BUFFER(MODULE_APP, LEVEL_INFO, ">> TEST_INFO   Data stored in test page >0: <<\r\n>>> TEST_INFO", 0);
        for(i = 0; i < 8; i++)
            DBG_BUFFER( MODULE_APP, LEVEL_INFO,"   %d",1, temp_data[i]);
        DBG_BUFFER( MODULE_APP, LEVEL_INFO,"<<\r\n>>> TEST_INFO   Store data to test page 1. <<\r\n>",0);
        //memcpy((void *)&temp_data,(void *)&test_full_0_data,sizeof(test_data_struct));
        errno = stNvramWrite((void *)full_1_data,8);
    }
    DBG_BUFFER(MODULE_APP, LEVEL_INFO, ">> TEST_INFO   errno = %d <<\r\n>", 1, errno);
    return;
}
Esempio n. 22
0
/*
 * si4713_send_command - sends a command to si4713 and waits its response
 * @sdev: si4713_device structure for the device we are communicating
 * @command: command id
 * @args: command arguments we are sending (up to 7)
 * @argn: actual size of @args
 * @response: buffer to place the expected response from the device (up to 15)
 * @respn: actual size of @response
 * @usecs: amount of time to wait before reading the response (in usecs)
 */
static int si4713_send_command(struct si4713_device *sdev, const u8 command,
				const u8 args[], const int argn,
				u8 response[], const int respn, const int usecs)
{
	struct i2c_client *client = v4l2_get_subdevdata(&sdev->sd);
	u8 data1[MAX_ARGS + 1];
	int err;

	if (!client->adapter)
		return -ENODEV;

	/* First send the command and its arguments */
	data1[0] = command;
	memcpy(data1 + 1, args, argn);
	DBG_BUFFER(&sdev->sd, "Parameters", data1, argn + 1);

	err = i2c_master_send(client, data1, argn + 1);
	if (err != argn + 1) {
		v4l2_err(&sdev->sd, "Error while sending command 0x%02x\n",
			command);
		return (err > 0) ? -EIO : err;
	}

	/* Wait response from interrupt */
	if (!wait_for_completion_timeout(&sdev->work,
				usecs_to_jiffies(usecs) + 1))
		v4l2_warn(&sdev->sd,
				"(%s) Device took too much time to answer.\n",
				__func__);

	/* Then get the response */
	err = i2c_master_recv(client, response, respn);
	if (err != respn) {
		v4l2_err(&sdev->sd,
			"Error while reading response for command 0x%02x\n",
			command);
		return (err > 0) ? -EIO : err;
	}

	DBG_BUFFER(&sdev->sd, "Response", response, respn);
	if (check_command_failed(response[0]))
		return -EBUSY;

	return 0;
}
Esempio n. 23
0
/**
  * @brief  Used internal, start the discovery of Simple BLE characteristics descriptor.
  *         NOTE--user can offer this interface for application if required.
  * @retval TRUE--send request to upper stack success.
  *         FALSE--send request to upper stack failed.
  */
static bool SimpBleClient_StartCharDescriptorDiscovery( TCharDescriptorDiscReq charDescriptorReq )
{
    DBG_BUFFER(MODULE_PROFILE, LEVEL_INFO, "SimpBleClient_StartCharDescriptorDiscovery", 0);
    if( clientAPI_AllCharDescriptorDiscovery( SimpClient_ClientID, charDescriptorReq ) == ProfileResult_Success )
    {
        return TRUE;
    }
    return FALSE;
}
Esempio n. 24
0
/**
  * @brief send indication of simple indicate characteristic value.
  *
  * @param[in] ServiceId         service ID of service.
  * @param[in] value             characteristic value to indicate
  * @return notification action result
  * @retval 1 TRUE
  * @retval 0 FALSE
  */
bool SimpBleService_SimpleV4Indicate( uint8_t ServiceId, uint8_t value)
{
    uint8_t *pData = (uint8_t *)&value;
    uint16_t dataLen = sizeof(value);

    DBG_BUFFER(MODULE_PROFILE, LEVEL_INFO, "<-- SimpBleService_SimpleV4Indicate", 0 );
    // send indication to client
    return ProfileAPI_SendData(ServiceId, SIMPLE_BLE_SERVICE_CHAR_V4_INDICATE_INDEX, pData, dataLen);
}
Esempio n. 25
0
/******************************************************************
 * @fn          GAP_SendBtMsgToApp
 * @brief      send BEE_IO_MSG to app task.            
 * @param    pBeeMsgBlk  - pointer to BEE_IO_MSG message
 *
 * @return     void
 */
void GAP_SendBtMsgToApp(BEE_IO_MSG *pmsg)
{
    portBASE_TYPE result;
    uint8_t event = 0;

    result = xQueueSend(hIoQueueHandle, pmsg, 0xFFFF);
    if (result != pdPASS)
    {
        DBG_BUFFER(MODULE_PROFILE, LEVEL_ERROR, "GAP_SendBtMsgToApp fail2", 1, result);
    }

    event = EVENT_NEWIODRIVER_TO_APP;
    result = xQueueSend(hEventQueueHandle, &event, 0xFFFF);
    if (result != pdPASS)
    {
        DBG_BUFFER(MODULE_PROFILE, LEVEL_ERROR, "GAP_SendBtMsgToApp fail", 1, result);
    }
}
Esempio n. 26
0
void MeshBeaconTest()
{
    uint8_t testRxBeacon[14] = {0x7f, 0x28, 0x9a, 0x8c, 0x32, 0x18, 0x8a, 0x3e, 0x01, 0x02, 0xa6, 0xc2, 0x3b, 0xef};
    TMeshBeaconSecNwk meshBeacon;
    
    memcpy(&meshBeacon, testRxBeacon, 14);

    uint8_t encryption_key[16];
    uint8_t temp_mac[16];
    uint8_t mac[16];
    uint8_t smnb[4] = {'s', 'm', 'n', 'b'};
    uint8_t netID[16];
    MeshEncryptionKeyGet(encryption_key);
    MeshNetIDGet(netID);
    uint16_t ivi = MeshIVindexGet();
    uint16_t CIVI = 0;

    uint8_t kr = meshBeacon.kr_nid[0]&0x80;
    CIVI = LE_EXTRN2WORD((uint8_t*)&meshBeacon.civi);
        

    DBG_BUFFER(MODULE_APP, LEVEL_INFO, "RX  KR= %d", 1, kr);
    DBG_BUFFER(MODULE_APP, LEVEL_INFO, "RX  CIVI= 0x%x", 1, CIVI);

    uint8_t kr_nid_civi[19];
    memcpy(kr_nid_civi, &kr, 1);
    memcpy(kr_nid_civi+1, netID, 16);
    memcpy(kr_nid_civi+1+16, &CIVI, 2);
    DBG_BUFFER(MODULE_APP, LEVEL_INFO, "kr_nid_civi = ", 0);
    MeshShowKey(kr_nid_civi, 19);            

    AES_CMAC(encryption_key, kr_nid_civi, 19, temp_mac);

    DBG_BUFFER(MODULE_APP, LEVEL_INFO, "Temp Mac = ", 0);
    MeshShowKey(temp_mac, 16);//pointer to cmac, offset 10

    AES_CMAC(temp_mac, smnb, 4, mac);

    DBG_BUFFER(MODULE_APP, LEVEL_INFO, "Received Beacon Mac = ", 0);
    MeshShowKey((uint8_t*)&meshBeacon+ 10, 4);//pointer to cmac, offset 10

    DBG_BUFFER(MODULE_APP, LEVEL_INFO, "Calc Beacon Mac = ", 0);
    MeshShowKey(mac, 16);
    
    if(memcmp((uint8_t*)&meshBeacon+ 10, mac+12, 4) == 0)
    {
         DBG_BUFFER(MODULE_APP, LEVEL_INFO, "MAC MATCH", 0);               
    }
    else
    {
         DBG_BUFFER(MODULE_APP, LEVEL_ERROR, "MAC dis-match", 0);
    }

}
static void dualmode_HandleBtGapStateChangeEvt(uint8_t new_state)
{
    DBG_BUFFER(MODULE_APP, LEVEL_INFO, "dualmode_HandleBtGapStateChangeEvt: new state = %d", 1, new_state);

    switch (new_state)
    {
    case GAPSTATE_IDLE_NO_ADV_NO_CONN:
    {
        if (gapProfileState == GAPSTATE_CONNECTED)
        {
            uint8_t disc_reason;
            peripheralGetGapParameter(GAPPRRA_DISCONNECTED_REASON, &disc_reason);
            DBG_BUFFER(MODULE_APP, LEVEL_INFO, "dualmode_HandleBtGapStateChangeEvt: disc_reason = %d", 1, disc_reason);
#if RSC_SERVICE_EN
            RSC_SetParameter(RSC_PARAM_CTL_PNT_PROG_CLR, 0, NULL);
#endif
#if CSC_SERVICE_EN
            CSC_SetParameter(CSC_PARAM_CTL_PNT_PROG_CLR, 0, NULL);
#endif
            peripheral_StartAdvertising();
        }
        else
        {
            /* Link disconnect cause switch to this state. Set Bee to connectable mode */
            peripheral_StartAdvertising();
        }
    }
        break;

    case GAPSTATE_ADVERTISING:
        break;

    case GAPSTATE_CONNECTED:
        break;

    case GAPSTATE_CONNECTED_ADV:
        break;

    default:
        break;
    }

    gapProfileState = (gaprole_States_t)new_state;
}
Esempio n. 28
0
/**
  * @brief  Called by profile client layer, when notification or indication arrived.
  * @param  wHandle: handle of the value in received data.
  * @param  iValueSize: size of the value in received data.
  * @param  pValue: pointer to the value in received data.
  * @retval ProfileResult_Success--procedure OK.
  *         other--procedure exception.
  */
static TProfileResult SimpBleClientNotifIndResultCb( uint16_t wHandle, int iValueSize, uint8_t *pValue )
{    
    TAppResult appResult = AppResult_Success;
    TSimpClientCB_Data cb_data;
    cb_data.cb_type = SIMP_CLIENT_CB_TYPE_NOTIF_IND_RESULT;

    DBG_BUFFER(MODULE_PROFILE, LEVEL_INFO, "SimpBleClientNotifIndResultCb: handle = 0x%4.4x", 1, wHandle);

    if ( wHandle == SimpHdlCache[HDL_SIMBLE_V3_NOTIFY] )
    {
        if(iValueSize <= sizeof(uint8_t))
        {
            cb_data.cb_content.notif_ind_data.receive_type = SIMP_NOTIF_RECEIVE_V3_NOTIFY;
            cb_data.cb_content.notif_ind_data.receive_content.v3_notify = *(uint8_t *)pValue;
        }
        else
        {
            cb_data.cb_content.notif_ind_data.receive_type = SIMP_NOTIF_IND_RECEIVE_FAIL;
        }
    }
    else if( wHandle == SimpHdlCache[HDL_SIMBLE_V4_INDICATE] )
    {
        if(iValueSize <= sizeof(uint8_t))
        {
            cb_data.cb_content.notif_ind_data.receive_type = SIMP_IND_RECEIVE_V4_INDICATE;
            cb_data.cb_content.notif_ind_data.receive_content.v4_indicate = *(uint8_t *)pValue;
        }
        else
        {
            cb_data.cb_content.notif_ind_data.receive_type = SIMP_NOTIF_IND_RECEIVE_FAIL;
        }
    }
    else if( wHandle == SimpHdlCache[HDL_SIMBLE_V5_CTL_PNT] )
    {
        if(iValueSize <= 3)
        {
            cb_data.cb_content.notif_ind_data.receive_type = SIMP_IND_RECEIVE_V5_CTL_PNT;
            memcpy(cb_data.cb_content.notif_ind_data.receive_content.v5_control_point, pValue, iValueSize);
        }
        else
        {
            cb_data.cb_content.notif_ind_data.receive_type = SIMP_NOTIF_IND_RECEIVE_FAIL;
        }
    }
    else
    {
        cb_data.cb_content.notif_ind_data.receive_type = SIMP_NOTIF_IND_RECEIVE_FAIL;
    }
    /* Inform application the notif/ind result. */
    if(pfnSimpClientAppCB)
    {
        appResult = (*pfnSimpClientAppCB)(SimpClient_ClientID, &cb_data);
    }

    return (clientAPI_GetProfileResult(appResult));
}
Esempio n. 29
0
void HidsCccdUpdateCb(uint8_t ServiceId, uint16_t Index, uint16_t wCCCBits)
{
    THID_CALLBACK_DATA callback_data;
    callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
    
    bool bHandle = TRUE;
    DBG_BUFFER(MODULE_PROFILE, LEVEL_INFO, "HidsCccdUpdate  Index = %d wCCCDBits %x", 2, Index, wCCCBits);
    switch (Index)
    {
    case GATT_SRV_HID_KB_BOOT_CCCD_INDEX:
        {

        }
        break;

    case GATT_SRV_HID_KB_CCCD_INDEX:
        {
            if (wCCCBits & GATT_CCCD_NOTIFICATION_BIT)
            {
                // Enable Notification
                callback_data.msg_data.notification_indification_index = HID_NOTIFY_INDICATE_KB_ENABLE;

            }
            else
            {
                callback_data.msg_data.notification_indification_index = HID_NOTIFY_INDICATE_KB_DISABLE;
            }

            break;
        }
#ifdef MULTIMEDIA_KEYBOARD
    case GATT_SRV_HID_MM_KB_INPUT_CCCD_INDEX:
        if (wCCCBits & GATT_CCCD_NOTIFICATION_BIT)
        {
            // Enable Notification
            callback_data.msg_data.notification_indification_index = HID_NOTIFY_INDICATE_MM_KB_ENABLE;

        }
        else
        {
            callback_data.msg_data.notification_indification_index = HID_NOTIFY_INDICATE_MM_KB_DISABLE;
        }
        break;
#endif
    default:
        bHandle = false;
        break;
    }

    if (pfnHIDsCB && (bHandle == TRUE))
    {
        pfnHIDsCB(ServiceId, (void*)&callback_data);
    }

    return;
}
Esempio n. 30
0
/**
 * @brief write characteristic data from service.
 *
 * @param ServiceID          ServiceID to be written.
 * @param iAttribIndex          Attribute index of characteristic.
 * @param wLength            length of value to be written.
 * @param pValue            value to be written.
 * @return Profile procedure result
*/
TProfileResult SimpBleServiceAttrWriteCb(uint8_t ServiceId, uint16_t iAttribIndex, uint16_t wLength, uint8_t * pValue, TGATTDWriteIndPostProc * pWriteIndPostProc)
{
    TSIMP_CALLBACK_DATA callback_data;
    TProfileResult  wCause = ProfileResult_Success;
    if (SIMPLE_BLE_SERVICE_CHAR_V2_WRITE_INDEX == iAttribIndex)
    {
        /* Make sure written value size is valid. */
        if ( (wLength > sizeof(uint8_t)) || (pValue == NULL) )
        {
            wCause  = ProfileResult_InvalidValueSize;
        }
        else
        {
            /* Notify Application. */
            callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
            callback_data.msg_data.write.opcode = SIMP_WRITE_V2;
            callback_data.msg_data.write.value = pValue[0];
            
            if (pfnSimpBleServiceCB)
            {
                pfnSimpBleServiceCB(ServiceId, (void*)&callback_data);
            }
        }
    }
    else if (SIMPLE_BLE_SERVICE_CHAR_V5_CTL_PNT_INDEX == iAttribIndex)
    {
        /* Make sure written value size is valid. */
        if ( (wLength > sizeof(simpleCharCtlPntValue)) || (pValue == NULL) )
        {
            wCause  = ProfileResult_InvalidValueSize;
        }
        /* Make sure Control Point is not "Process already in progress". */
        else if ( SIMPLE_BLE_SERVICE_CTL_PNT_OPERATE_ACTIVE(simpleCharCtlPntValue[0]) )
        {
            wCause  = ProfileResult_AppErr_ProcAlreadyInProgress;
        }
        /* Make sure Control Point is configured indication enable. */
        else if (simpleCharCtlPntIndFlag != GATT_CLIENT_CHAR_CONFIG_INDICATE)
        {
            wCause = ProfileResult_AppErr_CccdImproperlyConfigured;
        }
        else
        {
            *pWriteIndPostProc = SimpBleService_CtlPntHandleReq;
        }
    }
    else
    {
        DBG_BUFFER(MODULE_PROFILE, LEVEL_ERROR, "--> SimpBleServiceAttrWriteCb Error  iAttribIndex = 0x%x wLength=%d",
                   2,
                   iAttribIndex,
                   wLength);
        wCause = ProfileResult_AttrNotFound;
    }
    return wCause;
}