呂品品
摘要:本文介紹了一款基于藍牙、ARM 平臺和Java虛擬機手持設備的遙控智能音樂播放器的具體實現。詳細闡述了系統藍牙遙控的實現;為了在客戶端進行音樂播放,討論了基于OBEX協議的音樂文件的下載功能模塊的實現;設計實現了對客戶端音樂播放進度的控制,并對客戶端接收過程中遇到的藍牙字符串亂碼問題加以解決。
關鍵詞:音樂播放器;藍牙;OBEX
1.藍牙遙控的實現
藍牙通信實現不同設備之間的數據共享與數據交換,提供的是近距離設備之間的通信。藍牙鏈接的建立依據藍牙設備所處的地位分為主動鏈接和被動鏈接。對于每一次藍牙通信鏈接的建立,服務器總是出于被動鏈接的地位,服務器必須先行啟動,時刻監聽,只要有客戶機請求,就立即處理并響應回傳信息,但決不會主動提供服務。客戶機可以隨時提出請求,通過網絡得到服務,也可以關機離開,一次請求與服務的過程是由客戶機首先激發的。在客戶端建立主動鏈接的過程中,需要首先進行設備發現和服務發現,然后進行數據傳輸。在服務器建立被動鏈接的過程中,需要首先選擇傳輸協議,然后監聽到來的鏈接請求,之后接收鏈接請求,建立鏈接,開始進行數據的傳輸。
由于系統端口資源有限,對一個服務器應用程序不能獨自占用一個端口號,而且獨占端口會導致兩個不同的server程序在同一個端口進行監聽,出現端口沖突。為了解決這一問題,藍牙協議在標準端口運行SDP服務解決。當服務器程序啟動時會注冊服務記錄到SDP服務,SDP為其動態分配端口。當遠程客戶端鏈接到設備時,首先向服務器提供所搜索的服務的UUID,SDP server然后返回符合的服務列表,這樣就避免了問題的發生。
2.基于OBEX的客戶端文件推送與音樂文件下載
OBEX 傳輸協議定義了數據對象及兩個設備用來交換這些對象的通信協議。OBEX 使應用程序能在 Bluetooth 技術協議棧及 IrDA棧上工作。對于Bluetooth設備,僅支持面向連接的 OBEX。藍牙協議棧的RFCOMM協議可以仿效RS-232 串行端口的狀態和串行電纜線設置,用于提供串行數據傳輸。通過提供串行端口仿真,RFCOMM 可以同時支持系統保留串行端口應用程序以及應用程序中的OBEX協議。因此,選用了基于RFCOMM的OBEX實現文件的傳輸。
播放器服務器端在向進入服務區內的藍牙設備發送文件之前,需要先判斷該設備是否支持OBEX協議。若發現設備支持OBEX_FILE_PUSH服務并獲得其端口號,則推送客戶端給用戶,若沒有發現響應的端口則進行下一次的推送,直到所有被發現設備全部執行結束為止,客戶端推送結束。服務器對進入服務范圍內的藍牙手持設備,發送廣播信息,獲取設備的MAC地址。而后根據MAC地址,使用SDP協議,查詢手持設備上用于支持OBEX協議傳輸的RFCOMM所使用的channel號。通過該channel號,服務器與手持終端建立了面向連接的傳輸。服務器首先使用這個鏈接管道向手持終端發送提示信息,如果手持終端確認接受文件下載,那么服務器向管道寫入文件數據流,直至傳輸完畢;如果用戶選擇拒絕接受,服務器將與該客戶斷開連接,選擇下一個藍牙設備進行發送。
音樂下載功能的實現利用了文件推送模塊。客戶端鏈接管理線程收到下載音樂命令后通過OBEX協議對對應的音樂進行下載,為了實現代碼的復用,對當前客戶端的物理地址信息進行了標識,若搜索的設備地址信息與客戶端匹配,則建立鏈接并發送對應的歌曲到手機客戶端中。客戶端推送和音樂下載過程中都用到OBEX推送。在實現的過程中首先通過系統調用fork( )建立子進程,在子進程中再通過系統調用執行/mnt/yaffs目錄下的obex_test程序完成文件的具體推送。
3.客戶端歌曲播放進度的實現
為了實現歌曲播放時間的動態顯示,使用了java.util包下的Timer類和TimerTask類。首先通過timer = new Timer();初始化計時器對象。通過task = new ClockTask(this);初始化定時任務的對象實例。ClockTask擴展java.util包中的TimerTask類并且實現其中的run()方法,在run()方法中編寫邏輯代碼,ClockTask維持一個實例變量count,在每次run()運行的時候把count加1,這樣就可以記錄時間。為了實現暫停以及重新啟動,在ClockTask中添加一個boolean類型的標記。
通過timer.schedule(task, 0, 1000); 方法設定計時開始,每經過1s調用clocktask對象的run方法更新客戶端界面歌曲當前時間。由此實現了歌曲的播放時間進度顯示功能。
4. 客戶端接收藍牙字符串亂碼的解決
服務器通過L2CAP協議傳輸給客戶端信息的編碼方式為UNICODE,為了實現傳輸中文。需要將客戶端接收的信息進行處理。各種編碼格式如下,
UTF-8: 1-3字節可變;
UNICODE: 2字節一個字符;
GB2312: 2字節一個字符。
為了區分不同的字符,在服務器端對發送信息做了進一步的處理,在各個字符之間使用"#"進行間隔,在客戶端首先將接收字符串用"#"分割。對獲得的每個字符單獨處理,如字符長度為4則傳輸數據為整型數據,通過Java中靜態的處理方法,將其轉換為整形,并進一步追加到返回字符串中去,若本身為字符數據,則直接追加至返回字符串,由此實現了中文信息的傳輸。
參考文獻:
[1]博創科技.UP-NETARM2410-S Linux 嵌入式系統實驗指導書[M].北京: 博創興業科
[2]金純、林金朝,藍牙協議及其源代碼分析. 國防工業出版社,2006年第 1 版.
[3]孫瓊.嵌入式Linux應用程序開發詳解.人民郵電出版社,2006.
[4]周立功等.ARM嵌入式系統基礎教程.第1版.北京航空航天大學出版社.2005.
[5]高建華,王殊. 基于 S3C2410 型微處理器和 UDAl341 型立體聲音頻編解碼器的嵌入式音頻系統設計. 國外電子與元器件,2006.endprint