22/08/2018, 10:54

OBEX và kỹ thuật lập trình cho cổng hồng ngoại, Bluetooth

Chúng ta đang sống trong một thế giới mà các thiết bị không dây dần len lỏi vào cuộc sống của mỗi gia đình. Từ chiếc điện thoại di động (ĐTDĐ) xinh xắn, thiết bị hỗ trợ cá nhân đa năng (Pocket PC, Palm...), đến các phương tiện giải trí trong gia đình như hệ ...

Chúng ta đang sống trong một thế giới mà các thiết bị không dây dần len lỏi vào cuộc sống của mỗi gia đình. Từ chiếc điện thoại di động (ĐTDĐ) xinh xắn, thiết bị hỗ trợ cá nhân đa năng (Pocket PC, Palm...), đến các phương tiện giải trí trong gia đình như hệ thống loa, đầu DVD, tivi, tất cả được kết nối với nhau mà không cần một sợi dây nào. Nếu bạn đã từng đặt câu hỏi: "Có thể lập trình để truyền tải dữ liệu hình ảnh, âm thanh vào ĐTDĐ qua cổng hồng ngoại hay Bluetooth?" thì bài viết này sẽ giúp bạn hình dung cách thức và hướng giải quyết vấn đề trên.

OBEX LÀ GÌ?

OBEX (OBject EXchange) là giao thức trao đổi dữ liệu giữa các thiết bị dùng cổng hồng ngoại được hiệp hội IrDA (Infrared Data Association) đưa ra lần đầu tiên năm 1997. Ban đầu, giao thức này chỉ giới hạn cho các thiết bị sử dụng môi trường ánh sáng hồng ngoại, nhưng rất nhanh sau đó nó được tổ chức Bluetooth SIG (Bluetooth Special Interest Group) đưa vào hầu hết các thiết bị Bluetooth của mình.

1. Vị trí OBEX trong mô hình OSI

Cũng giống như các giao thức khác, giao thức OBEX được xây dựng trên nền mô hình OSI (Open Systems Interconnection) bao gồm hai thành phần chính:

OBEX session protocol (giao thức phiên OBEX): mô tả cấu trúc gói tin trong phiên làm việc giữa hai thiết bị.

OBEX application framework: tập các dịch vụ OBEX cung cấp cho các ứng dụng đầu cuối như truyền file, in ảnh...

OBEX Application

ó

Tầng ứng dụng
OBEX Framework
OBEX Session Tầng phiên
  Tầng trình diễn
Tiny TP RFCOMM Tầng giao vận
IrLMP L2CAP Tầng mạng
IrLAP Link
Manager
Tầng liên kết dữ liệu
IrPHY Baseband Tầng vật lý
IrDA Bluetooth OSI

Hình 1: Giao thức OBEX trong mô hình OSI

2. Cấu trúc gói tin trong giao thức phiên OBEX

Giao thức OBEX được sử dụng chủ yếu trong các ứng dụng kiểu "đẩy" (Push) hoặc "kéo" (Pull), cho phép máy khách (client) "đẩy" dữ liệu lên máy chủ (server) hoặc "kéo" dữ liệu từ server xuống. Để thực hiện điều này, các gói tin trao đổi giữa client và server phải tuân thủ chặt chẽ cấu trúc đề ra. Dưới đây là một vài cấu trúc được sử dụng trong quá trình truyền file giữa client và server (chi tiết có thể tham khảo tài liệu IrOBEX1.3 trên website http://www.hitekgroup.net).

2.1 Gói tin yêu cầu

Mọi gói tin yêu cầu đều có cấu trúc như sau:

 

Byte 0

    Byte 1, 2     Byte 3 đến n  
 

opcode

   

packet length

    Headers  

Opcode: Mã lệnh ứng với từng yêu cầu (Bảng 1). Bit cao nhất gọi là Final bit.

Packet length: Độ dài của gói tin

Header: Thông tin đầu có cấu trúc như sau:

  Byte 0     Byte 1, 2     Byte 3 đến n  
  header identifier     length (tuỳ chọn)     value  

  Bảng 1: Mã lệnh yêu cầu  
  Mã lệnh     Kiểu    

Mô tả

 
  0x80     CONNECT     Thiết lập phiên giao dịch  
  0x81     DISCONNECT     Ngừng phiên giao dịch  
  0x02 (0x82)     PUT     Gửi dữ liệu lên server  
  0x03 (0x83)     GET     Lấy dữ liệu từ server  
  0xFF     ABORT     Hủy bỏ phiên giao dịch  

  Bảng 2: Thông tin đầu  
  Định danh     Tên     Mô tả  
  0x01     NAME     Tên file (mã Unicode)  
  0xC3     LENGTH     Kích thước file theo byte  
  0x48     BODY     Đoạn dữ liệu của file  
  0x49     END OF BODY     Đoạn dữ liệu cuối cùng của file  

2.2 Gói tin trả lời

Giống như gói tin yêu cầu, gói tin trả lời có cấu trúc như sau:

  Byte 0     Byte 1, 2     Byte 3 to n  
  response opcode     response length     response data  

Một số mã trả lời (response opcode) thường gặp:

  Bảng 3: Mã trả lời  
  Mã trả lời     Mô tả  
  0x10 (0x90)     Tiếp tục yêu cầu hoặc trả lời  
  0x20 (0xA0)     Xác nhận kết thúc yêu cầu hoặc trả lời  
  0x40 (0xC0)     Lỗi yêu cầu  
  0x41 (0xC1)     Lỗi do không có quyền  
  0x43 (0xC3)     Phiên giao dịch bị huỷ bỏ  
  0x44 (0xC4)     Không tìm thấy file  

3. Cùng giải quyết

Quá trình trao đổi file giữa client và server được chia làm 3 giai đoạn:

Thiết lập phiên: CONNECT

Nhận/gửi file: GET/PUT

Ngừng phiên: DISCONNECT

3.1 Thiết lập phiên (CONNECT)

Gói tin CONNECT có cấu trúc như sau:

  Byte 0 0     Byte 1, 2     Byte 3     Byte 4     Byte 5, 6     Byte 7 to n  
  0x80     packet length     OBEX version number     flags     maximum OBEX packet length     optional headers  

OBEX version number: Phiên bản giao thức OBEX gồm major number lưu tại 4 bit cao, minor number lưu tại 4 bit thấp. Phiên bản hiện tại là 1.0, do đó giá trị này là 0x10.

Flags: Giá trị này luôn là 0x00 trong phiên bản hiện tại.

Maximum OBEX packet length: Giá trị lớn nhất của gói tin trong giao thức OBEX mà thiết bị có thể nhận hoặc gửi. Giá trị này ở client và server có thể khác nhau. Do đó khi thiết lập phiên, client cần gửi giá trị này lên server để kiểm tra xem kích thước gói tin lớn nhất mà server có thể nhận hoặc gửi là bao nhiêu?

Optional headers: Thông tin đầu được tùy chọn ứng với mục đích của mỗi phiên giao dịch. Trong ví dụ dưới đây, giá trị này có thể bỏ qua.

  Yêu cầu từ client     byte     Ý nghĩa  
  Mã yêu cầu     0x80     CONNECT  
      0x0007     Độ dài gói tin = 7 bytes  
      0x10     Phiên bản OBEX 1.0  
      0x00     Flags đối với phiên bản hiện tại  
      0x2000     Kích thước lớn nhất của gói tin là 8K  

  Trả lời từ server  
  Mã trả lời     0xA0    

SUCCESS

 
        0x0007     Độ dài gói tin = 7 bytes  
        0x10     Phiên bản OBEX 1.0  
        0x00     Flags đối với phiên bản hiện tại  
        0x0200     Kích thước lớn nhất của gói tin mà server có thể nhận hoặc gửi là 512 bytes  

3.2 Gửi file (PUT)

Không giống như gói tin CONNECT, gói tin PUT có thêm một số thông tin đầu sau:

NAME: Thông tin về tên file

LENGTH: Thông tin về kích thước file

BODY: Đoạn dữ liệu file

END OF BODY: Đoạn dữ liệu cuối cùng của file

Dưới đây là ví dụ gửi 1 file hello.gif có kích thước 721 bytes từ client (PC) lên server (ĐTDĐ). Do kích thước của file lớn hơn kích thước gói tin lớn nhất mà server có thể nhận (với Sony Ericsson T610 là 512 bytes) nên client sẽ chia file thành hai gói tin để gửi. Gói tin 1 có mã yêu cầu PUT là 0x02 (không thiết lập Final bit). Gói tin 2 có mã yêu cầu PUT là 0x82 (thiết lập Final bit).

  Yêu cầu từ client     byte     Ý nghĩa  
  Mã yêu cầu     0x02     PUT, Final bit không thiết lập để chỉ cho server biết client còn gửi yêu cầu tiếp theo  
      0x01E2     Độ dài gói tin = 482 bytes  
      0x01     Định danh thông tin đầu NAME (tên file)  
      0x0017     Độ dài của thông tin đầu NAME = 20+3 = 23 bytes  
      hello.gif     Tên file (unicode) có ký tự kết thúc NULL (20 bytes)  
      0xC3     Định danh thông tin đầu LENGTH (kích thước file)  
      0x000002D1     Kích thước file = 721 bytes  
      0x48     Định danh thông tin đầu BODY (dữ liệu file)  
      0x01C3 &
0