Symbian 中的sdp服務

其實SDP是一個很簡單的協議.關鍵在於搞清楚其中的概念.說實話,這裏面的概念的確是很容易亂.

服務: 是一個實體,是一個服務類的一個實體.用來提供信息,執行某個動作.它可以由軟件,硬件或兩者的結合來組成.服務句柄屬性是表示它的關鍵屬性.

服務記錄:保存了描述一個服務的信息.服務記錄是由一個服務屬性列表組成的.

服務類: 每一個服務都是服務類的一個實例。服務類定義提供對所有包含於服務記錄中屬性的定義。它也是用UUID來表示的.

服務屬性:描述了某一個服務的一個特徵。由兩部分組成屬性ID(16 bit)和屬性值.

屬性ID: 16位,也就是兩個字節.服務所屬的服務類決定了該服務的服務記錄中的屬性ID的語義.

屬性值: 是一個數據元.

服務瀏覽組:由服務記錄中的BrowseGroupList屬性來表現.這個屬性的值是一個UUID列表.其中保存的是瀏覽組的UUID.如果一個服務屬於某個瀏組,則它的BrowseGroupList屬性中就有這個瀏覽組的UUID.
GroupID定義了一個瀏覽組.它也是一個屬性值.

以上是SDP的核心概念.可以類比爲每個服務記錄是一個服務的定義.但服務類不需要服務記錄來實際的定義.它們都是在屬性中直接使用.因爲這些服務類是SIG(The Bluetooth Special Interest Group (SIG))已經定義的.它們的UUID可參見Assigned Numbers.但用戶自定義的服務瀏覽組是需要服務記錄來定義的.

以下兩個屬性是每一個記錄都必須有的
ServiceRecordHandle: 32位。SDP服務的服務記錄的該屬性爲0x0000 0000.
ServiceClassIDList: 該屬性決定了服務記錄所表示的服務所屬的服務類.

當某個服務的服務記錄的ServiceClassIDList屬性中包含了ServiceDiscoveryServerServiceClassID,則該服務記錄就是一個SDP服務的定義。它的服務句柄是固定的0x00000000.
當某個服務的服務記錄的ServiceClassIDList屬性中包含了BrowseGroupDescriptorServiceClassID,則該服務記錄就是一個瀏覽組的定義。這個服務記錄中要用GroupID屬性,定義該服務瀏覽組的UUID.
當某個服務的服務記錄的ServiceClassIDList屬性中包含了PublicBrowseRoot,則該服務屬於公共瀏覽根目錄.

ServiceDiscoveryServerServiceClassID = 0x1000
BrowseGroupDescriptorServiceClassID = 0x1001
PublicBrowseRoot = 0x1002 (注:在www.bluetooth.org新的Assigned Numbers文件中,PublicBrowseRoot已經改爲PublicBrowseGroup)
 
 
#include <btsdp.h> //sdpdatabase.lib
static const TInt KSerialClassID = 0x1101;
static const TInt KChannel = 1; // Channel
static const TInt KUidBTAdvertiserAppValue = { 0xEFF55B8B };
 
_LIT( KServiceName, "Serial" );
_LIT( KServiceDescription, "Serial transfer" );
 
private:    // Data

    RSdp iSdpSession;

    RSdpDatabase iSdpDatabase;

    TSdpServRecordHandle iRecord;

 
 
void CbtAppView::StartAdvertiserL()
 {
 if (!iIsConnected)
  {
  User::LeaveIfError(iSdpSession.Connect());
//  if (iSdpSession.Connect() != KErrNone)
//   Panic( EBTAdvertiserFailedToOpenSession );
  if (iSdpDatabase.Open(iSdpSession) != KErrNone)
   Panic( EBTAdvertiserFailedToOpenDatabase );
  iIsConnected =ETrue;
  }
 iSdpDatabase.CreateServiceRecordL(KSerialClassID, iRecord);
 
    CSdpAttrValueDES* protocolDescriptorList =
        CSdpAttrValueDES::NewDESL( NULL );
    CleanupStack::PushL( protocolDescriptorList );
   
    protocolDescriptorList
    ->StartListL()   //  List of protocols required for this method
        ->BuildDESL()
        ->StartListL()
            ->BuildUUIDL( KL2CAP )
        ->EndListL()
        ->BuildDESL()
        ->StartListL()
            ->BuildUUIDL( KRFCOMM )
            ->BuildUintL( TBuf8<1>( KChannel ) )
        ->EndListL()
    ->EndListL();
   
    iSdpDatabase.UpdateAttributeL(
        iRecord, KSdpAttrIdProtocolDescriptorList, *protocolDescriptorList );
    CleanupStack::PopAndDestroy( protocolDescriptorList );
   
    // Add a Unique ID to the record
    iSdpDatabase.UpdateAttributeL( iRecord,
                                  KSdpAttrIdServiceID,
                                  KUidBTAdvertiserAppValue );
    // Add a name to the record
    iSdpDatabase.UpdateAttributeL( iRecord,
                                  KSdpAttrIdBasePrimaryLanguage +
                                  KSdpAttrIdOffsetServiceName,
                                  KServiceName );
   
    // Add a description to the record
    iSdpDatabase.UpdateAttributeL( iRecord,
                                  KSdpAttrIdBasePrimaryLanguage +
                                  KSdpAttrIdOffsetServiceDescription,
                                  KServiceDescription );
 }
 
CbtAppView::~CbtAppView()
 {
    if ( IsAdvertising() )
        {
        StopAdvertiser();
        }
    iSdpDatabase.Close();
    iSdpSession.Close();
 }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章