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

📄 e32socketmodule.cpp

📁 python s60 1.4.5版本的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*
* ====================================================================
*  e32socketmodule.cpp
*  
* Copyright (c) 2005 - 2008 Nokia Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/


#include "Python.h"
#include "symbian_python_ext_util.h"

#if SERIES60_VERSION>=26
#define __BC70s__
#endif
#include <eikenv.h>
#include <e32std.h>
#include <es_sock.h>
#include <in_sock.h>
#include <bt_sock.h>
#include <btmanclient.h>
#include <bttypes.h>
#include <btextnotifiers.h>
#include <btsdp.h>
#include <OBEX.h>
#include "staticarrayc.h"
#ifdef HAVE_SSL
#include <SecureSocket.h>
#endif


#include <CommDbConnPref.h>

// If building for 2.8. These headers must be copied from 2.6 SDk
#include <aplistitemlist.h> 
#include <aputils.h> 

#include <apselect.h>
#include <COMMDB.H>

#include "apselection.h"

#ifdef PRESDK20
#define KProtocolUnknown 0xdead
#endif

#define MaxIPAddrLength 16
#define MaxBufferSize 1024
#define MaxAttributeSize 48
#define MaxServiceNameSize 48

#define KAfBT 0
#define KWaitAll 0x100     //random number to implement socket flag MSG_WAITALL

#define RfcommService 101  //random numbers
#define ObexService   102

#define KAUT 0x0001
#define KENC 0x0002
#define KAUTHOR 0x0004

const TInt KRfcommChannel = 1;
const TUint KBtProtocolIdOBEX = 0x0008;

const TUint KObServiceClass = 0x1105; 
const TInt KRFCServiceClass = 0x1101; 

//#define KProtocol_TLS 1502  //random numbers
//#define KProtocol_SSL 1503

_LIT(KRFCServiceDescription,"Rfcomm Transfer");
_LIT(KObServiceDescription,"Object Exchange");
_LIT(KServerTransportName,"RFCOMM");

static PyObject * PySocket_Err(TInt);
static PyObject * PySocket_Err(char*);


/*
 *.........................Bluetooth.............................*
 */
/*
 * implementation of virtual class MSdpAttributeValueVisitor
 */
enum TSdpAttributeParserPanics 
{
    ESdpAttributeParserInvalidCommand = 1,
    ESdpAttributeParserNoValue,
    ESdpAttributeParserValueIsList,
    ESdpAttributeParserValueTypeUnsupported
};


enum TBTServiceSearcherPanics 
{
    EBTServiceSearcherNextRecordRequestComplete = 1,
    EBTServiceSearcherAttributeRequestResult,
    EBTServiceSearcherAttributeRequestComplete,
    EBTServiceSearcherInvalidControlIndex,
    EBTServiceSearcherProtocolRead,
    EBTServiceSearcherAttributeRequest,
    EBTServiceSearcherSdpRecordDelete
};

class MSdpAttributeNotifier 
{
 public:
    virtual void FoundElementL(TInt aKey, CSdpAttrValue& aValue) = 0;
};

#ifndef EKA2
class TSdpAttributeParser : public MSdpAttributeValueVisitor 
#else
NONSHARABLE_CLASS(TSdpAttributeParser) : public MSdpAttributeValueVisitor 
#endif
{
 public:
    enum TNodeCommand { ECheckType, ECheckValue, ECheckEnd, ESkip, EReadValue, EFinished };
    struct SSdpAttributeNode { TNodeCommand iCommand; TSdpElementType iType; TInt iValue; };
    typedef const TStaticArrayC<SSdpAttributeNode> TSdpAttributeList;

    TSdpAttributeParser(TSdpAttributeList& aNodeList, MSdpAttributeNotifier& aObserver):
        iObserver(aObserver), iNodeList(aNodeList), iCurrentNodeIndex(0) {};
    TBool HasFinished() const { return CurrentNode().iCommand == EFinished; };

 public: // from MSdpAttributeValueVisitor
    void VisitAttributeValueL(CSdpAttrValue& aValue, TSdpElementType aType);
    void StartListL(CSdpAttrValueList& /*aList*/) {};
    void EndListL();

 private:
    void CheckTypeL(TSdpElementType aElementType) const;
    void CheckValueL(CSdpAttrValue& aValue) const;
    void ReadValueL(CSdpAttrValue& aValue) const 
        { iObserver.FoundElementL(CurrentNode().iValue, aValue); };
    const SSdpAttributeNode& CurrentNode() const
        { return  iNodeList[iCurrentNodeIndex]; };
    void AdvanceL();

 private:
    MSdpAttributeNotifier& iObserver;
    TSdpAttributeList& iNodeList;
    TInt iCurrentNodeIndex;
};





const TSdpAttributeParser::SSdpAttributeNode gRfcommProtocolListData[] = 
{
        { TSdpAttributeParser::ECheckType, ETypeDES },
           { TSdpAttributeParser::ECheckType, ETypeDES },
               { TSdpAttributeParser::ECheckValue, ETypeUUID, KL2CAP },
           { TSdpAttributeParser::ECheckEnd },
           { TSdpAttributeParser::ECheckType, ETypeDES },
               { TSdpAttributeParser::ECheckValue, ETypeUUID, KRFCOMM },
               { TSdpAttributeParser::EReadValue, ETypeUint, KRfcommChannel },
           { TSdpAttributeParser::ECheckEnd },
        { TSdpAttributeParser::ECheckEnd },
        { TSdpAttributeParser::EFinished }
};

const TSdpAttributeParser::SSdpAttributeNode gObexProtocolListData[] = 
{
        { TSdpAttributeParser::ECheckType, ETypeDES },
            { TSdpAttributeParser::ECheckType, ETypeDES },
                { TSdpAttributeParser::ECheckValue, ETypeUUID, KL2CAP },
            { TSdpAttributeParser::ECheckEnd },
            { TSdpAttributeParser::ECheckType, ETypeDES },
                { TSdpAttributeParser::ECheckValue, ETypeUUID, KRFCOMM },
                { TSdpAttributeParser::EReadValue, ETypeUint, KRfcommChannel },
            { TSdpAttributeParser::ECheckEnd }, 
            { TSdpAttributeParser::ECheckType, ETypeDES },
                { TSdpAttributeParser::ECheckValue, ETypeUUID, KBtProtocolIdOBEX },
            { TSdpAttributeParser::ECheckEnd },
        { TSdpAttributeParser::ECheckEnd },
        { TSdpAttributeParser::EFinished }
};

const TStaticArrayC<TSdpAttributeParser::SSdpAttributeNode> gRfcommProtocolList =
CONSTRUCT_STATIC_ARRAY_C(
    gRfcommProtocolListData
);

const TStaticArrayC<TSdpAttributeParser::SSdpAttributeNode> gObexProtocolList =
CONSTRUCT_STATIC_ARRAY_C(
    gObexProtocolListData
);

void TSdpAttributeParser::VisitAttributeValueL(CSdpAttrValue& aValue, TSdpElementType aType)
{
    switch(CurrentNode().iCommand)
        {
        case ECheckType:
            CheckTypeL(aType);
            break;
        case ECheckValue:
            CheckTypeL(aType);
            CheckValueL(aValue);
            break;
        case EReadValue:         
            CheckTypeL(aType);   
            ReadValueL(aValue);          
            break;
        case ECheckEnd:
        case EFinished:
            User::Leave(KErrGeneral);   
            break;
        case ESkip:
            break; 
        default:
            SPyErr_SetFromSymbianOSErr(ESdpAttributeParserInvalidCommand);
        }
    AdvanceL();
}


void TSdpAttributeParser::EndListL()
{
    if (CurrentNode().iCommand != ECheckEnd)
          User::Leave(KErrGeneral);
    AdvanceL();
}

void TSdpAttributeParser::CheckTypeL(TSdpElementType aElementType) const
{
    if (CurrentNode().iType != aElementType)
          User::Leave(KErrGeneral);   
}

void TSdpAttributeParser::CheckValueL(CSdpAttrValue& aValue) const
{
    switch(aValue.Type())
        {
        case ETypeNil:
            SPyErr_SetFromSymbianOSErr(ESdpAttributeParserNoValue);
            break;
        case ETypeUint:
            if (aValue.Uint() != (TUint)CurrentNode().iValue)
                User::Leave(KErrArgument);
            break;
        case ETypeInt:
            if (aValue.Int() != CurrentNode().iValue)
                User::Leave(KErrArgument);
            break;
        case ETypeBoolean:
            if (aValue.Bool() != CurrentNode().iValue)
                User::Leave(KErrArgument);
            break;
        case ETypeUUID:
            if (aValue.UUID() != TUUID(CurrentNode().iValue))
                User::Leave(KErrArgument);
            break;

        case ETypeDES:
        case ETypeDEA:
            SPyErr_SetFromSymbianOSErr(ESdpAttributeParserValueIsList);
            break;
        default:
            SPyErr_SetFromSymbianOSErr(ESdpAttributeParserValueTypeUnsupported);
            break;
        }
}



void TSdpAttributeParser::AdvanceL()
{
    if (CurrentNode().iCommand == EFinished)
          User::Leave(KErrEof);

    ++iCurrentNodeIndex;
}


/* Dictionary to store remotely advertised services and relative port numbers */

struct DictElement {
   TBuf8<MaxServiceNameSize> key;
   int value;
};

class Dictionary: CBase {
public:
  static Dictionary* NewL();
  int GetValue() { return item.value; };
  TBuf8<MaxServiceNameSize>& GetKey() { return item.key; };
  static const TInt iOffset; 
  DictElement item;

private:
  Dictionary(){};
  TSglQueLink* iLink;
};

Dictionary* Dictionary::NewL() {
  Dictionary* self = new (ELeave) Dictionary();
  self->item.key.FillZ(MaxServiceNameSize);
  self->item.value = 0;
  return self;
}

/* It sets the offset of the link object from the start of a list element */
const TInt Dictionary::iOffset = _FOFF(Dictionary,iLink);

#ifndef EKA2
class CStack: public CBase {
#else
NONSHARABLE_CLASS(CStack): public CBase {
#endif
public:
  static CStack* NewL();
  ~CStack();
  TSglQue<Dictionary>     iStack;
  TSglQueIter<Dictionary> iStackIter;
private:
  CStack();
};

CStack* CStack::NewL() {
  CStack* self = new (ELeave) CStack;
  return self;
}

CStack::CStack()
  :iStack(Dictionary::iOffset), iStackIter(iStack)
{}

CStack::~CStack(){
  Dictionary* d;
  iStackIter.SetToFirst();
  while ( (d = iStackIter++) != NULL) {
    iStack.Remove(*d);
    delete d;
  };
}





/*
 * implementation of virtual classes needed by CSdpAgent
 */

#ifndef EKA2 
class BTSearcher: public CBase,
                  public MSdpAgentNotifier,
                  public MSdpAttributeNotifier
#else
NONSHARABLE_CLASS(BTSearcher): public CBase,
                  public MSdpAgentNotifier,
                  public MSdpAttributeNotifier
#endif
{
public:
  BTSearcher(int); 
  ~BTSearcher();
        
  void SelectDeviceByDiscoveryL(TRequestStatus& aObserverRequestStatus);
  void FindServiceL(TRequestStatus&);
  void FindServiceL(TRequestStatus&, const TBTDevAddr&);
  
  void AttributeRequestComplete(TSdpServRecordHandle aHandle, TInt aError);
  void AttributeRequestResult(TSdpServRecordHandle aHandle, TSdpAttributeID aAttrID, CSdpAttrValue* aAttrValue);
  void NextRecordRequestComplete(TInt aError, TSdpServRecordHandle aHandle, TInt aTotalRecordsCount);

  TBool ReadNotStatus() { return iIsNotifierConnected; };
  void  WriteNotStatus(TBool aStatus) { iIsNotifierConnected = aStatus; };
  TInt Port() { return iPort; };

  CStack* SDPDict;
  
protected:
  virtual const TSdpAttributeParser::TSdpAttributeList& ProtocolList() 
        { return aServiceType == RfcommService ? gRfcommProtocolList : gObexProtocolList; };
  virtual void FoundElementL(TInt, CSdpAttrValue&);
  virtual const TUUID& ServiceClass() const { return iServiceClass; };  
  virtual TBool HasFinishedSearching() const { return EFalse; };
  void Finished(TInt aError = KErrNone);

 private:
    void NextRecordRequestCompleteL(TInt aError, TSdpServRecordHandle aHandle, TInt aTotalRecordsCount);
    void AttributeRequestResultL(TSdpServRecordHandle aHandle, TSdpAttributeID aAttrID, CSdpAttrValue* aAttrValue);
    void AttributeRequestCompleteL(TSdpServRecordHandle, TInt aError);

 public:
    TBTDeviceResponseParamsPckg  aResponse;
    RNotifier                    notifier;
    TBTDeviceSelectionParamsPckg selectionFilter;

 private:
    CSdpAgent           *iAgent;
    CSdpSearchPattern   *iSdpSearchPattern;
    TBool               iIsNotifierConnected;
    TBool               iIsNameFound;
    TBool               iIsServiceFound;
    TRequestStatus      *iStatusObserver;
    TUUID               iServiceClass;
    TInt                iPort;
    int                 aServiceType;
    TBuf8<MaxAttributeSize> attribute;
    /* since the parsing is done first at the port and later at service names, this variables is needed to avoid
       to get in the dictionary an item with the right port number but meaningless name */
    enum TSequence { NONE, ADDNAME, ADDATTR };
    TSequence    sequence;
    CSdpAttrIdMatchList *iMatchList;
};


BTSearcher::BTSearcher(int s):
  iIsNotifierConnected(EFalse),
  iIsNameFound(EFalse), 
  iIsServiceFound(EFalse), 
  iPort(-1),
  aServiceType(s)
{
  if (aServiceType == RfcommService)
    iServiceClass = KRFCServiceClass;
  else
    iServiceClass = KObServiceClass; 
  TRAPD(error, ( SDPDict = CStack::NewL()));
  if (error != KErrNone) {
    SPyErr_SetFromSymbianOSErr(error);
    return;
    }
  attribute.FillZ(MaxAttributeSize);
  sequence = NONE;
}

BTSearcher::~BTSearcher()
{
  if (iIsNotifierConnected)
    {
      notifier.CancelNotifier(KDeviceSelectionNotifierUid);
      notifier.Close();
      WriteNotStatus(EFalse);
    }
  delete iAgent;
  iAgent = NULL;
  delete iMatchList;
  iMatchList = NULL;
  delete iSdpSearchPattern;
  iSdpSearchPattern = NULL;
  delete SDPDict;
}


void BTSearcher::SelectDeviceByDiscoveryL(TRequestStatus &aStatus)
{
  if (!ReadNotStatus())
    {
      User::LeaveIfError(notifier.Connect());
      WriteNotStatus(ETrue);
    }
  selectionFilter().SetUUID(ServiceClass());
  notifier.StartNotifierAndGetResponse(aStatus, KDeviceSelectionNotifierUid, selectionFilter, aResponse);
}


void BTSearcher::FindServiceL(TRequestStatus &aStatus)
{
  if (!aResponse().IsValidBDAddr())
    User::Leave(KErrNotFound);

  iIsServiceFound = EFalse;
  iAgent = CSdpAgent::NewL(*this, aResponse().BDAddr());

  if (iSdpSearchPattern != NULL) {
    delete iSdpSearchPattern;
    iSdpSearchPattern = NULL;
  }
  iSdpSearchPattern = CSdpSearchPattern::NewL();

  iSdpSearchPattern->AddL(ServiceClass()); 

  iAgent->SetRecordFilterL(*iSdpSearchPattern);
  
  iStatusObserver = &aStatus;
  iAgent->NextRecordRequestL();
}


void BTSearcher::FindServiceL(TRequestStatus &aStatus, const TBTDevAddr &address)
{
  iIsServiceFound = EFalse;
  iAgent = CSdpAgent::NewL(*this, address);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -