bluetoothappprofiles/avrcp/playerinformation/src/playercapabilities.cpp
changeset 70 f5508c13dfe0
parent 67 16e4b9007960
child 71 083fd884d7dd
equal deleted inserted replaced
67:16e4b9007960 70:f5508c13dfe0
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // This file contains the capabilites part of playerinformation.
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @publishedAll
       
    21  @released
       
    22 */
       
    23 
       
    24 #include <bluetooth/logger.h>
       
    25 #include <remconinterfaceselector.h>
       
    26 #include <remcon/avrcpspec.h>
       
    27 #include <playerinformationtarget.h>
       
    28 
       
    29 #include "eventsmask.h"
       
    30 #include "playerinformation.h"
       
    31 
       
    32 #ifdef __FLOG_ACTIVE
       
    33 _LIT8(KLogComponent, LOG_COMPONENT_AVRCP_PLAYER_INFO);
       
    34 #endif
       
    35 
       
    36 class TRemConMetadataTransferGetCapabilities 
       
    37 	{
       
    38 public:
       
    39 	TUint8	 				iCapabilityID;
       
    40 	};
       
    41 
       
    42 EXPORT_C void MPlayerCapabilitiesObserver::ClearEvents()
       
    43 	{
       
    44 	DoClearEvents();
       
    45 	}
       
    46 
       
    47 EXPORT_C TInt MPlayerCapabilitiesObserver::AddEvent(TRegisterNotificationEvent aEvent)
       
    48 	{
       
    49 	return DoAddEvent(aEvent);
       
    50 	}
       
    51 	
       
    52 EXPORT_C TInt MPlayerCapabilitiesObserver::RemoveEvent(TRegisterNotificationEvent aEvent)
       
    53 	{
       
    54 	return DoRemoveEvent(aEvent);
       
    55 	}
       
    56 
       
    57 EXPORT_C void MPlayerCapabilitiesObserver::ClearCompanyIds()
       
    58 	{
       
    59 	DoClearCompanyIds();
       
    60 	}
       
    61 
       
    62 EXPORT_C TInt MPlayerCapabilitiesObserver::AddCompanyId(TInt aID)
       
    63 	{
       
    64 	return DoAddCompanyId( aID );
       
    65 	}
       
    66 
       
    67 EXPORT_C TInt MPlayerCapabilitiesObserver::RemoveCompanyID(TInt aID)
       
    68 	{
       
    69 	return DoRemoveCompanyID( aID );
       
    70 	}
       
    71 
       
    72 
       
    73 // from MPlayerCapabilitiesObserver
       
    74 void CPlayerInfoTarget::DoClearEvents()
       
    75 	{
       
    76 	// AVRCP 1.3 specification, Appendix H says that PlaybackStatusChanged
       
    77 	// and TrackChanged event notification support is mandatory, so add these
       
    78 	
       
    79 	iSupportedNotificationEventList->Reset();
       
    80 	iSupportedNotificationEventList->Append(ERegisterNotificationPlaybackStatusChanged);
       
    81 	iSupportedNotificationEventList->Append(ERegisterNotificationTrackChanged);
       
    82 	}
       
    83 
       
    84 
       
    85 TInt CPlayerInfoTarget::DoAddEvent( TRegisterNotificationEvent aEvent )
       
    86 	{
       
    87 	// check the event is supported (note system status is NOT supported)
       
    88 	if (   aEvent >= ERegisterNotificationReservedLast
       
    89 		|| aEvent == ERegisterNotificationSystemStatusChanged_NotSupported)
       
    90 		{
       
    91 		return KErrNotSupported;
       
    92 		}
       
    93 		
       
    94 	// check if aEvent is already in the list of supported events
       
    95 	if (!iSupportedNotificationEventList->Find(aEvent))
       
    96 		{
       
    97 		// not found so add it to the list
       
    98 		iSupportedNotificationEventList->Append(aEvent);
       
    99 		return KErrNone;
       
   100 		}
       
   101 	
       
   102 	// else return already in the list
       
   103 	return KErrAlreadyExists;
       
   104 	}
       
   105 
       
   106 
       
   107 TInt CPlayerInfoTarget::DoRemoveEvent( TRegisterNotificationEvent aEvent )
       
   108 	{
       
   109 	// AVRCP 1.3 specification, Appendix H says that PlaybackStatusChanged
       
   110 	// and TrackChanged event notification support is mandatory, so add these
       
   111 	TInt err = KErrNone;
       
   112 	if (   aEvent == ERegisterNotificationPlaybackStatusChanged
       
   113 		|| aEvent == ERegisterNotificationTrackChanged)
       
   114 		{
       
   115 		return KErrNotSupported;
       
   116 		}
       
   117 	
       
   118 	// Find aEvent in the list of supported events
       
   119 	if (iSupportedNotificationEventList->Find(aEvent))
       
   120 		{
       
   121 		// and then remove it
       
   122 		iSupportedNotificationEventList->Remove(aEvent);
       
   123 		TInt pendingPos = iPendingNotificationEventList.Find(aEvent);
       
   124 		if (pendingPos != KErrNotFound)
       
   125 			{
       
   126 			iPendingNotificationEventList.Remove( pendingPos );
       
   127 			
       
   128 			// Tell anyone waiting for a notification that an event has been
       
   129 			// removed. Alas, we can't specify _WHICH_ event has been removed
       
   130 			// since there's no way to indicate this in an INTERNAL_ERROR response
       
   131 			SendError(KErrAvrcpMetadataInternalError, 
       
   132 					  RAvrcpIPC::SetIPCOperationIdFromEventId(aEvent), 
       
   133 					  ERemConNotifyResponseChanged);
       
   134 			}
       
   135 		}
       
   136 	else
       
   137 		{
       
   138 		err = KErrNotFound;
       
   139 		}
       
   140 	return err;
       
   141 	}
       
   142 
       
   143 
       
   144 void CPlayerInfoTarget::DoClearCompanyIds()
       
   145 	{
       
   146 	// The Bluetooth SIG vendor id must always be present
       
   147 	// See AVRCP 1.3 Specification, section 5.5.1, table 5.4
       
   148 	iCompanyIdList.Reset();
       
   149 	iCompanyIdList.Append(KBluetoothSIGVendorId);
       
   150 	}
       
   151 
       
   152 
       
   153 TInt CPlayerInfoTarget::DoAddCompanyId( TInt aID )
       
   154 	{
       
   155 	if ( aID > KMaxCompanyID )
       
   156 		{
       
   157 		return KErrNotSupported;
       
   158 		}
       
   159 		
       
   160 	// check if the ID is already in the list
       
   161 	TInt pos = iCompanyIdList.Find( aID );
       
   162 
       
   163 	// add only if not present in list to avoid duplicates
       
   164 	if (pos != KErrNotFound)
       
   165 		{
       
   166 		return KErrAlreadyExists;
       
   167 		}
       
   168 	
       
   169 	// make sure the list cannot contain more than 255 items
       
   170 	if (iCompanyIdList.Count() >= KMaxNrOfCompanyIDs)
       
   171 		{
       
   172 		return KErrOverflow;
       
   173 		}
       
   174 		
       
   175 	return iCompanyIdList.Append( aID );
       
   176 	}
       
   177 
       
   178 
       
   179 TInt CPlayerInfoTarget::DoRemoveCompanyID( TInt aID )
       
   180 	{
       
   181 	// The Bluetooth SIG vendor id must always be present
       
   182 	// See AVRCP 1.3 Specification, section 5.5.1, table 5.4
       
   183 	if ( aID == KBluetoothSIGVendorId )
       
   184 		{
       
   185 		return KErrNotSupported;
       
   186 		}
       
   187 		
       
   188 	// check if the ID is in the list
       
   189 	TInt pos = iCompanyIdList.Find( aID );
       
   190 
       
   191 	// if found remove else do nothing
       
   192 	if (pos != KErrNotFound)
       
   193 		{
       
   194 		iCompanyIdList.Remove( pos );
       
   195 		return KErrNone;
       
   196 		}
       
   197 	return pos;
       
   198 	}
       
   199 
       
   200 
       
   201 void CPlayerInfoTarget::ProcessGetCapabilities(const TDesC8& aData)
       
   202 	{
       
   203 	LOG_STATIC_FUNC
       
   204 
       
   205 	/* Decode the get capability message */
       
   206 	TRemConMetadataTransferGetCapabilities getCapability;
       
   207 	
       
   208 	// check there is at least 1 byte of data
       
   209 	if (!aData.Length())
       
   210 		{
       
   211 		// Invalid packet
       
   212 		return SendError(KErrAvrcpMetadataInvalidParameter, EGetCapabilities);
       
   213 		}
       
   214 		
       
   215 	TPckgC<TRemConMetadataTransferGetCapabilities> data(*reinterpret_cast<const TRemConMetadataTransferGetCapabilities*>(aData.Ptr()));
       
   216 	getCapability = data();
       
   217 	TGetCapabilityValues id = (TGetCapabilityValues) getCapability.iCapabilityID;
       
   218 	
       
   219 	// format the response in a TRemConGetCapabilitiesResponse
       
   220 	RRemConGetCapabilitiesResponse response;
       
   221 
       
   222 	switch ( id )
       
   223 		{
       
   224 	case ECapabilityIdCompanyID:
       
   225 		// respond with ECapabilityIdCompanyID
       
   226 		response.iCapabilityId = ECapabilityIdCompanyID;
       
   227 
       
   228 		// followed by number of IDs
       
   229 		response.iCapabilityCount = iCompanyIdList.Count();
       
   230 
       
   231 		// and then list of company ids,
       
   232 		for (TInt i=0; i< iCompanyIdList.Count(); i++ )
       
   233 			{
       
   234 			TInt x = iCompanyIdList[i];
       
   235 			if (response.iCapabilities.Append(x) != KErrNone)
       
   236 				{
       
   237 				response.Close();
       
   238 				return SendError(KErrAvrcpMetadataInternalError, EGetCapabilities);   // Try to send internal error if OOM
       
   239 				}
       
   240 			}
       
   241 		break;
       
   242 		
       
   243 	case ECapabilityIdEventsSupported:
       
   244 		// respond with ECapabilityIdEventsSupported
       
   245 		response.iCapabilityId = ECapabilityIdEventsSupported;
       
   246 		
       
   247 		// followed by number of supported events, and then list of events
       
   248 		response.iCapabilityCount = 0;
       
   249 		iSupportedNotificationEventList->Begin();
       
   250 		while(iSupportedNotificationEventList->Next())
       
   251 			{
       
   252 			if (KErrNone != response.iCapabilities.Append(iSupportedNotificationEventList->Get()))
       
   253 				{
       
   254 				response.Close();
       
   255 				return SendError(KErrAvrcpMetadataInternalError, EGetCapabilities);   // Try to send internal error if OOM
       
   256 				}
       
   257 			response.iCapabilityCount++;
       
   258 			}
       
   259 		break;	
       
   260 		
       
   261 	default:
       
   262 		/* other IDs are reserved */
       
   263 		return SendError(KErrAvrcpMetadataInvalidParameter, EGetCapabilities);  // Invalid packet
       
   264 		}
       
   265 
       
   266 	TInt error = 0;
       
   267 	TRAP(error, response.WriteL(iOutBuf));   // Don't send error if OOM
       
   268 	response.Close();
       
   269 	if (error == KErrNone)
       
   270 		// send the result back to the CT
       
   271 		InterfaceSelector().SendUnreliable(TUid::Uid(KRemConPlayerInformationUid),
       
   272 											EGetCapabilities, ERemConResponse, iOutBuf );
       
   273 	}
       
   274