2
/***************************************************************************
3
* Copyright (C) 2003 by Fred Schaettgen *
4
* kdebluetooth@schaettgen.de *
6
* This program is free software; you can redistribute it and/or modify *
7
* it under the terms of the GNU General Public License as published by *
8
* the Free Software Foundation; either version 2 of the License, or *
9
* (at your option) any later version. *
10
***************************************************************************/
12
#include "sdpservice.h"
13
#include <qstringlist.h>
14
#include <qtextcodec.h>
33
void Service::addAttribute(int id, const Attribute& attr)
38
attributeList.push_back(entry);
40
// if a LanguageBaseIDList attribute is added, we
41
// use it to set the preferrred language bases according
42
// to the current locale
43
if (id == 0x6 /*LanguageBaseAttributeIDList*/) {
44
QStringList preferredLanguages = KGlobal::locale()->languagesTwoAlpha();
45
AttrVec vec = attr.getSequence();
46
languageBases.clear();
47
languageBaseToMibEnum.clear();
48
for (uint langNum = 0; langNum < preferredLanguages.size(); ++langNum) {
49
bool foundLanguage = false;
50
for (uint n=0; n<vec.size()/3; ++n) {
51
uint16_t intISO = uint16_t(vec[n*3+0].getUInt().lo);
52
uint16_t intEnc = uint16_t(vec[n*3+1].getUInt().lo);
53
uint16_t intOff = uint16_t(vec[n*3+2].getUInt().lo);
55
iso += char(intISO >> 8);
56
iso += char(intISO & 0xFF);
57
kdDebug() << "Found language base attribute with ISO code '"<< iso << "'" << endl;
58
if (iso == preferredLanguages[langNum]) {
59
kdDebug() << "Appending preferred language base " << intOff << endl;
60
languageBases.push_back(intOff);
61
languageBaseToMibEnum[intOff] = intEnc;
68
const Attribute& Service::getAttribute(int index)
70
return attributeList[index].attr;
73
int Service::getAttributeID(int index)
75
return attributeList[index].id;
78
bool Service::getAttributeByID(int id, Attribute& attrib)
80
for (unsigned int n=0; n<attributeList.size(); ++n)
82
if (attributeList[n].id == id)
84
attrib = attributeList[n].attr;
91
bool Service::getI18nAttributeByID(int id, Attribute& attrib, int &languageBase)
93
for (vector<int>::iterator it = languageBases.begin();
94
it != languageBases.end(); ++it)
97
if (getAttributeByID(id + languageBase, attrib)) {
98
kdDebug() << "Using preferred language base " << *it << endl;
102
kdDebug() << "Using default language base" << endl;
103
languageBase = 0x100;
104
return getAttributeByID(id + languageBase, attrib);
107
QString Service::decodeI18nString(int languageBase, const QCString &cstring)
109
QTextCodec *codec = NULL;
110
if (languageBaseToMibEnum.find(languageBase) != languageBaseToMibEnum.end()) {
111
codec = QTextCodec::codecForMib(languageBaseToMibEnum[languageBase]);
114
codec = QTextCodec::codecForName("utf-8");
116
kdDebug() << "Decode string with " << codec->name() << " codec" << endl;
117
return codec->toUnicode(cstring);
120
bool Service::getServiceRecordHandle(uint32_t *handle)
123
bool ret = getAttributeByID(0x00, attrib);
126
if (attrib.getType() == Attribute::UINT)
128
*handle = (uint32_t)attrib.getUInt().lo;
135
bool Service::getServiceName(QString &name)
139
bool ret = getI18nAttributeByID(0x0, attrib, languageBase);
142
if (attrib.getType() == Attribute::STRING)
144
QCString cname = attrib.getString();
145
name = decodeI18nString(languageBase, cname);
152
bool Service::getServiceDescription(QString &desc)
156
bool ret = getI18nAttributeByID(0x1, attrib, languageBase);
159
if (attrib.getType() == Attribute::STRING)
161
QCString cdesc = attrib.getString();
162
desc = decodeI18nString(languageBase, cdesc);
169
vector<SDP::uuid_t> Service::getAllUUIDs()
171
vector<SDP::uuid_t> uuidList;
172
vector<AttributeEntry>::iterator it;
173
for (it = attributeList.begin();
174
it != attributeList.end(); ++it)
176
vector<SDP::uuid_t> subList = it->attr.getAllUUIDs();
177
copy(subList.begin(), subList.end(), back_inserter(uuidList));
182
bool Service::getRfcommChannel(unsigned int &n)
184
// Get the rfcomm channel
185
Attribute protoDescAttr;
186
// Get the the protocol descriptor list attribute (0x04)
187
if (getAttributeByID(0x04 , protoDescAttr) == false) {
191
std::vector<SDP::Attribute> protoDescList = protoDescAttr.getSequence();
192
std::vector<SDP::Attribute>::iterator it;
194
//Search in all subLists of the Protocol Description List.
195
for(it = protoDescList.begin(); it != protoDescList.end(); ++it) {
196
std::vector<SDP::Attribute> attrList = it->getSequence();
197
std::vector<SDP::Attribute>::iterator it;
199
//The List must have at least 2 Attributes
201
// UUID16 : 0x0003 - RFCOMM
202
// Channel/Port (Integer) : 0x6
204
if(attrList.size() >= 2) {
205
it = attrList.begin();
207
// The first Attribute of the list must be an UUID
208
if(it->getType() != Attribute::UUID)
210
// The UUID must have the value of "0x0003" that's the RFCOMM UUID
211
SDP::uuid_t rfcommUUID;
212
rfcommUUID.fromString("0x0003");
213
if(it->getUUID() != rfcommUUID) //RFCOMM UUID
216
//If the UUID is ok we get the rfcomm channel number
217
if(it->getType() != Attribute::UINT)
219
n = it->getUInt().lo;
223
// If we're here, we haven't found a correct Rfcomm channel, so we return false
227
bool Service::haveServiceClassID(SDP::uuid_t uuid) {
229
Attribute ClassIDAttr;
230
// Get the the ClassID descriptor list attribute (0x01)
231
if (getAttributeByID(0x01 , ClassIDAttr) == false)
234
AttrVec ClassIDList = ClassIDAttr.getSequence();
235
AttrVec::iterator it;
236
for(it = ClassIDList.begin(); it != ClassIDList.end(); ++it) {
237
if(it->getType() != Attribute::UUID)
239
if(it->getUUID() == uuid)
245
/** Get a vector of UUID of the services class Id List */
246
SDP::UUIDVec Service::getClassIdList() {
248
SDP::UUIDVec uuidList;
250
Attribute ClassIDAttr;
251
// Get the the ClassID descriptor list attribute (0x01)
252
if (getAttributeByID(0x01 , ClassIDAttr) == false)
255
AttrVec ClassIDList = ClassIDAttr.getSequence();
256
AttrVec::iterator it;
257
for(it = ClassIDList.begin(); it != ClassIDList.end(); ++it) {
258
if(it->getType() != Attribute::UUID)
260
uuidList.push_back(it->getUUID());