📄 e32socketmodule.cpp
字号:
if (iSdpSearchPattern != NULL) {
delete iSdpSearchPattern;
iSdpSearchPattern = NULL;
}
iSdpSearchPattern = CSdpSearchPattern::NewL();
iSdpSearchPattern->AddL(ServiceClass());
iAgent->SetRecordFilterL(*iSdpSearchPattern);
iStatusObserver = &aStatus;
iAgent->NextRecordRequestL();
}
void BTSearcher::AttributeRequestComplete(TSdpServRecordHandle aHandle, TInt aError)
{
TRAPD(error,
(AttributeRequestCompleteL(aHandle, aError) ));
if (error != KErrNone) {
SPyErr_SetFromSymbianOSErr(EBTServiceSearcherAttributeRequestComplete);
return;
}
}
void BTSearcher::AttributeRequestCompleteL(TSdpServRecordHandle /*aHandle*/, TInt /*aError*/)
{
if (!HasFinishedSearching()) // have not found a suitable record so request another
iAgent->NextRecordRequestL();
else
Finished();
}
void BTSearcher::AttributeRequestResult(TSdpServRecordHandle aHandle, TSdpAttributeID aAttrID, CSdpAttrValue* aAttrValue )
{
TRAPD(error,
(AttributeRequestResultL(aHandle, aAttrID, aAttrValue) ));
if (error != KErrNone) {
SPyErr_SetFromSymbianOSErr(EBTServiceSearcherAttributeRequestResult);
return;
}
if (sequence == ADDNAME)
if (iIsNameFound && iIsServiceFound) {
Dictionary* tmp = Dictionary::NewL();
tmp->item.key.Copy(attribute.Ptr(), attribute.Length());
tmp->item.value = Port();
SDPDict->iStack.AddLast(*tmp);
sequence = NONE;
}
attribute.FillZ(MaxAttributeSize);
delete aAttrValue;
}
void BTSearcher::AttributeRequestResultL(TSdpServRecordHandle /*aHandle*/, TSdpAttributeID aAttrID,
CSdpAttrValue* aAttrValue)
{
TSdpAttributeParser parser(ProtocolList(), *this);
if ( aAttrID == KSdpAttrIdBasePrimaryLanguage+KSdpAttrIdOffsetServiceName ) {
if ( aAttrValue->Type() == ETypeString) {
TPtrC8 tmp(aAttrValue->Des());
attribute.Copy((TUint8*)(tmp.Ptr()), tmp.Length());
if (tmp.Length()>0)
iIsNameFound = ETrue;
sequence = ADDNAME;
}
}
if (aAttrID == KSdpAttrIdProtocolDescriptorList) {
if (aAttrValue->Type() == ETypeUint) {
iPort = aAttrValue->Uint();
}
if ((aAttrValue->Type() == ETypeDEA) || (aAttrValue->Type() == ETypeDES)) {
aAttrValue->AcceptVisitorL(parser);
sequence = ADDATTR;
}
if (parser.HasFinished()) // Found a suitable record so change state
iIsServiceFound = ETrue;
}
}
void BTSearcher::NextRecordRequestComplete(TInt aError, TSdpServRecordHandle aHandle, TInt aTotalRecordsCount)
{
TRAPD(error,
(NextRecordRequestCompleteL(aError, aHandle, aTotalRecordsCount) ));
if (error != KErrNone) {
SPyErr_SetFromSymbianOSErr(EBTServiceSearcherNextRecordRequestComplete);
return;
}
}
void BTSearcher::NextRecordRequestCompleteL(TInt aError, TSdpServRecordHandle aHandle, TInt aTotalRecordsCount)
{
if (aError == KErrEof) {
Finished();
return;
}
if (aError != KErrNone) {
Finished(aError);
return;
}
if (aTotalRecordsCount == 0) {
Finished(KErrNotFound);
PyErr_SetString(PyExc_TypeError, "NRRC No records");
return;
}
iMatchList = CSdpAttrIdMatchList::NewL();
iMatchList->AddL(TAttrRange(KSdpAttrIdProtocolDescriptorList));
iMatchList->AddL(TAttrRange(KSdpAttrIdBasePrimaryLanguage+KSdpAttrIdOffsetServiceName));
iAgent->AttributeRequestL(aHandle, *iMatchList);
}
void BTSearcher::Finished(TInt aError) //KErrNone given by defualt
{
if (aError == KErrNone && !iIsServiceFound && !iIsNameFound)
aError = KErrNotFound;
User::RequestComplete(iStatusObserver, aError);
}
void BTSearcher::FoundElementL(TInt /*aKey*/, CSdpAttrValue& aValue)
{
iPort = aValue.Uint();
}
/* client object for Obex connection */
#ifndef EKA2
class CObjectExchangeClient : public CActive
#else
NONSHARABLE_CLASS(CObjectExchangeClient) : public CActive
#endif
{
public:
static CObjectExchangeClient* NewL(const TInt&);
~CObjectExchangeClient();
void ConnectL();
void Disconnect();
void SendObjectL();
void StopL();
TBool IsConnected() { return iState == EWaitingToSend; };
TBool IsBusy() { return IsActive(); };
TInt DevServResearch();
TInt ServiceResearch(const TBTDevAddr &);
TInt ObexSend(TBTSockAddr &, TInt &, TPtrC &);
void SetPort(TInt aPort) { port = aPort; };
BTSearcher* iBTSearcher;
protected:
void DoCancel() {};
void RunL();
private:
static CObjectExchangeClient* NewLC(const TInt&);
CObjectExchangeClient(const TInt&);
void ConstructL();
void ConnectToServerL(TBTSockAddr &, TInt &);
private:
enum TState { EWaitingToGetDevice, EGettingDevice, EWaitingToSend, EDisconnecting, EDone };
TState iState;
#ifdef HAVE_ACTIVESCHEDULERWAIT
CActiveSchedulerWait locker;
#endif
CObexClient* obexClient;
CObexFileObject* obexObject;
TInt port;
int iService;
TInt error;
};
CObjectExchangeClient* CObjectExchangeClient::NewL(const TInt &whichService)
{
CObjectExchangeClient* self = NewLC(whichService);
return self;
}
CObjectExchangeClient* CObjectExchangeClient::NewLC(const TInt &whichService)
{
CObjectExchangeClient* self = new (ELeave) CObjectExchangeClient(whichService);
self->ConstructL();
return self;
}
CObjectExchangeClient::CObjectExchangeClient(const TInt &whichService):
CActive(CActive::EPriorityStandard),
iState(EWaitingToGetDevice),
port(-1),
error(KErrNone)
{
if ( whichService == RfcommService)
iService = RfcommService;
else
iService = ObexService;
CActiveScheduler::Add(this);
}
void CObjectExchangeClient::ConstructL()
{
iBTSearcher = new BTSearcher(iService);
}
CObjectExchangeClient::~CObjectExchangeClient()
{
StopL();
// Cancel();
Disconnect();
delete obexObject;
obexObject = NULL;
delete obexClient;
obexClient = NULL;
delete iBTSearcher;
iBTSearcher = NULL;
}
TInt CObjectExchangeClient::DevServResearch()
{
TRAP(error, (ConnectL() ));
if (error != KErrNone)
return error;
Py_BEGIN_ALLOW_THREADS
#ifdef HAVE_ACTIVESCHEDULERWAIT
locker.Start();
#else
CActiveScheduler::Start();
#endif
Py_END_ALLOW_THREADS
return error;
}
TInt CObjectExchangeClient::ServiceResearch(const TBTDevAddr &aAddress)
{
iState = EDone;
iStatus = KRequestPending;
TRAP(error, (iBTSearcher->FindServiceL(iStatus, aAddress) ));
if (error != KErrNone)
return error;
SetActive();
Py_BEGIN_ALLOW_THREADS
#ifdef HAVE_ACTIVESCHEDULERWAIT
locker.Start();
#else
CActiveScheduler::Start();
#endif
Py_END_ALLOW_THREADS
return error;
}
TInt CObjectExchangeClient::ObexSend(TBTSockAddr &address, TInt &port, TPtrC &obj)
{
TRAP(error, (obexObject = CObexFileObject::NewL(obj) ));
if (error != KErrNone)
return error;
TRAP(error, (obexObject->SetDescriptionL(obj) ));
if (error != KErrNone)
return error;
TRAP(error, (obexObject->InitFromFileL(obj) ));
if (error != KErrNone)
return error;
TRAP(error, (ConnectToServerL(address, port) ));
if (error != KErrNone)
return error;
Py_BEGIN_ALLOW_THREADS
#ifdef HAVE_ACTIVESCHEDULERWAIT
locker.Start();
#else
CActiveScheduler::Start();
#endif
Py_END_ALLOW_THREADS
TRAP(error, (SendObjectL() ));
if (error != KErrNone)
return error;
Py_BEGIN_ALLOW_THREADS
#ifdef HAVE_ACTIVESCHEDULERWAIT
locker.Start();
#else
CActiveScheduler::Start();
#endif
Py_END_ALLOW_THREADS
return error;
}
void CObjectExchangeClient::RunL()
{
if (iStatus != KErrNone) {
iState = EDone;
error = iStatus.Int();
#ifdef HAVE_ACTIVESCHEDULERWAIT
locker.AsyncStop();
#else
CActiveScheduler::Stop();
#endif
}
else {
switch (iState) {
case EGettingDevice:
iState = EDone;
iStatus = KRequestPending; // this means that the RunL can not be called until
// this program does something to iStatus
TRAP(error, (iBTSearcher->FindServiceL(iStatus) ));
if (error != KErrNone) return;
SetActive();
break;
case EDisconnecting:
iState = EWaitingToGetDevice;
#ifdef HAVE_ACTIVESCHEDULERWAIT
locker.AsyncStop();
#else
CActiveScheduler::Stop();
#endif
break;
case EDone:
#ifdef HAVE_ACTIVESCHEDULERWAIT
locker.AsyncStop();
#else
CActiveScheduler::Stop();
#endif
break;
default:
PyErr_SetString(PyExc_TypeError, "BT Object Exchange Sdp Record Delete");
break;
};
}
}
void CObjectExchangeClient::ConnectL()
{
if (iState == EWaitingToGetDevice && !IsActive()) {
iBTSearcher->SelectDeviceByDiscoveryL(iStatus);
iState = EGettingDevice;
SetActive();
}
else {
SPyErr_SetFromSymbianOSErr(KErrInUse);
return;
}
iBTSearcher->WriteNotStatus(ETrue);
}
void CObjectExchangeClient::ConnectToServerL(TBTSockAddr &BTSAddress, TInt &port)
{
TObexBluetoothProtocolInfo protocolInfo;
protocolInfo.iTransport.Copy(KServerTransportName);
protocolInfo.iAddr.SetBTAddr(BTSAddress.BTAddr());
protocolInfo.iAddr.SetPort(port);
if (obexClient) {
delete obexClient;
obexClient = NULL;
}
obexClient = CObexClient::NewL(protocolInfo);
obexClient->Connect(iStatus);
SetActive();
iState = EDone;
}
void CObjectExchangeClient::SendObjectL()
{
if (IsActive())
User::Leave(KErrInUse);
obexClient->Put(*obexObject, iStatus);
SetActive();
iState = EDone;
}
void CObjectExchangeClient::StopL()
{
if (obexClient && obexClient->IsConnected()) {
obexClient->Abort();
iState = EDone;
}
iBTSearcher->WriteNotStatus(EFalse);
}
void CObjectExchangeClient::Disconnect()
{
if (iState == EGettingDevice) {
SPyErr_SetFromSymbianOSErr(KErrInUse);
return;
}
if (IsConnected())
if ((iState == EWaitingToSend) || (iState == EDone)) {
iState = EDisconnecting;
obexClient->Disconnect(iStatus);
SetActive();
Py_BEGIN_ALLOW_THREADS
#ifdef HAVE_ACTIVESCHEDULERWAIT
locker.Start();
#else
CActiveScheduler::Start();
#endif
Py_END_ALLOW_THREADS
iBTSearcher->WriteNotStatus(EFalse);
}
error = iStatus.Int();
// KErrDisconnected is a valid behaviour: the server dropped the transport before sending an Obex response
if ((error != KErrNone) && (error != KErrDisconnected)) return;
}
/* service advertiser class */
#ifndef EKA2
class CBTServiceAdvertiser : public CBase
#else
NONSHARABLE_CLASS(CBTServiceAdvertiser) : public CBase
#endif
{
public:
~CBTServiceAdvertiser();
void StartAdvertisingL(TInt, TPtrC16&);
void StopAdvertisingL();
TBool IsAdvertising() { return iRecord != 0; };
void UpdateAvailabilityL(TBool aIsAvailable);
protected:
CBTServiceAdvertiser():
iRecord(0), iIsConnected(EFalse) {};
virtual void BuildProtocolDescriptionL(CSdpAttrValueDES* aProtocolDescriptor, TInt aPort) = 0;
virtual TInt ServiceClass() = 0;
virtual const TPtrC ServiceName() = 0;
virtual const TDesC& ServiceDescription() = 0;
private:
void ConnectL();
private:
RSdp iSdpSession;
RSdpDatabase iSdpDatabase;
TSdpServRecordHandle iRecord;
TInt iRecordState;
TBool iIsConnected;
};
CBTServiceAdvertiser::~CBTServiceAdvertiser()
{
if (IsAdvertising()) {
TRAPD(err, StopAdvertisingL());
if (err != KErrNone) {
PySocket_Err(err);
return;
}
}
iSdpDatabase.Close();
iSdpSession.Close();
}
void CBTServiceAdvertiser::ConnectL()
{
if (!iIsConnected) {
User::LeaveIfError(iSdpSession.Connect());
User::LeaveIfError(iSdpDatabase.Open(iSdpSession));
iIsConnected = ETrue;
}
}
void CBTServiceAdvertiser::StartAdvertisingL(TInt aPort, TPtrC16& attributeName)
{
if (IsAdvertising())
StopAdvertisingL(); // could be advertising on a different port
if (! iIsConnected)
ConnectL();
iSdpDatabase.CreateServiceRecordL(ServiceClass(), iRecord);
CSdpAttrValueDES* vProtocolDescriptor = CSdpAttrValueDES::NewDESL(NULL);
CleanupStack::PushL(vProtocolDescriptor);
BuildProtocolDescriptionL(vProtocolDescriptor,aPort);
iSdpDatabase.UpdateAttributeL(iRecord, KSdpAttrIdProtocolDescriptorList, *vProtocolDescriptor);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -