--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/commonappservices/alarmserver/Client/Source/ASCliSession.cpp Tue Feb 02 10:12:00 2010 +0200
@@ -0,0 +1,1377 @@
+// Copyright (c) 1999-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:
+//
+
+#include <asclisession.h>
+
+// System includes
+#include <s32mem.h>
+
+// User includes
+#include <asshdalarm.h>
+#include "ASShdPragma.h"
+#include "ASShdOpCodes.h"
+//
+#include <asclisoundplay.h>
+#include <ascliclientutils.h>
+#include <asclidefinitions.h>
+
+// Type definitions
+
+// Constants
+const TInt KNumberOfServerStartupAttempts = 2;
+
+// Enumerations
+
+
+//
+// ----> RASCliSession (source)
+//
+
+/**
+
+Default constructor.
+
+Creates an instance of the RASCliSession class, setting its pointers to null.
+
+*/
+EXPORT_C RASCliSession::RASCliSession()
+: iPackage(NULL, 0, 0), iAlarmIdPointer(NULL, 0, 0)
+ {
+ }
+
+
+/**
+
+Connects the client process to the alarm server, starting the server if it
+is not already running.
+@capability None
+@return KErrNone if successful, otherwise one of the system-wide errors.
+
+*/
+EXPORT_C TInt RASCliSession::Connect()
+ {
+ TInt startupAttempts = KNumberOfServerStartupAttempts;
+ for(;;)
+ {
+ TInt ret = CreateSession(ASCliDefinitions::ServerAndThreadName(), ASCliDefinitions::Version(), KAlarmServerAsynchronousSlotCount);
+
+ if (ret != KErrNotFound && ret != KErrServerTerminated)
+ {
+ return ret;
+ }
+
+ if (startupAttempts-- == 0)
+ {
+ return ret;
+ }
+
+ ret = AlarmClientUtils::StartAlarmServer();
+ if (ret != KErrNone && ret != KErrAlreadyExists)
+ {
+ return ret;
+ }
+ }
+ }
+
+
+/** Provides the version number of the alarm server.
+@capability None
+@return The version number. */
+EXPORT_C TVersion RASCliSession::Version() const
+ {
+ return ASCliDefinitions::Version();
+ }
+
+
+//
+//
+//
+
+
+/** Validates an alarm object, allocates an unique identifier to it, and adds the
+object synchronously to the alarm server's queue.
+
+@capability WriteUserData
+@param aAlarm The alarm object to add. On return, contains a unique identifier
+that the client can use to identify the alarm.
+@return KErrNone if successful, otherwise one of the system-wide error codes. */
+EXPORT_C TInt RASCliSession::AlarmAdd(TASShdAlarm& aAlarm) const
+ {
+ return DoAlarmAdd(aAlarm, KNullDesC8);
+ }
+
+/**
+@capability WriteUserData
+*/
+TInt RASCliSession::DoAlarmAdd(TASShdAlarm& aAlarm, const TDesC8& aData) const
+ {
+ TPckg<TASShdAlarm> package(aAlarm);
+ TIpcArgs args(&package, aData.Length(), &aData);
+
+ // Send message to server.
+ return SendReceive(EASShdOpCodeAlarmAdd, args);
+ }
+
+
+/** Validates an alarm object, allocates an unique identifier to it, and adds the
+object with data synchronously to the alarm server's queue.
+
+@capability WriteUserData
+@param aAlarm The alarm object to add. On return, contains a unique identifier
+that the client can use to identify the alarm.
+@param aData Client-specific data to associate with the alarm.
+@return KErrNone if successful, otherwise one of the system-wide error codes.*/
+EXPORT_C TInt RASCliSession::AlarmAdd(TASShdAlarm& aAlarm, const TDesC8& aData) const
+ {
+ return DoAlarmAdd(aAlarm, aData);
+ }
+
+
+/** Makes an asynchronous request to add an alarm object to the alarm server's
+queue.
+
+It also allocates a unique identifier of type TAlarmId to the alarm object and
+adds the alarm object to the alarm server's queue.
+
+When the alarm expires, or is cancelled, the alarm server notifies the client
+by completing the outstanding request.
+
+@capability WriteUserData
+@param aStatus On completion of the request, this object holds the completion
+code.
+@param aAlarm The alarm to add. On return, contains the unique identifier. KNullAlarmId indicates failure.*/
+EXPORT_C void RASCliSession::AlarmAddWithNotification(TRequestStatus& aStatus, TASShdAlarm& aAlarm)
+ {
+ DoAlarmAddWithNotification(aStatus, aAlarm, KNullDesC8);
+ }
+
+/**
+@capability WriteUserData
+*/
+void RASCliSession::DoAlarmAddWithNotification(TRequestStatus& aStatus, TASShdAlarm& aAlarm, const TDesC8& aData)
+ {
+ // Set the session specific flag
+ aAlarm.Characteristics().Set(EAlarmCharacteristicsSessionSpecific);
+
+ // add the alarm and wait for notification.
+ TIpcArgs args(&iPackage, aData.Length(), &aData);
+ //
+ iPackage.Set((TUint8*) &aAlarm, sizeof(TASShdAlarm), sizeof(TASShdAlarm));
+
+ // Unfortunately there is no way to send a request flag synchronously
+ // The basic idea behind the asynchronous sendReceive is that we can attach a
+ // status flag to get informed whenever the server has accomplished the given task,
+ // specifyed by the OpCode. However, in this case the flag is used when an alarm
+ // expires and not when the alarm server is ready registrating the alarm.
+ // Therefore, we have to make a synchronous call afterwards to synchronise the client and server
+ aAlarm.Id() = KNullAlarmId;
+ SendReceive(EASShdOpCodeAlarmAddWithNotification, args, aStatus);
+
+ // The synchronous call to synchronise the client and server.
+ SendReceive(EASShdOpCodeFlushServer);
+ }
+
+
+/**
+Makes an asynchronous request to add an alarm object
+with the agenda entry information attached to the alarm server's
+queue.
+
+It also allocates a unique identifier of type TAlarmId to the alarm object and
+adds the alarm object to the alarm server's queue.
+
+When the alarm expires, or is cancelled, the alarm server notifies the client
+by completing the outstanding request.
+
+@capability WriteUserData
+@param aStatus On completion of the request, this object holds the completion
+code.
+@param aAlarm The alarm to add. On return, contains the unique identifier. KNullAlarmId indicates failure.
+@param aData Client-specific data to associate with the alarm.
+*/
+EXPORT_C void RASCliSession::AlarmAddWithNotification(TRequestStatus& aStatus, TASShdAlarm& aAlarm, const TDesC8& aData)
+ {
+ DoAlarmAddWithNotification(aStatus, aAlarm, aData);
+ }
+
+
+/** Cancels an outstanding notification for an alarm and removes it from the queue.
+@capability Note If the user does not have WriteDeviceData capability then we need to check
+that the alarm belongs to the user SID (The SID is stored as part of the alarm)
+@param aAlarmId The unique identifier of the alarm to be cancelled. */
+EXPORT_C void RASCliSession::AlarmNotificationCancelAndDequeue(TAlarmId aAlarmId) const
+ {
+ TIpcArgs args(aAlarmId);
+ // Backup/Restore locking the file or the Server dying are not programming
+ // errors - any other error panics the client.
+ const TInt error = SendReceive(EASShdOpCodeAlarmNotificationCancelAndDeQueue, args);
+ __ASSERT_ALWAYS(error == KErrNone || error == KErrServerTerminated || error == KErrLocked, AlarmClientUtils::Panic(AlarmClientUtils::EAlarmClientPanicNotificationCancel));
+ }
+
+
+/** Retrieves information about a specified alarm.
+
+@capability Note If the user does not have ReadUserData capability then we need to check
+that the alarm belongs to the user SID (The SID is stored as part of the alarm)
+@param aAlarmId The unique identifier of the alarm under query.
+@param aAlarm On return, contains details of the alarm sought.
+@return KErrNone if successful, KErrCouldNotConnect if the time zone server is
+not available, otherwise one of the other system-wide error codes. */
+EXPORT_C TInt RASCliSession::GetAlarmDetails(TAlarmId aAlarmId, TASShdAlarm& aAlarm) const
+ {
+ TPckg<TASShdAlarm> package(aAlarm);
+ TIpcArgs args(aAlarmId,&package);
+ return SendReceive(EASShdOpCodeGetAlarmDetails, args);
+ }
+
+
+
+/** Deletes an alarm from the alarm server.
+@capability Note If the user does not have WriteDeviceData capability then we need to check
+that the alarm belongs to the user SID (The SID is stored as part of the alarm)
+@param aAlarmId The unique identifier of the alarm to be deleted.
+@return KErrNone if successful, KErrNotFound if the specified alarm does not
+exist, KErrAccessDenied if the alarm has an outstanding notification, or else
+one of the system-wide error codes. */
+EXPORT_C TInt RASCliSession::AlarmDelete(TAlarmId aAlarmId) const
+ {
+ TIpcArgs args(aAlarmId);
+ return SendReceive(EASShdOpCodeAlarmDelete, args);
+ }
+
+
+/** Retrieves the category of an alarm.
+
+@capability None
+@param aAlarmId The unique identifier of the alarm under query.
+@param aCategory On return, contains the category of the alarm.
+@return KErrNone if successful, KErrNotFound if the alarm does not exist, otherwise
+one of the system-wide error codes. */
+EXPORT_C TInt RASCliSession::GetAlarmCategory(TAlarmId aAlarmId, TAlarmCategory& aCategory) const
+ {
+ TPckg<TAlarmCategory> package(aCategory);
+ TIpcArgs args(aAlarmId, &package);
+ //
+ return SendReceive(EASShdOpCodeGetAlarmCategory, args);
+ }
+
+
+/** @deprecated 8.0
+
+Retrieves the full name of the thread that owns the specified alarm.
+
+@capability None
+@param aAlarmId The unique identifier of the alarm under query.
+@param aThreadName On return, contains the name of the owning session.
+@return KErrNone if successful, KErrNotFound if the alarm has no originating
+session ID or if the session is no longer connected, otherwise one of the
+system-wide errors. */
+EXPORT_C TInt RASCliSession::GetAlarmOwner(TAlarmId aAlarmId, TFullName& aThreadName) const
+ {
+//
+// From 8.0 onwards, this function returns a NULL string.
+// See CASSrvSession::MASSrvSessionFullName
+//
+ TIpcArgs args(aAlarmId, &aThreadName);
+ return SendReceive(EASShdOpCodeGetAlarmOwner, args);
+ }
+
+
+/** Sets an alarm's status to either enabled or disabled.
+
+@capability Note If the user does not have WriteDeviceData capability then we need to check
+that the alarm belongs to the user SID (The SID is stored as part of the alarm)
+@param aAlarmId Unique identifier of the alarm.
+@param aStatus Contains the status to be applied.
+@return KErrNone if successful, otherwise one of the system-wide error codes. */
+EXPORT_C TInt RASCliSession::SetAlarmStatus(TAlarmId aAlarmId, TAlarmStatus aStatus) const
+ {
+ TIpcArgs args(aAlarmId, aStatus);
+ return SendReceive(EASShdOpCodeSetAlarmStatus, args);
+ }
+
+/** Sets the alarm status for calendar file
+
+@param aFileName Calendar file name
+@param aStatus Contains the status to be applied.
+@return KErrNone if successful, otherwise one of the system-wide error codes. */
+EXPORT_C TInt RASCliSession::SetAlarmStatusForCalendarFile(const TDesC& aFileName, TAlarmStatus aStatus) const
+ {
+ TIpcArgs args(&aFileName, aStatus);
+ return SendReceive(EASShdOpCodeSetAlarmStatusForCalendarFile, args);
+ }
+
+/** Retrieves the status of the alarm.
+
+@capability None
+@param aAlarmId The unique identifier of an alarm under query.
+@param aStatus On return, the alarm status.
+@return KErrNone if successful, KErrNotFound if the alarm does not exist, otherwise
+one of the system-wide errors. */
+EXPORT_C TInt RASCliSession::GetAlarmStatus(TAlarmId aAlarmId, TAlarmStatus& aStatus) const
+ {
+ TPckg<TAlarmStatus> package(aStatus);
+ TIpcArgs args(aAlarmId, &package);
+ //
+ return SendReceive(EASShdOpCodeGetAlarmStatus, args);
+ }
+
+
+/** Specifies whether an alarm belongs to a timed or untimed event.
+
+@capability Note If the user does not have WriteDeviceData capability then we need to check
+that the alarm belongs to the user SID (The SID is stored as part of the alarm)
+@param aAlarmId Unique identifier of the alarm.
+@param aDayOrTimed Whether an alarm is for a timed or untimed event.
+@return KErrNone if successful, otherwise one of the system-wide errors. */
+EXPORT_C TInt RASCliSession::SetAlarmDayOrTimed(TAlarmId aAlarmId, TAlarmDayOrTimed aDayOrTimed) const
+ {
+ TIpcArgs args(aAlarmId, aDayOrTimed);
+ return SendReceive(EASShdOpCodeSetAlarmDayOrTimed, args);
+ }
+
+
+/** Tests whether the specified alarm is for a timed or untimed event.
+
+@capability None
+@param aAlarmId Unique identifier of the alarm under query.
+@param aDayOrTimed On return, whether an alarm is for a timed or untimed event.
+@return KErrNone if successful, otherwise one of the system-wide errors. */
+EXPORT_C TInt RASCliSession::GetAlarmDayOrTimed(TAlarmId aAlarmId, TAlarmDayOrTimed& aDayOrTimed) const
+ {
+ TPckg<TAlarmDayOrTimed> package(aDayOrTimed);
+ TIpcArgs args(aAlarmId, &package);
+ //
+ return SendReceive(EASShdOpCodeGetAlarmDayOrTimed, args);
+ }
+
+
+/** Sets the characteristics of a specified alarm.
+
+If the session-specific flag is removed, the outstanding notification
+is completed.
+
+@capability Note If the user does not have WriteDeviceData capability then we need to check
+that the alarm belongs to the user SID (The SID is stored as part of the alarm)
+@param aAlarmId Unique identifier of the alarm.
+@param aCharacteristics Alarm characteristics to apply.
+@return KErrNone if successful, otherwise one of the system-wide errors. */
+EXPORT_C TInt RASCliSession::SetAlarmCharacteristics(TAlarmId aAlarmId, TAlarmCharacteristicsFlags aCharacteristics) const
+ {
+ TPckgC<TAlarmCharacteristicsFlags> package(aCharacteristics);
+ TIpcArgs args(aAlarmId, &package);
+ //
+ return SendReceive(EASShdOpCodeSetAlarmCharacteristics, args);
+ }
+
+
+/** Gets the characteristics of an alarm.
+
+@capability None
+@param aAlarmId Unique identifier of the alarm under query.
+@param aCharacteristics On return, contains the charcteristics of the alarm
+specified.
+@return KErrNone if successful, otherwise one of the system-wide errors. */
+EXPORT_C TInt RASCliSession::GetAlarmCharacteristics(TAlarmId aAlarmId, TAlarmCharacteristicsFlags& aCharacteristics) const
+ {
+ TPckg<TAlarmCharacteristicsFlags> package(aCharacteristics);
+ TIpcArgs args(aAlarmId, &package);
+ //
+ return SendReceive(EASShdOpCodeGetAlarmCharacteristics, args);
+ }
+
+/** Sets if the alarm is a wakeup alarm
+
+@capability None
+@param aAlarmId Unique identifier of the alarm under query.
+@param aEnabled if the alarm is to be a wakeup alarm.
+@return KErrNone if successful, otherwise one of the system-wide errors. */
+
+#ifdef SYMBIAN_SYSTEM_STATE_MANAGEMENT
+EXPORT_C TInt RASCliSession::SetWakeup(TAlarmId aAlarmId, TBool aEnabled) const
+ {
+ TIpcArgs args(aAlarmId, aEnabled);
+ return SendReceive(EASShdOpCodeSetWakeup, args);
+ }
+#endif
+
+#ifdef SYMBIAN_ALARM_REPEAT_EXTENSIONS
+/**
+Sets which days of the week an alarm with a repeat definition of
+EAlarmRepeatDefintionRepeatDailyOnGivenDays activates on. By default, an alarm
+with a repeat definition of EAlarmRepeatDefinitionRepeatDailyOnGivenDays will be
+active on all days of the week.
+
+@prototype
+
+@capability
+ WriteDeviceData
+ Note: If the client does not have WriteDeviceData capability then it must
+ own the alarm. A client owns an alarm if the SID of the client matches the
+ SID of the alarm.
+
+@param aAlarmId
+ Identifies the alarm whose alarm days are to be set.
+
+@param aAlarmDays
+ The days of the week that the alarm activates on. Days are combined using
+ the bitwise OR operator e.g. EAlarmDayMonday|EAlarmDayTuesday.
+
+@return
+ KErrNone if successful, KErrArgument if aAlarmDays is an invalid value
+ otherwise one of the system-wide errors.
+*/
+EXPORT_C TInt RASCliSession::SetAlarmDays(TAlarmId aAlarmId, TUint8 aAlarmDays) const
+ {
+ TIpcArgs args(aAlarmId, aAlarmDays);
+ return SendReceive(EASShdOpCodeSetAlarmDays, args);
+ }
+
+/**
+Gets the days of the week that the given alarm activates on. This value is only
+applicable if the alarm’s repeat definition is
+EAlarmRepeatDefinitionRepeatDailyOnGivenDays. By default, an alarm with a
+repeat definition of EAlarmRepeatDefinitionRepeatDailyOn-GivenDays will be
+active on all days of the week.
+
+@prototype
+
+@param aAlarmId
+ Identifies the alarm whose alarm days are to be returned.
+
+@param aAlarmDays
+ On return the days of the week that the alarm activates on. The value will
+ be a combination of the values defined in the TAlarmDays enumeration.
+
+@return
+ KErrNone if successful, otherwise one of the system-wide errors.
+*/
+EXPORT_C TInt RASCliSession::GetAlarmDays(TAlarmId aAlarmId, TUint8& aAlarmDays) const
+ {
+ TPckg<TUint8> package(aAlarmDays);
+ TIpcArgs args(aAlarmId, &package);
+ return SendReceive(EASShdOpCodeGetAlarmDays, args);
+ }
+
+/**
+Sets the continuous state of the given alarm.
+
+@prototype
+
+@capability
+ WriteDeviceData
+ Note: If the client does not have WriteDeviceData capability then it must
+ own the alarm. A client owns an alarm if the SID of the client matches the
+ SID of the alarm.
+
+@param aAlarmId
+ Identifies the alarm whose continuous state is to be set.
+
+@param aContinuous
+ ETrue if the alarm is continuous, EFalse if the alarm is not continuous.
+
+@return
+ KErrNone if successful, otherwise one of the system-wide errors.
+*/
+EXPORT_C TInt RASCliSession::SetContinuous(TAlarmId aAlarmId, TBool aContinuous) const
+ {
+ TIpcArgs args(aAlarmId, aContinuous);
+ return SendReceive(EASShdOpCodeSetContinuous, args);
+ }
+
+/**
+Gets the continuous state of the given alarm.
+
+@prototype
+
+@param aAlarmId
+ Identifies the alarm whose continuous state is to be returned.
+
+@param aContinuous
+ On return ETrue if the alarm is continuous, EFalse if the alarm is not
+ continuous.
+
+@return
+ KErrNone if successful, otherwise one of the system-wide errors.
+*/
+EXPORT_C TInt RASCliSession::GetContinuous(TAlarmId aAlarmId, TBool& aContinuous) const
+ {
+ TPckg<TBool> package(aContinuous);
+ TIpcArgs args(aAlarmId, &package);
+ return SendReceive(EASShdOpCodeGetContinuous, args);
+ }
+#endif
+
+/** Updates an alarm's client-specific data in the alarm server.
+
+The TASShdAlarm class contains a number of client-specific fields. These fields
+are for use by clients of the alarm server to hold any data associated with
+an alarm. Although this data is not used in any way by the alarm server itself,
+clients can ensure that the alarm server keeps its own copy of the specified
+alarm up to date with that of the client.
+
+@capability Note If the user does not have WriteDeviceData capability then we need to check
+that the alarm belongs to the user SID (The SID is stored as part of the alarm)
+@param aAlarm The client-side alarm, whose corresponding server-side alarm
+is to be updated.
+@return KErrNone if successful, otherwise one of the system-wide error codes. */
+EXPORT_C TInt RASCliSession::SetClientData(const TASShdAlarm& aAlarm)
+ {
+ TPckgC<TASShdAlarm> package(aAlarm);
+ TIpcArgs args(aAlarm.Id(), &package);
+ //
+ return SendReceive(EASShdOpCodeSetClientData, args);
+ }
+
+
+//
+//
+//
+
+
+/** Associates the specified data with an alarm.
+
+This is arbitrary client-specific data, for which the alarm
+server simply acts as a router.
+
+@capability Note If the user does not have WriteDeviceData capability then we need to check
+that the alarm belongs to the user SID (The SID is stored as part of the alarm)
+@param aAlarmId Unique identifier of the alarm.
+@param aData Client-specific data to associate with the alarm.
+@return KErrNone if successful, KErrInUse if the specified alarm already has
+data assigned to it, or one of the system-wide error codes. */
+EXPORT_C TInt RASCliSession::AlarmDataAttachL(TAlarmId aAlarmId, const TDesC8& aData) const
+ {
+ TIpcArgs args(aAlarmId, aData.Length(), &aData);
+ return SendReceive(EASShdOpCodeAlarmDataAttach, args);
+ }
+
+
+/** Removes any previously attached alarm data from the specified alarm.
+
+This releases any resources allocated by the alarm server for this alarm.
+
+@capability Note If the user does not have WriteDeviceData capability then we need to check
+that the alarm belongs to the user SID (The SID is stored as part of the alarm)
+@param aAlarmId Unique identifier for the alarm.
+@return KErrNone if successful, KErrNotFound if the specified alarm does not
+exist (or the specified alarm does not have any data), or another of the system-wide
+error codes. */
+EXPORT_C TInt RASCliSession::AlarmDataDetach(TAlarmId aAlarmId) const
+ {
+ TIpcArgs args(aAlarmId);
+ return SendReceive(EASShdOpCodeAlarmDataDetach, args);
+ }
+
+
+/** Returns the size in bytes of any data associated with the specified alarm.
+
+@capability None
+@param aAlarmId Unique identifier of the alarm under query.
+@return The size in bytes of the alarm's data, or an error. KErrNotFound is
+returned if the specified alarm does not have any associated data. */
+EXPORT_C TInt RASCliSession::AlarmDataSize(TAlarmId aAlarmId) const
+ {
+ TIpcArgs args(aAlarmId);
+ return SendReceive(EASShdOpCodeAlarmDataSize, args);
+ }
+
+
+/** Retrieves the data attached to the specified alarm.
+
+This is data previously attached using AlarmDataAttachL().
+
+@capability Note If the user does not have ReadUserData capability then we need to check
+that the alarm belongs to the user SID (The SID is stored as part of the alarm)
+@param aAlarmId Unique identifier of the alarm under query.
+@param aSink On return, contains the data associated with the alarm. This buffer
+must be large enough to contain all the data or a panic occurs.
+@return KErrNone if successful, KErrNotFound if the specified alarm does not
+have any associated data, or a system-wide error. */
+EXPORT_C TInt RASCliSession::GetAlarmData(TAlarmId aAlarmId, TDes8& aSink) const
+ {
+ TIpcArgs args(aAlarmId, aSink.MaxLength(), &aSink);
+ return SendReceive(EASShdOpCodeGetAlarmData, args);
+ }
+
+
+/** Retrieves the data attached to the specified alarm.
+
+This is data previously attached using AlarmDataAttachL().
+
+@capability Note If the user does not have ReadUserData capability then we need to check
+that the alarm belongs to the user SID (The SID is stored as part of the alarm)
+@param aAlarmId Unique identifier of the alarm under query.
+@param aSink On return, contains the data associated with the alarm, or
+NULL if the specified alarm does not have any associated data, or an error was returned.
+@return KErrNone if successful, KErrNotFound if the specified alarm does not
+have any associated data, or a system-wide error. */
+EXPORT_C TInt RASCliSession::GetAlarmData(TAlarmId aAlarmId, HBufC8*& aSink) const
+ {
+ aSink = NULL;
+ TInt r = AlarmDataSize(aAlarmId);
+
+ if (r > 0)
+ {
+ aSink = HBufC8::New(r);
+ if (!aSink)
+ {
+ return KErrNoMemory;
+ }
+
+ TPtr8 data = aSink->Des();
+ r = GetAlarmData(aAlarmId, data);
+
+ if (r != KErrNone)
+ {
+ delete aSink;
+ aSink = NULL;
+ }
+ }
+
+ return r;
+ }
+
+
+//
+//
+//
+
+
+/** Set the status of all alarms in the specified category.
+
+@capability Note If the user does not have WriteDeviceData capability then we need to check
+that the alarm belongs to the user SID (The SID is stored as part of the alarm)
+@param aCategory An alarm category.
+@param aStatus An alarm status.
+@return KErrNone if successful, otherwise one of the system-wide error codes. */
+EXPORT_C TInt RASCliSession::SetAlarmStatusByCategory(TAlarmCategory aCategory, TAlarmStatus aStatus) const
+ {
+ TIpcArgs args(aCategory.iUid, aStatus);
+ return SendReceive(EASShdOpCodeSetAlarmStatusByCategory, args);
+ }
+
+
+/** Returns the number of alarms in a specified category.
+
+@capability None
+@param aCategory Category of alarm under query.
+@return Number of alarms in the specified category, or, if negative, one of
+the standard error codes.. */
+EXPORT_C TInt RASCliSession::GetAlarmCountForCategory(TAlarmCategory aCategory) const
+ {
+ TPckgBuf<TInt> package;
+ TIpcArgs args(aCategory.iUid, &package);
+ //
+ const TInt error = SendReceive(EASShdOpCodeGetAlarmCountForCategory, args);
+ if (error != KErrNone)
+ return error;
+ return package();
+ }
+
+
+/** Deletes all alarms in the queue corresponding to a specified category.
+
+You can also specify that only the orphaned alarms of that category be deleted.
+
+@capability Note If the user does not have WriteDeviceData capability then we need to check
+that the alarm belongs to the user SID (The SID is stored as part of the alarm)
+@param aCategory Category of alarms to be deleted.
+@param aDeleteOnlyOrphanedAlarmsInCategory ETrue: delete only orphaned alarms
+within the category. EFalse: delete all alarms within the category.
+@return KErrNone if successful, otherwise one of the system-wide error codes. */
+EXPORT_C TInt RASCliSession::AlarmDeleteAllByCategory(TAlarmCategory aCategory, TBool aDeleteOnlyOrphanedAlarmsInCategory) const
+ {
+ TIpcArgs args(aCategory.iUid, aDeleteOnlyOrphanedAlarmsInCategory);
+ return SendReceive(EASShdOpCodeAlarmDeleteAllByCategory, args);
+ }
+
+
+/** Deletes alarms in the queue corresponding to a specified category and type.
+
+@capability Note If the user does not have WriteDeviceData capability then we need to check
+that the alarm belongs to the user SID (The SID is stored as part of the alarm)
+@param aCategory Category of alarms to be deleted.
+@param aWhatToDelete specify what type of alarms to delte
+within the category.
+@return KErrNone if successful, otherwise one of the system-wide error codes. */
+EXPORT_C TInt RASCliSession::AlarmDeleteByCategory(TAlarmCategory aCategory, TDeleteType aWhatToDelete) const
+ {
+ TIpcArgs args(aCategory.iUid, aWhatToDelete);
+ return SendReceive(EASShdOpCodeAlarmDeleteByCategory, args);
+ }
+
+/**
+@internalComponent
+
+Delete alarms based on their type and the Calendar filename to which alarms belong
+
+@capability Note If the user does not have WriteDeviceData capability then we need to check
+that the alarm belongs to the user SID (The SID is stored as part of the alarm)
+@param aWhatToDelete specify what type of alarms to delte
+within the category.
+@param aFileName specify the name of the Calendar file which alarms came from
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+*/
+EXPORT_C TInt RASCliSession::AlarmDeleteByCalendarFile(const TDesC& aFileName, TDeleteType aWhatToDelete) const
+ {
+ TIpcArgs args(&aFileName, aWhatToDelete);
+ return SendReceive(EASShdOpCodeAlarmDeleteByCalendarFile, args);
+ }
+
+
+/**
+
+Retrieves a list of all alarm categories in use within the alarm server.
+
+@capability None
+@param aCategories On return, contains the list of available categories.
+
+*/
+EXPORT_C void RASCliSession::GetAvailableCategoryListL(RArray<TAlarmCategory>& aCategories) const
+ {
+ // First step is to build the transfer buffer in the server
+ // and get the size (in bytes) so that we know
+ // how big to make the client-side (corresponding) temporary one.
+ TPckgBuf<TInt> sizeOfTransferBuffer;
+ TIpcArgs args(&sizeOfTransferBuffer);
+ User::LeaveIfError(SendReceive(EASShdOpCodeGetAvailableCategoryList, args));
+
+ // Next step is to create a buffer of sufficient size in order to fetch the
+ // buffer from the server
+ CBufBase* buffer = FetchTransferBufferLC(sizeOfTransferBuffer());
+
+ // The buffer just contains serialized TAlarmCategories so we need to
+ // extract them and populate the array.
+ TAlarmCategory category;
+ aCategories.Reset();
+ RBufReadStream stream(*buffer);
+ CleanupClosePushL(stream); // Don't think this is necessary
+ const TInt count = stream.ReadInt32L();
+ for(TInt i=0; i<count; i++)
+ {
+ stream >> category;
+ User::LeaveIfError(aCategories.Append(category));
+ }
+ //
+ stream.Close();
+ CleanupStack::PopAndDestroy(2, buffer);
+ }
+
+
+/**
+
+Retrieves a list of all alarm identifiers for alarms within the server of a
+specified category.
+
+@capability None
+@param aCategory Category of alarms to find.
+@param aAlarmIds On return, contains the list of alarms.
+
+*/
+
+EXPORT_C void RASCliSession::GetAlarmIdListForCategoryL(TAlarmCategory aCategory, RArray<TAlarmId>& aAlarmIds) const
+ {
+ // First step is to build the transfer buffer in the server
+ // and get the size (in bytes) so that we know
+ // how big to make the client-side (corresponding) temporary one.
+ TPckgBuf<TInt> sizeOfTransferBuffer;
+ TIpcArgs args(aCategory.iUid, &sizeOfTransferBuffer);
+ User::LeaveIfError(SendReceive(EASShdOpCodeGetAlarmIdListForCategory, args));
+
+ // Fetch the array
+ FetchAlarmIdsFromBufferL(aAlarmIds, sizeOfTransferBuffer());
+ }
+
+
+//
+//
+//
+
+
+/**
+
+Returns the number of alarms in a specified state.
+
+@capability None
+@param aState Alarm state of interest.
+@return Number of alarms in the specified state.
+
+*/
+EXPORT_C TInt RASCliSession::AlarmCountByState(TAlarmState aState) const
+ {
+ TPckgBuf<TInt> package;
+ TIpcArgs args(aState, &package);
+ //
+ const TInt error = SendReceive(EASShdOpCodeAlarmCountByState, args);
+ if (error != KErrNone)
+ return error;
+ return package();
+ }
+
+
+/**
+
+Retrieves a list of the unique identifiers of all alarms in a specified state.
+
+@capability None
+@param aState Alarm state that you are interested in.
+@param aAlarmIds On return, contains the unique identifiers of the alarms in
+the specified state.
+
+*/
+EXPORT_C void RASCliSession::GetAlarmIdListByStateL(TAlarmState aState, RArray<TAlarmId>& aAlarmIds) const
+ {
+ // First step is to build the transfer buffer in the server
+ // and get the size (in bytes) so that we know
+ // how big to make the client-side (corresponding) temporary one.
+ TPckgBuf<TInt> sizeOfTransferBuffer;
+ TIpcArgs args(aState, &sizeOfTransferBuffer);
+ User::LeaveIfError(SendReceive(EASShdOpCodeGetAlarmIdListByState, args));
+
+ // Fetch the array
+ FetchAlarmIdsFromBufferL(aAlarmIds, sizeOfTransferBuffer());
+ }
+
+
+/**
+
+Retrieves a list of the unique identifiers of all the alarms in the alarm server.
+
+@capability None
+@param aAlarmIds On return, contains a list of unique identifiers.
+
+*/
+EXPORT_C void RASCliSession::GetAlarmIdListL(RArray<TAlarmId>& aAlarmIds) const
+ {
+ // First step is to build the transfer buffer in the server
+ // and get the size (in bytes) so that we know
+ // how big to make the client-side (corresponding) temporary one.
+ TPckgBuf<TInt> sizeOfTransferBuffer;
+ // We put this in slot 1 because of the way the server has been written.
+ TIpcArgs args(TIpcArgs::ENothing, &sizeOfTransferBuffer);
+ User::LeaveIfError(SendReceive(EASShdOpCodeGetAlarmIdList, args));
+
+ // Fetch the array
+ FetchAlarmIdsFromBufferL(aAlarmIds, sizeOfTransferBuffer());
+ }
+
+
+/**
+
+Retrieves the unique identifier of the next alarm in the alarm server queue.
+
+@capability None
+@param aAlarmId On return, contains the unique identifier of the next alarm
+due.
+@return KErrNone if successful, KNullAlarmId if there are no alarms in the
+queue, otherwise another one of the system-wide error codes.
+
+*/
+EXPORT_C TInt RASCliSession::GetNextDueAlarmId(TAlarmId& aAlarmId) const
+ {
+ TPckg<TAlarmId> package(aAlarmId);
+ TIpcArgs args(&package);
+ //
+ return SendReceive(EASShdOpCodeGetNextDueAlarmId, args);
+ }
+
+
+/**
+
+Returns the number of alarms that are currently active within the alarm queue.
+Active alarms are:
+
+Alarms that have not yet notified.
+
+Alarms that are in the queued or snoozed state, and are enabled.
+
+
+@capability None
+@return Number of active alarms, or an error code.
+
+*/
+EXPORT_C TInt RASCliSession::NumberOfAlarmsActiveInQueue() const
+ {
+ TPckgBuf<TInt> package;
+ TIpcArgs args(&package);
+ //
+ const TInt error = SendReceive(EASShdOpCodeNumberOfAlarmsActiveInQueue, args);
+ if (error != KErrNone)
+ return error;
+ return package();
+ }
+
+
+//
+//
+//
+
+
+/**
+
+Sets the alarm sound state to on or off.
+
+@capability WriteDeviceData
+@param aState The alarm sound state.
+@return KErrNone if successful, otherwise one of the system-wide errors.
+
+*/
+EXPORT_C TInt RASCliSession::SetAlarmSoundState(TAlarmGlobalSoundState aState) const
+ {
+ TIpcArgs args(aState);
+ return SendReceive(EASShdOpCodeSetAlarmSoundState, args);
+ }
+
+
+/**
+
+Retrieves the alarm sound state. The alarm sound can be on or off.
+
+@capability None
+@param aState On return, contains the alarm sound state.
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+
+*/
+EXPORT_C TInt RASCliSession::GetAlarmSoundState(TAlarmGlobalSoundState& aState) const
+ {
+ TPckg<TAlarmGlobalSoundState> package(aState);
+ TIpcArgs args(&package);
+ //
+ return SendReceive(EASShdOpCodeGetAlarmSoundState, args);
+ }
+
+
+/**
+
+Disables alarm sounds until a specified time.
+
+Alarms still expire and clients are notified during this period, but no sound
+is played.
+
+@capability WriteDeviceData
+@param aLocalTime Time, in local time, when alarm sounds are to be played once
+more.
+@return KErrNone if successful, KErrArgument if the time is in the past,
+otherwise another one of the system-wide error codes.
+
+*/
+EXPORT_C TInt RASCliSession::SetAlarmSoundsSilentUntil(const TTime& aLocalTime) const
+ {
+ TPckgC<TTime> package(aLocalTime);
+ TIpcArgs args(&package);
+ //
+ return SendReceive(EASShdOpCodeSetAlarmSoundsSilentUntil, args);
+ }
+
+
+/**
+
+Disables alarm sounds for a specified interval.
+
+Alarms still expire and clients are notified during this period, but no sound
+is played.
+
+NOTE: If user or some application changes system time or UTC offset (for example by using
+User::SetUTCOffset(), User::SetHomeTime(), User::SetUTCTimeAndOffset() etc)
+the silent periond will be cancelled.
+
+@capability WriteDeviceData
+@param aTimeToRemainSilentFor Time interval in minutes, during which no sound
+is to be played.
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+
+*/
+EXPORT_C TInt RASCliSession::SetAlarmSoundsSilentFor(TTimeIntervalMinutes aTimeToRemainSilentFor) const
+ {
+ TPckgC<TTimeIntervalMinutes> package(aTimeToRemainSilentFor);
+ TIpcArgs args(&package);
+ //
+ return SendReceive(EASShdOpCodeSetAlarmSoundsSilentFor, args);
+ }
+
+
+/**
+
+Retrieves the time at which all alarm sounds resume.
+
+@capability None
+@param aLocalTime On return, contains the time, in local time, when sounds resume.
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+
+*/
+EXPORT_C TInt RASCliSession::GetAlarmSoundsSilentUntil(TTime& aLocalTime) const
+ {
+ TPckg<TTime> package(aLocalTime);
+ TIpcArgs args(&package);
+ //
+ return SendReceive(EASShdOpCodeGetAlarmSoundsSilentUntil, args);
+ }
+
+
+/**
+
+Cancels the silent period, turning the alarm sounds on.
+
+@capability WriteDeviceData
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+
+*/
+EXPORT_C TInt RASCliSession::CancelAlarmSilence() const
+ {
+ return SendReceive(EASShdOpCodeCancelAlarmSilence);
+ }
+
+
+/**
+
+Tests whether the alarm server has temporarily disabled sounds.
+
+@capability None
+@return ETrue: alarms are temporarily silent. EFalse: sounds are not silent.
+
+*/
+EXPORT_C TBool RASCliSession::AlarmSoundsTemporarilySilenced() const
+ {
+ TPckgBuf<TBool> package;
+ TIpcArgs args(&package);
+ //
+ const TInt error = SendReceive(EASShdOpCodeAlarmSoundsTemporarilySilenced, args);
+ if (error != KErrNone)
+ return EFalse;
+ return package();
+ }
+
+
+/**
+
+Sets the list of alarm intervals.
+
+Alarm intervals consist of a duration and an offset.
+
+@capability WriteDeviceData
+@param aIntervals Contains one or more alarm intervals. There must be one
+interval in the array with an offset of zero.
+@leave KErrGeneral If the array is inappropriate, for example, if intervals
+overlap or has no elements. Also, from v9.2 onwards, if the array has only one
+element and the Repeat Setting is set to RepeatLast.
+@leave KErrArgument If no interval has an offset of zero.
+@leave KErrNotSupported The Alarm Play Intervals cannot be set because Alarm Play Intervals is disabled by resource file. (from v9.2 onwards)
+
+*/
+EXPORT_C void RASCliSession::SetAlarmPlayIntervalsL(const CArrayFix<TASCliSoundPlayDefinition>& aIntervals) const
+ {
+ // Create the buffer first off.
+ const TInt count = aIntervals.Count();
+ CBufBase* buffer = CBufFlat::NewL((count + 1) * sizeof(TASCliSoundPlayDefinition)); // approximation
+ CleanupStack::PushL(buffer);
+
+ // Stream out all the details
+ RBufWriteStream stream(*buffer);
+ CleanupClosePushL(stream); // don't think this is necessary
+ stream.WriteInt32L(count);
+ for(TInt i=0; i<count; i++)
+ {
+ const TASCliSoundPlayDefinition& interval = aIntervals[i];
+ //
+ stream.WriteInt32L(interval.Offset().Int());
+ stream.WriteInt32L(interval.Duration().Int());
+ }
+
+ // Prepare our arguments
+ TPtr8 ptr=buffer->Ptr(0); //To stop a warning
+ TIpcArgs args(&ptr, buffer->Size(), count);
+
+ // Send to server, and tidy up afterwards
+ const TInt error = SendReceive(EASShdOpCodeSetAlarmPlayIntervals, args);
+ User::LeaveIfError(error);
+ CleanupStack::PopAndDestroy(2, buffer);
+ }
+
+
+/**
+
+Retrieves the list of alarm intervals.
+
+They are stored in ascending order of offset.
+
+@capability None
+@param aIntervals On return, contains the list of alarm intervals.
+
+*/
+EXPORT_C void RASCliSession::GetAlarmPlayIntervalsL(CArrayFix<TASCliSoundPlayDefinition>& aIntervals) const
+ {
+ // First step is to build the transfer buffer in the server
+ // and get the size (in bytes) so that we know
+ // how big to make the client-side (corresponding) temporary one.
+ TPckgBuf<TInt> sizeOfTransferBuffer;
+ TIpcArgs args(&sizeOfTransferBuffer);
+ User::LeaveIfError(SendReceive(EASShdOpCodeGetAlarmPlayIntervals, args));
+
+ // Get buffer
+ CBufBase* buffer = FetchTransferBufferLC(sizeOfTransferBuffer());
+ RBufReadStream stream(*buffer);
+ CleanupClosePushL(stream);
+ //
+ aIntervals.Reset();
+ const TInt count = stream.ReadInt32L();
+ for(TInt i=0; i<count; i++)
+ {
+ const TTimeIntervalMinutes offset(stream.ReadUint32L());
+ const TTimeIntervalSeconds duration(stream.ReadUint32L());
+ //
+ aIntervals.AppendL(TASCliSoundPlayDefinition(offset, duration));
+ }
+ //
+ CleanupStack::PopAndDestroy(2, buffer);
+ }
+
+
+//
+//
+//
+
+
+/**
+
+Enables client notification when alarm settings change, and when the next alarm
+time is calculated.
+
+A panic occurs if notification is already active.
+
+@capability None
+@param aStatus The request status object that is to be signalled. On return,
+contains one of the TAlarmChangeEvent enumeration values. If an error occurs,
+the TRequestStatus object contains one of the standard system-wide error codes.
+@param aAlarmId An alarm identifier relating to the type of event that took
+place. If the type of event that occurred relates to a particular alarm, this
+object is populated with that alarm's identiifer. Otherwise it contains an
+undefined value.
+@see TAlarmChangeEvent
+
+*/
+EXPORT_C void RASCliSession::NotifyChange(TRequestStatus& aStatus, TAlarmId& aAlarmId)
+ {
+ iAlarmIdPointer.Set((TUint8*) &aAlarmId, sizeof(TAlarmId), sizeof(TAlarmId));
+ TIpcArgs args(&iAlarmIdPointer, EFalse);
+ SendReceive(EASShdOpCodeNotifyChange, args, aStatus);
+ }
+
+
+/**
+
+Cancels any previous change notification request.
+
+@capability None
+@panic Panics with AlarmClientUtils::EAlarmClientPanicNotificationCancel if the
+notification fails to occur.
+
+*/
+EXPORT_C void RASCliSession::NotifyChangeCancel() const
+ {
+ const TInt error = SendReceive(EASShdOpCodeNotifyChangeCancel);
+ __ASSERT_ALWAYS(error == KErrNone || error == KErrServerTerminated, AlarmClientUtils::Panic(AlarmClientUtils::EAlarmClientPanicNotificationCancel));
+ }
+
+
+//
+//
+//
+
+
+/**
+@internalComponent
+
+In debug builds, this will cause the Alarm Server to terminate.
+
+@capability None
+*/
+EXPORT_C void RASCliSession::__DbgShutDownServer() const
+ {
+#ifdef _DEBUG
+ const TInt error = SendReceive(EASShdOpCodeDbgShutDownServer);
+ __ASSERT_DEBUG(error == KErrNone || error == KErrServerTerminated, AlarmClientUtils::Fault(AlarmClientUtils::EAlarmClientFaultDebugFuncError));
+ //the following line is to make sure that the funtion will not return until the server is closed down.
+ while (NumberOfAlarmsActiveInQueue()!=KErrServerTerminated)
+ {
+ User::After(100000);
+ }
+#endif
+ }
+
+
+/**
+@internalComponent
+
+In debug builds, this will fail a memory allocation.
+
+@capability None
+@param aCount Set this to the number of allocations to fail, or 0
+to reset the failure tool.
+
+*/
+EXPORT_C void RASCliSession::__DbgFailAlloc(TInt
+#ifdef _DEBUG
+ aCount
+#endif
+ ) const
+ {
+#ifdef _DEBUG
+ TIpcArgs args(aCount);
+ const TInt error = SendReceive(EASShdOpCodeDbgFailAlloc, args);
+ __ASSERT_DEBUG(error == KErrNone || error == KErrServerTerminated, AlarmClientUtils::Fault(AlarmClientUtils::EAlarmClientFaultDebugFuncError));
+#endif
+ }
+
+
+/**
+@internalComponent
+
+In debug builds, this will prevent the Alarm Server from notifying the Alarm
+Alert Server about the expiry of an alarm.
+
+@capability None
+@param aShouldStop ETrue: Alarm Alert Server is not notified on alarm expiry
+EFalse: Alarm Alert Server is notified on alarm expiry
+
+*/
+EXPORT_C void RASCliSession::__DbgPreventUserNotify(TBool
+#ifdef _DEBUG
+ aShouldStop
+#endif
+ ) const
+ {
+#ifdef _DEBUG
+ TIpcArgs args(aShouldStop);
+ const TInt error = SendReceive(EASShdOpCodeDbgPreventUserNotify, args);
+ __ASSERT_DEBUG(error == KErrNone || error == KErrServerTerminated, AlarmClientUtils::Fault(AlarmClientUtils::EAlarmClientFaultDebugFuncError));
+#endif
+ }
+
+
+/**
+
+@internalComponent
+
+In debug builds, this will cause the specified alarm to be snoozed.
+
+@capability None
+@param aAlarmId Unique identifier of the alarm.
+@param aNewTime Time to reawaken alarm (as UTC time).
+@return Returns whether the alarm could be snoozed.
+
+ */
+EXPORT_C TInt RASCliSession::__DbgSnoozeAlarm(TAlarmId
+#ifdef _DEBUG
+ aAlarmId
+#endif
+ , const TTime&
+#ifdef _DEBUG
+ aNewTime
+#endif
+ ) const
+ {
+ TInt error = KErrNotSupported;
+ //
+#ifdef _DEBUG
+ TPckgC<TTime> package(aNewTime);
+ TIpcArgs args(aAlarmId, &package);
+ error = SendReceive(EASShdOpCodeDbgSnoozeAlarm, args);
+#endif
+ //
+ return error;
+ }
+
+/**
+
+@internalComponent
+
+In debug builds, this will switch handling of time/date changes by CASSrvEnvironmentChangeManager
+
+@capability None
+@param aFlag ETrue to enable and EFalse to disable handling
+ */
+
+EXPORT_C TInt RASCliSession::__DbgSetEnvChgHandling(TBool
+#ifdef _DEBUG
+ aFlag
+#endif
+ ) const
+ {
+ TInt error = KErrNotSupported;
+ //
+#ifdef _DEBUG
+ TIpcArgs args(aFlag);
+ error = SendReceive(EASShdOpCodeDbgSetEnvironmentChangesHandling, args);
+#endif
+ return error;
+ }
+
+//
+//
+//
+
+/**
+@capability None
+*/
+void RASCliSession::FetchAlarmIdsFromBufferL(RArray<TAlarmId>& aAlarmIds, TInt aBufferSize) const
+ {
+ CBufBase* buffer = FetchTransferBufferLC(aBufferSize);
+
+ // The buffer just contains serialized TAlarmId's so we need to
+ // extract them and populate the array.
+ aAlarmIds.Reset();
+ RBufReadStream stream(*buffer);
+ CleanupClosePushL(stream);
+ //
+ const TInt count = stream.ReadInt32L();
+ for(TInt i=0; i<count; i++)
+ {
+ const TAlarmId id = stream.ReadInt32L();
+ aAlarmIds.AppendL(id);
+ }
+ //
+ CleanupStack::PopAndDestroy(2, buffer);
+ }
+
+/**
+Create a buffer of sufficient size in order to fetch the buffer from the server
+
+@capability None
+*/
+CBufBase* RASCliSession::FetchTransferBufferLC(TInt aBufferSize) const
+ {
+ // Create a buffer of sufficient size in order to fetch the
+ // buffer from the server
+ CBufBase* buffer = CBufFlat::NewL(aBufferSize);
+ CleanupStack::PushL(buffer);
+ buffer->ResizeL(aBufferSize);
+
+ // Now fetch the transfer buffer from the server
+ TPtr8 pBuffer(buffer->Ptr(0));
+ //
+ TIpcArgs args(&pBuffer);
+ User::LeaveIfError(SendReceive(EASShdOpCodeFetchTransferBuffer, args));
+ //
+ return buffer;
+ }
+
+
+
+
+
+
+
+