📄 e32socketmodule.cpp
字号:
CleanupStack::PopAndDestroy(vProtocolDescriptor);
iSdpDatabase.UpdateAttributeL(iRecord,
KSdpAttrIdBasePrimaryLanguage+KSdpAttrIdOffsetServiceName,
attributeName);
iSdpDatabase.UpdateAttributeL(iRecord,
KSdpAttrIdBasePrimaryLanguage+KSdpAttrIdOffsetServiceDescription,
ServiceDescription());
}
void CBTServiceAdvertiser::UpdateAvailabilityL(TBool aIsAvailable)
{
TUint state;
if (aIsAvailable)
state = 0xFF; // Fully unused
else
state = 0x00; // Fully used -> can't connect
// Update the availibility attribute field
iSdpDatabase.UpdateAttributeL(iRecord, KSdpAttrIdServiceAvailability, state);
// Mark the record as changed - by increasing its state number (version)
iSdpDatabase.UpdateAttributeL(iRecord, KSdpAttrIdServiceRecordState, ++iRecordState);
}
void CBTServiceAdvertiser::StopAdvertisingL()
{
if (IsAdvertising()) {
iSdpDatabase.DeleteRecordL(iRecord);
iRecord = 0;
}
}
#ifndef EKA2
class CObjectExchangeServiceAdvertiser : public CBTServiceAdvertiser
#else
NONSHARABLE_CLASS(CObjectExchangeServiceAdvertiser) : public CBTServiceAdvertiser
#endif
{
public:
static CObjectExchangeServiceAdvertiser* NewL(TPtrC&);
static CObjectExchangeServiceAdvertiser* NewLC(TPtrC&);
~CObjectExchangeServiceAdvertiser() {};
void SetServiceType(int);
protected: // from CBTServiceAdvertiser
void BuildProtocolDescriptionL(CSdpAttrValueDES* aProtocolDescriptor, TInt aPort);
void BuildProtocolDescriptionRfcommL(CSdpAttrValueDES* aProtocolDescriptor, TInt aPort);
void BuildProtocolDescriptionObexL(CSdpAttrValueDES* aProtocolDescriptor, TInt aPort);
TInt ServiceClass()
{ return aServiceType == RfcommService ? KRFCServiceClass : KObServiceClass; };
const TPtrC ServiceName()
{ return serviceName; };
const TDesC& ServiceDescription()
{ return aServiceType == RfcommService ? KRFCServiceDescription : KObServiceDescription; };
private:
int aServiceType;
TUUID iServiceClass;
TDesC& serviceName;
CObjectExchangeServiceAdvertiser(TPtrC &sName):
serviceName(sName) {};
void ConstructL() {};
};
CObjectExchangeServiceAdvertiser* CObjectExchangeServiceAdvertiser::NewL(TPtrC &aName)
{
CObjectExchangeServiceAdvertiser* self = CObjectExchangeServiceAdvertiser::NewLC(aName);
return self;
}
CObjectExchangeServiceAdvertiser* CObjectExchangeServiceAdvertiser::NewLC(TPtrC &aName)
{
CObjectExchangeServiceAdvertiser* self = new (ELeave) CObjectExchangeServiceAdvertiser(aName);
self->ConstructL();
return self;
}
void CObjectExchangeServiceAdvertiser::SetServiceType(int st)
{
aServiceType = st;
if (aServiceType == RfcommService)
iServiceClass = KRFCServiceClass;
else
iServiceClass = KObServiceClass;
};
void CObjectExchangeServiceAdvertiser::BuildProtocolDescriptionL(CSdpAttrValueDES* aProtocolDescriptor, TInt aPort)
{
if (aServiceType == ObexService)
BuildProtocolDescriptionObexL(aProtocolDescriptor, aPort);
else if (aServiceType == RfcommService)
BuildProtocolDescriptionRfcommL(aProtocolDescriptor, aPort);
else
User::Leave(KErrArgument);
}
void CObjectExchangeServiceAdvertiser::BuildProtocolDescriptionObexL(CSdpAttrValueDES* aProtocolDescriptor, TInt aPort)
{
TBuf8<1> channel;
channel.Append((TChar)aPort);
aProtocolDescriptor
->StartListL()
->BuildDESL()
->StartListL()
->BuildUUIDL(KL2CAP)
->EndListL()
->BuildDESL()
->StartListL()
->BuildUUIDL(KRFCOMM)
->BuildUintL(channel)
->EndListL()
->BuildDESL()
->StartListL()
->BuildUUIDL(KBtProtocolIdOBEX)
->EndListL()
->EndListL();
}
void CObjectExchangeServiceAdvertiser::BuildProtocolDescriptionRfcommL(CSdpAttrValueDES* aProtocolDescriptor, TInt aPort)
{
TBuf8<1> channel;
channel.Append((TChar)aPort);
aProtocolDescriptor
->StartListL()
->BuildDESL()
->StartListL()
->BuildUUIDL(KL2CAP)
->EndListL()
->BuildDESL()
->StartListL()
->BuildUUIDL(KRFCOMM)
->BuildUintL(channel)
->EndListL()
->EndListL();
}
/* server object for obex connection */
#ifndef EKA2
class CObjectExchangeServer: public CBase,
public MObexServerNotify
#else
NONSHARABLE_CLASS(CObjectExchangeServer): public CBase,
public MObexServerNotify
#endif
{
public:
static CObjectExchangeServer* NewL();
~CObjectExchangeServer();
int StartSrv();
void DisconnectL();
TBool IsConnected() { return iObexServer != NULL; };
void SetPort(TInt aPort) { port = aPort; };
static void SetSecurityOnChannelL(TBool aAuthentication, TBool aEncryption, TBool aAuthorisation, TInt aPort);
TBool IsPortSet() { return (port != -1) ? ETrue: EFalse; };
TBuf<50> fileName;
private:
CObjectExchangeServer():
port(-1), error(KErrNone) {};
void ConstructL();
void UpdateAvailabilityL(TBool aIsAvailable);
void InitialiseServerL();
static TInt AvailableServerChannelL();
private:
// from MObexServerNotify (these methods are defined as private in MObexServerNotify)
void ErrorIndication(TInt /*aError*/) {};
void TransportUpIndication() {};
void TransportDownIndication() {};
TInt ObexConnectIndication(const TObexConnectInfo& /*aRemoteInfo*/, const TDesC8& /*aInfo*/)
{ return KErrNone; };
void ObexDisconnectIndication(const TDesC8& /*aInfo*/) {};
CObexBufObject* PutRequestIndication() { return iObexBufObject; };
TInt PutPacketIndication() { return KErrNone; };
TInt PutCompleteIndication();
CObexBufObject* GetRequestIndication(CObexBaseObject* /*aRequestedObject*/) { return NULL; };
TInt GetPacketIndication() { return KErrNone; };
TInt GetCompleteIndication() { return KErrNone; };
TInt SetPathIndication(const CObex::TSetPathInfo& /*aPathInfo*/, const TDesC8& /*aInfo*/)
{ return KErrNone; };
void AbortIndication() {};
private:
CObexServer* iObexServer; /* manages the OBEX client connection */
CBufFlat* iObexBufData; /* the raw data that has been transferred */
CObexBufObject* iObexBufObject; /* the OBEX object that has been transferred*/
#ifdef HAVE_ACTIVESCHEDULERWAIT
CActiveSchedulerWait locker;
#endif
TInt port;
TInt error;
};
CObjectExchangeServer* CObjectExchangeServer::NewL()
{
CObjectExchangeServer* self = new (ELeave) CObjectExchangeServer();
self->ConstructL();
return self;
}
void CObjectExchangeServer::ConstructL()
{
iObexBufData = CBufFlat::NewL(MaxBufferSize);
iObexBufObject = CObexBufObject::NewL(iObexBufData);
}
CObjectExchangeServer::~CObjectExchangeServer()
{
if (iObexServer && iObexServer->IsStarted())
iObexServer->Stop();
delete iObexServer;
iObexServer = NULL;
DisconnectL();
delete iObexBufData;
iObexBufData = NULL;
delete iObexBufObject;
iObexBufObject = NULL;
}
TInt CObjectExchangeServer::PutCompleteIndication()
{
TPtrC filePath(fileName);
error = iObexBufObject->WriteToFile(filePath);
#ifdef HAVE_ACTIVESCHEDULERWAIT
locker.AsyncStop();
#else
CActiveScheduler::Stop();
#endif
return error;
}
void CObjectExchangeServer::DisconnectL()
{
if (iObexServer && iObexServer->IsStarted())
iObexServer->Stop();
delete iObexServer;
iObexServer = NULL;
}
int CObjectExchangeServer::StartSrv()
{
TRAPD(err, InitialiseServerL());
Py_BEGIN_ALLOW_THREADS
#ifdef HAVE_ACTIVESCHEDULERWAIT
locker.Start();
#else
CActiveScheduler::Start();
#endif
Py_END_ALLOW_THREADS
if (err != KErrNone)
DisconnectL();
return err;
}
void CObjectExchangeServer::InitialiseServerL()
{
RSocketServ socketServer;
RSocket socket;
TBool newServerSession = EFalse;
if (iObexServer) {
ASSERT(IsConnected()); // server already running
return;
}
TInt channel;
if (!IsPortSet())
channel = AvailableServerChannelL();
else {
User::LeaveIfError(socketServer.Connect());
newServerSession = ETrue;
User::LeaveIfError(socket.Open(socketServer, KServerTransportName));
channel = port;
}
SetSecurityOnChannelL(EFalse, EFalse, ETrue, channel);
TObexBluetoothProtocolInfo obexProtocolInfo;
obexProtocolInfo.iTransport.Copy(KServerTransportName);
obexProtocolInfo.iAddr.SetPort(channel);
iObexServer = CObexServer::NewL(obexProtocolInfo);
iObexServer->Start(this);
if (newServerSession) {
socket.Close();
socketServer.Close();
}
}
TInt CObjectExchangeServer::AvailableServerChannelL()
{
RSocketServ socketServer;
RSocket socket;
User::LeaveIfError(socketServer.Connect());
User::LeaveIfError(socket.Open(socketServer, KServerTransportName));
TInt channel;
User::LeaveIfError( socket.GetOpt(KRFCOMMGetAvailableServerChannel, KSolBtRFCOMM, channel));
socket.Close();
socketServer.Close();
return channel;
}
void CObjectExchangeServer::SetSecurityOnChannelL(TBool aAuthentication, TBool aEncryption,
TBool aAuthorisation, TInt aChannel)
{
#ifndef EKA2
RBTMan secManager;
#if SERIES60_VERSION>=26
RBTSecuritySettingsB secSettingsSession;
#else
RBTSecuritySettings secSettingsSession;
#endif
User::LeaveIfError(secManager.Connect());
User::LeaveIfError(secSettingsSession.Open(secManager));
/* NOTE: original implementation uses like first paramether the App UId.
It must just be an unique identifier for the service */
const TUid KUidBTObjectExchangeApp = {0x10105b8e};
#if SERIES60_VERSION>=26
TBTServiceSecurityB serviceSecurity(KUidBTObjectExchangeApp, KSolBtRFCOMM, 0);
#else
TBTServiceSecurity serviceSecurity(KUidBTObjectExchangeApp, KSolBtRFCOMM, 0);
#endif
serviceSecurity.SetAuthentication(aAuthentication);
serviceSecurity.SetEncryption(aEncryption);
serviceSecurity.SetAuthorisation(aAuthorisation);
serviceSecurity.SetChannelID(aChannel);
TRequestStatus status;
secSettingsSession.RegisterService(serviceSecurity, status);
User::WaitForRequest(status);
User::LeaveIfError(status.Int());
#endif /*EKA2*/
}
/*
*
* Implementation of Bluetooth API's for Python
*
*/
#define BTDevice_type ((PyTypeObject*)SPyGetGlobalString("BTDeviceType"))
struct BTDevice_data {
CObjectExchangeServer *aBTObjExSrv;
CObjectExchangeClient *aBTObjExCl;
TBTDevAddr address;
TInt port;
TInt error;
};
/*
*
* Implementation of e32socket.Socket object and methods
*
*/
#define AP_type ((PyTypeObject*)SPyGetGlobalString("APType"))
struct AP_object {
PyObject_VAR_HEAD
RConnection* connection;
TInt apId;
TBool started;
};
class TStaticData {
public:
RSocketServ rss;
AP_object *apo;
};
extern "C"
void socket_mod_cleanup();
extern "C" PyObject *
ap_start(AP_object *self, PyObject* /*args*/);
extern "C" PyObject *
ap_stop(AP_object *self, PyObject* /*args*/);
TStaticData* GetServer()
{
if (Dll::Tls())
{
return static_cast<TStaticData*>(Dll::Tls());
}
else
{
TInt error = KErrNone;
TStaticData* sd = NULL;
TRAP(error, {
sd = new (ELeave) TStaticData;
});
if(error!=KErrNone){
return (TStaticData*) SPyErr_SetFromSymbianOSErr(error);
}
// Nullify the content.
sd->apo=NULL;
error = sd->rss.Connect(KESockDefaultMessageSlots*2);
if (error != KErrNone){
delete sd;
return (TStaticData*) SPyErr_SetFromSymbianOSErr(error);
}
error = Dll::SetTls(sd);
if(error!=KErrNone){
sd->rss.Close();
delete sd;
return (TStaticData*) SPyErr_SetFromSymbianOSErr(error);
}
PyThread_AtExit(socket_mod_cleanup);
return static_cast<TStaticData*>(Dll::Tls());
}
}
/*
* CSocketEngine
*/
class CSocketEngine;
#ifndef EKA2
class CSocketAo : public CActive
#else
NONSHARABLE_CLASS(CSocketAo) : public CActive
#endif
{
public:
CSocketAo():CActive(EPriorityStandard),iState(EIdle),iDataBuf(0,0) {
CActiveScheduler::Add(this);
}
PyObject* HandleReturn(PyObject* aSo) {
Py_XINCREF(aSo);
iState = EBusy;
SetActive();
if (iPyCallback) {
iSo = aSo;
Py_INCREF(iPyCallback);
Py_INCREF(Py_None);
return Py_None;
}
Py_BEGIN_ALLOW_THREADS
#ifdef HAVE_ACTIVESCHEDULERWAIT
iWait.Start();
#else
CActiveScheduler::Start();
#endif
Py_END_ALLOW_THREADS
PyObject* r = iCallback(iStatus.Int(), this);
Py_XDECREF(aSo);
return r;
}
TAny* (iData)[3];
PyObject* iPyCallback;
PyObject* (*iCallback)(TInt, CSocketAo*);
enum {EIdle, EBusy} iState;
TPtr8 iDataBuf;
TSockXfrLength iXLen;
TInetAddr iInetAddr;
TBTSockAddr iBtAddr;
private:
void RunL();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -