Skip to content

Conversation

chengkai15
Copy link
Contributor

@chengkai15 chengkai15 commented Aug 15, 2025

Implementation Overview
Serial Port Profile (SPP) implementation providing full client/server functionality and comprehensive test tools. The solution enables reliable serial communication over RFCOMM for IoT devices, peripherals, and bridge applications.

reopen from PR: #77017

Core Components

  1. SPP Server Implementation:Service registration with SDP record management
int bt_spp_server_register(struct bt_spp_server *server);
  1. SPP Client Implementation:Connection lifecycle handling (connect/disconnect)
int bt_spp_disconnect(struct bt_spp *spp);
int bt_spp_connect(struct bt_conn *conn, struct bt_spp *spp);
  1. Data send and reception via callback API
void (*recv)(struct bt_spp *spp, struct net_buf *buf);
int bt_spp_send(struct bt_spp *spp, struct net_buf *buf);
  1. Shell Test Tool

shell

# Server operations
spp register channel  9         # Start SPP server with channel 9
or 
spp register uuid  00001101-0000-1000-8000-00805F9B34FB    # Start SPP server with uuid:00001101-0000-1000-8000-00805F9B34FB 

# Client operations
br connect XX:XX:XX:XX:XX:XX
spp connect     # Connect to peer
spp send   5     # Send data 5 bytest 0xff 

@jhedberg
Copy link
Member

Seems like this still doesn't address the request that was pointed out here: #77017 (comment)

@chengkai15 chengkai15 changed the title Bluetooth: Classic: Add support for Serial Port Profile (SPP) Bluetooth: SPP: Add support for Serial Port Profile Aug 15, 2025
@chengkai15
Copy link
Contributor Author

Seems like this still doesn't address the request that was pointed out here: #77017 (comment)

@jhedberg thanks for your suggestion

I know your needs. User apps can send and receive SPP data via UART, as NUT GATT service does. If necessary, I would like to submit these changes for SPP NUT with another PR(SPP Based NUT Service vid UART) .

This PR is only for SPP protocol stack, ensuring SPP stack function works well. Do you agree?

@jhedberg
Copy link
Member

Seems like this still doesn't address the request that was pointed out here: #77017 (comment)

@jhedberg thanks for your suggestion

I know your needs.

This isn't about "my needs". I'm merely (as maintainer) providing guidance to help steer the design in a direction that will be maximally useful for users of Zephyr, and in line with existing "serial port" abstractions in the Bluetooth stack.

User apps can send and receive SPP data via UART, as NUT GATT service does. If necessary, I would like to submit these changes for SPP NUT with another PR(SPP Based NUT Service vid UART) .

What is "NUT"? Do you mean NUS (Nordic UART Service)? The request isn't about NUS, rather about following a similar design wrt how it's exposed as a Zephyr UART driver and instances created through devicetree nodes.

This PR is only for SPP protocol stack, ensuring SPP stack function works well. Do you agree?

I'm not quite sure. This is exposing a new public API, which may not be the ideal choice for someone wanting to use SPP if a UART driver API was also available.

@jhedberg jhedberg requested a review from ubieda August 15, 2025 08:57
@jhedberg
Copy link
Member

I'd also appreciate an answer to the question from @ubieda here: #77017 (comment)

I'd like to get hold of such HW as well, so that I can do proper testing of Bluetooth Classic PRs.

@chengkai15
Copy link
Contributor Author

chengkai15 commented Aug 15, 2025

Seems like this still doesn't address the request that was pointed out here: #77017 (comment)

@jhedberg thanks for your suggestion
I know your needs.

This isn't about "my needs". I'm merely (as maintainer) providing guidance to help steer the design in a direction that will be maximally useful for users of Zephyr, and in line with existing "serial port" abstractions in the Bluetooth stack.

User apps can send and receive SPP data via UART, as NUT GATT service does. If necessary, I would like to submit these changes for SPP NUT with another PR(SPP Based NUT Service vid UART) .

What is "NUT"? Do you mean NUS (Nordic UART Service)? The request isn't about NUS, rather about following a similar design wrt how it's exposed as a Zephyr UART driver and instances created through devicetree nodes.

This PR is only for SPP protocol stack, ensuring SPP stack function works well. Do you agree?

I'm not quite sure. This is exposing a new public API, which may not be the ideal choice for someone wanting to use SPP if a UART driver API was also available.

Seems like this still doesn't address the request that was pointed out here: #77017 (comment)

@jhedberg thanks for your suggestion
I know your needs.

This isn't about "my needs". I'm merely (as maintainer) providing guidance to help steer the design in a direction that will be maximally useful for users of Zephyr, and in line with existing "serial port" abstractions in the Bluetooth stack.

User apps can send and receive SPP data via UART, as NUT GATT service does. If necessary, I would like to submit these changes for SPP NUT with another PR(SPP Based NUT Service vid UART) .

What is "NUT"? Do you mean NUS (Nordic UART Service)? The request isn't about NUS, rather about following a similar design wrt how it's exposed as a Zephyr UART driver and instances created through devicetree nodes.

This PR is only for SPP protocol stack, ensuring SPP stack function works well. Do you agree?

I'm not quite sure. This is exposing a new public API, which may not be the ideal choice for someone wanting to use SPP if a UART driver API was also available.

sorry typo for NUS

For example, We have a requirement that on the Nuttx or Linux platform, where the Zephyr kernel is not running, and SPP data transmission and reception are need through the API.
Don't we need to think about it?

@chengkai15
Copy link
Contributor Author

I'd also appreciate an answer to the question from @ubieda here: #77017 (comment)

I'd like to get hold of such HW as well, so that I can do proper testing of Bluetooth Classic PRs.

I test it with qemu_x86 tests/bluetooth/shell such as

enable BT_SPP config then run qemu with BT USB dongle

west build -b qemu_x86 tests/bluetooth/shell
west build -t run

then test with SPP client or server tool

Copy link
Member

@jhedberg jhedberg left a comment

Choose a reason for hiding this comment

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

Some more comments

@jhedberg
Copy link
Member

on the Nuttx or Linux platform, where the Zephyr kernel is not running, and SPP data transmission and reception are need through the API

What do you mean by "the API"? Surely nuttx and Linux don't use this new API that you're exposing. The requirement to transmit data over SPP is clear, however I don't think that puts any specific requirements on the API as long as it allows the transmission of data.

@chengkai15
Copy link
Contributor Author

on the Nuttx or Linux platform, where the Zephyr kernel is not running, and SPP data transmission and reception are need through the API

What do you mean by "the API"? Surely nuttx and Linux don't use this new API that you're exposing. The requirement to transmit data over SPP is clear, however I don't think that puts any specific requirements on the API as long as it allows the transmission of data.

What we are talking about here is a private implementation of our internal, which has been used in the product since it relies on the API interface, which may mislead you. However it doesn't matter anymore, as long as the API is exposed

@jhedberg
Copy link
Member

What we are talking about here is a private implementation of our internal, which has been used in the product since it relies on the API interface, which may mislead you. However it doesn't matter anymore, as long as the API is exposed

In an upstream context (e.g. this PR) it's not really relevant what you have in some internal tree. It should be possible to reason and provide justifications in a purely upstream context.

@chengkai15 chengkai15 force-pushed the dev_spp branch 2 times, most recently from 2154239 to f093346 Compare August 18, 2025 08:51
@zephyrbot zephyrbot added the area: Bluetooth Host Bluetooth Host (excluding BR/EDR) label Aug 18, 2025
Copy link
Member

@jhedberg jhedberg left a comment

Choose a reason for hiding this comment

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

A couple of inline comments. However in general, I get the feeling that this is potentially over engineering the whole thing. Isn't SPP pretty much RFCOMM + SDP handling (registering the right kind of record and discovering the right kind of record). In that sense, I'd expect to just have helpers for the SDP handling and then for the rest it should be possible just use exiting public RFCOMM APIs. Or am I missing something? Is there something more advanced that's needed?

@chengkai15
Copy link
Contributor Author

A couple of inline comments. However in general, I get the feeling that this is potentially over engineering the whole thing. Isn't SPP pretty much RFCOMM + SDP handling (registering the right kind of record and discovering the right kind of record). In that sense, I'd expect to just have helpers for the SDP handling and then for the rest it should be possible just use exiting public RFCOMM APIs. Or am I missing something? Is there something more advanced that's needed?

thanks for you suggestion. Some changes have been taken to simplify the process


union {
/** UUID (service) to discovery remote SPP service */
const struct bt_uuid *uuid;
Copy link
Contributor

Choose a reason for hiding this comment

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

If the peer use the same uuid to define many spp sdp services with different channels value, then the uuid is used to connect peer, how the spp knows which channel to connect? It seems that the all SDP related logic should be in application.

Copy link
Contributor Author

@chengkai15 chengkai15 Sep 27, 2025

Choose a reason for hiding this comment

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

If the peer use the same uuid to define many spp sdp services with different channels value, then the uuid is used to connect peer, how the spp knows which channel to connect? It seems that the all SDP related logic should be in application.

@MarkWangChinese thanks very much for you attentivenesss. it would be compatible in that case.
if user would like to conenct channels with that uuid, it could be done by uuid. SDP related logic could be reuesed.
if user would like to connect a specific channel, it could be done by channel. and sdp related logic could be done in application.

Copy link
Contributor

Choose a reason for hiding this comment

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

For one specific uuid and there are two rfcomm channels that uses the uuid. I think you mean that user can find the spp sdp services in application or user can use the uuid parameter to let spp profile codes to find the sdp services. How user knows the specific uuid has multiple rfcomm channels in peer, so application needs to find the sdp services firstly. Since the application needs to find the sdp services firstly, I still think it's not neccessary to put the sdp discovery in spp profile.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For one specific uuid and there are two rfcomm channels that uses the uuid. I think you mean that user can find the spp sdp services in application or user can use the uuid parameter to let spp profile codes to find the sdp services. How user knows the specific uuid has multiple rfcomm channels in peer, so application needs to find the sdp services firstly. Since the application needs to find the sdp services firstly, I still think it's not neccessary to put the sdp discovery in spp profile.

@MarkWangChinese It doesn't sound like it's necessary to remove it.
In most case,there would be only a rfcomm channel within in a specific sdp. in many rfcomm channel cases, bt_spp_connect would connect all channel one by one. The current implementation is just like Android do.

and app could connect spp by channel as well. I think we need to consider ease of use that api

Add SPP test shell commands, support client and server features.
include `register`, `connect`, `send` and `disconnect`.

Signed-off-by: Kai Cheng <[email protected]>
zephyr_library()
zephyr_library_sources(bredr.c)
zephyr_library_sources_ifdef(CONFIG_BT_RFCOMM rfcomm.c)
zephyr_library_sources_ifdef(CONFIG_BT_RFCOMM spp.c)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

move rfcomm.c to bredr.c?

Copy link

@lylezhu2012 lylezhu2012 changed the title Bluetooth: SPP: Add support for Serial Port Profile Bluetooth: Classic: SPP: Add SPP command set Oct 15, 2025
@cvinayak cvinayak removed their request for review October 15, 2025 06:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: Bluetooth Classic Bluetooth Classic (BR/EDR) area: Bluetooth Host Bluetooth Host (excluding BR/EDR) area: Bluetooth

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants