Symbian OS Communications (779884), страница 64
Текст из файла (страница 64)
Equally, when receiving data, alarge maximum packet size is no use if the device sending the data isonly capable of sending packets smaller than the maximum size. In thesecases, the unused capacity of the buffers used to store incoming andoutgoing packets is simply wasted RAM.The aim in setting the maximum packet sizes is therefore to balanceimproved performance against memory consumption. If RAM were not aconsideration and OBEX were operating in isolation, the ideal maximumpacket size would be the smaller of the 65,536 byte limit imposed by theOBEX protocol and the total size of the object to be transferred. However,RAM conservation should always be a consideration when implementingcode for a Symbian OS device, so this may not be practical.
Additionally,OBEX does not operate in isolation – the data transferred using OBEX isgoing to be processed in some way (e.g., music files might be written todisk, vCards transferred might be deposited in a database). This processingmight introduce throughput limitations that mean there is no point in usingadditional RAM to improve OBEX throughput beyond a certain point.The 4000 byte default maximum packet size in Symbian OS is atthe low end of the available range – for applications that will be transferring larger objects, increasing this to a packet size of 32 kB should310OBEXgive a reasonable performance without excessive memory consumption, while allowing reasonable responsiveness for Abort operations.
Asmay be appreciated though, performance, especially where protocols isconcerned, is a very complex subject, and experimentation is probably the best way to determine the optimum packet sizes for any givenapplication.Note: for interoperability purposes with some other IrDA implementations, the OBEX packet size for the IrDA transport has been fixed atthe negotiated payload size of the underlying IrDA Tiny TP session.ConnectLOnce an OBEX client application has created its CObexClient object,usually the next step is to attempt to initiate an OBEX session.
The clientapplication can achieve this by using CObexClient::Connect() orConnectL().CObexClient offers a number of overloads of Connect() andConnectL(), and the overload to use depends upon two things: whetherthe server is to be authenticated during connection, and whether there isdata that must be transferred as part of the connection.For situations where authentication of the server is not required andthere is no data to be transferred during connection, there is a simpleConnect() overload that takes a single TRequestStatus& parameter.The TRequestStatus is used to signal completion upon successor failure of the connection attempt. When the Connect() function is initially called, CObexClient sets the TRequestStatus toKRequestPending to indicate that the request is in progress.
If theTRequestStatus later completes with a value of KErrNone, an OBEXsession has been successfully established with the OBEX server on theremote device. A completion with any other value indicates that anerror has occurred, and no session has been established. The specificerror value may indicate a particular type of failure (see Table 10.5). TheTRequestStatus parameter is used in this same way for all overloadsof Connect() and ConnectL().If authentication of the server is required during connection, there is aConnectL() overload that takes a descriptor reference in addition to theTRequestStatus&.
The descriptor contains the password that shouldbe used to challenge the remote OBEX server during connection – that is,the password that we expect to see the remote OBEX server provide to usto prove its authenticity.If there is data to be transferred during connection, there is a ConnectL() overload that takes a CObexBaseObject& in addition tothe TRequestStatus&. The CObexBaseObject should have beenOBEX IN SYMBIAN OS311prepared with all the headers that need to be transferred during theconnection (this is how a Target header is supplied for use duringestablishment of directed connections).Note: the code that created the CObexBaseObject retains ownership, and so must ensure that it gets deleted when the Connectcommand is complete.For situations where both authentication and connect data are required,there is an overload of ConnectL() that incorporates a descriptor containing a password, a CObexBaseObject& and a TRequestStatus&.Following a successful connect using any of these overloads, the clientis able to start issuing further commands over the established OBEXsession.void CMyObexClientApp::ConnectWithTarget(){const TUint8 KTargetHeaderHi = 0x46;_LIT8(KTargetValue,"\xF9\xEC\x7B\xC4\x95\x3C\x11\xd2\x98\x4E\x52\x54\x00\xDC\x9E\x09"); // Folder Browsing// iClient is an initialised member variable of type CObexClient*// iTargetHeaderObj is a member variable of type CObexBaseObject*delete iTargetHeaderObj;iTargetHeaderObj = NULL;iTargetHeaderObj = CObexNullObject::NewL();CObexHeader* targetHeader = CObexHeader::NewL();CleanupStack::PushL(targetHeader);targetHeader->SetByteSeqL(KTargetHeaderHi, KTargetValue());iTargetHeaderObj->AddHeaderL(*targetHeader);CleanupStack::Pop(targetHeader);//Ownership has been passediClient->Connect(*iTargetHeaderObj, iStatus);SetActive();////}Successful or unsuccessful completion of Connect command willresult in RunL of this object being called.Example 10.9Use of Connect()PutThe Put function allows the OBEX client application to initiate thetransfer of an object to the remote OBEX server.
The function takes twoparameters: a CObexBaseObject& and a TRequestStatus&. TheCObexBaseObject must have been prepared with a source of bodydata (a file or buffer) and all the associated headers to be sent. The312OBEXTRequestStatus is used in the normal way, as with ConnectL(), tosignal successful or unsuccessful completion of the Put() command.void{//////CMyObexClientApp::Put()iClient is an initialised member variable of type CObexClient*iFileObj is an initialised member variable of typeCObexBaseObject*iClient->Put(*iFileObj,iStatus);SetActive();////}Successful or unsuccessful completion of Connect command willresult in RunL of this object being called.Example 10.10Use of PutGetGet() allows the OBEX client application to initiate the transfer ofan object from the remote OBEX server.
It takes parameters identical tothose of Put(), but uses the CObexBaseObject& parameter in differentway.When Get() is called, the CObexBaseObject must have beenprepared by the OBEX client application with all the headers that need tobe transferred to the OBEX server during the specification phase of the Getcommand.
CObexClient will ensure that the contents of the object aretransferred during the specification phase. When the specification phaseis complete, CObexClient resets the object (removes all its headers andbody data) and then reuses it to store the object data returned from theOBEX server during the second phase of the Get command.The TRequestStatus is used in the normal way to signal successfulor unsuccessful completion of the Get command.void CMyObexClientApp::GetByName(){// iClient is an initialised member variable of type CObexClient*// iObject is an initialised member variable of type// CObexBaseObject*// Set up iObject to act as specification for the Get command// Specify name of object to be ‘‘got’’ as ‘‘contact.vcf’’const TUint8 KNameHeaderHi = 0x01;_LIT(KFileName, "Contact.vcf");iObject->Reset();CObexHeader* nameHeader = CObexHeader::NewL();CleanupStack::PushL(nameHeader);OBEX IN SYMBIAN OS313nameHeader->SetUnicodeL(KNameHeaderHi, KFileName());iObject->AddHeaderL(*nameHeader);CleanupStack::Pop(nameHeader);//Ownership has been passediClient->Get(*iObject, iStatus);SetActive();////////}Successful or unsuccessful completion of Get command willresult in RunL of this object being called.Where the result is success, iObject will contain the retrievedobject headers and body data.Example 10.11Use of GetSetPathThe SetPath function allows the OBEX client application to initiatean OBEX SetPath command to the remote OBEX server.
It takes twoparameters: a TSetPathInfo& and a TRequestStatus&.The TSetPathInfo class is defined with the scope of CObex class. Itholds all the data that is transferred as part of a SetPath command, namelythe flag byte, the constants byte and the value to be used in the nameheader. The OBEX client application must set the appropriate flags and(optionally) the name field in a TSetPathInfo object before calling theSetPath function (these fields can be set directly by user code, as theyare defined as public member variables).The TRequestStatus is used in the normal way to signal successfulor unsuccessful completion of the SetPath command.void CMyObexClientApp::SetPath(){const TInt KDontCreateFolderFlag = 2;// iClient is an initialised member variable of type CObexClient*_LIT(KSubDirName, "symbianoscommsprogramming");CObex::TSetPathInfo info;info.iNamePresent = ETrue;info.iName = KSubDirName();info.iFlags |= KDontCreateFolderFlag;iClient->SetPath(info,iStatus);SetActive();////}Successful or unsuccessful completion of SetPath command willresult in RunL of this object being called.Example 10.12Use of SetPath314OBEXAbortThe Abort function is used by the OBEX client application to abandonan ongoing OBEX command.
The function has no parameters or returnvalue, and has no effect if there is no OBEX command in progress.If an OBEX command is in progress, the CObexClient will send anAbort request packet to the server in place of the next request packet in theongoing OBEX command request–response exchange (CObexClientmust obey the conversational protocol and wait for the OBEX server torespond before it can send another request).
Once the server responds tothe Abort request, the request that initiated the aborted OBEX commandwill have completion signalled with the value KErrAbort.Except in error situations, the OBEX session will remain connectedand synchronized following such an aborted command, which allowsthe OBEX client application to initiate further OBEX commands withoutdisconnecting and reconnecting the session.void CMyObexClientApp::Abort(){// iClient is an initialised member variable of type CObexClient*// A command is in progressiClient->Abort();//////}The command will be aborted at the next opportunity, and theTRequestStatus passed in when the command was started willcomplete with KErrAbort.Example 10.13Use of AbortDisconnectOnce all the necessary operations have been completed for a given OBEXsession, the OBEX client application can tear down the OBEX sessionand the transport connection over which it runs.