<commit_before>/* mbed Microcontroller Library
 * Copyright (c) 2017-2017 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <algorithm>
#include "CordioBLE.h"
#include "CordioGattServer.h"
#include "mbed.h"
#include "wsf_types.h"
#include "att_api.h"

namespace ble {
namespace vendor {
namespace cordio {

namespace {

static UUID CCCD_UUID(BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG);
static const uint16_t CCCD_SIZE = sizeof(uint16_t);

static const unsigned int READ_PROPERTY =
    GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ;
static const unsigned int WRITE_PROPERTY =
    GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE;
static const unsigned int WRITE_WITHOUT_RESPONSE_PROPERTY =
    GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE;
static const unsigned int SIGNED_WRITE_PROPERTY =
    GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_AUTHENTICATED_SIGNED_WRITES;
static const unsigned int NOTIFY_PROPERTY =
    GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY;
static const unsigned int INDICATE_PROPERTY =
    GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE;

static const uint8_t WRITABLE_PROPERTIES =
    WRITE_PROPERTY |
    WRITE_WITHOUT_RESPONSE_PROPERTY |
    SIGNED_WRITE_PROPERTY;

static const uint8_t UPDATE_PROPERTIES =
    NOTIFY_PROPERTY |
    INDICATE_PROPERTY;

static const uint16_t CONNECTION_ID_LIMIT = 0x100;

} // end of anonymous namespace

GattServer &GattServer::getInstance()
{
    static GattServer m_instance;
    return m_instance;
}

void GattServer::initialize()
{
    AttsAuthorRegister(atts_auth_cb);
    add_generic_access_service();
    add_generic_attribute_service();
}

ble_error_t GattServer::addService(GattService &service)
{
    // create and fill the service structure
    internal_service_t *att_service = new internal_service_t;
    att_service->attGroup.pNext = NULL;
    att_service->attGroup.readCback = atts_read_cb;
    att_service->attGroup.writeCback = atts_write_cb;

    // Determine the attribute list length
    uint16_t attributes_count = compute_attributes_count(service);

    // Create cordio attribute list
    att_service->attGroup.pAttr =
        (attsAttr_t*) alloc_block(attributes_count * sizeof(attsAttr_t));
    if (att_service->attGroup.pAttr == NULL) {
        return BLE_ERROR_BUFFER_OVERFLOW;
    }

    // insert every element in the iterator
    attsAttr_t *attribute_it = att_service->attGroup.pAttr;

    /* Service */
    insert_service_attribute(service, attribute_it);
    att_service->attGroup.startHandle = currentHandle;
    service.setHandle(currentHandle);

    /* Add characteristics to the service */
    for (int i = 0; i < service.getCharacteristicCount(); i++) {
        ble_error_t err = insert_characteristic(
            service.getCharacteristic(i),
            attribute_it
        );
        if (err) {
            // FIXME: proper cleanup of data structure:
            //   - att_service->attGroup.pAttr
            //   - blocks allocated for characteristics value
            // NOTE: those are rightfully released when reset() is called.
            delete att_service;
            return err;
        }
    }
    att_service->attGroup.endHandle = currentHandle;

    // add the service to the list of registered services<commit_msg>Cordio BLE: Fix potential memory leak in GattServer.<commit_after>/* mbed Microcontroller Library
 * Copyright (c) 2017-2017 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <algorithm>
#include "CordioBLE.h"
#include "CordioGattServer.h"
#include "mbed.h"
#include "wsf_types.h"
#include "att_api.h"

namespace ble {
namespace vendor {
namespace cordio {

namespace {

static UUID CCCD_UUID(BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG);
static const uint16_t CCCD_SIZE = sizeof(uint16_t);

static const unsigned int READ_PROPERTY =
    GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ;
static const unsigned int WRITE_PROPERTY =
    GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE;
static const unsigned int WRITE_WITHOUT_RESPONSE_PROPERTY =
    GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE;
static const unsigned int SIGNED_WRITE_PROPERTY =
    GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_AUTHENTICATED_SIGNED_WRITES;
static const unsigned int NOTIFY_PROPERTY =
    GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY;
static const unsigned int INDICATE_PROPERTY =
    GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE;

static const uint8_t WRITABLE_PROPERTIES =
    WRITE_PROPERTY |
    WRITE_WITHOUT_RESPONSE_PROPERTY |
    SIGNED_WRITE_PROPERTY;

static const uint8_t UPDATE_PROPERTIES =
    NOTIFY_PROPERTY |
    INDICATE_PROPERTY;

static const uint16_t CONNECTION_ID_LIMIT = 0x100;

} // end of anonymous namespace

GattServer &GattServer::getInstance()
{
    static GattServer m_instance;
    return m_instance;
}

void GattServer::initialize()
{
    AttsAuthorRegister(atts_auth_cb);
    add_generic_access_service();
    add_generic_attribute_service();
}

ble_error_t GattServer::addService(GattService &service)
{
    // create and fill the service structure
    internal_service_t *att_service = new internal_service_t;
    att_service->attGroup.pNext = NULL;
    att_service->attGroup.readCback = atts_read_cb;
    att_service->attGroup.writeCback = atts_write_cb;

    // Determine the attribute list length
    uint16_t attributes_count = compute_attributes_count(service);

    // Create cordio attribute list
    att_service->attGroup.pAttr =
        (attsAttr_t*) alloc_block(attributes_count * sizeof(attsAttr_t));
    if (att_service->attGroup.pAttr == NULL) {
        delete att_service;
        return BLE_ERROR_BUFFER_OVERFLOW;
    }

    // insert every element in the iterator
    attsAttr_t *attribute_it = att_service->attGroup.pAttr;

    /* Service */
    insert_service_attribute(service, attribute_it);
    att_service->attGroup.startHandle = currentHandle;
    service.setHandle(currentHandle);

    /* Add characteristics to the service */
    for (int i = 0; i < service.getCharacteristicCount(); i++) {
        ble_error_t err = insert_characteristic(
            service.getCharacteristic(i),
            attribute_it
        );
        if (err) {
            // FIXME: proper cleanup of data structure:
            //   - att_service->attGroup.pAttr
            //   - blocks allocated for characteristics value
            // NOTE: those are rightfully released when reset() is called.
            delete att_service;
            return err;
        }
    }
    att_service->attGroup.endHandle = currentHandle;

    // add the service to the list of registered services
{'fraction_non_alphanumeric': 0.07333593851765012, 'fraction_numerical': 0.007033997655334115, 'mean_word_length': 3.9186418962203717, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7591116', 'n_tokens_mistral': 2351, 'n_tokens_neox': 2288, 'n_words': 596}