// 这个函数是设置蓝牙服务安全,没有仔细研究,simple中搬出来
void CBtSvr::SetSecurityOnChannelL(TBool aAuthentication,
TBool aEncryption,
TBool aAuthorisation,
TInt aChannel)
{
const TUid KUidBTMobTimeObexAppValue = {0x0};
// a connection to the security manager
RBTMan secManager;
// a security session
RBTSecuritySettings secSettingsSession;
// define the security on this port
User::LeaveIfError(secManager.Connect());
CleanupClosePushL(secManager);
User::LeaveIfError(secSettingsSession.Open(secManager));
CleanupClosePushL(secSettingsSession);
// the security settings
TBTServiceSecurity serviceSecurity(KUidBTMobTimeObexAppValue, KSolBtRFCOMM, 0);
//Define security requirements
serviceSecurity.SetAuthentication(aAuthentication);
serviceSecurity.SetEncryption(aEncryption);
serviceSecurity.SetAuthorisation(aAuthorisation);
serviceSecurity.SetChannelID(aChannel);
TRequestStatus status;
secSettingsSession.RegisterService(serviceSecurity, status);
User::WaitForRequest(status); // wait until the security settings are set
User::LeaveIfError(status.Int());
CleanupStack::PopAndDestroy(); // secManager
CleanupStack::PopAndDestroy(); // secSettingsSession
}
// 注册蓝牙串口服务
int CBtSvr::RegieterBlueToothServerL(const TDesC& KServiceName, TInt KSerialClassID)
{
// reg the sdp server database
RSdp sdp;
RSdpDatabase iSdpDatabase;
TSdpServRecordHandle iRecord;
// sdp服务器连接
if(sdp.Connect() != KErrNone) {
return -CNSE_SYS_ERR;
}
// 打开数据库
if(iSdpDatabase.Open(sdp) != KErrNone) {
return -CNSE_SYS_ERR;
}
// 创建一个服务
iSdpDatabase.CreateServiceRecordL(KSerialClassID, iRecord);
// add a Protocol to the record
CSdpAttrValueDES* vProtocolDescriptor = CSdpAttrValueDES::NewDESL(NULL);
CleanupStack::PushL(vProtocolDescriptor);
// 设置protocl相关信息
BuildProtocolDescriptionL(vProtocolDescriptor, channelNum);
iSdpDatabase.UpdateAttributeL(iRecord,
KSdpAttrIdProtocolDescriptorList,
*vProtocolDescriptor);
// Add 0x5 display 设置为可见
CSdpAttrValueDES* browseGroupList = CSdpAttrValueDES::NewDESL(NULL);
CleanupStack::PushL(browseGroupList);
browseGroupList
->StartListL() // List of protocols required for this method
->BuildUUIDL(TUUID(TUint16(0x1002)))
->EndListL();
iSdpDatabase.UpdateAttributeL(iRecord, KSdpAttrIdBrowseGroupList, *browseGroupList);
CleanupStack::PopAndDestroy(2);
// Add a name to the record,名字
iSdpDatabase.UpdateAttributeL(iRecord,
KSdpAttrIdBasePrimaryLanguage +
KSdpAttrIdOffsetServiceName,
KServiceName);
// Add a description to the record,描述
iSdpDatabase.UpdateAttributeL(iRecord,
KSdpAttrIdBasePrimaryLanguage +
KSdpAttrIdOffsetServiceDescription,
KServiceName);
iSdpDatabase.Close();
sdp.Close();
return 0;
}
// 这里设置蓝牙SDP服务中的协议相关信息
void CBtSvr::BuildProtocolDescriptionL(CSdpAttrValueDES* aProtocolDescriptor, TInt aPort)
{
TBuf8<1> channel;
channel.Append((TChar)aPort);
aProtocolDescriptor
->StartListL()
->BuildDESL()
->StartListL() // Details of lowest level protocol
// L2CAP层之上
->BuildUUIDL(KL2CAP)
->EndListL()
->BuildDESL()
->StartListL()
->BuildUUIDL(KRFCOMM)
// 这里是绑定的RFCOMM的端口号
->BuildUintL(channel)
->EndListL()
->EndListL();
}
int CBtSvr::BuildSerivce(const TDesC& ServiceName, TInt KSerialClassID)
{
TBTSockAddr add;
int ret;
_LIT(KRFCOMM, "RFCOMM");
// connect to server
if (sockSvr.Connect() != KErrNone) {
return -1;
}
// Open a socket
if(listenSock.Open(sockSvr, KRFCOMM) != KErrNone) { // ERR_OPEN
ret = -1;
goto ERR_CONN;
}
// 得到一个可用的RFCOMM端口号
listenSock.GetOpt(KRFCOMMGetAvailableServerChannel, KSolBtRFCOMM, channelNum);
add.SetPort(channelNum);
if(listenSock.Bind(add) != KErrNone) {
ret = -1;
goto ERR_OPEN;
}
else {
// 设置安全信息
TRAPD(err, (SetSecurityOnChannelL(EFalse, EFalse, ETrue, channelNum)));
if (err != KErrNone) {
ret = -1;
goto ERR_OPEN;
}
// 注册SDP服务
TRAP(err, (RegieterBlueToothServerL(ServiceName, KSerialClassID)));
if (err != KErrNone) {
ret = -1;
goto ERR_OPEN;
}
return 0;
}
ERR_OPEN:
listenSock.Close();
ERR_CONN:
sockSvr.Close();
return ret;
}
整个CBtSvr就完成了,其实看着代码比较多,其实就实现了两个功能。蓝牙服务如果有什么不清楚可以多看看SDK自带的那几个示例代码,还有一些nokia提供的相关文档。