/********************************** (C) COPYRIGHT *******************************
* File Name          : gattprofile.C
* Author             : WCH
* Version            : V1.0
* Date               : 2018/12/10
* Description        : 自定义包含五种不同属性的服务，包含可读、可写、通知、可读可写、安全可读
            
*******************************************************************************/

/*********************************************************************
 * INCLUDES
 */
//#include "CONFIG.h"
#include "gattprofile.h"
#include "net.h"
#include "peripheral.h"
#include "aLiYun.h"
#include "SPI_SRAM.h"
/*********************************************************************
 * MACROS
 */

/*********************************************************************
 * CONSTANTS
 */

// Position of simpleProfilechar4 value in attribute array
#define SIMPLEPROFILE_CHAR4_VALUE_POS            11

/*********************************************************************
 * TYPEDEFS
 */
BLE_SEND_INFO         ble_send_info = {0};

BLE_DEVICE_CONFIG*   Ble_Device_Info_Ptr = NULL;                   //读取配置信息后再分配

/*********************************************************************
 * 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)
};



// GAP GATT Attributes
uint8 attDeviceName[BLE_DEVICE_NAME_LEN] = "BLV-C1 RCU:8888";


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_WRITE;

// Characteristic 1 Value
static uint8 simpleProfileChar1[SIMPLEPROFILE_CHAR1_LEN] = { 0 };

// Simple Profile Characteristic 1 User Description
static uint8 simpleProfileChar1UserDesp[] = "Characteristic 1\0";


// Simple Profile Characteristic 2 Properties
//static uint8 simpleProfileChar2Props = GATT_PROP_READ;
static uint8 simpleProfileChar2Props = GATT_PROP_READ | GATT_PROP_WRITE;

// Characteristic 2 Value
static uint8 simpleProfileChar2[SIMPLEPROFILE_CHAR2_LEN] = {192,168,1,202};

// Simple Profile Characteristic 2 User Description
static uint8 simpleProfileChar2UserDesp[] = "Characteristic 2, R/W ip addr\0";


// Simple Profile Characteristic 3 Properties
static uint8 simpleProfileChar3Props = GATT_PROP_READ | GATT_PROP_WRITE;

// Characteristic 3 Value
//static uint8 simpleProfileChar3[SIMPLEPROFILE_CHAR3_LEN] = { 0 };

// Simple Profile Characteristic 3 User Description
static uint8 simpleProfileChar3UserDesp[] = "Characteristic 3 R/W dev_name MAXlen:20\0";


// 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[4];
                                        
// Simple Profile Characteristic 4 User Description
static uint8 simpleProfileChar4UserDesp[] = "Characteristic 4\0";


// Simple Profile Characteristic 5 Properties
static uint8 simpleProfileChar5Props = GATT_PROP_READ | GATT_PROP_WRITE;

// Characteristic 5 Value
static uint8 simpleProfileChar5[SIMPLEPROFILE_CHAR5_LEN] = { 0 };

// Simple Profile Characteristic 5 User Description
static uint8 simpleProfileChar5UserDesp[] = "Characteristic 5 R/W DHCP ENABLE\0";


/*********************************************************************
 * Profile Attributes - Table
 */

static gattAttribute_t simpleProfileAttrTbl[] = 
{
  /*******************服务**************************************************************************************************/
  { 
    { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
    GATT_PERMIT_READ,                         /* permissions */
    0,                                        /* handle */
    (uint8 *)&simpleProfileService            /* pValue */  //FFE0
  },

    /*****************特征1*************************************************************/
    { 
      { ATT_BT_UUID_SIZE, characterUUID },
      GATT_PERMIT_READ, 
      0,
      &simpleProfileChar1Props                //只写
    },

      // Characteristic Value 1
      { 
        { ATT_BT_UUID_SIZE, simpleProfilechar1UUID },    //FFE1
        GATT_PERMIT_WRITE, 
        0, 
        simpleProfileChar1                               //需要写的数据
      },

      // Characteristic 1 User Description
      { 
        { ATT_BT_UUID_SIZE, charUserDescUUID },
        GATT_PERMIT_READ, 
        0, 
        simpleProfileChar1UserDesp                     //配置特征1用户描述
      },      

    /*****************特征2*************************************************************/
    { 
      { ATT_BT_UUID_SIZE, characterUUID },
      GATT_PERMIT_READ, 
      0,
      &simpleProfileChar2Props                          //读写属性 
    },

      // Characteristic Value 2
      { 
        { ATT_BT_UUID_SIZE, simpleProfilechar2UUID },   //0xFFE2
        GATT_PERMIT_READ | GATT_PERMIT_WRITE, 
        0, 
        simpleProfileChar2                              //需要读取的数据(本机ip地址)
      },

      // Characteristic 2 User Description
      { 
        { ATT_BT_UUID_SIZE, charUserDescUUID },
        GATT_PERMIT_READ, 
        0, 
        simpleProfileChar2UserDesp                     //配置特征2用户描述
      },           
      
    /*****************特征3*************************************************************/
    { 
      { ATT_BT_UUID_SIZE, characterUUID },
      GATT_PERMIT_READ, 
      0,
      &simpleProfileChar3Props                        //读写属性
    },

      // Characteristic Value 3
      { 
        { ATT_BT_UUID_SIZE, simpleProfilechar3UUID },  //0xFFE3
        GATT_PERMIT_READ | GATT_PERMIT_WRITE, 
        0, 
        attDeviceName                             //需要写的数据 
//				&dataFlash_save_t.scanRspData[2]
      },

      // Characteristic 3 User Description
      { 
        { ATT_BT_UUID_SIZE, charUserDescUUID },
        GATT_PERMIT_READ, 
        0, 
        simpleProfileChar3UserDesp                   //配置特征3用户描述
      },

    /*****************特征4*************************************************************/
    { 
      { ATT_BT_UUID_SIZE, characterUUID },
      GATT_PERMIT_READ, 
      0,
      &simpleProfileChar4Props                       //通知属性
    },

      // Characteristic Value 4
      { 
        { ATT_BT_UUID_SIZE, simpleProfilechar4UUID },  //0xFFE4
        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                    //配置特征4用户描述
      },
      
    /*****************特征5*************************************************************/
    { 
      { ATT_BT_UUID_SIZE, characterUUID },
      GATT_PERMIT_READ, 
      0,
      &simpleProfileChar5Props                       //读写属性 
    },

      // Characteristic Value 5
      { 
        { ATT_BT_UUID_SIZE, simpleProfilechar5UUID },      //0xFFE5
        GATT_PERMIT_READ | GATT_PERMIT_WRITE,              //读写
        0, 
        simpleProfileChar5                            //需要读取的数据
      },

      // Characteristic 5 User Description
      { 
        { ATT_BT_UUID_SIZE, charUserDescUUID },
        GATT_PERMIT_READ, 
        0, 
        simpleProfileChar5UserDesp                   //配置特征5用户描述
      },
};

/*********************************************************************
 * LOCAL FUNCTIONS
 */
static bStatus_t simpleProfile_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr, 
                            uint8 *pValue, uint16 *pLen, uint16 offset, uint16 maxLen,uint8 method );
static bStatus_t simpleProfile_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
                                 uint8 *pValue, uint16 len, uint16 offset,uint8 method );

static void simpleProfile_HandleConnStatusCB( uint16 connHandle, uint8 changeType );


/*********************************************************************
 * PROFILE CALLBACKS
 */
// Simple Profile Service Callbacks
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 = SUCCESS;

  // Initialize Client Characteristic Configuration attributes
	//初始化客户端特征配置属性
  GATTServApp_InitCharCfg( INVALID_CONNHANDLE, simpleProfileChar4Config );  

  // Register with Link DB to receive link status change callback
  linkDB_Register( simpleProfile_HandleConnStatusCB );     //使用此函数注册以在连接状态发生更改时接收回调。
  
  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 );
  }

  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 right
 * @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 ) 
      {
        tmos_memcpy( simpleProfileChar1, value, SIMPLEPROFILE_CHAR1_LEN );
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    case SIMPLEPROFILE_CHAR2:
      if ( len == SIMPLEPROFILE_CHAR2_LEN ) 
      {
        tmos_memcpy( simpleProfileChar2, value, SIMPLEPROFILE_CHAR2_LEN );
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    case SIMPLEPROFILE_CHAR3:
      if ( len < BLE_DEVICE_NAME_LEN ) 
      {
//        tmos_memcpy( &dataFlash_save_t.scanRspData[2], value, len );   //设置名字
				tmos_memcpy( attDeviceName, value, len );   //设置名字
      }
      else
      {
//        tmos_memcpy( &dataFlash_save_t.scanRspData[2], value, BLE_DEVICE_NAME_LEN );   //设置名字
				tmos_memcpy( attDeviceName, value, BLE_DEVICE_NAME_LEN );   //设置名字
      }
      break;

    case SIMPLEPROFILE_CHAR4:
      if ( len == SIMPLEPROFILE_CHAR4_LEN ) 
      {
        tmos_memcpy( simpleProfileChar4, value, SIMPLEPROFILE_CHAR4_LEN );
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    case SIMPLEPROFILE_CHAR5:
      if ( len == SIMPLEPROFILE_CHAR5_LEN ) 
      {
        tmos_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:
      tmos_memcpy( value, simpleProfileChar1, SIMPLEPROFILE_CHAR1_LEN );
      break;

    case SIMPLEPROFILE_CHAR2:
      tmos_memcpy( value, simpleProfileChar2, SIMPLEPROFILE_CHAR2_LEN );
      break;      

    case SIMPLEPROFILE_CHAR3:
//      tmos_memcpy( value, &dataFlash_save_t.scanRspData[2], dataFlash_save_t.bleName_len );      //读取设备名
			tmos_memcpy( value, attDeviceName, strlen((char*)attDeviceName) );      //读取设备名
      break;  

    case SIMPLEPROFILE_CHAR4:
      tmos_memcpy( value, simpleProfileChar4, SIMPLEPROFILE_CHAR4_LEN );
      break;

    case SIMPLEPROFILE_CHAR5:
      tmos_memcpy( value, simpleProfileChar5, SIMPLEPROFILE_CHAR5_LEN );
      break;      
      
    default:
      ret = INVALIDPARAMETER;
      break;
  }
  
  return ( ret );
}

/*********************************************************************
 * @fn          simpleProfile_Notify
 *
 * @brief       Send a notification containing a heart rate
 *              measurement.
 *
 * @param       connHandle - connection handle
 * @param       pNoti - pointer to notification structure
 *
 * @return      Success or Failure
 */
bStatus_t simpleProfile_Notify( uint16 connHandle, attHandleValueNoti_t *pNoti )
{
  uint16 value = GATTServApp_ReadCharCfg( connHandle, simpleProfileChar4Config );

  // If notifications enabled
  if ( value & GATT_CLIENT_CFG_NOTIFY )
  {
    // Set the handle
    pNoti->handle = simpleProfileAttrTbl[SIMPLEPROFILE_CHAR4_VALUE_POS].handle;
  
    // Send the notification
    return GATT_Notification( connHandle, pNoti, FALSE );
  }
  return bleIncorrectMode;
}

/*********************************************************************
 * @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
 *
 * @return      Success or Failure
 */
static bStatus_t simpleProfile_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr, 
                            uint8 *pValue, uint16 *pLen, uint16 offset, uint16 maxLen,uint8 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 )
  {
    // 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:
        *pLen = SIMPLEPROFILE_CHAR1_LEN;
        tmos_memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR1_LEN );
        break;
      
      case SIMPLEPROFILE_CHAR2_UUID:
        *pLen = SIMPLEPROFILE_CHAR2_LEN;
        tmos_memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR2_LEN );
        break;
			
			case SIMPLEPROFILE_CHAR3_UUID:
        *pLen = strlen((char*)attDeviceName);
//				*pLen = dataFlash_save_t.bleName_len;
        tmos_memcpy( pValue, pAttr->pValue, *pLen );
        break;
      
      case SIMPLEPROFILE_CHAR4_UUID:
        *pLen = SIMPLEPROFILE_CHAR4_LEN;
        tmos_memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR4_LEN );
        break;
      
      case SIMPLEPROFILE_CHAR5_UUID:
        *pLen = SIMPLEPROFILE_CHAR5_LEN;
        tmos_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
 *
 * @return  Success or Failure
 */
static bStatus_t simpleProfile_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
                                 uint8 *pValue, uint16 len, uint16 offset,uint8 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 )
  {
    // 16-bit UUID
    uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
    switch ( uuid )
    {
      case SIMPLEPROFILE_CHAR1_UUID:
        //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;
        }
        
        //Write the value
        if ( status == SUCCESS )
        {
          tmos_memcpy( pAttr->pValue, pValue, SIMPLEPROFILE_CHAR1_LEN );
					if(ble_send_info.BLE_WriteAddr != NULL )
					{
						SRAM_Write_Byte(len, ble_send_info.BLE_WriteAddr);               //接收长度
						SRAM_Write_Buff(pValue, len, ble_send_info.BLE_WriteAddr +1);   //数据内容
						
						ble_send_info.BLE_WriteAddr += BLE_BUFF_MAX_LEN;
						if(ble_send_info.BLE_WriteAddr >= SRAM_BLE_RECEIVE_END)
						{
							ble_send_info.BLE_WriteAddr = SRAM_BLE_RECEIVE_START;
						}
					}
          notifyApp = SIMPLEPROFILE_CHAR1;        
        }            
        break;
				
			case SIMPLEPROFILE_CHAR2_UUID:
				if ( offset == 0 )
        {
          if ( len > SIMPLEPROFILE_CHAR2_LEN )
          {
            status = ATT_ERR_INVALID_VALUE_SIZE;
          }
        }
        else
        {
          status = ATT_ERR_ATTR_NOT_LONG;
        }
        
        //Write the value
        if ( status == SUCCESS )
        {
//					if(server_info.ip_auto_flg == 1)                                    //允许手动修改ip
//					{
//						//tmos_memcpy( pAttr->pValue, pValue, SIMPLEPROFILE_CHAR2_LEN );
//						if(memcmp(net_info.local_ip, pValue, SIMPLEPROFILE_CHAR2_LEN) != 0)    //ble修改ip，不同，重启网络
//						{
//							memcpy(net_info.local_ip, pValue, SIMPLEPROFILE_CHAR2_LEN);
//							Dbg_Print(DBG_BIT_NET_STATUS_bit,"ble, NetWork_Restart!\n");
//							NetWork_Restart();        //重启网络
//							server_info.ble_setip_flg = 1;                                 //标记ble修改ip
//						}
//						notifyApp = SIMPLEPROFILE_CHAR2;
//					}
//					else status = ATT_ERR_WRITE_NOT_PERMITTED;
        }      
				
			break;
        
      case SIMPLEPROFILE_CHAR3_UUID:
        //Validate the value
        // Make sure it's not a blob oper
        if ( offset == 0 )
        {
//          if ( len > BLE_DEVICE_NAME_LEN )
//          {
//            status = ATT_ERR_INVALID_VALUE_SIZE;
//          }
        }
        else
        {
          status = ATT_ERR_ATTR_NOT_LONG;
        }
        
        //Write the value
        if ( status == SUCCESS )
        {
					if ( len >= BLE_DEVICE_NAME_LEN )
					{
						tmos_memcpy( pAttr->pValue, pValue, BLE_DEVICE_NAME_LEN );
//						Set_BleDevice_Name(pValue, BLE_DEVICE_NAME_LEN);
					}
					else
					{
						tmos_memset(pAttr->pValue, 0, BLE_DEVICE_NAME_LEN);
						tmos_memcpy( pAttr->pValue, pValue, len );
						
//						Set_BleDevice_Name(pValue, len);
					}
					
          notifyApp = SIMPLEPROFILE_CHAR3;        
        }            
        break;
				
			case SIMPLEPROFILE_CHAR5_UUID:
				if ( offset == 0 )
        {
          if ( len > SIMPLEPROFILE_CHAR5_LEN )
          {
            status = ATT_ERR_INVALID_VALUE_SIZE;
          }
        }
        else
        {
          status = ATT_ERR_ATTR_NOT_LONG;
        }
        
        //Write the value
        if ( status == SUCCESS )
				{
//					tmos_memcpy( pAttr->pValue, pValue, SIMPLEPROFILE_CHAR5_LEN );      //修改ip获取方式
//					server_info.ip_auto_flg = *pValue;
          notifyApp = SIMPLEPROFILE_CHAR5; 
				}
				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 charactersitic value changed then callback function to notify application of change
  if ( (notifyApp != 0xFF ) && simpleProfile_AppCBs && simpleProfile_AppCBs->pfnSimpleProfileChange )
  {
    simpleProfile_AppCBs->pfnSimpleProfileChange( notifyApp );  
  }
  
  return ( status );
}

/*********************************************************************
 * @fn          simpleProfile_HandleConnStatusCB
 *
 * @brief       Simple Profile link status change handler function.
 *
 * @param       connHandle - connection handle
 * @param       changeType - type of change
 *
 * @return      none
 */
static void simpleProfile_HandleConnStatusCB( uint16 connHandle, uint8 changeType )
{ 
  // Make sure this is not loopback connection
	//确保这不是环回连接
  if ( connHandle != LOOPBACK_CONNHANDLE )
  {
    // Reset Client Char Config if connection has dropped
		//如果连接已断开，则重置客户端字符配置
    if ( ( changeType == LINKDB_STATUS_UPDATE_REMOVED )      ||
         ( ( changeType == LINKDB_STATUS_UPDATE_STATEFLAGS ) && 
           ( !linkDB_Up( connHandle ) ) ) )
    { 
      GATTServApp_InitCharCfg( connHandle, simpleProfileChar4Config );
    }
  }
}

/*****************************************
*函数名：Ble_Parameter_Init
*作  用：蓝牙参数初始化
*返回值：无
*****************************************/
void Ble_Parameter_Init()
{
	ble_send_info.BLE_WriteAddr = SRAM_BLE_RECEIVE_START;
	ble_send_info.BLE_ReadAddr  = SRAM_BLE_RECEIVE_START;
	ble_send_info.BLE_SendAddr  = SRAM_BLE_SEND_START;
}

/*****************************************
*函数名：Ble_Recive_Task
*作  用：蓝牙接收处理，主循环调用
*返回值：无
*****************************************/
void Ble_Recive_Task(void)
{
	if(ble_send_info.BLE_ReadAddr != ble_send_info.BLE_WriteAddr)
	{
		uint8_t len = SRAM_Read_Byte(ble_send_info.BLE_ReadAddr);
		uint8_t* data = malloc(len);
		if(data == NULL)    return;
		SRAM_Read_Buff(data, len, ble_send_info.BLE_ReadAddr +1);   //数据内容
		PRINT("Ble Recive data: %s, len: %d\r\n", data, len);     //数据处理
		
//		if(mqtt_info.con_flag)    //已连接阿里云
//		MQTT_Publish(mqtt_info.mqtt_socket, mqtt_info.pub_topic, (uint8*)data, len, 0);    //把蓝牙数据发送到阿里云
		free(data);
//		if(ble_send_info.send_flg == 0)
//		{
//			memcpy(ble_send_info.sendDATA, &BLE_ReadAddr[1], BLE_ReadAddr[0]);     //发送给蓝牙从机
//			ble_send_info.sendLEN = BLE_ReadAddr[0];
//			ble_send_info.ble_type = BLE_TYPE_PERIPHERAL;
//			ble_send_info.device_type = 0x01;                   //设备类型
//			ble_send_info.device_addr = 0x00;                   //设备地址
//			ble_send_info.char_uuid   = SIMPLEPROFILE_CHAR1_UUID;
//			ble_send_info.send_flg = 1;
//		}
		
		ble_send_info.BLE_ReadAddr += BLE_BUFF_MAX_LEN;
		if(ble_send_info.BLE_ReadAddr > SRAM_BLE_RECEIVE_END)
		{
			ble_send_info.BLE_ReadAddr = SRAM_BLE_RECEIVE_START;
		}
	}
}

/*********************************************************************
*********************************************************************/
