diff -r 78fbd574edf4 -r da856f45b798 zeroconf/client/src/cmdnsclient.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zeroconf/client/src/cmdnsclient.cpp Thu Jun 24 19:09:47 2010 +0530 @@ -0,0 +1,252 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// cmdnsclient.cpp +// +// +/** +@file +@PublishedAll +*/ + +//User include +#include "cmdnsclient.h" +#include "cmdnsserverconstants.h" + + +//System include +#include +#include +#include + +__FLOG_STMT(_LIT8(KComponent,"MDNSClient");) +/* + * Default constructor -Assigns the buffer pointer to Null + */ +EXPORT_C RMdns::RMdns():iBufPointer(NULL,0) + { + __FLOG_OPEN(KMDNSSubsystem, KComponent); + } + +/* + * Interface to start the Mdns server . + * KMdnsServerName referes to the name of the Mdns server. + * @param aConnectionHandle handle to the RConnection object // TODO + * @param aSocketServerHandle handler to the RSocketServ object //TODO + * + */ +EXPORT_C TInt RMdns::Open(TInt aConnectionHandle) + { + __FLOG(_L8("RMdns::Open - Entry")); + TVersion serverVersion(0, 0, 0); + //creates a new session if the server exists and it is up and running . + //returns KErrNotFound if the server needs to be launched. + TInt err = CreateSession(KMdnsServerName, serverVersion, 2); + if (err == KErrNotFound) + { + // try starting the server, since create session didn't work + //iap refers to the iap application wants to use. + TBuf<16> iap; + iap.AppendNum(aConnectionHandle); + RProcess server; + User::LeaveIfError(server.Create(KMdnsServerExe, iap)); + server.Resume(); + TRequestStatus status; + status = KRequestPending; + server.Rendezvous(status); + //waits for the server to construct all the required object. + User::WaitForRequest(status); + User::LeaveIfError(status.Int()); + User::LeaveIfError(CreateSession(KMdnsServerName, serverVersion, 2)); + server.Close(); + } + else + { + User::LeaveIfError(err); + } + iNotifierCount =0; + //creates a buffer object with buffer length KDnsBufferlength = 1000 this is the max application + //could send stored in the bundle. + iBuffer = HBufC8::NewL(KDnsBufferlength); + //Set the pointer to point buffer. + iBufPointer.Set(iBuffer->Des()); + //Create a notifier which will be used to catch all the publish and + // query response . There will be only one eventobserver for the client. + //Will be destroyed when the client will be closed. + TRAPD(error,iEventNotifier = CMdnsQueryPublishNotifier::NewL(*this)); + __FLOG(_L8("RMdns::Open - Exit")); + return error; + } + +/* + * Hanldes any queries either the ptr ,srv txt and address record + * IN case of PTR query will be send to the network . + * For SRV and TXT if it exist in the cache ,request will be completed immediately . + * @param aQueryParams contains the query bundle. + * Leaves with KErrAlreadyExists if a request is pending. + */ +EXPORT_C void RMdns::QueryL( const RPnPParameterBundle& aQueryParams ) + { + __FLOG(_L8("RMdns::QueryL - Entry")); + //Get the status of the event notifies . If it is KRequestPending + //there exists a query which needs to be completed . + //Leaves with KErrAlreadyExist if there is query which is pending. + TRequestStatus &status = iEventNotifier->EventNotifierStatus(); + if( status.Int() == KRequestPending) + { + User::Leave(KErrAlreadyExists); + } + //Set the buffer pointer to zero and convert bundle in to buffer and store it in buffer. + iBufPointer.Zero(); + TInt temp = aQueryParams.Length(); + aQueryParams.Store(iBufPointer); + //TODO + //Create a reference to buffer length and send it along the with the request. + //On completion contains the length of the buffer client should create to get the + //response for the query. + //TPckg len(iEventNotifier->BufferLength()); + TIpcArgs args(&iBufPointer,&iEventNotifier->BufferLength()); + //Set Event notifier active + iEventNotifier->SetEventNotifierActive(); + iEventNotifier->SetPnpObserver(aQueryParams.PnPObserver()); + //Set the state as query message so that on response it can decide wheteher it is query or publish. + iEventNotifier->SetState(EMdnsServerQueryMessages); + TRAPD(error,SendReceive(EMdnsServerQueryMessages,args, status)); + __FLOG(_L8("RMdns::QueryL - Exit")); + } + +//TODO yet to decide wat to do with this +//as query itself can handle all the requests + +EXPORT_C void RMdns::ResolveL( const RPnPParameterBundle& aResolveParams ) + { + __FLOG(_L8("RMdns::ResolveL - Entry")); + QueryL(aResolveParams); + __FLOG(_L8("RMdns::ResolveL - Exit")); + } + +/* + * Interferace for the applicaion to register for a particular service it serves + * on the network , A copy of this will be kept in the cache . + * applicaion dont have to renew the service .Consistency Manager will take care of renewing the service. + * @param aPublishParam contains the srv record and the txt record if required need to be published. + * + */ +EXPORT_C void RMdns::RegisterServiceL( const RPnPParameterBundle& aPublishParams ,TBool aIsUpdate) + { + __FLOG(_L8("RMdns::RegisterServiceL - Entry")); + iBufPointer.Zero(); + aPublishParams.Store(iBufPointer); + TIpcArgs args(&iBufPointer,&iEventNotifier->BufferLength(),aIsUpdate); + iEventNotifier->SetEventNotifierActive(); + iEventNotifier->SetPnpObserver(aPublishParams.PnPObserver()); + TRequestStatus &status = iEventNotifier->EventNotifierStatus(); + iEventNotifier->SetState(EMndsServerPublishMessages); + TRAPD(error,SendReceive(EMndsServerPublishMessages,args,status)); + User::LeaveIfError(error); + __FLOG(_L8("RMdns::RegisterServiceL - Exit")); + } + +/* + * An Asychronous request which tells the mdns about the service it is interested in . + * Internally it calls RecieveNotifyMessageL which is a private function, feasible only to CMDnsregisterNotifier + * CMDnsRegisterNotifier is an active object running all the time waiting for any ptr enteries. + * @param aNotifyParam contains the ptr type the application is interrested in ;to be notified. + */ +EXPORT_C void RMdns::WaitForNotificationL( const RPnPParameterBundle& aNotifyParams ) + { + __FLOG(_L8("RMdns::WaitForNotificationL - Entry")); + if(!iRegisterNotifier) + { + iRegisterNotifier = CMdnsRegisterNotifier::NewL(*this); + } + iRegisterNotifier->SetPnpObserver(aNotifyParams.PnPObserver()); + HBufC8* buffer = HBufC8::NewL(KDnsBufferlength); + TPtr8 aNotifyMessage(NULL,0,0); + aNotifyMessage.Set(buffer->Des()); + aNotifyParams.Store(aNotifyMessage); + TIpcArgs args(&aNotifyMessage); + SendReceive(EMdnsServerStartNotifyMessages,args); + iNotifierCount++; + delete buffer; + __FLOG(_L8("RMdns::WaitForNotificationL - Exit")); + } + +/* + *Interface to cancel any notification client requested for . + *@param aCancelParams contains the name of the ptr type client is not interested to be notified. + * + */ +EXPORT_C TInt RMdns::Cancel( const RPnPParameterBundle& aCancelParams ) + { + __FLOG(_L8("RMdns::Cancel - Entry")); + //notifier count keeps track of the number of entries requested for. + iNotifierCount--; + HBufC8* buffer = HBufC8::NewL(KDnsBufferlength); + TPtr8 aNotifyMessage(NULL,0,0); + aNotifyMessage.Set(buffer->Des()); + aCancelParams.Store(aNotifyMessage); + TIpcArgs args(&aNotifyMessage); + SendReceive(EMdnsServerStopNotifyMessages,args); + //when notifier count is zero close the CMdnsRegisterNotifier active object. + //count =0 means the concerned client is not interested in any notification. + if(iNotifierCount == 0) + { + iRegisterNotifier->Cancel(); + } + delete buffer; + __FLOG(_L8("RMdns::Cancel - Exit")); + return KErrNone; + } + +/* + * Destructor + */ +EXPORT_C TInt RMdns::Close() + { + __FLOG(_L8("RMdns::Close - Entry")); + RSessionBase::Close(); + delete iEventNotifier; + delete iRegisterNotifier; + delete iBuffer; + __FLOG(_L8("RMdns::Close - Exit")); + __FLOG_CLOSE; + return KErrNone; + } + +/* + * Private function used by the Query and publish notifier . + * Based on the size of the buffer recieved by the query and publish request. + * a new buffer is allocated and sent to recieve the response. + * @param aData contains the buffer allocated to recieve the response. + */ +void RMdns::RecieveMessage(TDes8& aData) + { + __FLOG(_L8("RMdns::RecieveMessage - Entry")); + TIpcArgs args(&aData); + TRAPD(error,SendReceive(EMdnsServerRecieveMessages,args)); + __FLOG(_L8("RMdns::RecieveMessage - Exit")); + } + +/* + * An synchronous request will be running all the time . whenever a waitfornotification been called. + * @param aData contains the buffer for which data to be set to . + * @param aStatus used to complete the asynchronous request. + */ +void RMdns::RecieveNotifyMessageL(TDes8& aData,TRequestStatus& aStatus) + { + __FLOG(_L8("RMdns::RecieveNotifyMessageL - Entry")); + TIpcArgs args(&aData); + SendReceive(EMdnsServerRecieveNotifyMessages,args,aStatus); + __FLOG(_L8("RMdns::RecieveNotifyMessageL - Exit")); + }