Ejemplo n.º 1
0
static HRESULT muteControlHandler(DataStream *pAvcStream, FUNCTION_BLOCK_PARMS *pFbParms, uint32 audioChannel, PB *packetBlock)
{
	uint8	muteValue=0;
	uint32	fbIDOperand = 4;
	uint8	fbID = 0;
	uint32	streamPosMute;	// save stream position in case its a status command
	HRESULT	hResult = NO_ERROR;

	streamPosMute = dsGetPosition(pAvcStream);

	if (AVC_AUDIO_CHANNEL_MASTER != audioChannel)
	{
		hResult = E_PKT_AVC_NOT_IMPLEMENTED;		// only one mute is supported, mutes all channels
	}
	if (NO_ERROR == hResult)
	{
		dsSetPosition(pAvcStream, fbIDOperand);
		hResult = dsRead8Bits (pAvcStream, &fbID);
		if (fbID != 1)
		{
			hResult = E_PKT_AVC_NOT_IMPLEMENTED;
		}
	}
			
	if (NO_ERROR == hResult)
	{
		/* Switch depending on command type and control attribute.
			General inquiry CTYPE has been handled at the highest level, so
			we can ignore that one. */

		switch (pFbParms->ctype_attribute)
		{
			// ctype GENERAL INQUIRY has been handled already at some higher level

			// ctype NOTIFY is supported for Current only
			case CTYPE_ATTRIBUTE (AVC_CTYPE_NOTIFY, AVC_FB_CTRL_ATTRIBUTE_CURRENT):
					// wants to be 'notified' when current delay changes
					hResult = postNotifyMute(audioChannel, pFbParms->fbId, packetBlock);
					if (NO_ERROR == hResult)
					{
						hResult = E_PKT_AVC_INTERIM;
					}
					break;

			// ctype CONTROL
			case CTYPE_ATTRIBUTE (AVC_CTYPE_CONTROL, AVC_FB_CTRL_ATTRIBUTE_CURRENT):
					// getp the mute parameter
					dsSetPosition(pAvcStream, fbIDOperand+6);
					hResult = dsRead8Bits (pAvcStream, &muteValue);
					SYS_DEBUG(SYSDEBUG_TRACE_AVC_MUSIC, "mute value: %x\n\r", muteValue);
					if (AVC_AUDIO_MUTE_ON == muteValue)
					{
						avsRxMute(0, TRUE);
						hResult = avrDrdSetMute (TRUE);
					}
					else if (AVC_AUDIO_MUTE_OFF == muteValue)
					{
						avsRxMute(0, FALSE);
						hResult = avrDrdSetMute (FALSE); 
					}
					if (NO_ERROR == hResult)
					{
						// all ok, return 'accepted' to avc_main and avc_main will send the response
						hResult = E_PKT_AVC_ACCEPTED;
					}
					break;

			// ctype STATUS
			case CTYPE_ATTRIBUTE (AVC_CTYPE_STATUS, AVC_FB_CTRL_ATTRIBUTE_CURRENT):
					dsSetPosition(pAvcStream, streamPosMute);
					hResult = dsSwitchMode(pAvcStream, dsMODE_WRITE);
					if (NO_ERROR == hResult)
					{
						if (avrDrdHostState.mute)
						{
						 	hResult = dsWrite8Bits (pAvcStream, AVC_AUDIO_MUTE_ON);
						}
						else
						{
						 	hResult = dsWrite8Bits (pAvcStream, AVC_AUDIO_MUTE_OFF);
						}
					}
					if (NO_ERROR == hResult)
					{
						// all ok, return 'stable' to avc_main and avc_main will send the response
						hResult = E_PKT_AVC_STABLE;
					}
					break;

			// ctype SPECIFIC INQUIRY
			case CTYPE_ATTRIBUTE (AVC_CTYPE_SPECIFIC_INQUIRY, AVC_FB_CTRL_ATTRIBUTE_CURRENT):
					hResult = E_PKT_AVC_IMPLEMENTED;
					break;

			default:
					hResult = E_PKT_AVC_NOT_IMPLEMENTED;
					break;
		}
	}

	return(hResult);
}
Ejemplo n.º 2
0
HRESULT avcCmdSignalSource(AVC_HEADER *pHeader, PB *packetBlock, pDataStream pStream)
{
	HRESULT		hResultError = E_PKT_AVC_NOT_IMPLEMENTED;
	HRESULT		hResult = NO_ERROR;
	uint8		inByte = 0;
	uint16		inVal = 0;
	uint8		dest_su = 0;
	uint8		dest_plug_id = 0;
	uint8		source_su = 0;
	uint8		source_plug_id = 0;
	uint8		status = 0;
	AVC_SIGNAL_PATH	*path = NULL;

	switch (pHeader->ctype)
	{
		case AVC_CTYPE_NOTIFY:	// - : M:Mandatory, R:Recommended, O:Optional, -:Not Defined
			hResultError = E_PKT_AVC_REJECTED;
			break;

		case AVC_CTYPE_STATUS:	// - : M:Mandatory, R:Recommended, O:Optional, -:Not Defined
			hResultError = E_PKT_AVC_REJECTED;

			// operand[0,1]: 0xFFFF
			hResult = dsRead16Bits(pStream, &inVal);
			if (hResult != NO_ERROR) return hResultError;
			if (inVal != 0xFFFF) return hResultError;

			// operand[2]: 0xFE
			hResult = dsRead8Bits(pStream, &inByte);
			if (hResult != NO_ERROR) return hResultError;
			if (inByte != 0xFE) return hResultError;
			
			// operand[3]: signal_dest_su
			hResult = dsRead8Bits(pStream, &dest_su);
			if (hResult != NO_ERROR) return hResultError;

			// operand[4]: signal_dest_plug_id
			hResult = dsRead8Bits(pStream, &dest_plug_id);
			if (hResult != NO_ERROR) return hResultError;

			// incoming status command has parsed successfully

			SYS_DEBUG(SYSDEBUG_TRACE_AVC_MUSIC, "Sig Src status: dest_su: 0x%02x, dest_plug_id 0x%02x\n\r", dest_su, dest_plug_id);
			hResult = targetSignalSourceFindPath(dest_plug_id, dest_su, &source_plug_id, &source_su, &status, &path);
			if (NO_ERROR != hResult)
			{
				return E_PKT_AVC_REJECTED;
			}

			// reply with the appropriate contents - go back to beginning of operand[0]
			hResult = dsGotoMarker(pStream, DSMARKER_OPERAND_0);
			if (hResult != NO_ERROR) return hResultError;

			hResult = dsSwitchMode(pStream, dsMODE_WRITE);
			if (hResult != NO_ERROR) return hResultError;

			// operand[0]: 3:output_status, 1:conv, 4:signal_status
			hResult = dsWrite8Bits(pStream, status);
			if (hResult != NO_ERROR) return hResultError;

			// operand[1]: source_su
			hResult = dsWrite8Bits(pStream, source_su);
			if (hResult != NO_ERROR) return hResultError;
			
			// operand[2]: source_plug_id
			hResult = dsWrite8Bits(pStream, source_plug_id);
			if (hResult != NO_ERROR) return hResultError;
			
			// operand[3]: dest_su
			hResult = dsWrite8Bits(pStream, dest_su);
			if (hResult != NO_ERROR) return hResultError;
			
			// operand[4]: dest_plug_id
			hResult = dsWrite8Bits(pStream, dest_plug_id);
			if (hResult != NO_ERROR) return hResultError;
			
			if (pHeader->ctype == AVC_CTYPE_STATUS)
			{
				hResult = E_PKT_AVC_STABLE;
			}
			break;

		case AVC_CTYPE_SPECIFIC_INQUIRY:	// asking if a plug is a possible clock sync source
		case AVC_CTYPE_CONTROL:				// setting the clock sync source to a plug
			{
				BYTE src_su = 0;
				BYTE src_plug_id = 0;
				BYTE dst_su = 0;
				BYTE dst_plug_id = 0;

				hResultError = E_PKT_AVC_NOT_IMPLEMENTED;

				// operand[1]: 0x0F
				hResult = dsRead8Bits(pStream, &inByte);
				if (hResult != NO_ERROR) return hResultError;
				
				// operand[2]: signal_src subunit
				hResult = dsRead8Bits(pStream, &src_su);
				if (hResult != NO_ERROR) return hResultError;

				// operand[3]: signal_src plug id
				hResult = dsRead8Bits(pStream, &src_plug_id);
				if (hResult != NO_ERROR) return hResultError;

				// operand[4]: signal_dest subunit
				hResult = dsRead8Bits(pStream, &dst_su);
				if (hResult != NO_ERROR) return hResultError;
				
				// operand[5]: signal_dest plug id
				hResult = dsRead8Bits(pStream, &dst_plug_id);
				if (hResult != NO_ERROR) return hResultError;

				SYS_DEBUG(SYSDEBUG_TRACE_AVC_MUSIC, "Sig Src s_su 0x%02x, s_id 0x%02x, d_su 0x%02x, d_id 0x%02x\n\r", src_su, src_plug_id, dst_su, dst_plug_id);

				if ( avcDriverPlugIsSyncPath(dst_su, dst_plug_id, src_su, src_plug_id) )
				{
					// host is asking if it can connect a unit input plug to a subunit output plug (i.e. for sync)
					hResult = dsGotoMarker(pStream, DSMARKER_OPERAND_0);
					if (hResult != NO_ERROR) return hResultError;

					hResult = dsSwitchMode(pStream, dsMODE_WRITE);
					if (hResult != NO_ERROR) return hResultError;

					hResult = dsWrite8Bits(pStream, 0x00); // accepted
					if (hResult != NO_ERROR) return hResultError;

					hResult = dsWrite8Bits(pStream, 0xff);
					if (hResult != NO_ERROR) return hResultError;

					if (AVC_CTYPE_SPECIFIC_INQUIRY == pHeader->ctype)
					{
						SYS_DEBUG(SYSDEBUG_TRACE_AVC_MUSIC, " accepted clock source inquiry, src_plug_id: %d\n\r", src_plug_id);
						return E_PKT_AVC_ACCEPTED; 
					}
					else if (AVC_CTYPE_CONTROL == pHeader->ctype)		// set clock source
					{
						hResult = avcDriverSetClockSrc(src_su, src_plug_id);
						if (hResult != NO_ERROR) return hResultError;

						SYS_DEBUG(SYSDEBUG_TRACE_AVC_MUSIC, " accepted set clock source, src_plug_id: %d\n\r", src_plug_id);
					}
					return E_PKT_AVC_ACCEPTED; 
				}

				SYS_DEBUG(SYSDEBUG_TRACE_AVC_MUSIC, " rejected clock source inquiry\n\r");
				hResult = E_PKT_AVC_REJECTED;
			}
			break;

		case AVC_CTYPE_GENERAL_INQUIRY:
			// don't even bother parsing
			hResult = E_PKT_AVC_IMPLEMENTED;
			break;
		
		default:
			hResult = hResultError;
			break;
	}

	return hResult;
}
Ejemplo n.º 3
0
static HRESULT delayControlHandler(DataStream *pAvcStream, FUNCTION_BLOCK_PARMS *pFbParms, uint32 audioChannel, PB *packetBlock)
{
	uint8	valueMsb=0;
	uint8	valueLsb=0;
	uint32	streamPosDelay;	// save stream position in case its a status command
	HRESULT	hResult=NO_ERROR;

	streamPosDelay = dsGetPosition(pAvcStream);

	if (AVC_AUDIO_CHANNEL_MASTER == audioChannel)	
	{
		hResult = E_PKT_AVC_NOT_IMPLEMENTED;		// delay is not available on master channel
	}

	// trap the delay parameters
	if (NO_ERROR == hResult)
	{
		hResult = dsRead8Bits (pAvcStream, &valueMsb);
		if (NO_ERROR == hResult)
		{
			hResult = dsRead8Bits (pAvcStream, &valueLsb);
		}
	}
				
	if (NO_ERROR == hResult)
	{
		/* diverge again, depending on command type and control attribute.
			General inquiry CTYPE has been handled at the highest level, so
			we can ignore that one. */

		switch (pFbParms->ctype_attribute)
		{
			// ctype GENERAL INQUIRY has been handled already at some higher level

			// ctype NOTIFY is supported for Current only
			case CTYPE_ATTRIBUTE (AVC_CTYPE_NOTIFY, AVC_FB_CTRL_ATTRIBUTE_CURRENT):
					// wants to be 'notified' when current delay changes
					hResult = postNotifyDelay(audioChannel, pFbParms->fbId, packetBlock);
					if (NO_ERROR == hResult)
					{
						hResult = E_PKT_AVC_INTERIM;
					}
					break;

			// ctype CONTROL
			case CTYPE_ATTRIBUTE (AVC_CTYPE_CONTROL, AVC_FB_CTRL_ATTRIBUTE_CURRENT):
					// change current delay for a channel
					{
						uint32	delay  = (valueMsb << 8) + valueLsb;

						hResult = avrDrdSetAudioDelay (delay, audioChannel);
						if (NO_ERROR == hResult)
						{
							hResult = E_PKT_AVC_ACCEPTED;
						}
						break;
					}


			// ctype STATUS
			case CTYPE_ATTRIBUTE (AVC_CTYPE_STATUS, AVC_FB_CTRL_ATTRIBUTE_CURRENT):
					/* get the requested delay and write it into the packet block at the
						previously saved location, overwriting the delay field */
					{
						uint32	delay;

					   	delay = avrDrdHostState.audioDelays[audioChannel];

						valueMsb = (uint8)((delay >> 8) & 0xFF);
						valueLsb = (uint8)(delay  & 0xFF);

						dsSetPosition(pAvcStream, streamPosDelay);
						hResult = dsSwitchMode(pAvcStream, dsMODE_WRITE);
						if (NO_ERROR == hResult)
						{
							hResult = dsWrite8Bits (pAvcStream, valueMsb);
							if (NO_ERROR == hResult)
							{
								hResult = dsWrite8Bits (pAvcStream, valueLsb);
							}
						}

						if (NO_ERROR == hResult)
						{
							// all ok, return 'stable' to avc_main and avc_main will send the response
							hResult = E_PKT_AVC_STABLE;
						}
						break;
					}


			// ctype SPECIFIC INQUIRY
			case CTYPE_ATTRIBUTE (AVC_CTYPE_SPECIFIC_INQUIRY, AVC_FB_CTRL_ATTRIBUTE_DELTA):
			case CTYPE_ATTRIBUTE (AVC_CTYPE_SPECIFIC_INQUIRY, AVC_FB_CTRL_ATTRIBUTE_CURRENT):
					hResult = E_PKT_AVC_IMPLEMENTED;
					break;

			default:
					hResult = E_PKT_AVC_NOT_IMPLEMENTED;
					break;
		}
	}

	return(hResult);
}
Ejemplo n.º 4
0
static HRESULT volumeControlHandler(DataStream *pAvcStream, FUNCTION_BLOCK_PARMS *pFbParms, uint32 audioChannel, PB *packetBlock)
{
	uint8	valueMsb=0;
	uint8	valueLsb=0;
	uint32	streamPosVolume;	// save stream position in case its a status command
	HRESULT	hResult = NO_ERROR;

	streamPosVolume = dsGetPosition(pAvcStream);

	// trap the volume parameters
	hResult = dsRead8Bits (pAvcStream, &valueMsb);
	if (NO_ERROR == hResult)
	{
		hResult = dsRead8Bits (pAvcStream, &valueLsb);
	}
			
	if (NO_ERROR == hResult)
	{
		/* diverge again, depending on command type and control attribute.
			General inquiry CTYPE has been handled at the highest level, so
			we can ignore that one. */

		switch (pFbParms->ctype_attribute)
		{
			// ctype GENERAL INQUIRY has been handled already at some higher level

			// ctype NOTIFY is supported for Current only
			case CTYPE_ATTRIBUTE (AVC_CTYPE_NOTIFY, AVC_FB_CTRL_ATTRIBUTE_CURRENT):
					// wants to be 'notified' when current volume changes
					hResult = postNotifyVolume(audioChannel, pFbParms->fbId, packetBlock);
					if (NO_ERROR == hResult)
					{
						hResult = E_PKT_AVC_INTERIM;
					}
					break;

			// ctype CONTROL
			case CTYPE_ATTRIBUTE (AVC_CTYPE_CONTROL, AVC_FB_CTRL_ATTRIBUTE_DELTA):
					// relative change in volume
					{
						int16	relativeVolume = (int16)((valueMsb << 8) + valueLsb);	// signed value

						/* Request is a relative change, based on a 16-bit signed value.
							We will convert this to an absolute volume value and set it 
							as such for the appropriate channel. */
						if (AVC_AUDIO_CHANNEL_MASTER == audioChannel)
						{
							hResult = avrDrdSetMasterVolume (
											(uint32)(avrDrdHostState.masterVolume + relativeVolume));
						}
						else
						{
							hResult = avrDrdSetTrimVolume (
											(uint32)(avrDrdHostState.masterVolume + relativeVolume),
											audioChannel);
						}
						if (NO_ERROR == hResult)
						{
							hResult = E_PKT_AVC_ACCEPTED;
						}
					}
					break;

			case CTYPE_ATTRIBUTE (AVC_CTYPE_CONTROL, AVC_FB_CTRL_ATTRIBUTE_CURRENT):
					// absolute change in volume
					{
						uint32	absoluteVolume  = (valueMsb << 8) + valueLsb;

						if (AVC_AUDIO_CHANNEL_MASTER == audioChannel)
						{
							hResult = avrDrdSetMasterVolume (absoluteVolume);
						}
						else
						{
							hResult = avrDrdSetTrimVolume (absoluteVolume, audioChannel);
						}
						if (NO_ERROR == hResult)
						{
							hResult = E_PKT_AVC_ACCEPTED;
						}
					}
					break;


			// ctype STATUS
			case CTYPE_ATTRIBUTE (AVC_CTYPE_STATUS, AVC_FB_CTRL_ATTRIBUTE_CURRENT):
					/* get the requested volume and write it into the packet block at the
						previously saved location, overwriting the volume field */
					{
						uint32	volume;

						if (AVC_AUDIO_CHANNEL_MASTER == audioChannel)
						{
							volume = avrDrdHostState.masterVolume;
						}
						else
						{
							volume = avrDrdHostState.trimVolume[audioChannel];
						}

						valueMsb = (uint8)((volume >> 8) & 0xFF);
						valueLsb = (uint8)(volume  & 0xFF);

						dsSetPosition(pAvcStream, streamPosVolume);
						hResult = dsSwitchMode(pAvcStream, dsMODE_WRITE);
						if (NO_ERROR == hResult)
						{
							hResult = dsWrite8Bits (pAvcStream, valueMsb);
							if (NO_ERROR == hResult)
							{
								hResult = dsWrite8Bits (pAvcStream, valueLsb);
							}
						}

						if (NO_ERROR == hResult)
						{
							// all ok, return 'stable' to avc_main and avc_main will send the response
							hResult = E_PKT_AVC_STABLE;
						}
					}
					break;

			// ctype STATUS
			case CTYPE_ATTRIBUTE (AVC_CTYPE_STATUS, AVC_FB_CTRL_ATTRIBUTE_RESOLUTION):
					/* get the requested value and write it into the packet block at the
						previously saved location, overwriting the return parameter field */
					{
						dsSetPosition(pAvcStream, streamPosVolume);
						hResult = dsSwitchMode(pAvcStream, dsMODE_WRITE);
						if (NO_ERROR == hResult)
						{
							hResult = dsWrite8Bits (pAvcStream, 0x01);
							if (NO_ERROR == hResult)
							{
								hResult = dsWrite8Bits (pAvcStream, 0x00);
							}
						}

						if (NO_ERROR == hResult)
						{
							// all ok, return 'stable' to avc_main and avc_main will send the response
							hResult = E_PKT_AVC_STABLE;
						}
					}
					break;

			// ctype STATUS
			case CTYPE_ATTRIBUTE (AVC_CTYPE_STATUS, AVC_FB_CTRL_ATTRIBUTE_MINIMUM):
					/* get the requested value and write it into the packet block at the
						previously saved location, overwriting the return parameter field */
					{
						dsSetPosition(pAvcStream, streamPosVolume);
						hResult = dsSwitchMode(pAvcStream, dsMODE_WRITE);
						if (NO_ERROR == hResult)
						{
							hResult = dsWrite8Bits (pAvcStream, 0x89);
							if (NO_ERROR == hResult)
							{
								hResult = dsWrite8Bits (pAvcStream, 0x00);
							}
						}

						if (NO_ERROR == hResult)
						{
							// all ok, return 'stable' to avc_main and avc_main will send the response
							hResult = E_PKT_AVC_STABLE;
						}
					}
					break;

			// ctype STATUS
			case CTYPE_ATTRIBUTE (AVC_CTYPE_STATUS, AVC_FB_CTRL_ATTRIBUTE_MAXIMUM):
					/* get the requested value and write it into the packet block at the
						previously saved location, overwriting the return parameter field */
					{
						dsSetPosition(pAvcStream, streamPosVolume);
						hResult = dsSwitchMode(pAvcStream, dsMODE_WRITE);
						if (NO_ERROR == hResult)
						{
							hResult = dsWrite8Bits (pAvcStream, 0x00);
							if (NO_ERROR == hResult)
							{
								hResult = dsWrite8Bits (pAvcStream, 0x00);
							}
						}

						if (NO_ERROR == hResult)
						{
							// all ok, return 'stable' to avc_main and avc_main will send the response
							hResult = E_PKT_AVC_STABLE;
						}
					}
					break;


			// ctype SPECIFIC INQUIRY
			case CTYPE_ATTRIBUTE (AVC_CTYPE_SPECIFIC_INQUIRY, AVC_FB_CTRL_ATTRIBUTE_DELTA):
			case CTYPE_ATTRIBUTE (AVC_CTYPE_SPECIFIC_INQUIRY, AVC_FB_CTRL_ATTRIBUTE_CURRENT):
					hResult = E_PKT_AVC_IMPLEMENTED;
					break;

			default:
					hResult = E_PKT_AVC_NOT_IMPLEMENTED;
					break;
		}
	}

	return(hResult);
}
Ejemplo n.º 5
0
/* Handle the AV/C function block command
*/
static HRESULT changeConfigurationHandler(DataStream	*pAvcStream,
										  AVC_HEADER	*pAvcHeaderInfo,
										  PB			*pPacketBlock)
{
	uint8	configIdLsb=0;
	uint8	configIdMsb;
	uint32	configId;
	uint32	streamConfigIdPosition;
	HRESULT	hResult = NO_ERROR;

	UNUSED_ARG(pPacketBlock);

	// stream is positioned at operand[0], the config id msb		
	streamConfigIdPosition = dsGetPosition(pAvcStream);

	// extract the config id
	hResult = dsRead8Bits(pAvcStream, &configIdMsb);
	if (NO_ERROR == hResult)
	{
		hResult = dsRead8Bits(pAvcStream, &configIdLsb);
	}
	if (NO_ERROR != hResult)
	{
		return(hResult);
	}
	configId = (configIdMsb << 8) + configIdLsb;
	
	switch (pAvcHeaderInfo->ctype)
	{
		case AVC_CTYPE_CONTROL:
				// tell host to change its mode
				hResult = avrDrdSetAudioMode (configId);
				if (NO_ERROR == hResult)
				{
					// all ok, return 'accepted' to avc_main and avc_main will send the response
					hResult = E_PKT_AVC_ACCEPTED;
				}
				break;
		case AVC_CTYPE_STATUS:
				// send a response with the current configuration
				configId = avrDrdHostState.audioMode;
				configIdMsb = (uint8)((configId >> 8) & 0xFF);
				configIdLsb = (uint8)(configId & 0xFF);

				// repostion stream at the config id location
				dsSetPosition(pAvcStream, streamConfigIdPosition);
				hResult = dsSwitchMode(pAvcStream, dsMODE_WRITE);
				if (NO_ERROR == hResult)
				{
					hResult = dsWrite8Bits(pAvcStream, configIdMsb);
					if (NO_ERROR == hResult)
					{
						hResult = dsWrite8Bits(pAvcStream, configIdLsb);
					}
				}
				if (NO_ERROR == hResult)
				{
					// all ok, return 'stable' to avc_main and avc_main will send the response
					hResult = E_PKT_AVC_STABLE;
				}
				break;

		case AVC_CTYPE_NOTIFY:
				hResult = AVC_RESPONSE_NOT_IMPLEMENTED;
				break;

		case AVC_CTYPE_SPECIFIC_INQUIRY:
		case AVC_CTYPE_GENERAL_INQUIRY:
				hResult = AVC_RESPONSE_IMPLEMENTED;
				break;
		default:
				hResult = AVC_RESPONSE_NOT_IMPLEMENTED;
				break;
	}

	return(hResult);
}
Ejemplo n.º 6
0
/* Handle the AV/C function block command
*/
static HRESULT functionBlockHandler(DataStream			*pAvcStream,
									AVC_HEADER			*pAvcHeaderInfo,
									PB					*pPacketBlock)
{
	HRESULT					hResult = NO_ERROR;
	FUNCTION_BLOCK_PARMS	fbParms;

	/* Before peeling the onion some more, check the command type.
			general inquiry can be executed right here. */
	if (AVC_CTYPE_GENERAL_INQUIRY == pAvcHeaderInfo->ctype)
	{
		hResult = (AVC_RESPONSE_IMPLEMENTED);
		goto functionBlockExit;
	}

	/* parse common function block parameters.
		Unfortunately, fb type and id are defined by the spec as possibly being extended,
		so we need help with these. */

	hResult = avcDecodeFunctionBlockType (pAvcStream, &fbParms.fbType);		// operand[0]
	if (NO_ERROR == hResult)
	{
		hResult = avcDecodeFunctionBlockID (pAvcStream, &fbParms.fbId);		// operand[1]
	}
	if (NO_ERROR == hResult)
	{
		hResult = dsRead8Bits (pAvcStream, &fbParms.fbAttribute);			// operand[2]
	}
	if (NO_ERROR == hResult)
	{
		// verify that function block in fact does exist
		if (!functionBlockExists(fbParms.fbType, fbParms.fbId))
		{
			hResult = E_PKT_AVC_REJECTED;
		}
	}

	if (NO_ERROR != hResult)
	{
		goto functionBlockExit;
	}

	/* combine ctype and attribute into a single 16-bit value */
	//KBJ??? ASSERT(256 > pAvcHeaderInfo->ctype);		// ctype must be 8-bits max
	fbParms.ctype_attribute = (CTYPE_ATTRIBUTE)(CTYPE_ATTRIBUTE(pAvcHeaderInfo->ctype, fbParms.fbAttribute));

	/* Now we've parsed up to Operand[3].  At this point, handling diverges depending
		on the function block type. */

	switch (fbParms.fbType)
	{
		case AVC_FB_TYPE_SELECTOR:
				hResult = selectorFbHandler(pAvcStream, &fbParms, pAvcHeaderInfo, pPacketBlock);
				break;
				
		case AVC_FB_TYPE_FEATURE:
				hResult = featureFbHandler(pAvcStream, &fbParms, pAvcHeaderInfo, pPacketBlock);
				break;
				
		case AVC_FB_TYPE_PROCESSING:
				hResult = processingFbHandler(pAvcStream, &fbParms, pAvcHeaderInfo, pPacketBlock);
				break;
				
		case AVC_FB_TYPE_CODEC:
				hResult = codecFbHandler(pAvcStream, &fbParms, pAvcHeaderInfo, pPacketBlock);
				break;
				
		case AVC_FB_TYPE_SUBUNIT_DEST_PLUG:
		case AVC_FB_TYPE_SUBUNIT_SOURCE_PLUG:
				hResult = E_PKT_AVC_NOT_IMPLEMENTED;
				break;
		default:
				hResult = E_PKT_AVC_NOT_IMPLEMENTED;
				break;
	}

functionBlockExit:

	return(hResult);
}		
Ejemplo n.º 7
0
static HRESULT featureFbHandler(DataStream 				*pAvcStream, 
								FUNCTION_BLOCK_PARMS	*pFbParms,
								AVC_HEADER				*avcHeaderInfo,
								PB						*pPacketBlock)
{
	HRESULT	hResult = NO_ERROR;
	uint8	featureBlockLength;	// Operand[3]
	uint8	audioChannel=0; 			// Operand[4]
	uint8	controlSelector=0;		// Operand[5]
	uint8	controlLength=0;			// Operand[6]

	UNUSED_ARG(avcHeaderInfo);
	UNUSED_ARG(pPacketBlock);

	/* trap common operands 3, 4, 5, and 6 */

	hResult = dsRead8Bits (pAvcStream, &featureBlockLength);
	if (NO_ERROR == hResult)
	{
		hResult = dsRead8Bits (pAvcStream, &audioChannel);
		if (NO_ERROR == hResult)
		{
			hResult = dsRead8Bits (pAvcStream, &controlSelector);
			if (NO_ERROR == hResult)
			{
				hResult = dsRead8Bits (pAvcStream, &controlLength);
			}
		}
	}

	if (NO_ERROR == hResult)
	{
		if (2 != featureBlockLength)
		{
			// operand 3 is always 2 for a feature function block, section 11.3
			sysDebugPrintf("avcAudio, feature function block - bad length %d\n\r", featureBlockLength);
			hResult = E_PKT_AVC_NOT_IMPLEMENTED;
		}
		else if(!AudioChannelIsValid(audioChannel))
		{
			sysDebugPrintf("avcAudio, invalid audio channel %d\n\r", audioChannel);
			hResult = E_PKT_AVC_NOT_IMPLEMENTED;
		}
	}

	if (hResult == NO_ERROR)
	{

		/* Now we diverge again, depending on which control is being commanded - 
			datastream is now at start of operand[7] */

		switch (controlSelector)
		{
			case AVC_AUDIO_VOLUME_CONTROL:
					if (2 != controlLength)
					{
						sysDebugPrintf("avcAudio, volume control - bad control length %d\n\r", controlLength);
						hResult = E_PKT_AVC_NOT_IMPLEMENTED;
					}
					else
					{
						hResult = volumeControlHandler(pAvcStream, pFbParms, audioChannel, pPacketBlock);
					}
					break;

			case AVC_AUDIO_MUTE_CONTROL:
					if (1 != controlLength)
					{
						sysDebugPrintf("avcAudio, mute control - bad control length %d\n\r", controlLength);
						hResult = E_PKT_AVC_NOT_IMPLEMENTED;
					}
					else
					{
						hResult = muteControlHandler(pAvcStream, pFbParms, audioChannel, pPacketBlock);
					}
					break;

			case AVC_AUDIO_DELAY_CONTROL:
					if (2 != controlLength)
					{
						sysDebugPrintf("avcAudio, delay control - bad control length %d\n\r", controlLength);
						hResult = E_PKT_AVC_NOT_IMPLEMENTED;
					}
					else
					{
						hResult = delayControlHandler(pAvcStream, pFbParms, audioChannel, pPacketBlock);
					}
					break;


			default:
					hResult = E_PKT_AVC_NOT_IMPLEMENTED;
					break;
					;
		}  // switch (controlSelector)
	}

	return hResult;
}