Linux下基於bluez與obex的服務端實現流程:
一個服務端需要給對方提供OBEX Object Push服務的通道,所以在開啟伺服器之前需要確定已經將該服務註冊到SDP伺服器,Linux下使用sdptool註冊該服務的命令為:sdptool add opush;
1.OBEX_Init()用於初始化一個obex instance handle;
arg1:OBEX_TRANS_BLUETOOTH用於聲明傳輸協議為bluetooth;
arg2:callback function;
arg3:flag=OBEX_FL_KEEPSERVER,接收到請求後,伺服器可以繼續接收其他用戶端的請求;
2.OBEX_SetUserData()設定使用者自己的變數,該函數的使用完全取決於使用者自己;
3.BtOBEX_ServerRegister();一個專用於藍芽協議的服務端函數,用於監聽用戶端發送的請求;
該函數內部建立了一個
socket(調用socket(AF_BLUETOOTH, SOCK_STREAM,
BTPROTO_RFCOMM)),bind該socket到本地藍芽地址,將該socket轉化為監聽sockt,之後該socket才能夠監聽連接埠上
來自用戶端的串連請求;
4.OBEX_HandleInput()函數用於讀取並處理接收到的資料,如果沒有資料到達,該函數將會阻塞;
該函數內部調用了selet()函數,向系統登記了參數handle的用戶端sockt與服務端sockt,讓系統監聽socket上的事件,如果是服務端socket上有資料到達,則調用accept()函數為用戶端建立一個新的sockt,
如果OBEX_Init()的flag不是設定為OBEX_FL_KEEPSERVER,則關掉服務端socket,禁止其他用戶端的串連請求;
(???:accept()
為用戶端建立一個新的socket,並返回其描述符,那麼新建立的socket的連接埠是重新分配的呢還是原先服務端的channel,如果重新分配,則只
在服務端的channel上註冊了服務,如果沒有重新分配,那麼是多個用戶端用同一個channel麼o(∩_∩)o...)
5.callback:OBEX_EV_ACCEPTHINT;
6.OBEX_ServerAccept()該函數返回上述用戶端的socket;
函數內部重新建立了一個obex instance handle,並將上述伺服器handle的參數複製到該handle,獲得伺服器handle的fd(accept為用戶端建立的socket)後,清除伺服器本身的fd;
該函數同時也為新建立的obex instance handle設定callback function及Userdata;
至此,已經為用戶端建立了一個與服務端完全獨立的obex instance handle,此後該服務端的操作都由該handle標識,而伺服器的socket則繼續監聽其他用戶端的串連請求;
7.callback:OBEX_EV_REQHINT一個請求即將到來;
調用OBEX_ObjectSetRsp(object,OBEX_RSP_CONTINUE,OBEX_RSP_SUCCESS)設定響應作業碼;
8.callback:OBEX_EV_REQ::OBEX_CMD_CONNECT
調用OBEX_ObjectSetRsp(object,OBEX_RSP_SUCCESS,OBEX_RSP_SUCCESS)設定響應作業碼;
9.callback:OBEX_EV_REQDONE:OBEX_CMD_CONNECT;
10.callback:OBEX_EV_REQHINT一個請求即將到來;
調用OBEX_ObjectSetRsp(object,OBEX_RSP_CONTINUE,OBEX_RSP_SUCCESS)設定響應作業碼
11.callback:OBEX_EV_REQCHECK:第一個接收到的請求包已經被解析;
12.callback:OBEX_EV_PROGRESS(收到n個此事件,說明用戶端正在傳輸檔案內容);
13.callback:OBEX_EV_REQ :OBEX_CMD_PUT;
OBEX_ObjectSetRsp(object,OBEX_RSP_CONTINUE,OBEX_RSP_SUCCESS)設定響應作業碼;
此時,用戶端檔案傳輸完畢,需進行處理:
OBEX_ObjectGetNextHeader()分別取得檔案的名稱與內容;
14.callback:OBEX_EV_REQDONE:OBEX_CMD_PUT;
15.callback:OBEX_EV_REQHINT一個請求即將到來
16.callback:OBEX_EV_REQ::OBEX_CMD_DISCONNECT
OBEX_ObjectSetRsp(object,OBEX_RSP_SUCCESS,OBEX_RSP_SUCCESS)設定響應作業碼;
17.callback:OBEX_EV_REQDONE:OBEX_CMD_DISCONNECT;
OBEX_TransportDisconnect(handle)中斷連線;
注意:該函數只是將socket關閉,並沒有釋放handle所佔用的資源,所以在應用時需要釋放handle佔用的資源;
18.OBEX_Cleanup()關掉obex handle並釋放該handle佔用的資源。
(該函數同樣關閉了用戶端及服務端socket);
至此,伺服器接收用戶端的一個案例完成。