ble_error_t MaximGattServer::addService(GattService &service) { currentHandle = (currentHandle + 0xF) & ~0xF; uint16_t startHandle = currentHandle; mxmService_t *mxmSvc = new mxmService_t; // Create WiCentric attribute group mxmSvc->attGroup = new attsGroup_t; // Determine the attribute list length unsigned int attListLen = 1; for (int i = 0; i < service.getCharacteristicCount(); i++) { attListLen += 2; GattCharacteristic *p_char = service.getCharacteristic(i); if (p_char->getProperties() & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) { // add a CCCD attListLen++; } } // Create WiCentric attribute list mxmSvc->attGroup->pAttr = (attsAttr_t*)malloc(attListLen * sizeof(attsAttr_t));; if (mxmSvc->attGroup->pAttr == NULL) { return BLE_ERROR_BUFFER_OVERFLOW; } // Create characteristics mxmSvc->chars = new mxmChar_t [service.getCharacteristicCount()]; attsAttr_t *currAtt = mxmSvc->attGroup->pAttr; /* Service */ currAtt->pUuid = attPrimSvcUuid; if (service.getUUID().shortOrLong() == UUID::UUID_TYPE_LONG) { mxmSvc->uuidLen = UUID::LENGTH_OF_LONG_UUID; } else { mxmSvc->uuidLen = sizeof(UUID::ShortUUIDBytes_t); } currAtt->pValue = (uint8_t*)malloc(mxmSvc->uuidLen); memcpy(currAtt->pValue, service.getUUID().getBaseUUID(), mxmSvc->uuidLen); currAtt->maxLen = mxmSvc->uuidLen; currAtt->pLen = &mxmSvc->uuidLen; currAtt->settings = 0; currAtt->permissions = ATTS_PERMIT_READ; currAtt++; /* Add characteristics to the service */ for (int i = 0; i < service.getCharacteristicCount(); i++) { GattCharacteristic *p_char = service.getCharacteristic(i); /* Skip any incompletely defined, read-only characteristics. */ if ((p_char->getValueAttribute().getValuePtr() == NULL) && (p_char->getValueAttribute().getLength() == 0) && (p_char->getProperties() == GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ)) { continue; } // Create Characteristic Attribute currentHandle += 2; currAtt->pUuid = attChUuid; p_char->getValueAttribute().setHandle(currentHandle); mxmSvc->chars[i].descLen = 1 + sizeof(currentHandle) + p_char->getValueAttribute().getUUID().getLen(); currAtt->pValue = (uint8_t*)malloc(mxmSvc->chars[i].descLen); uint8_t *pValue = currAtt->pValue; *pValue++ = p_char->getProperties(); memcpy(pValue, ¤tHandle, sizeof(currentHandle)); pValue += sizeof(currentHandle); memcpy(pValue, p_char->getValueAttribute().getUUID().getBaseUUID(), p_char->getValueAttribute().getUUID().getLen()); currAtt->pLen = &mxmSvc->chars[i].descLen; currAtt->maxLen = mxmSvc->chars[i].descLen; currAtt->settings = 0; currAtt->permissions = ATTS_PERMIT_READ; currAtt++; // Create Value Attribute currAtt->pUuid = p_char->getValueAttribute().getUUID().getBaseUUID(); currAtt->pValue = p_char->getValueAttribute().getValuePtr(); currAtt->pLen = p_char->getValueAttribute().getLengthPtr(); currAtt->maxLen = p_char->getValueAttribute().getMaxLength(); currAtt->settings = ATTS_SET_WRITE_CBACK | ATTS_SET_READ_CBACK; if (p_char->getValueAttribute().getUUID().shortOrLong() == UUID::UUID_TYPE_LONG) { currAtt->settings |= ATTS_SET_UUID_128; } currAtt->permissions = 0; if (p_char->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ) { currAtt->permissions |= ATTS_PERMIT_READ; } if (p_char->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE) { currAtt->permissions |= ATTS_PERMIT_WRITE; } currAtt++; bool cccCreated = false; for (int i = 0; i < p_char->getDescriptorCount(); i++) { GattAttribute *p_att = p_char->getDescriptor(i); currentHandle++; currAtt->pUuid = p_att->getUUID().getBaseUUID(); currAtt->pValue = p_att->getValuePtr(); currAtt->pLen = p_att->getLengthPtr(); currAtt->maxLen = p_att->getMaxLength(); currAtt->settings = 0; currAtt->permissions = 0; if (p_att->getUUID().shortOrLong() == UUID::UUID_TYPE_LONG) { currAtt->settings |= ATTS_SET_UUID_128; } if (p_att->getUUID() == UUID(BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG)) { cccCreated = true; currAtt->settings |= ATTS_SET_CCC; currAtt->permissions |= ATTS_PERMIT_READ; currAtt->permissions |= ATTS_PERMIT_WRITE; if (cccCnt < MAX_CCC_CNT) { cccSet[cccCnt].handle = currentHandle; cccSet[cccCnt].valueRange = 0; if (p_char->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) { cccSet[cccCnt].valueRange |= ATT_CLIENT_CFG_NOTIFY; } if (p_char->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE) { cccSet[cccCnt].valueRange |= ATT_CLIENT_CFG_INDICATE; } cccSet[cccCnt].secLevel = DM_SEC_LEVEL_NONE; cccHandles[cccCnt] = p_char->getValueAttribute().getHandle(); cccCnt++; } else { return BLE_ERROR_PARAM_OUT_OF_RANGE; } } currAtt++; } if (!cccCreated && (p_char->getProperties() & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) { /* There was not a CCCD included in the descriptors, but this * characteristic is notifiable and/or indicatable. A CCCD is * required so create one now. */ if (cccCnt >= MAX_CCC_CNT) { return BLE_ERROR_PARAM_OUT_OF_RANGE; } currentHandle++; currAtt->pUuid = cccUUID.getBaseUUID(); currAtt->pValue = (uint8_t*)&cccValues[cccCnt]; currAtt->pLen = (uint16_t*)&cccSize; currAtt->maxLen = sizeof(uint16_t); currAtt->settings = ATTS_SET_CCC; currAtt->permissions = (ATTS_PERMIT_READ | ATTS_PERMIT_WRITE); cccSet[cccCnt].handle = currentHandle; cccSet[cccCnt].valueRange = 0; if (p_char->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) { cccSet[cccCnt].valueRange |= ATT_CLIENT_CFG_NOTIFY; } if (p_char->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE) { cccSet[cccCnt].valueRange |= ATT_CLIENT_CFG_INDICATE; } cccSet[cccCnt].secLevel = DM_SEC_LEVEL_NONE; cccHandles[cccCnt] = p_char->getValueAttribute().getHandle(); cccCnt++; currAtt++; } } mxmSvc->attGroup->pNext = NULL; mxmSvc->attGroup->readCback = attsReadCback; mxmSvc->attGroup->writeCback = attsWriteCback; mxmSvc->attGroup->startHandle = startHandle; mxmSvc->attGroup->endHandle = currentHandle; AttsAddGroup(mxmSvc->attGroup); AttRegister(attCback); AttsCccRegister(cccCnt, (attsCccSet_t*)cccSet, cccCback); return BLE_ERROR_NONE; }
void BLE::stack_setup() { MBED_ASSERT(_hci_driver != NULL); wsfHandlerId_t handlerId; buf_pool_desc_t buf_pool_desc = _hci_driver->get_buffer_pool_description(); // use the buffer for the WSF heap SystemHeapStart = buf_pool_desc.buffer_memory; SystemHeapSize = buf_pool_desc.buffer_size; // Initialize buffers with the ones provided by the HCI driver uint16_t bytes_used = WsfBufInit(buf_pool_desc.pool_count, (wsfBufPoolDesc_t*)buf_pool_desc.pool_description); // Raise assert if not enough memory was allocated MBED_ASSERT(bytes_used != 0); SystemHeapStart += bytes_used; SystemHeapSize -= bytes_used; // This warning will be raised if we've allocated too much memory if(bytes_used < buf_pool_desc.buffer_size) { MBED_WARNING1(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_INVALID_SIZE), "Too much memory allocated for Cordio memory pool, reduce buf_pool_desc.buffer_size by value below.", buf_pool_desc.buffer_size - bytes_used); } WsfTimerInit(); // Note: SecInit required for RandInit. SecInit(); SecRandInit(); #if BLE_FEATURE_SECURITY SecAesInit(); SecCmacInit(); SecEccInit(); #endif handlerId = WsfOsSetNextHandler(HciHandler); HciHandlerInit(handlerId); handlerId = WsfOsSetNextHandler(DmHandler); #if BLE_ROLE_BROADCASTER DmAdvInit(); #endif #if BLE_ROLE_OBSERVER DmScanInit(); #endif #if BLE_FEATURE_CONNECTABLE DmConnInit(); #endif #if BLE_ROLE_CENTRAL DmConnMasterInit(); #endif #if BLE_ROLE_PERIPHERAL DmConnSlaveInit(); #endif #if BLE_FEATURE_SECURITY DmSecInit(); #endif #if BLE_FEATURE_PHY_MANAGEMENT DmPhyInit(); #endif #if BLE_FEATURE_SECURE_CONNECTIONS DmSecLescInit(); #endif #if BLE_FEATURE_PRIVACY DmPrivInit(); #endif DmHandlerInit(handlerId); #if BLE_ROLE_PERIPHERAL handlerId = WsfOsSetNextHandler(L2cSlaveHandler); L2cSlaveHandlerInit(handlerId); #endif #if BLE_FEATURE_CONNECTABLE L2cInit(); #endif #if BLE_ROLE_PERIPHERAL L2cSlaveInit(); #endif #if BLE_ROLE_CENTRAL L2cMasterInit(); #endif #if BLE_FEATURE_ATT handlerId = WsfOsSetNextHandler(AttHandler); AttHandlerInit(handlerId); #if BLE_FEATURE_GATT_SERVER AttsInit(); AttsIndInit(); #if BLE_FEATURE_SECURITY AttsAuthorRegister(GattServer::atts_auth_cb); #endif #if BLE_FEATURE_SIGNING AttsSignInit(); #endif #endif // BLE_FEATURE_GATT_SERVER #if BLE_FEATURE_GATT_CLIENT AttcInit(); #if BLE_FEATURE_SIGNING AttcSignInit(); #endif #endif // BLE_FEATURE_GATT_CLIENT #endif // BLE_FEATURE_ATT #if BLE_FEATURE_SECURITY handlerId = WsfOsSetNextHandler(SmpHandler); SmpHandlerInit(handlerId); #if BLE_ROLE_PERIPHERAL SmprInit(); #if BLE_FEATURE_SECURE_CONNECTIONS SmprScInit(); #endif #endif #if BLE_ROLE_CENTRAL SmpiInit(); #if BLE_FEATURE_SECURE_CONNECTIONS SmpiScInit(); #endif #endif // BLE_ROLE_CENTRAL #endif // BLE_FEATURE_SECURITY stack_handler_id = WsfOsSetNextHandler(&BLE::stack_handler); HciSetMaxRxAclLen(100); DmRegister(BLE::device_manager_cb); #if BLE_FEATURE_CONNECTABLE DmConnRegister(DM_CLIENT_ID_APP, BLE::device_manager_cb); #endif #if BLE_FEATURE_GATT_SERVER AttConnRegister(BLE::connection_handler); #endif #if BLE_FEATURE_ATT #if BLE_FEATURE_GATT_CLIENT AttRegister((attCback_t) ble::pal::vendor::cordio::CordioAttClient::att_client_handler); #else AttRegister((attCback_t) ble::vendor::cordio::GattServer::att_cb); #endif // BLE_FEATURE_GATT_CLIENT #endif }