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