You are here

Creating a Bluetooth LE Peripheral using ModusToolbox #5 | 赛普拉斯半导体

Creating a Bluetooth LE Peripheral using ModusToolbox #5

It is time to take the final step in our week-long BLE adverture. Hopefully you have a working peripheral already. You should be able to send messages from your phone and have it send messages to you. OK, it's just a find me application and battery monitor right now, but those two things tell you a lot of what you need to know to make bigger, more interesting peripherals. Our last task is to make sure your device only talks to the right people. That process is called pairing and we shall control that with a passkey.

We shall start this job in familiar territory - the BLE Configurator. Switch the view to the GAP Settings and look at "Security configuration 0". Note that more complex peripherals can implement multiple configurations but we are only making one.

Change the Security level to "Authenticated pairing with encryption". The authentication means that the pairing requires a passkey. The IO Capability should be "Display" which means the peripheral has a way for presenting a passkey to the user. In our case that is the terminal and we will write a little code to print the key. Some peripherals do not have a display and so the authentication process has to done differently - for example, the passkey can be sent to, and displayed on, the phone instead and the a simple button can be used to accept the number on the peripheral. The last edit is for Binding, which should be set to "No Bond". In real-world applications you alnmost always bond, to the point that pairing and bonding are often considered to be synonyms. Strictly, bonding is just the storage of pairing information in non-volatile memory which enables bonded phones and devices to automatically recognize each other and connect without a passkey. We are not going to bond because it's a lot easy to learn about piring without the need to force your phone and peripheral to forget each other all the time. Let's get good at pairing first!

Setting up security in the ModusToolbox BLE Configurator

Saving the configurator edits, we need to add four events to our stack_handler() function.

  • CY_BLE_EVT_GAP_AUTH_REQ occurs when the phone asks to initiate pairing. The peripheral responds by sending back the authentication method(s) that it can support (in our case this means "display").
  • CY_BLE_EVT_GAP_PASSKEY_DISPLAY_REQUEST means the central wants the peripheral to display the passkey. The phone asks the user to enter the value (6-digit code with leading zeros).
  • CY_BLE_EVT_GAP_AUTH_COMPLETE means that the phone has sent the user's passkey and it matched the displayed value.
  • CY_BLE_EVT_GAP_AUTH_FAILED means the value entered was wrong, or the user waited too long, or some other reason for not allowing pairing.

Here is the code to handle those events. Just add it into the switch statement in stack_handler().

/* Include stdio.h at the top of main.c */

#include "stdio.h"

...

char passkey_str[50]; /* Put the string declaration at the top of stack_handler() */

...

case CY_BLE_EVT_GAP_AUTH_REQ:
   Cy_SCB_UART_PutString( KIT_UART_HW, "Authenticating\r\n" );
   /* Send the authentication settings set by the BLE Configurator - GAP Settings */
   Cy_BLE_GAPP_AuthReqReply( &cy_ble_config.authInfo[CY_BLE_SECURITY_CONFIGURATION_0_INDEX] );
break;

case CY_BLE_EVT_GAP_PASSKEY_DISPLAY_REQUEST:
   sprintf( passkey_str, "Passkey requested\tKey = %06ld\r\n", ( (cy_stc_ble_gap_auth_pk_info_t*)eventParam )->passkey );
   Cy_SCB_UART_PutString( KIT_UART_HW, passkey_str );
break;

case CY_BLE_EVT_GAP_AUTH_COMPLETE:
   Cy_SCB_UART_PutString( KIT_UART_HW, "Authentication complete\r\n" );
break;

case CY_BLE_EVT_GAP_AUTH_FAILED:
   Cy_SCB_UART_PutString( KIT_UART_HW, "Authentication fail\r\n" );
break;

As you can see, there is not a lot to it. The stack does the hard part of communicating with the phone and deciding whether to pair. The call to Cy_BLE_GAPP_AuthReqReply() takes an argument that is in the generated code from the BLE Configurator. The variable cy_ble_config is a big struct containing all the user selections from that tool. The authInfo member contains the information we just provided in an array of one element (CY_BLE_SECURITY_CONFIGURATION_0_INDEX is the only element in that array because we only have one configuration). So, sending that information up to the phone is all that is required to tell it to pop up a passkey request dialog.

CySmart prompting for a passkey

of course, we have to print the passkey to give the user a chance to guess right! That happens in the CY_BLE_EVT_GAP_PASSKEY_DISPLAY_REQUEST event. The stack generates a random number and passes it into the event handler in the eventParam argument.

When you build and program the application, you should connect to it as normal. When you try to open the Battery service the CySmart app should automatically pop up the passkey request, as above. Note that the Android version of the app does this as soon as you connect but the iPhone version waits for you to do something that requires the peripheral to respond. On the iPhone, then, you can send an Immediate Alert before pairing and, while the phone says it was sent (it was) the peripheral ignores the message (and the LED does not light). Everything is working correctly in both cases, because you need to have completed pairing before either service will be honored by the peripheral.

Here is the terminal output for a session where I got the password wrong. There is no code to enable a re-try so you need to disconnect and reconnect on order to try again. When I got it right I could send and receive messages with the usual wild abandon! When you play with this, remember to include any leading zeros when entering the passkey - you must enter all 6 digits.

PSoC BLE Peripheral output

So that's the full set of BLE exercises. I hope you followed along and had some fun with it. We have a large array of examples of how to take this further and I have attached a template for you to recreate exactly what I have done here. To use the template download and unzip it, then open the New Application dialog, select the prototyping kit, then use the "Import..." button to open the modus.mk file in the BLE_proj folder.

Happy Blootoothing!!!

Blog: 

本网站上的所有内容和材料均“按原样”提供。赛普拉斯半导体公司及其各个供应商对这些材料用于任何用途的适用性不作陈述,并且对关于这些材料的所有担保和条件概不负责,包括但不限于有关适销性、针对特定用途之适用性、权利和不侵犯任何第三方知识产权的所有暗示担保和条件。赛普拉斯半导体公司不授予任何明示或暗示的许可(无论是以默许方式或是任何其他方式)。使用本网站上的信息可能需要第三方的许可,或赛普拉斯半导体公司的许可。

本网站上的内容可能包含或必须遵守关于使用的特定准则或限制。所有帖子和使用本网站上的内容都必须遵守本网站的条款与条件;使用这些内容的第三方必须同意遵守任何限制或准则,并遵守本网站的条款与条件。赛普拉斯半导体公司及其供应商保留随时对内容和材料、产品、计划和服务进行纠正、删除、修改、增强、改进或其他变更,或者移动或终止任何内容、产品、计划或服务的权利,恕不另行通知。