Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of nRF51822 by
custom_helper.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 "custom_helper.h" 00018 00019 /* 00020 * The current version of the soft-device doesn't handle duplicate 128-bit UUIDs 00021 * very well. It is therefore necessary to filter away duplicates before 00022 * passing long UUIDs to sd_ble_uuid_vs_add(). The following types and data 00023 * structures involved in maintaining a local cache of 128-bit UUIDs. 00024 */ 00025 typedef struct { 00026 LongUUID_t uuid; 00027 uint8_t type; 00028 } converted_uuid_table_entry_t; 00029 static const unsigned UUID_TABLE_MAX_ENTRIES = 8; /* This is the maximum number 00030 * of 128-bit UUIDs with distinct bases that 00031 * we expect to be in use; increase this 00032 * limit if needed. */ 00033 static unsigned uuidTableEntries = 0; /* current usage of the table */ 00034 converted_uuid_table_entry_t convertedUUIDTable[UUID_TABLE_MAX_ENTRIES]; 00035 00036 /** 00037 * lookup the cache of previously converted 128-bit UUIDs to find a type value. 00038 * @param uuid long UUID 00039 * @param recoveredType the type field of the 3-byte nRF's uuid. 00040 * @return true if a match is found. 00041 */ 00042 static bool 00043 lookupConvertedUUIDTable(const LongUUID_t uuid, uint8_t *recoveredType) 00044 { 00045 unsigned i; 00046 for (i = 0; i < uuidTableEntries; i++) { 00047 if (memcmp(convertedUUIDTable[i].uuid, 00048 uuid, 00049 LENGTH_OF_LONG_UUID) == 0) { 00050 *recoveredType = convertedUUIDTable[i].type; 00051 return true; 00052 } 00053 } 00054 00055 return false; 00056 } 00057 00058 static void 00059 addToConvertedUUIDTable(const LongUUID_t uuid, uint8_t type) 00060 { 00061 if (uuidTableEntries == UUID_TABLE_MAX_ENTRIES) { 00062 return; /* recovery needed; or at least the user should be 00063 * warned about this fact.*/ 00064 } 00065 00066 memcpy(convertedUUIDTable[uuidTableEntries].uuid, uuid,LENGTH_OF_LONG_UUID); 00067 convertedUUIDTable[uuidTableEntries].type = type; 00068 uuidTableEntries++; 00069 } 00070 00071 /** 00072 * The nRF transport has its own 3-byte representation of a UUID. If the user- 00073 * specified UUID is 128-bits wide, then the UUID base needs to be added to the 00074 * soft-device and converted to a 3-byte handle before being used further. This 00075 * function is responsible for this translation of user-specified UUIDs into 00076 * nRF's representation. 00077 * 00078 * @param[in] uuid 00079 * user-specified UUID 00080 * @return nRF 00081 * 3-byte UUID (containing a type and 16-bit UUID) representation 00082 * to be used with SVC calls. 00083 */ 00084 ble_uuid_t custom_convert_to_nordic_uuid(const UUID &uuid) 00085 { 00086 ble_uuid_t nordicUUID = { 00087 .uuid = uuid.getShortUUID(), 00088 .type = BLE_UUID_TYPE_UNKNOWN /* to be set below */ 00089 }; 00090 00091 if (uuid.shortOrLong() == UUID::UUID_TYPE_SHORT) { 00092 nordicUUID.type = BLE_UUID_TYPE_BLE; 00093 } else { 00094 if (!lookupConvertedUUIDTable(uuid.getBaseUUID(), &nordicUUID.type)) { 00095 nordicUUID.type = custom_add_uuid_base(uuid.getBaseUUID()); 00096 addToConvertedUUIDTable(uuid.getBaseUUID(), nordicUUID.type); 00097 } 00098 } 00099 00100 return nordicUUID; 00101 } 00102 00103 /**************************************************************************/ 00104 /*! 00105 @brief Adds the base UUID to the custom service. All UUIDs used 00106 by this service are based on this 128-bit UUID. 00107 00108 @note This UUID needs to be added to the SoftDevice stack before 00109 adding the service's primary service via 00110 'sd_ble_gatts_service_add' 00111 00112 @param[in] p_uuid_base A pointer to the 128-bit UUID array (8*16) 00113 00114 @returns The UUID type. 00115 A return value of 0 should be considered an error. 00116 00117 @retval 0x00 BLE_UUID_TYPE_UNKNOWN 00118 @retval 0x01 BLE_UUID_TYPE_BLE 00119 @retval 0x02 BLE_UUID_TYPE_VENDOR_BEGIN 00120 00121 @section EXAMPLE 00122 @code 00123 00124 // Take note that bytes 2/3 are blank since these are used to identify 00125 // the primary service and individual characteristics 00126 #define CFG_CUSTOM_UUID_BASE "\x6E\x40\x00\x00\xB5\xA3\xF3\x93\xE0\xA9\xE5\x0E\x24\xDC\xCA\x9E" 00127 00128 uint8_t uuid_type = custom_add_uuid_base(CFG_CUSTOM_UUID_BASE); 00129 ASSERT(uuid_type > 0, ERROR_NOT_FOUND); 00130 00131 // We can now safely add the primary service and any characteristics 00132 // for our custom service ... 00133 00134 @endcode 00135 */ 00136 /**************************************************************************/ 00137 uint8_t custom_add_uuid_base(uint8_t const *const p_uuid_base) 00138 { 00139 ble_uuid128_t base_uuid; 00140 uint8_t uuid_type = 0; 00141 00142 /* Reverse the bytes since ble_uuid128_t is LSB */ 00143 for (uint8_t i = 0; i<16; i++) { 00144 base_uuid.uuid128[i] = p_uuid_base[15 - i]; 00145 } 00146 00147 ASSERT_INT( ERROR_NONE, sd_ble_uuid_vs_add( &base_uuid, &uuid_type ), 0); 00148 00149 return uuid_type; 00150 } 00151 00152 /**************************************************************************/ 00153 /*! 00154 00155 */ 00156 /**************************************************************************/ 00157 error_t custom_decode_uuid_base(uint8_t const *const p_uuid_base, 00158 ble_uuid_t *p_uuid) 00159 { 00160 LongUUID_t uuid_base_le; 00161 00162 /* Reverse the bytes since ble_uuid128_t is LSB */ 00163 for (uint8_t i = 0; i<16; i++) { 00164 uuid_base_le[i] = p_uuid_base[15 - i]; 00165 } 00166 00167 ASSERT_STATUS( sd_ble_uuid_decode(16, uuid_base_le, p_uuid)); 00168 00169 return ERROR_NONE; 00170 } 00171 00172 /**************************************************************************/ 00173 /*! 00174 @brief Adds a new characteristic to the custom service, assigning 00175 properties, a UUID add-on value, etc. 00176 00177 @param[in] service_handle 00178 @param[in] p_uuid The 16-bit value to add to the base UUID 00179 for this characteristic (normally >1 00180 since 1 is typically used by the primary 00181 service). 00182 @param[in] char_props The characteristic properties, as 00183 defined by ble_gatt_char_props_t 00184 @param[in] max_length The maximum length of this characeristic 00185 @param[in] p_char_handle 00186 00187 @returns 00188 @retval ERROR_NONE Everything executed normally 00189 */ 00190 /**************************************************************************/ 00191 error_t custom_add_in_characteristic(uint16_t service_handle, 00192 ble_uuid_t *p_uuid, 00193 uint8_t properties, 00194 uint8_t *p_data, 00195 uint16_t min_length, 00196 uint16_t max_length, 00197 ble_gatts_char_handles_t *p_char_handle) 00198 { 00199 /* Characteristic metadata */ 00200 ble_gatts_attr_md_t cccd_md; 00201 ble_gatt_char_props_t char_props; 00202 00203 memcpy(&char_props, &properties, 1); 00204 00205 if (char_props.notify || char_props.indicate) { 00206 /* Notification requires cccd */ 00207 memclr_( &cccd_md, sizeof(ble_gatts_attr_md_t)); 00208 cccd_md.vloc = BLE_GATTS_VLOC_STACK; 00209 BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); 00210 BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm); 00211 } 00212 00213 ble_gatts_char_md_t char_md = {0}; 00214 00215 char_md.char_props = char_props; 00216 char_md.p_cccd_md = 00217 (char_props.notify || char_props.indicate) ? &cccd_md : NULL; 00218 00219 /* Attribute declaration */ 00220 ble_gatts_attr_md_t attr_md = {0}; 00221 00222 attr_md.vloc = BLE_GATTS_VLOC_STACK; 00223 attr_md.vlen = (min_length == max_length) ? 0 : 1; 00224 00225 if (char_props.read || char_props.notify || char_props.indicate) { 00226 BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); 00227 } 00228 00229 if (char_props.write) { 00230 BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); 00231 } 00232 00233 ble_gatts_attr_t attr_char_value = {0}; 00234 00235 attr_char_value.p_uuid = p_uuid; 00236 attr_char_value.p_attr_md = &attr_md; 00237 attr_char_value.init_len = min_length; 00238 attr_char_value.max_len = max_length; 00239 attr_char_value.p_value = p_data; 00240 00241 ASSERT_STATUS ( sd_ble_gatts_characteristic_add(service_handle, 00242 &char_md, 00243 &attr_char_value, 00244 p_char_handle)); 00245 00246 return ERROR_NONE; 00247 }
Generated on Tue Jul 12 2022 19:00:52 by
