A common problem with Bluetooth devices is that they often have no user interface, other than the Bluetooth connection, but still need to support authentication. This article presents one method for accomplishing this.
The Bluetooth specification determines the pairing mechanism based on the reported I/O capabilities of the two devices. When one of the devices has no I/O capabilities at all then the selected method is JustWorks pairing. This ensures an encrypted connection but does not allow for any authentication and allows any Bluetooth device in range request pairing or bonding. The simplest way around this problem is to only allow bonding for a short period of time after power-up. This provides a little extra protection since the exposure is limited to the time that the device is bondable. However, this doesn’t prevent a rogue device from connecting. A better method is to use a fixed passkey that is made unique. Bluetooth allows for a 6 digit passkey. Since each device has a unique address, the Bluetooth address, it is possible to create a passcode based on this address. However, the number of device addresses is much larger than the number of passkey combinations so the passkey generated will not be truly unique.
The pairing method can be forced to passkey entry by configuring the peripheral as “display only”. The passkey will have to be shared with the user by some medium such as a printed hardcopy.
The first step in this setup is to get the device’s unique address with the following call
public_address = gecko_cmd_system_get_bt_address()->address;
The next step is to make a 32 bit integer from this 6 byte array. The easiest way to do this is to simply add the bytes together but if you experiment with a few addresses you’ll see that there is not much variation in the generated passkeys. In order to increase the variation in the keys, each byte is shifted by 8 bits before being added. Once the passkey has been created as follows
passkey = makePasskeyFromAddress(public_address);
it can be set as the system passkey with the following call
To ensure that the pairing method chosen is the passkey method. This allows the master, such as a mobile phone or tablet, to enter a passkey. This is done with the following call
The flags chosen in the first parameter require MITM protection, require bonding for encryption and require LE secure connections.
Now make the device bondable as shown
For simplicity, the attached example code requests any connection to be secured by calling gecko_cmd_sm_increase_security(). Normally this is done by giving at least one of the characteristics a property that requires security, such as authenticated_read/authenticated_write.
To build this application,
The easiest way to send printf() output over UART is by adding the retargetserial driver as follows
The method shown here is fairly simple, it is recommended that you develop your own algorithm for generating a passkey from the device address.
For each Bluetooth connection, there is a set of parameters that can be changed changed on the fly, depending on the application requirements. These include: connection interval, slave latency and supervision timeout. For example, to minimize power consumption you can increase the connection interval and slave latency. This reduces the RF duty cycle and allows the peripheral to stay longer in sleep mode if there is no need to transmit any user data.
More details about Bluetooth connections can be found in document UG103.14: Application Development Fundamentals: Bluetooth® Smart Technology.
An important thing to note about connection parameters is that the master (typically a mobile device) controls what parameters are used. When master initiates a connection to a slave, it selects the default parameters that are used. The slave can request updating of the connection parameters. However, it is up to the master to either accept or reject this request.
Depending on the master, they may be different restrictions on which parameter combinations are accepted. This article focuses on the recommendations for iOS devices specified by Apple.
The rules for selecting connection parameters for BLE peripherals that are defined in the document Accessory Design Guidelines for Apple Devices, available for download at:
The BLE connection parameters are discussed in section 10.6 Connection Parameters. For example, the minimum connection interval is specified as 15 ms. Note that the minimum interval allowed by the Bluetooth core specification is 7.5 ms.
At the time of writing, the latest version of the guideline document is R5 (dated 2018-03-27).
There are several rules that need to be fulfilled to be compliant with the iOS guidelines. To help selecting a set of compatible parameters, an Excel sheet is provided as an attachment.
To use the checker, you can enter the connection parameters in the cells that are marked in grey color. The input parameters are in the same order and using the same units as in the BGAPI call cmd_le_gap_set_conn_parameters.
Below the parameters, there is one line for each rule (numbered #1 .. #7). Next to each rule, there is a column with text OK / NOT OK, depending if the rule is passed or not. By changing the parameters, you can easily see which rules are violated and tune the parameters accordingly.
An example set of parameters that complies with all the rules is shown below.
There is OK displayed next to each of the rules 1..7, indicating that there are no violations.
The next example shows a set of parameters that is not fully compliant with the iOS design guidelines.
In this latter example, it is easy to identify which of the rules are violated. The connection interval must be an integer multiple of 15 ms. Additionally, the supervision timeout is too short. To fix this, you can change the minimum interval (using e.g. 150ms) and increase the supervision timeout.
NOTE: there are many possible ways to fix the parameters. In the above case, it is possible to also decrese the slave latency to be compliant with the last rule #7.
The parameters used in these examples are randomly selected just for illustration purposes. The parameters used in real applications is something that the application developer needs to decide case by case. The purpose of this tool is simply to help check the compatibility of a set of parameters against the rules listed in the Apple guideline document.
The following BGAPI commands and events are related to connection parameter adjustments:
cmd_le_connection_set_parameters: Used to request a change of connection parameters after a connection has been opened.
evt_le_connection_parameters: Triggered when connection is opened and any time the connection parameters are changed.
When the slave calls cmd_le_connection_set_parameters and the function returns success, this does not mean that the parameters are changed. It only indicates that the request has been registered in the stack. The stack then tries to update the parameters and if they are successfully changed then event evt_le_connection_parameters is triggered. Therefore the slave application must monitor this event to see what are the actual parameters that are effective for the current connection.
NOTE: command cmd_le_gap_set_conn_parameters is used to set the default connection parameters. This only affects connections that the device is opening as a master. This command is not relevant for slave devices because the master selects the default parameters.
The maximum transmission unit (MTU) is the largest amount of data that can be exchanged in a single GATT operation. Any read or write operation that fits within this limit can be accomplished in a single operation. However, if the data to be read or written is larger than MTU then a so-called long read/write operation must be used. This article demonstrates how to implement this.
According to the Bluetooth specification, the maximum size of any attribute is 512 bytes. The attached application handles reading and writing a characteristic of 512 bytes.
When reading a user characteristic longer than MTU, multiple gatt_server_user_read_request events will be generated on the server side, each containing the offset from the beginning of the characteristic. The application code must use the offset parameter to send the correct chunk of data.
Characteristics can be written by calling gecko_cmd_gatt_write_characteristic_value. If the characteristic data fits within MTU – 3 bytes then a single operation used, otherwise the ‘write long ‘ procedure is used. The write long procedure consists of a prepare write request operation and an execute write request operation. A maximum of MTU – 5 bytes can be sent in a single prepare_value_write operation. The application can also access these operations directly by calling gecko_cmd_gatt_prepare_characteristic_value_write() and gecko_cmd_gatt_execute_characteristic_value_write(). This is a useful approach if the size of the characteristic is greater than 255 bytes.
Notifications and Indications are limited to MTU – 3 bytes. Since all notifications and indications must fit within a single GATT operation, the application does not demonstrate them.
The attached application can operate in either slave or master mode. The application starts in slave mode, to switch to master mode, press PB0 on the WSTK.
As soon as the device is switched into master mode, it begins scanning for a device advertising a service with the following UUID cdb5433c-d716-4b02-87f5-c49263182377. When a device advertising this service is found a connection is formed. The gecko_evt_gatt_mtu_exchanged event saves the MTU size for the connection, this will be needed for writing the long characteristic later.
The master now discovers service and characteristic handles. Once the long_data characteristic is found, the master performs a read of this characteristic by calling gecko_cmd_gatt_read_characteristic_value(). The size of this characteristic is 512 bytes so the “read long” procedure will always be used.
The master can also write data to this characteristic. Pressing PB1 on the WSTK triggers a write of an array of test data to this long characteristic. This action is handled by a helper function called write_characteristic() which in turn uses a helper function called queueCharacteristicChunk. This function can handle any data size up to 512 bytes. Writing the characteristic data is handled by queueing data with as many calls to gecko_cmd_gatt_prepare_characteristic_value_write() as necessary, once all of the data has been queued up, it is written with a call to gecko_cmd_gatt_execute_characteristic_value_write(). Since only one GATT operation can take place at a time for a given connection, the gatt_procedure_completed event is used to drive the process of queueing writes. To get the process started queueCharacteristicChunk() is called directly from write_characteristic(), after that queueCharacteristicChunk() is called from the gatt_procedure_completed event. This ensures that the previous procedure is finished before attempting to start another.
Upon startup the slave begins advertising the service mentioned above. This service contains a single user-type characteristic of 512 bytes. The gecko_evt_gatt_server_user_read_request event handler takes care of read requests from the master. Since the characteristic is known to be larger than an MTU, this event handler uses the connection mtu size and offset parameters passed in to the event to send the correct portion of the array to the master. This event will be generated as many times as necessary to allow reading the entire characteristic. A gatt_server_attribute_value event is generated for each queued write performed by the master and a gatt_server_execute_write_completed event is generated when all of the queued writes have been completed. The result parameter indicates whether an error has occurred. A user_write_request response must be sent by the application for each queued write, this is handled in the user_write_request event handler.
Get started by creating an soc-empty application for your chosen device with the Appbuilder in SimplicityStudio. Once that’s complete, you can extract the zip file attached to this article and copy it to your project folder. Open hal-config.h and change the definition of from HAL_VCOM_ENABLE 0 to 1.
Open the .isc file for your project and import the gatt.xml file included in the zip by clicking the import icon on the right side of the .isc file, when the file has imported click generate and then build the project. As mentioned previously, this application can act as either a master or a slave. Flash the application onto to two evaluation boards and open a terminal window such as Teraterm or SimplicityStudio console for each. Choose one of the kits to be a master and press PB0. Now you’ll see a message indicating that the device has entered master mode and once it has found the slave, indicates that it has connected and has read the characteristic in three steps since the MTU size is 247 bytes. Once this process has completed you’ll see a message indicating that the read has finished and to press PB1 to write a block of test data to the slave. The master displays messages indicating how many bytes are written to the slave in each operation and the message “exec_result = 0x00” when complete.
I am developing a new product with the EFR32MG13 wireless MCU for an automotive application in which the device will operate in harsh environmental conditions (high temperature). These questions concern the operation of the HFXO using either a quartz crystal or an external clock (MEMS oscillator).
1) Can either a MEMS oscillator or a quartz crystal be used with the EFR32MG13 HFXO?
2) What recommendations do you have concerning operation of the HFXO at high temperatures?
3) What are the requirements for phase noise /phase jitter of the 38.4MHz HFXTAL input to ensure robust BLE communication?
1) Both MEMS oscillators as well as crystals that meet our datasheet specifications will likely work in this application. The mode of operation for the EFR32MG13 HFXO will be different depending on your choice. For instance, for a crystal oscillator will require that the HFXO be in XTAL mode (CMU_HFXOCTRL.MODE = 0), whereas the MEMS oscillator with CMOS output will require the HFXO to be in EXTCLK mode (MCU_HFXOCTRL.MODE = 1).
Please note that we have a list of recommended crystals in application note AN0016.1: Oscillator Design Considerations (see page 16). In addition, this section lists recommended TCXOs, which will have improved temperature stability. Any of these devices are recommended for wireless applications.
2) Oscillator temperature sensitivity can be a major consideration in applications experiencing a wide range of operating temperatures. We have had some exposure to applications of the EFR32 devices in high temperature environments and with issues involving temperature compensation. It is possible implement a scenario in which you can monitor the temperature of a crystal and adjust the CTUNE value (on-chip load capacitance) to maintain a stable frequency as temperature changes.
An alternative to implementing a temperature compensation scheme involving firmware monitoring of the crystal temperature and subsequent oscillator tuning is to use a temperature compensated crystal oscillator (TCXO).
3) Any phase noise that is present in the HFXO is multiplied up by the RF PLL and therefore becomes phase noise at RF. This has implications for transmit modulation performance and receive blocking performance. We do not currently have data to specify what phase noise tolerance is acceptable at the HFXO input in order to still maintain good BLE performance. Thus, there is a risk associated with using a high phase noise oscillator.
Based on some internal work with external clocks for other wireless applications we have concluded that MEMS oscillators do not have good enough phase noise. Crystals are regularly used in automotive applications, and it would be fair to say that a TCXO is probably the safest bet for an external oscillator. We do use these for some wireless applications where tight temperature tolerance is required.
I recommend using one of the crystals or TCXOs listed under section "7. Recommended Crystals" on page 15 of AN0016.1 (see specifically Table 7.1 and 7.2), as these have been tested by us in the past.
As one last note, we recommend against using crystals with a low peak power (which is characteristic of small crystals) since the device drives the crystal resonator with significant power to reduce phase noise.