Initial release

Fork of nrf51-sdk by Lancaster University

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ble_advdata.c Source File

ble_advdata.c

00001 /*
00002  * Copyright (c) Nordic Semiconductor ASA
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without modification,
00006  * are permitted provided that the following conditions are met:
00007  *
00008  *   1. Redistributions of source code must retain the above copyright notice, this
00009  *   list of conditions and the following disclaimer.
00010  *
00011  *   2. Redistributions in binary form must reproduce the above copyright notice, this
00012  *   list of conditions and the following disclaimer in the documentation and/or
00013  *   other materials provided with the distribution.
00014  *
00015  *   3. Neither the name of Nordic Semiconductor ASA nor the names of other
00016  *   contributors to this software may be used to endorse or promote products
00017  *   derived from this software without specific prior written permission.
00018  *
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00021  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00022  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00023  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
00024  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00025  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00026  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00027  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00028  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00029  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030  *
00031  */
00032 
00033 #include "ble_advdata.h "
00034 #include "nordic_common.h"
00035 #include "nrf_error.h"
00036 #include "ble_gap.h"
00037 #include "ble_srv_common.h "
00038 #include "app_util.h "
00039 
00040 // NOTE: For now, Security Manager Out of Band Flags (OOB) are omitted from the advertising data.
00041 
00042 // Types of LE Bluetooth Device Address AD type
00043 #define AD_TYPE_BLE_DEVICE_ADDR_TYPE_PUBLIC 0UL
00044 #define AD_TYPE_BLE_DEVICE_ADDR_TYPE_RANDOM 1UL
00045 
00046 static uint32_t tk_value_encode(ble_advdata_tk_value_t * p_tk_value,
00047                                 uint8_t                * p_encoded_data,
00048                                 uint16_t               * p_offset,
00049                                 uint16_t                 max_size)
00050 {
00051     int8_t i;
00052 
00053     // Check for buffer overflow.
00054     if (((*p_offset) + AD_TYPE_TK_VALUE_SIZE) > max_size)
00055     {
00056         return NRF_ERROR_DATA_SIZE;
00057     }
00058 
00059     // Encode LE Role.
00060     p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_TK_VALUE_DATA_SIZE);
00061     *p_offset                 += ADV_LENGTH_FIELD_SIZE;
00062     p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE;
00063     *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
00064 
00065     for (i = AD_TYPE_TK_VALUE_DATA_SIZE - 1; i >= 0; i--, (*p_offset)++)
00066     {
00067         p_encoded_data[*p_offset] = p_tk_value->tk[i];
00068     }
00069 
00070     return NRF_SUCCESS;
00071 }
00072 
00073 static uint32_t le_role_encode(ble_advdata_le_role_t   le_role,
00074                                uint8_t               * p_encoded_data,
00075                                uint16_t              * p_offset,
00076                                uint16_t                max_size)
00077 {
00078     // Check for buffer overflow.
00079     if (((*p_offset) + AD_TYPE_LE_ROLE_SIZE) > max_size)
00080     {
00081         return NRF_ERROR_DATA_SIZE;
00082     }
00083 
00084     // Encode LE Role.
00085     p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_LE_ROLE_DATA_SIZE);
00086     *p_offset                 += ADV_LENGTH_FIELD_SIZE;
00087     p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_LE_ROLE;
00088     *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
00089     switch(le_role)
00090     {
00091         case BLE_ADVDATA_ROLE_ONLY_PERIPH:
00092             p_encoded_data[*p_offset] = 0;
00093             break;
00094         case BLE_ADVDATA_ROLE_ONLY_CENTRAL:
00095             p_encoded_data[*p_offset] = 1;
00096             break;
00097         case BLE_ADVDATA_ROLE_BOTH_PERIPH_PREFERRED:
00098             p_encoded_data[*p_offset] = 2;
00099             break;
00100         case BLE_ADVDATA_ROLE_BOTH_CENTRAL_PREFERRED:
00101             p_encoded_data[*p_offset] = 3;
00102             break;
00103         default:
00104             return NRF_ERROR_INVALID_PARAM;
00105     }
00106     *p_offset += AD_TYPE_LE_ROLE_DATA_SIZE;
00107 
00108     return NRF_SUCCESS;
00109 }
00110 
00111 static uint32_t ble_device_addr_encode(uint8_t  * p_encoded_data,
00112                                        uint16_t * p_offset,
00113                                        uint16_t   max_size)
00114 {
00115     uint32_t err_code;
00116     ble_gap_addr_t device_addr;
00117 
00118     // Check for buffer overflow.
00119     if (((*p_offset) + AD_TYPE_BLE_DEVICE_ADDR_SIZE) > max_size)
00120     {
00121         return NRF_ERROR_DATA_SIZE;
00122     }
00123 
00124     // Get BLE address
00125     err_code = sd_ble_gap_address_get(&device_addr);
00126     if (err_code != NRF_SUCCESS)
00127     {
00128         return err_code;
00129     }
00130 
00131     // Encode LE Bluetooth Device Address
00132     p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE +
00133                                                AD_TYPE_BLE_DEVICE_ADDR_DATA_SIZE);
00134     *p_offset                 += ADV_LENGTH_FIELD_SIZE;
00135     p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS;
00136     *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
00137     memcpy(&p_encoded_data[*p_offset], &device_addr.addr[0], BLE_GAP_ADDR_LEN);
00138     *p_offset                 += BLE_GAP_ADDR_LEN;
00139     if(BLE_GAP_ADDR_TYPE_PUBLIC == device_addr.addr_type)
00140     {
00141         p_encoded_data[*p_offset] = AD_TYPE_BLE_DEVICE_ADDR_TYPE_PUBLIC;
00142     }
00143     else
00144     {
00145         p_encoded_data[*p_offset] = AD_TYPE_BLE_DEVICE_ADDR_TYPE_RANDOM;
00146     }
00147     *p_offset += AD_TYPE_BLE_DEVICE_ADDR_TYPE_SIZE;
00148 
00149     return NRF_SUCCESS;
00150 }
00151 
00152 static uint32_t name_encode(const ble_advdata_t * p_advdata,
00153                             uint8_t             * p_encoded_data,
00154                             uint16_t            * p_offset,
00155                             uint16_t              max_size)
00156 {
00157     uint32_t err_code;
00158     uint16_t rem_adv_data_len;
00159     uint16_t actual_length;
00160     uint8_t  adv_data_format;
00161 
00162 
00163     // Validate parameters
00164     if((BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) && (0 == p_advdata->short_name_len))
00165     {
00166         return NRF_ERROR_INVALID_PARAM;
00167     }
00168 
00169     // Check for buffer overflow.
00170     if ( (((*p_offset) + ADV_AD_DATA_OFFSET) > max_size) ||
00171          ( (BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) &&
00172            (((*p_offset) + ADV_AD_DATA_OFFSET + p_advdata->short_name_len) > max_size)))
00173     {
00174         return NRF_ERROR_DATA_SIZE;
00175     }
00176 
00177     rem_adv_data_len = max_size - (*p_offset) - ADV_AD_DATA_OFFSET;
00178     actual_length    = rem_adv_data_len;
00179 
00180     // Get GAP device name and length
00181     err_code = sd_ble_gap_device_name_get(&p_encoded_data[(*p_offset) + ADV_AD_DATA_OFFSET],
00182                                           &actual_length);
00183     if (err_code != NRF_SUCCESS)
00184     {
00185         return err_code;
00186     }
00187     
00188     // Check if device intend to use short name and it can fit available data size.
00189     if ((p_advdata->name_type == BLE_ADVDATA_FULL_NAME) && (actual_length <= rem_adv_data_len))
00190     {
00191         // Complete device name can fit, setting Complete Name in Adv Data.
00192         adv_data_format = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME;
00193     }
00194     else
00195     {
00196         // Else short name needs to be used. Or application has requested use of short name.
00197         adv_data_format = BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME;
00198 
00199         // If application has set a preference on the short name size, it needs to be considered,
00200         // else fit what can be fit.
00201         if ((BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) &&
00202                 (p_advdata->short_name_len <= rem_adv_data_len))
00203         {
00204             // Short name fits available size.
00205             actual_length = p_advdata->short_name_len;
00206         }
00207         // Else whatever can fit the data buffer will be packed.
00208         else
00209         {
00210             actual_length = rem_adv_data_len;
00211         }
00212     }
00213 
00214     // There is only 1 byte intended to encode length which is (actual_length + ADV_AD_TYPE_FIELD_SIZE)
00215     if(actual_length > (0x00FF - ADV_AD_TYPE_FIELD_SIZE))
00216     {
00217         return NRF_ERROR_DATA_SIZE;
00218     }
00219 
00220     // Complete name field in encoded data.
00221     p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + actual_length);
00222     *p_offset                 += ADV_LENGTH_FIELD_SIZE;
00223     p_encoded_data[*p_offset]  = adv_data_format;
00224     *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
00225     *p_offset                 += actual_length;
00226 
00227     return NRF_SUCCESS;
00228 }
00229 
00230 
00231 static uint32_t appearance_encode(uint8_t  * p_encoded_data,
00232                                   uint16_t * p_offset,
00233                                   uint16_t   max_size)
00234 {
00235     uint32_t err_code;
00236     uint16_t appearance;
00237 
00238     // Check for buffer overflow.
00239     if (((*p_offset) + AD_TYPE_APPEARANCE_SIZE) > max_size)
00240     {
00241         return NRF_ERROR_DATA_SIZE;
00242     }
00243 
00244     // Get GAP appearance field.
00245     err_code = sd_ble_gap_appearance_get(&appearance);
00246     if (err_code != NRF_SUCCESS)
00247     {
00248         return err_code;
00249     }
00250 
00251     // Encode Length, AD Type and Appearance.
00252     p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_APPEARANCE_DATA_SIZE);
00253     *p_offset                 += ADV_LENGTH_FIELD_SIZE;
00254     p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_APPEARANCE;
00255     *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
00256     *p_offset                 += uint16_encode(appearance, &p_encoded_data[*p_offset]);
00257 
00258     return NRF_SUCCESS;
00259 }
00260 
00261 static uint32_t flags_encode(int8_t     flags,
00262                              uint8_t  * p_encoded_data,
00263                              uint16_t * p_offset,
00264                              uint16_t   max_size)
00265 {
00266     // Check for buffer overflow.
00267     if (((*p_offset) + AD_TYPE_FLAGS_SIZE) > max_size)
00268     {
00269         return NRF_ERROR_DATA_SIZE;
00270     }
00271 
00272     // Encode flags.
00273     p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_FLAGS_DATA_SIZE);
00274     *p_offset                 += ADV_LENGTH_FIELD_SIZE;
00275     p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_FLAGS;
00276     *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
00277     p_encoded_data[*p_offset]  = flags;
00278     *p_offset                 += AD_TYPE_FLAGS_DATA_SIZE;
00279 
00280     return NRF_SUCCESS;
00281 }
00282 
00283 static uint32_t sec_mgr_oob_flags_encode(uint8_t    oob_flags,
00284                                          uint8_t  * p_encoded_data,
00285                                          uint16_t * p_offset,
00286                                          uint16_t   max_size)
00287 {
00288     // Check for buffer overflow.
00289     if (((*p_offset) + AD_TYPE_OOB_FLAGS_SIZE) > max_size)
00290     {
00291         return NRF_ERROR_DATA_SIZE;
00292     }
00293 
00294     // Encode flags.
00295     p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_OOB_FLAGS_DATA_SIZE);
00296     *p_offset                 += ADV_LENGTH_FIELD_SIZE;
00297     p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS;
00298     *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
00299     p_encoded_data[*p_offset]  = oob_flags;
00300     *p_offset                 += AD_TYPE_OOB_FLAGS_DATA_SIZE;
00301 
00302     return NRF_SUCCESS;
00303 }
00304 
00305 static uint32_t tx_power_level_encode(int8_t     tx_power_level,
00306                                       uint8_t  * p_encoded_data,
00307                                       uint16_t * p_offset,
00308                                       uint16_t   max_size)
00309 {
00310     // Check for buffer overflow.
00311     if (((*p_offset) + AD_TYPE_TX_POWER_LEVEL_SIZE) > max_size)
00312     {
00313         return NRF_ERROR_DATA_SIZE;
00314     }
00315 
00316     // Encode TX Power Level.
00317     p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE +
00318                                                   AD_TYPE_TX_POWER_LEVEL_DATA_SIZE);
00319     *p_offset                 += ADV_LENGTH_FIELD_SIZE;
00320     p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_TX_POWER_LEVEL;
00321     *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
00322     p_encoded_data[*p_offset]  = tx_power_level;
00323     *p_offset                 += AD_TYPE_TX_POWER_LEVEL_DATA_SIZE;
00324 
00325     return NRF_SUCCESS;
00326 }
00327 
00328 
00329 static uint32_t uuid_list_sized_encode(const ble_advdata_uuid_list_t * p_uuid_list,
00330                                        uint8_t                         adv_type,
00331                                        uint8_t                         uuid_size,
00332                                        uint8_t                       * p_encoded_data,
00333                                        uint16_t                      * p_offset,
00334                                        uint16_t                        max_size)
00335 {
00336     int      i;
00337     bool     is_heading_written = false;
00338     uint16_t start_pos          = *p_offset;
00339     uint16_t length;
00340 
00341     for (i = 0; i < p_uuid_list->uuid_cnt; i++)
00342     {
00343         uint32_t   err_code;
00344         uint8_t    encoded_size;
00345         ble_uuid_t uuid = p_uuid_list->p_uuids[i];
00346         
00347         // Find encoded uuid size.
00348         err_code = sd_ble_uuid_encode(&uuid, &encoded_size, NULL);
00349         if (err_code != NRF_SUCCESS)
00350         {
00351             return err_code;
00352         }
00353 
00354         // Check size.
00355         if (encoded_size == uuid_size)
00356         {
00357             uint8_t heading_bytes = (is_heading_written) ? 0 : ADV_AD_DATA_OFFSET;
00358             
00359             // Check for buffer overflow
00360             if (((*p_offset) + encoded_size + heading_bytes) > max_size)
00361             {
00362                 return NRF_ERROR_DATA_SIZE;
00363             }
00364 
00365             if (!is_heading_written)
00366             {
00367                 // Write AD structure heading.
00368                 *p_offset                 += ADV_LENGTH_FIELD_SIZE;
00369                 p_encoded_data[*p_offset]  = adv_type;
00370                 *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
00371                 is_heading_written         = true;
00372             }
00373 
00374             // Write UUID.
00375             err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &p_encoded_data[*p_offset]);
00376             if (err_code != NRF_SUCCESS)
00377             {
00378                 return err_code;
00379             }
00380             *p_offset += encoded_size;
00381         }
00382     }
00383 
00384     if (is_heading_written)
00385     {
00386         // Write length.
00387         length = (*p_offset) - (start_pos + ADV_LENGTH_FIELD_SIZE);
00388         // There is only 1 byte intended to encode length
00389         if(length > 0x00FF)
00390         {
00391             return NRF_ERROR_DATA_SIZE;
00392         }
00393         p_encoded_data[start_pos] = (uint8_t)length;
00394     }
00395 
00396     return NRF_SUCCESS;
00397 }
00398 
00399 
00400 static uint32_t uuid_list_encode(const ble_advdata_uuid_list_t * p_uuid_list,
00401                                  uint8_t                         adv_type_16,
00402                                  uint8_t                         adv_type_128,
00403                                  uint8_t                       * p_encoded_data,
00404                                  uint16_t                      * p_offset,
00405                                  uint16_t                        max_size)
00406 {
00407     uint32_t err_code;
00408 
00409     // Encode 16 bit UUIDs.
00410     err_code = uuid_list_sized_encode(p_uuid_list,
00411                                       adv_type_16,
00412                                       sizeof(uint16_le_t),
00413                                       p_encoded_data,
00414                                       p_offset,
00415                                       max_size);
00416     if (err_code != NRF_SUCCESS)
00417     {
00418         return err_code;
00419     }
00420 
00421     // Encode 128 bit UUIDs.
00422     err_code = uuid_list_sized_encode(p_uuid_list,
00423                                       adv_type_128,
00424                                       sizeof(ble_uuid128_t),
00425                                       p_encoded_data,
00426                                       p_offset,
00427                                       max_size);
00428     if (err_code != NRF_SUCCESS)
00429     {
00430         return err_code;
00431     }
00432 
00433     return NRF_SUCCESS;
00434 }
00435 
00436 
00437 static uint32_t conn_int_check(const ble_advdata_conn_int_t *p_conn_int)
00438 {
00439     // Check Minimum Connection Interval.
00440     if ((p_conn_int->min_conn_interval < 0x0006) ||
00441         (
00442             (p_conn_int->min_conn_interval > 0x0c80) &&
00443             (p_conn_int->min_conn_interval != 0xffff)
00444         )
00445        )
00446     {
00447         return NRF_ERROR_INVALID_PARAM;
00448     }
00449 
00450     // Check Maximum Connection Interval.
00451     if ((p_conn_int->max_conn_interval < 0x0006) || 
00452         (
00453             (p_conn_int->max_conn_interval > 0x0c80) && 
00454             (p_conn_int->max_conn_interval != 0xffff)
00455         )
00456        )
00457     {
00458         return NRF_ERROR_INVALID_PARAM;
00459     }
00460 
00461     // Make sure Minimum Connection Interval is not bigger than Maximum Connection Interval.
00462     if ((p_conn_int->min_conn_interval != 0xffff) &&
00463         (p_conn_int->max_conn_interval != 0xffff) &&
00464         (p_conn_int->min_conn_interval > p_conn_int->max_conn_interval)
00465         )
00466     {
00467         return NRF_ERROR_INVALID_PARAM;
00468     }
00469 
00470     return NRF_SUCCESS;
00471 }
00472 
00473 
00474 static uint32_t conn_int_encode(const ble_advdata_conn_int_t * p_conn_int,
00475                                 uint8_t                      * p_encoded_data,
00476                                 uint16_t                     * p_offset,
00477                                 uint16_t                       max_size)
00478 {
00479     uint32_t err_code;
00480 
00481     // Check for buffer overflow.
00482     if (((*p_offset) + AD_TYPE_CONN_INT_SIZE) > max_size)
00483     {
00484         return NRF_ERROR_DATA_SIZE;
00485     }
00486 
00487     // Check parameters.
00488     err_code = conn_int_check(p_conn_int);
00489     if (err_code != NRF_SUCCESS)
00490     {
00491         return err_code;
00492     }
00493 
00494     // Encode Length and AD Type.
00495     p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_CONN_INT_DATA_SIZE);
00496     *p_offset                 += ADV_LENGTH_FIELD_SIZE;
00497     p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE;
00498     *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
00499 
00500     // Encode Minimum and Maximum Connection Intervals.
00501     *p_offset += uint16_encode(p_conn_int->min_conn_interval, &p_encoded_data[*p_offset]);
00502     *p_offset += uint16_encode(p_conn_int->max_conn_interval, &p_encoded_data[*p_offset]);
00503 
00504     return NRF_SUCCESS;
00505 }
00506 
00507 
00508 static uint32_t manuf_specific_data_encode(const ble_advdata_manuf_data_t * p_manuf_sp_data,
00509                                            uint8_t                        * p_encoded_data,
00510                                            uint16_t                       * p_offset,
00511                                            uint16_t                         max_size)
00512 {
00513     uint32_t data_size = AD_TYPE_MANUF_SPEC_DATA_ID_SIZE + p_manuf_sp_data->data.size;
00514 
00515     // Check for buffer overflow.
00516     if (((*p_offset) + ADV_AD_DATA_OFFSET + data_size) > max_size)
00517     {
00518         return NRF_ERROR_DATA_SIZE;
00519     }
00520 
00521     // There is only 1 byte intended to encode length which is (data_size + ADV_AD_TYPE_FIELD_SIZE)
00522     if(data_size > (0x00FF - ADV_AD_TYPE_FIELD_SIZE))
00523     {
00524         return NRF_ERROR_DATA_SIZE;
00525     }
00526 
00527     // Encode Length and AD Type.
00528     p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + data_size);
00529     *p_offset                 += ADV_LENGTH_FIELD_SIZE;
00530     p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA;
00531     *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
00532     
00533     // Encode Company Identifier.
00534     *p_offset += uint16_encode(p_manuf_sp_data->company_identifier, &p_encoded_data[*p_offset]);
00535     
00536     // Encode additional manufacturer specific data.
00537     if (p_manuf_sp_data->data.size > 0)
00538     {
00539         if (p_manuf_sp_data->data.p_data == NULL)
00540         {
00541             return NRF_ERROR_INVALID_PARAM;
00542         }
00543         memcpy(&p_encoded_data[*p_offset], p_manuf_sp_data->data.p_data, p_manuf_sp_data->data.size);
00544         *p_offset += p_manuf_sp_data->data.size;
00545     }
00546 
00547     return NRF_SUCCESS;
00548 }
00549 
00550 // Implemented only for 16-bit UUIDs
00551 static uint32_t service_data_encode(const ble_advdata_t * p_advdata,
00552                                     uint8_t             * p_encoded_data,
00553                                     uint16_t            * p_offset,
00554                                     uint16_t              max_size)
00555 {
00556     uint8_t i;
00557 
00558     // Check parameter consistency.
00559     if (p_advdata->p_service_data_array == NULL)
00560     {
00561         return NRF_ERROR_INVALID_PARAM;
00562     }
00563 
00564     for (i = 0; i < p_advdata->service_data_count; i++)
00565     {
00566         ble_advdata_service_data_t * p_service_data;
00567         uint32_t                     data_size;
00568 
00569         p_service_data = &p_advdata->p_service_data_array[i];
00570         // For now implemented only for 16-bit UUIDs
00571         data_size      = AD_TYPE_SERV_DATA_16BIT_UUID_SIZE + p_service_data->data.size;
00572 
00573         // There is only 1 byte intended to encode length which is (data_size + ADV_AD_TYPE_FIELD_SIZE)
00574         if(data_size > (0x00FF - ADV_AD_TYPE_FIELD_SIZE))
00575         {
00576             return NRF_ERROR_DATA_SIZE;
00577         }
00578 
00579         // Encode Length and AD Type.
00580         p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + data_size);
00581         *p_offset                 += ADV_LENGTH_FIELD_SIZE;
00582         p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_SERVICE_DATA;
00583         *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
00584 
00585         // Encode service 16-bit UUID.
00586         *p_offset += uint16_encode(p_service_data->service_uuid, &p_encoded_data[*p_offset]);
00587 
00588         // Encode additional service data.
00589         if (p_service_data->data.size > 0)
00590         {
00591             if (p_service_data->data.p_data == NULL)
00592             {
00593                 return NRF_ERROR_INVALID_PARAM;
00594             }
00595             memcpy(&p_encoded_data[*p_offset], p_service_data->data.p_data, p_service_data->data.size);
00596             *p_offset += p_service_data->data.size;
00597         }
00598     }
00599 
00600     return NRF_SUCCESS;
00601 }
00602 
00603 uint32_t adv_data_encode(ble_advdata_t const * const p_advdata,
00604                          uint8_t             * const p_encoded_data,
00605                          uint16_t            * const p_len)
00606 {
00607     uint32_t err_code = NRF_SUCCESS;
00608     uint16_t max_size = *p_len;
00609     *p_len = 0;
00610 
00611     //Encode Security Manager OOB Flags
00612     if (p_advdata->p_sec_mgr_oob_flags != NULL)
00613     {
00614         err_code = sec_mgr_oob_flags_encode(*p_advdata->p_sec_mgr_oob_flags,
00615                                              p_encoded_data,
00616                                              p_len,
00617                                              max_size);
00618         if (err_code != NRF_SUCCESS)
00619         {
00620             return err_code;
00621         }
00622     }
00623         
00624     // Encode Security Manager TK value
00625     if (NULL != p_advdata->p_tk_value)
00626     {
00627         err_code = tk_value_encode(p_advdata->p_tk_value, p_encoded_data, p_len, max_size);
00628         if (err_code != NRF_SUCCESS)
00629         {
00630             return err_code;
00631         }
00632     }
00633 
00634     // Encode LE Role
00635     if (BLE_ADVDATA_ROLE_NOT_PRESENT != p_advdata->le_role)
00636     {
00637         err_code = le_role_encode(p_advdata->le_role, p_encoded_data, p_len, max_size);
00638         if (err_code != NRF_SUCCESS)
00639         {
00640             return err_code;
00641         }
00642     }
00643 
00644     // Encode LE Bluetooth Device Address
00645     if (p_advdata->include_ble_device_addr)
00646     {
00647         err_code = ble_device_addr_encode(p_encoded_data, p_len, max_size);
00648         if (err_code != NRF_SUCCESS)
00649         {
00650             return err_code;
00651         }
00652     }
00653 
00654     // Encode appearance.
00655     if (p_advdata->include_appearance)
00656     {
00657         err_code = appearance_encode(p_encoded_data, p_len, max_size);
00658         if (err_code != NRF_SUCCESS)
00659         {
00660             return err_code;
00661         }
00662     }
00663 
00664     //Encode Flags
00665     if(p_advdata->flags != 0 )
00666     {
00667         err_code = flags_encode(p_advdata->flags, p_encoded_data, p_len, max_size);
00668         if (err_code != NRF_SUCCESS)
00669         {
00670             return err_code;
00671         }
00672     } 
00673 
00674     // Encode TX power level.
00675     if (p_advdata->p_tx_power_level != NULL)
00676     {
00677         err_code = tx_power_level_encode(*p_advdata->p_tx_power_level,
00678                                          p_encoded_data,
00679                                          p_len,
00680                                          max_size);
00681         if (err_code != NRF_SUCCESS)
00682         {
00683             return err_code;
00684         }
00685     }
00686     
00687     // Encode 'more available' uuid list.
00688     if (p_advdata->uuids_more_available.uuid_cnt > 0)
00689     {
00690         err_code = uuid_list_encode(&p_advdata->uuids_more_available,
00691                                     BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE,
00692                                     BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE,
00693                                     p_encoded_data,
00694                                     p_len,
00695                                     max_size);
00696         if (err_code != NRF_SUCCESS)
00697         {
00698             return err_code;
00699         }
00700     }
00701 
00702     // Encode 'complete' uuid list.
00703     if (p_advdata->uuids_complete.uuid_cnt > 0)
00704     {
00705         err_code = uuid_list_encode(&p_advdata->uuids_complete,
00706                                     BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE,
00707                                     BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE,
00708                                     p_encoded_data,
00709                                     p_len,
00710                                     max_size);
00711         if (err_code != NRF_SUCCESS)
00712         {
00713             return err_code;
00714         }
00715     }
00716 
00717     // Encode 'solicited service' uuid list.
00718     if (p_advdata->uuids_solicited.uuid_cnt > 0)
00719     {
00720         err_code = uuid_list_encode(&p_advdata->uuids_solicited,
00721                                     BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT,
00722                                     BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT,
00723                                     p_encoded_data,
00724                                     p_len,
00725                                     max_size);
00726         if (err_code != NRF_SUCCESS)
00727         {
00728             return err_code;
00729         }
00730     }
00731 
00732     // Encode Slave Connection Interval Range.
00733     if (p_advdata->p_slave_conn_int != NULL)
00734     {
00735         err_code = conn_int_encode(p_advdata->p_slave_conn_int, p_encoded_data, p_len, max_size);
00736         if (err_code != NRF_SUCCESS)
00737         {
00738             return err_code;
00739         }
00740     }
00741 
00742     // Encode Manufacturer Specific Data.
00743     if (p_advdata->p_manuf_specific_data != NULL)
00744     {
00745         err_code = manuf_specific_data_encode(p_advdata->p_manuf_specific_data,
00746                                               p_encoded_data,
00747                                               p_len,
00748                                               max_size);
00749         if (err_code != NRF_SUCCESS)
00750         {
00751             return err_code;
00752         }
00753     }
00754 
00755     // Encode Service Data.
00756     if (p_advdata->service_data_count > 0)
00757     {
00758         err_code = service_data_encode(p_advdata, p_encoded_data, p_len, max_size);
00759         if (err_code != NRF_SUCCESS)
00760         {
00761             return err_code;
00762         }
00763     }
00764 
00765     // Encode name. WARNING: it is encoded last on purpose since too long device name is truncated.
00766     if (p_advdata->name_type != BLE_ADVDATA_NO_NAME)
00767     {
00768         err_code = name_encode(p_advdata, p_encoded_data, p_len, max_size);
00769         if (err_code != NRF_SUCCESS)
00770         {
00771             return err_code;
00772         }
00773     }
00774 
00775     return err_code;
00776 }
00777 
00778 
00779 static uint32_t advdata_check(const ble_advdata_t * p_advdata)
00780 {
00781     // Flags must be included in advertising data, and the BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED flag must be set.
00782     if (
00783         ((p_advdata->flags & BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) == 0)
00784        )
00785     {
00786         return NRF_ERROR_INVALID_PARAM;
00787     }
00788 
00789     return NRF_SUCCESS;
00790 }
00791 
00792 
00793 static uint32_t srdata_check(const ble_advdata_t * p_srdata)
00794 {
00795     // Flags shall not be included in the scan response data.
00796     if (p_srdata->flags)
00797     {
00798         return NRF_ERROR_INVALID_PARAM;
00799     }
00800 
00801     return NRF_SUCCESS;
00802 }
00803 
00804 
00805 uint32_t ble_advdata_set(const ble_advdata_t * p_advdata, const ble_advdata_t * p_srdata)
00806 {
00807     uint32_t  err_code;
00808     uint16_t  len_advdata = BLE_GAP_ADV_MAX_SIZE;
00809     uint16_t  len_srdata  = BLE_GAP_ADV_MAX_SIZE;
00810     uint8_t   encoded_advdata[BLE_GAP_ADV_MAX_SIZE];
00811     uint8_t   encoded_srdata[BLE_GAP_ADV_MAX_SIZE];
00812     uint8_t * p_encoded_advdata;
00813     uint8_t * p_encoded_srdata;
00814 
00815     // Encode advertising data (if supplied).
00816     if (p_advdata != NULL)
00817     {
00818         err_code = advdata_check(p_advdata);
00819         if (err_code != NRF_SUCCESS)
00820         {
00821             return err_code;
00822         }
00823 
00824         err_code = adv_data_encode(p_advdata, encoded_advdata, &len_advdata);
00825         if (err_code != NRF_SUCCESS)
00826         {
00827             return err_code;
00828         }
00829         p_encoded_advdata = encoded_advdata;
00830     }
00831     else
00832     {
00833         p_encoded_advdata = NULL;
00834         len_advdata = 0;
00835     }
00836 
00837     // Encode scan response data (if supplied).
00838     if (p_srdata != NULL)
00839     {
00840         err_code = srdata_check(p_srdata);
00841         if (err_code != NRF_SUCCESS)
00842         {
00843             return err_code;
00844         }
00845 
00846         err_code = adv_data_encode(p_srdata, encoded_srdata, &len_srdata);
00847         if (err_code != NRF_SUCCESS)
00848         {
00849             return err_code;
00850         }
00851         p_encoded_srdata = encoded_srdata;
00852     }
00853     else
00854     {
00855         p_encoded_srdata = NULL;
00856         len_srdata = 0;
00857     }
00858 
00859     // Pass encoded advertising data and/or scan response data to the stack.
00860     return sd_ble_gap_adv_data_set(p_encoded_advdata, len_advdata, p_encoded_srdata, len_srdata);
00861 }