Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Central Update #1

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open

Conversation

jakejunk150
Copy link

Summary

The central sample was updated to now support multiple devices and filter found device by name.

Q1 - Implementation Summary

bt_data_parse accepts three parameters: a buffer of the ad data, a callback function, and a pointer where the parsed data of interest can be stored.

Line 52 and 53 of main.c define the character array that will be used to store the parsed data. The variable decays to a pointer to the first element of the array when passed to bt_data_parse.

bt_data_parse calls find_device_name repeated until false is returns. False indicates the device name has been found and parsing can stop.

if (data->type == BT_DATA_NAME_COMPLETE) {
        memcpy(device_name, data->data, data->data_len);
        device_name[data->data_len] = '\0';
        return false;
    }
    else {
        return true;
    }

Device name is printed using printk.

Q2 - Implementation Summary

Support for multiple devices is effectively managed by utilizing 3 global variables.

static struct bt_conn *conn_connecting = NULL;
static uint8_t volatile conn_count;
static bool volatile is_connecting = false;

bt_conn is the major data structure used in Zephyr's Bluetooth stack that keeps track of a connected device's important information. It is passed to bt_conn_le_create, which creates the connection and adds it to a list of connected devices.

bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN,
				BT_LE_CONN_PARAM_DEFAULT, &conn_connecting);

In the connected function, is_connecting is set back to false, conn_connecting is set back to NULL and conn_count is incremented. Similar logic is used in disconnected callback function.

is_connecting = false;
conn_connecting = NULL;
conn_count++;

Main enters an infinite while loop after initiating the first scan. The while loop will check to see if a new scan should be initiated and intermittently yield CPU.

k_sleep(K_MSEC(100));

if (conn_count < CONFIG_BT_MAX_CONN && !is_connecting) {
    start_scan();
}

Other Functionality Implemented

  • The settings subsystem was configured to store device pairing information.
  • SMP was configured for additional security.
  • Privacy was configured for added anonymity.

prj.conf

  • System is configured to support up to 5 simultaneous connections and remember up to 10 devices.
CONFIG_BT=y 
CONFIG_BT_CENTRAL=y
CONFIG_BT_MAX_CONN=5
CONFIG_BT_MAX_PAIRED=10 
CONFIG_BT_SMP=y 
CONFIG_BT_PRIVACY=y
CONFIG_BT_SETTINGS=y
CONFIG_SETTINGS=y
CONFIG_BT_HCI=y

Files Changed

main.c and prj.conf

updated main.c and prj.conf of central sample to filter by device found and support multiple connections
README summarizes changes made to central sample.
src/main.c Outdated
// bt_data_parse accepts a buffer of the ad data,
// a callback function, and a place to store the parsed data

bt_data_parse(ad, find_device_name, (void *)device_name);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jakejunk150 We should handle the bt_conn_le_create inside bt_data_parse. Can you update it?
Besides that, can you filter with the device name contains DXC and create the connect when you find it only?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@trungkiena6 Is it okay if I handle the bt_conn_le_create inside my callback function (find_device_name), or should I edit the source code for bt_data_parse?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jakejunk150 I refer to handle the bt_conn_le_create inside your callback function. It would be better than modifying the Zephyr source. Also, that is how we manage user API in Stel :).

src/main.c Outdated
k_sleep(K_MSEC(100));

// initiate a scan if max device count is not reached and a device is not currently being connected.
if (conn_count < CONFIG_BT_MAX_CONN && !is_connecting) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jakejunk150 I think you should make a work_delayable or work to start new scan after you created the connection. Can you change it?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@trungkiena6 Would you be able to elaborate more on this one? When you say make a work_delayable or work, do you mean a function or a variable? And, if so, should I get rid of the infinite while loop? Thank you!

Copy link

@trungkiena6 trungkiena6 Jul 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jakejunk150
The BLE processes will follow step:

  • Scan -> Found -> Connecting -> Connected (The callback function connected) -> Internal handler -> Disconnected (The callback function disconnected)

There is one rule. From scan to connected event, you can't activate the multiple scan.
So, if you want to support multiple connection, you will need to re-scan after the current device got connection.
The idea to handle is:

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@trungkiena6 I have made another commit to implement k_work_delayable and also updated find_device_name to filter by "DMX". I am not super confident that I utilized k_work_delayable correctly, but I am happy to update it again! Thanks Kien

- connection is only attempting when device name matches
- schedules new work scan after making a connection
src/main.c Outdated
// I am unsure the of the proper way to handle a
// bt_le_scan_stop failure but I know a connection should not be
// attempted if it fails
continue;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jakejunk150 No worried about it. You can ignore it from now. In general, it should be a bug or work-around to force BLE stop then re-init.

- updates outlined in readme
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants