BLECharacteristicImp::BLECharacteristicImp(const bt_uuid_t* uuid, 
                                           unsigned char properties,
                                           uint16_t handle,
                                           const BLEDevice& bledevice):
    BLEAttribute(uuid, BLETypeCharacteristic),
    _value_length(0),
    _value_buffer(NULL),
    _value_updated(false),
    _value_handle(handle),
    _cccd_handle(0),
    _attr_chrc_value(NULL),
    _attr_cccd(NULL),
    _subscribed(false),
    _reading(false),
    _ble_device()
{
    _value_size = BLE_MAX_ATTR_DATA_LEN;// Set as MAX value. TODO: long read/write need to twist
    _value = (unsigned char*)malloc(_value_size);

    // TODO: Enable when max value is not set.
    //    if (_value_size > BLE_MAX_ATTR_DATA_LEN)
    //    {
    //        _value_buffer = (unsigned char*)malloc(_value_size);
    //    }

    if (_value)
    {
      memset(_value, 0, _value_size);
    }
    else
    {
        errno = ENOMEM;
    }
    
    memset(&_ccc_cfg, 0, sizeof(_ccc_cfg));
    memset(&_ccc_value, 0, sizeof(_ccc_value));
    memset(&_gatt_chrc, 0, sizeof(_gatt_chrc));
    memset(&_sub_params, 0, sizeof(_sub_params));
    memset(&_discover_params, 0, sizeof(_discover_params));
    
    _ccc_value.cfg = &_ccc_cfg;
    _ccc_value.cfg_len = 1;
    if (BLERead & properties)
    {
        _gatt_chrc.properties |= BT_GATT_CHRC_READ;
    }
    if (BLEWrite & properties)
    {
        _gatt_chrc.properties |= BT_GATT_CHRC_WRITE;
    }
    if (BLEWriteWithoutResponse & properties)
    {
        _gatt_chrc.properties |= BT_GATT_CHRC_WRITE_WITHOUT_RESP;
    }
    if (BLENotify & properties)
    {
        _gatt_chrc.properties |= BT_GATT_CHRC_NOTIFY;
        _sub_params.value |= BT_GATT_CCC_NOTIFY;
    }
    if (BLEIndicate & properties)
    {
        _gatt_chrc.properties |= BT_GATT_CHRC_INDICATE;
        _sub_params.value |= BT_GATT_CCC_INDICATE;
    }
    _gatt_chrc.uuid = (bt_uuid_t*)this->bt_uuid();//&_characteristic_uuid;//this->uuid();
    memset(_event_handlers, 0, sizeof(_event_handlers));
    memset(_oldevent_handlers, 0, sizeof(_oldevent_handlers));
    
    _sub_params.notify = profile_notify_process;
        
    // Update BLE device object
    _ble_device.setAddress(*bledevice.bt_le_address());
    
    memset(&_descriptors_header, 0, sizeof(_descriptors_header));
}
BLECharacteristicImp::BLECharacteristicImp(BLECharacteristic& characteristic, 
                                           const BLEDevice& bledevice):
    BLEAttribute(characteristic.uuid(), BLETypeCharacteristic),
    _value_length(0),
    _value_buffer(NULL),
    _value_updated(false),
    _value_handle(0),
    _cccd_handle(0),
    _attr_chrc_value(NULL),
    _attr_cccd(NULL),
    _subscribed(false),
    _reading(false),
    _ble_device()
{
    unsigned char properties = characteristic._properties;
    _value_size = characteristic._value_size;
    _value = (unsigned char*)malloc(_value_size);
    if (_value == NULL)
    {
        errno = ENOMEM;
    }
    if (_value_size > BLE_MAX_ATTR_DATA_LEN)
    {
        _value_buffer = (unsigned char*)malloc(_value_size);
    }
    
    memset(&_ccc_cfg, 0, sizeof(_ccc_cfg));
    memset(&_ccc_value, 0, sizeof(_ccc_value));
    memset(&_gatt_chrc, 0, sizeof(_gatt_chrc));
    memset(&_sub_params, 0, sizeof(_sub_params));
    memset(&_discover_params, 0, sizeof(_discover_params));
    
    _ccc_value.cfg = &_ccc_cfg;
    _ccc_value.cfg_len = 1;
    if (BLERead & properties)
    {
        _gatt_chrc.properties |= BT_GATT_CHRC_READ;
    }
    if (BLEWrite & properties)
    {
        _gatt_chrc.properties |= BT_GATT_CHRC_WRITE;
    }
    if (BLEWriteWithoutResponse & properties)
    {
        _gatt_chrc.properties |= BT_GATT_CHRC_WRITE_WITHOUT_RESP;
    }
    if (BLENotify & properties)
    {
        _gatt_chrc.properties |= BT_GATT_CHRC_NOTIFY;
        _sub_params.value |= BT_GATT_CCC_NOTIFY;
    }
    if (BLEIndicate & properties)
    {
        _gatt_chrc.properties |= BT_GATT_CHRC_INDICATE;
        _sub_params.value |= BT_GATT_CCC_INDICATE;
    }
    _gatt_chrc.uuid = (bt_uuid_t*)this->bt_uuid();//&_characteristic_uuid;//this->uuid();

    memcpy(_event_handlers, characteristic._event_handlers, sizeof(_event_handlers));
    memcpy(_oldevent_handlers, characteristic._oldevent_handlers, sizeof(_oldevent_handlers));
    
    _sub_params.notify = profile_notify_process;
    
    if (NULL != characteristic._value)
    {
        memcpy(_value, characteristic._value, _value_size);
    }
        
    // Update BLE device object
    _ble_device.setAddress(*bledevice.bt_le_address());
    
    characteristic.setBLECharacteristicImp(this);
    memset(&_descriptors_header, 0, sizeof(_descriptors_header));
}