mbed HRM11017を使ってkonashi.jsでナイトライダー

Dependencies:   BLE_API_Native_IRC mbed

Fork of BLE_RCBController by Junichi Katsu

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers nRF51GattServer.cpp Source File

nRF51GattServer.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2013 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016   
00017 #include "nRF51GattServer.h"
00018 #include "mbed.h"
00019 
00020 #include "common/common.h "
00021 #include "btle/custom/custom_helper.h"
00022 
00023 /**************************************************************************/
00024 /*!
00025     @brief  Adds a new service to the GATT table on the peripheral
00026             
00027     @returns    ble_error_t
00028     
00029     @retval     BLE_ERROR_NONE
00030                 Everything executed properly
00031                 
00032     @section EXAMPLE
00033 
00034     @code
00035 
00036     @endcode
00037 */
00038 /**************************************************************************/
00039 ble_error_t nRF51GattServer::addService(GattService & service)
00040 {
00041     /* ToDo: Make sure we don't overflow the array, etc. */
00042     /* ToDo: Make sure this service UUID doesn't already exist (?) */
00043     /* ToDo: Basic validation */
00044     
00045     /* Add the service to the nRF51 */
00046     ble_uuid_t uuid;
00047 
00048     if (service.primaryServiceID.type == UUID::UUID_TYPE_SHORT)
00049     {
00050       /* 16-bit BLE UUID */
00051       uuid.type = BLE_UUID_TYPE_BLE;
00052     }
00053     else
00054     {
00055       /* 128-bit Custom UUID */
00056       uuid.type = custom_add_uuid_base( service.primaryServiceID.base );
00057     }
00058 
00059     uuid.uuid = service.primaryServiceID.value;
00060 
00061     ASSERT( ERROR_NONE == sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &uuid, &service.handle), BLE_ERROR_PARAM_OUT_OF_RANGE );
00062 
00063     /* Add characteristics to the service */
00064     for (uint8_t i = 0; i < service.characteristicCount; i++)
00065     {
00066       GattCharacteristic * p_char = service.characteristics[i];
00067 
00068       uuid.uuid = p_char->uuid;
00069       ASSERT ( ERROR_NONE == custom_add_in_characteristic(service.handle, &uuid, p_char->properties,
00070                                                           NULL, p_char->lenMin, p_char->lenMax, &nrfCharacteristicHandles[characteristicCount]), BLE_ERROR_PARAM_OUT_OF_RANGE );
00071         
00072       /* Update the characteristic handle */
00073       p_char->handle = characteristicCount;
00074       p_characteristics[characteristicCount++] = p_char;
00075     }
00076 
00077     serviceCount++;
00078     
00079     return BLE_ERROR_NONE;
00080 }
00081 
00082 /**************************************************************************/
00083 /*!
00084     @brief  Reads the value of a characteristic, based on the service
00085             and characteristic index fields
00086 
00087     @param[in]  charHandle
00088                 The handle of the GattCharacteristic to read from
00089     @param[in]  buffer
00090                 Buffer to hold the the characteristic's value
00091                 (raw byte array in LSB format)
00092     @param[in]  len
00093                 The number of bytes read into the buffer
00094             
00095     @returns    ble_error_t
00096     
00097     @retval     BLE_ERROR_NONE
00098                 Everything executed properly
00099                 
00100     @section EXAMPLE
00101 
00102     @code
00103 
00104     @endcode
00105 */
00106 /**************************************************************************/
00107 ble_error_t nRF51GattServer::readValue(uint16_t charHandle, uint8_t buffer[], uint16_t len)
00108 {
00109     ASSERT( ERROR_NONE == sd_ble_gatts_value_get(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), BLE_ERROR_PARAM_OUT_OF_RANGE);
00110     
00111     return BLE_ERROR_NONE;
00112 }
00113 
00114 /**************************************************************************/
00115 /*!
00116     @brief  Updates the value of a characteristic, based on the service
00117             and characteristic index fields
00118 
00119     @param[in]  charHandle
00120                 The handle of the GattCharacteristic to write to
00121     @param[in]  buffer
00122                 Data to use when updating the characteristic's value
00123                 (raw byte array in LSB format)
00124     @param[in]  len
00125                 The number of bytes in buffer
00126             
00127     @returns    ble_error_t
00128     
00129     @retval     BLE_ERROR_NONE
00130                 Everything executed properly
00131                 
00132     @section EXAMPLE
00133 
00134     @code
00135 
00136     @endcode
00137 */
00138 /**************************************************************************/
00139 ble_error_t nRF51GattServer::updateValue(uint16_t charHandle, uint8_t buffer[], uint16_t len)
00140 {
00141   if ((p_characteristics[charHandle]->properties & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)) &&
00142       (m_connectionHandle != BLE_CONN_HANDLE_INVALID) )
00143   {
00144     /* HVX update for the characteristic value */
00145     ble_gatts_hvx_params_t hvx_params;
00146 
00147     hvx_params.handle = nrfCharacteristicHandles[charHandle].value_handle;
00148     hvx_params.type   = (p_characteristics[charHandle]->properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)  ? BLE_GATT_HVX_NOTIFICATION : BLE_GATT_HVX_INDICATION;
00149     hvx_params.offset = 0;
00150     hvx_params.p_data = buffer;
00151     hvx_params.p_len  = &len;
00152 
00153     error_t error = (error_t) sd_ble_gatts_hvx(m_connectionHandle, &hvx_params);
00154 
00155     /* ERROR_INVALID_STATE, ERROR_BUSY, ERROR_GATTS_SYS_ATTR_MISSING and ERROR_NO_TX_BUFFERS the ATT table has been updated. */
00156     if ( (error != ERROR_NONE                      ) && (error != ERROR_INVALID_STATE) &&
00157          (error != ERROR_BLE_NO_TX_BUFFERS         ) && (error != ERROR_BUSY         ) &&
00158          (error != ERROR_BLEGATTS_SYS_ATTR_MISSING ) )
00159     {
00160       ASSERT_INT( ERROR_NONE, sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), BLE_ERROR_PARAM_OUT_OF_RANGE );
00161     }
00162   } else
00163   {
00164     ASSERT_INT( ERROR_NONE, sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), BLE_ERROR_PARAM_OUT_OF_RANGE );
00165   }
00166     
00167   return BLE_ERROR_NONE;
00168 }
00169 
00170 /**************************************************************************/
00171 /*!
00172     @brief  Callback handler for events getting pushed up from the SD
00173 */
00174 /**************************************************************************/
00175 void nRF51GattServer::hwCallback(ble_evt_t * p_ble_evt)
00176 {
00177   uint16_t handle_value;
00178   GattServerEvents::gattEvent_t event;
00179 
00180   switch (p_ble_evt->header.evt_id)
00181   {
00182     case BLE_GATTS_EVT_WRITE:
00183       /* There are 2 use case here: Values being updated & CCCD (indicate/notify) enabled */
00184       
00185       /* 1.) Handle CCCD changes */
00186       handle_value = p_ble_evt->evt.gatts_evt.params.write.handle;
00187       for(uint8_t i=0; i<characteristicCount; i++)
00188       {
00189         if ( (p_characteristics[i]->properties & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)) &&
00190              (nrfCharacteristicHandles[i].cccd_handle == handle_value) )
00191         {
00192           uint16_t cccd_value = (p_ble_evt->evt.gatts_evt.params.write.data[1] << 8) | p_ble_evt->evt.gatts_evt.params.write.data[0]; /* Little Endian but M0 may be mis-aligned */
00193 
00194           if ( ((p_characteristics[i]->properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE) && (cccd_value & BLE_GATT_HVX_INDICATION  )) ||
00195                ((p_characteristics[i]->properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY  ) && (cccd_value & BLE_GATT_HVX_NOTIFICATION)))
00196           {
00197             event = GattServerEvents::GATT_EVENT_UPDATES_ENABLED;
00198           } else
00199           {
00200             event = GattServerEvents::GATT_EVENT_UPDATES_DISABLED;
00201           }
00202 
00203           handleEvent(event, i);
00204           return;
00205         }
00206       }
00207 
00208       /* 2.) Changes to the characteristic value will be handled with other events below */
00209       event = GattServerEvents::GATT_EVENT_DATA_WRITTEN;
00210       break;
00211 
00212     case BLE_GATTS_EVT_HVC:
00213       /* Indication confirmation received */
00214       event        = GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED;
00215       handle_value = p_ble_evt->evt.gatts_evt.params.hvc.handle;
00216       break;
00217 
00218     default: 
00219       return;
00220   }
00221 
00222   /* Find index (charHandle) in the pool */
00223   for(uint8_t i=0; i<characteristicCount; i++)
00224   {
00225     if (nrfCharacteristicHandles[i].value_handle == handle_value)
00226     {
00227       handleEvent(event, i);
00228       break;
00229     }
00230   }
00231 }