⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 e32socketmodule.cpp

📁 python s60 1.4.5版本的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:

  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 + -