
Tìm hiểu công nghệ Bluetooth và viết ứng dụng minh họa
socket L2CAP, “port” sử dụng là Protocol/Service Multiplexer (PSM) , đối với
Bluetooth Socket RFCOMM thì “port” sử dụng là server chanel.
+ Hàm Connect() được sử dụng :
void RSocket::Connect(TSockAddr& anAddr,
TRequestStatus &aRequest)
Tham số : anAddr : địa chỉ socket của thiết bị.
aRequetStatus : Chứa mã lỗi trả về.
Địa chỉ của socket được thể hiện bởi lớp TBTSockAddr vốn kế thừa từ
lớp TSockAddr. Mỗi thiết bị Bluetooth có một địa chỉ 48 bit được thể hiện bởi
lớp TBTDevAddr, lớp TBTSockAddr có hàm SetBTAddr() dùng để gán địa chỉ
thiết bị Bluetooth cho đối tượng của lớp này và hàm SetPort() để chọn một
Channel cụ thể.
void SetBTAddr(const TBTDevAddr& aRemote);
void SetPort(TUint aPort);
Mỗi client phải có các thành phần sau:
SocketServer (RSocketServ): Dùng để giao tiếp với socket server của thiết bị.
SendingSocket: Dùng để kết nối, nhận và gửi dữ liệu đến server socket
Đoạn code sau mô tả việc thực hiện kết nối :
RSocketServ SocketServer;
TInt err;
err = SocketServer.Connect();
User::LeaveIfError(err);
RSocket SendingSocket;
err = SendingSocket.Open(SocketServer,
KBTAddrFamily,
KSockStream,
KRFCOMM);
User::LeaveIfError(err);
TBTSockAddr addr;
Đào Quý Thái An – Trần Thị Mỹ Hạnh 185

Tìm hiểu công nghệ Bluetooth và viết ứng dụng minh họa
TRequestStatus status;
addr.SetBTAddr(…);
addr.SetPort(…);
SendingSocket.Connect(addr, status);
// Nhận và gửi dữ liệu ở đây .....
7.4.4. Trao đổi dữ liệu thông qua Bluetooth socket :
Sau khi thiết lập kết nối thành công, việc nhận và gửi dữ liệu với
Bluetooth socket cũng tương tự như với bất kì loại socket nào khác trên
Symbian (IrDA socket, Internet socket).
* Để nhận dữ liệu ta có thể dùng các hàm Read(), Recv() , hoặc
ReceiveOneOrMore().:
- void Read( TDes8& aDesc,TRequestStatus& aStatus );
- void Recv( TDes8& aDesc,
TUint flags,
TRequestStatus& aStatus);
- void Recv( TDes8& aDesc,
TUint flags,
TRequestStatus& aStatus,
TSockXfrLength& aLen);
- void RecvOneOrMore( TDes8& aDesc,
TUint flags,
TRequestStatus& aStatus,
TSockXfrLength& aLen);
Trong đó:
+ TDes8& aDesc : buffer chứa dữ liệu nhận được.
+ TRequestStatus& aStatus : Sau khi hàm kết thúc, biến này chứa mã lỗi trả về.
Nếu không có lỗi, giá trị của aStatus là KerrNone.
+ TUint flags : các thông tin về Protocol, I/O.
Đào Quý Thái An – Trần Thị Mỹ Hạnh 186

Tìm hiểu công nghệ Bluetooth và viết ứng dụng minh họa
+ TsockXfrLength& aLen : Chiều dài dữ liệu nhận được.
* Để gửi dữ liệu, ta dùng hàm Write():
+ void Write(const TDesC8& aDesc, TRequestStatus& aStatus);
+ void Send(const TDesC8& aDesc,
TUint someFlags,
TRequestStatus& aStatus);
+ void Send(const TDesC8& aDesc,
TUint someFlags,
TRequestStatus& aStatus,
TSockXfrLength& aLen);
Trong đó:
+ TDesC8& aDesc : Dữ liệu cần gửi đi.
+ TResquestStatus& aStatus : Sau khi hàm kết thúc, mã lỗi được
trả về qua biền này.
+ TUint flags : các thông tin về Protocol, I/O.
+ TsockXfrLength& aLen : Chiều dài dữ liệu gửi đi.
7.5. Bluetooth Service Discovery Database:
Mỗi dịch vụ Bluetooth được lưu trong một record trong SDP database,
nhờ đó, các thiết bị khác có thể biết được trên thiết bị Bluetooth đó có những
dịch vụ nào. Bluetooth Service Discovery Database cho phép các dịch vụ trên
nội bộ thiết bị có thể đưa các đặc tính của nó vào trong Bluetooth Service
Database, nhờ đó, các thiết bị Bluetooth khác có thể phát hiện được là dịch vụ
đó được hỗ trợ trên thiết bị đó.
7.5.1. Kết nối vào Bluetooth Service Discovery Database :
Để có thể sử dụng Service Discovery Database, client phải thực hiện các
bước sau :
Đào Quý Thái An – Trần Thị Mỹ Hạnh 187

Tìm hiểu công nghệ Bluetooth và viết ứng dụng minh họa
+ Tạo một phiên làm việc (session) với đối tượng database RSdp và mở
một kết nối
+ Tạo ra một phiên làm việc con (subsession) tới đối tượng Database
RsdpDatabase và mở kết nối. Một client có thể có nhiều phiên làm việc con
đồng thời.
+ Đóng subsession và session khi đã sử dụng xong.
Đoạn code sau minh họa cách thức kết nối tới Service Database :
//1. Tạo và mở một phiên làm việc đến database
RSdp sdp;
User::LeaveIfError(sdp.Connect());
// 2. Create and open a subsession
RSdpDatabase sdpSubSession;
User::LeaveIfError(sdpSubSession.Open(sdp));
...
// 3. Đóng các kêt nối đã mở.
sdpSubSession.Close();
sdp.Close();
7.5.2. Đăng kí một dịch vụ vào Service Database :
Sau khi Service Discovery Database được mở ra, một service record có
thể được tạo ra. Việc đó được thực hiện bằng việc cung cấp một giá trị UUID
(Bluetooth Universally Unique Identifier) cho lớp dịch vụ (service class) của
record. Service class có thể là một giá trị UUID hoặc một list các giá trị UUID
ở dạng DES.
Các bước đăng kí một dịch vụ vào Database :
+ Tạo ra một record dịch vụ trống thuộc đối tượng
TSdpServRecordHandle, là handle của một service record.
+ Nếu thuộc tính của service class là một giá trị đơn UUID, tạo ra và
thiết lập một đối tượng TUUID. Nếu thuộc tính của service class là một danh
Đào Quý Thái An – Trần Thị Mỹ Hạnh 188

Tìm hiểu công nghệ Bluetooth và viết ứng dụng minh họa
sách các giá trị UUID, tạo ra một đối tượng danh sách thuộc tính thuộc lớp
CSdpAttrValueDES hoặc lớp CSdpAttrValueDEA , và gọi hàm
MsdpElementBuilder::BuildUUIDL() đối với từng thuộc tính để đưa vào danh
sách thuộc tính.
+ Gọi hàm RSdpDatabase::CreateServiceRecordL() ở trong một
subsession đã mở. Hàm trả về một handle trỏ tới service record mới tạo.
* Đoạn code sau một tả cách tạo một service record với một đối tượng
dịch vụ đơn (single service class) :
/* Giả sử sdpSession là một phiên làm việc với đối tượng Database đã được
mở thành công, sdpsubsession : phiên làm việc con */
// 1. Tạo ra một Record Handle trống
TSdpServRecordHandle recordHandle = 0;
// 2.Tạo ra đối tượng service class đơn và thiết lập giá trị của nó
TUUID uuid(0x20000);
// 3. Đưa record mới tạo vào Database .
sdpSubSession.CreateServiceRecordL(uuid, recordHandle);
* Đối với danh sách thuộc tính, ta dùng hàm StartListL() để báo hiệu
việc bắt đầu thao tác với list, hàm BuildxxxL() để thêm dữ liệu vào danh sách,
tùy vào loại dữ liệu mà sử dụng các hàm BuildxxxL() khác nhau, như hàm
BuildURLL(), BuildDESL(), BuildIntL(), BuildUUIDL()....., Sau đó, ta dùng
hàm EndList() để đóng danh sách lại.
* Giả sử ứng dụng cần đưa vào service record một thuộc tính là danh
sách các giao thức (protocol) mà ứng dụng hỗ trợ, đoạn chương trình sau minh
họa việc tạo một danh sách gồm 2 protocol. Protocol đầu tiên là L2CAP.
Protocol thứ 2 là RFCOMM kèm theo một số nguyên đại diện cho kênh truyền
(channel), và đưa vào Database.
/ /1. Tạo ra một record handle trống :
TSdpServRecordHandle recordhandle =0;
Đào Quý Thái An – Trần Thị Mỹ Hạnh 189

