⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iap.c

📁 本程序为ST公司开发的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/************************************************** * * iAP.c * * CVS ID:   $Id: iAP.c,v 1.9 2007/11/09 11:20:45 longauer Exp $ * Author:   Leos Longauer [LL] - STM * Date:     $Date: 2007/11/09 11:20:45 $ * Revision: $Revision: 1.9 $ *  * Description: *  *   source code: iPod Accessory Protocol layer * *************************************************** *  * COPYRIGHT (C) ST Microelectronics  2005 *            All Rights Reserved * *************************************************** * * STM CVS Log: * * $Log: iAP.c,v $ * Revision 1.9  2007/11/09 11:20:45  longauer * long ipod packets/telegrams transmission is supported + variables/functions movement * * Revision 1.8  2007/11/07 11:57:06  trubac * fixes for message tx and rx * * Revision 1.7  2007/11/06 15:23:11  trubac * added ipod message handling for virtual navigation * * Revision 1.6  2007/10/18 10:47:42  longauer * handle authentication and automatically switches to the extended mode * * Revision 1.5  2007/09/20 21:35:52  longauer * virtual iPod authentication is working * * Revision 1.4  2007/09/04 16:54:27  longauer * coprocessor data processing; IAP_ProcessFsm() established; * * Revision 1.3  2007/09/03 13:25:19  longauer * Ipod Rx Archive; files affected: ACP.h,  iAP.*, player.c, gendef.h * * Revision 1.2  2007/08/10 12:33:29  longauer * IPOD_AP compilation switch enables future iAP * * Revision 1.1  2007/07/09 10:45:08  longauer * first commit * * ***************************************************/#include "configuration.h"#include "debug.h"#include "gendef.h"#if (0 != IPOD_AP)#include "hwreg.h"#include "osal.h"#ifdef _USB_DEBUG#include "utility.h" /* GPIO */#endif /*_USB_DEBUG*/#include "controller.h"#include "usb.h"#include "ACP.h"#include "iAP.h"//#include "utility.h"	//dbg/*************************** DEBUGGING ****************************/#ifdef _IAP_DEBUG#endif /*_IAP_DEBUG*//**************************** GLOBALS *****************************/tIap gIap;uint8 gIapArchiveBuffer[C_IAP_ARCHIVE_BUFFER_SIZE];uint8 gIapCmdBuffer[C_IAP_BUFFER_SIZE];uint8 gIapTxBuffer[C_IAP_BUFFER_SIZE];#if 0 //moved to ipodvirt.ct_iap_msg IPod_Message;t_iap_msg *pIPod_Message = NULL;uint8* pIPodMessageData;#endif#define M_IAP_GET_CMD_BUFFER_BASE() gIapCmdBuffer#define M_IAP_GET_TX_BUFFER_BASE() gIapTxBuffer#define M_IAP_TX_BUFFER_FREE_SIZE() (C_IAP_BUFFER_SIZE - gIap.Tx.DataLength)#define M_IAP_IS_TX_BUFFER_FREE_FOR(_req_free_len_) (_req_free_len_<=(C_IAP_BUFFER_SIZE - gIap.Tx.DataLength))/******************************************************************///TBD - following definitions will be moved/restructuralizedtypedef struct{	uint8 AccInfoNAME[16];	uint8 AccInfoMFACTURER[8];	uint8 AccInfoMODEL[16];	uint8 AccInfoSN[8];	uint8 AccInfoMaxPSize;	union	{		uint32 flags;		tIapGenDevLingoesSpoken flag;	} DevLingoesSpoken;} tIapPRESET;tIapPRESET gIapPRESET = {	{"ACCORDO+\0"},	{"ST\0"},	{"STA1052\0"},	{"???\0"},	128,	0x11000000};/****************************** FORWARDS **********************************/void IAP_SetTimer(uint32 time);void IAP_PauseTimer(void);void IAP_ContinueTimer(void);void IAP_Init(tIap* pIap);void IAP_Close(tIap* pIap);t_player_state IAP_ProcessRx(tIapRx* pIapRx);t_player_state IAP_ProcessAcpRx(tIapAcp* pIapAcp);t_player_state IAP_ProcessCmd(tIapReq* pIapReq, uint8 bIsExtMode);t_player_state IAP_ProcessFsm(tIap* pIap);t_player_state IAP_ProcessTxCopro(tIapAcp* pIapAcp, t_acp_cmd Cmd, void* pCmdData);t_player_state IAP_ProcessTxRequest(tIap* pIap, teIapLingoId IapLingoId, tIapCmdId IapCmdId, tIapItem* pCmdItem, void* pCmdData);t_player_state IAP_DecodeRx(tIap* pIap, tIapItem* pRxItem);t_player_state IAP_DecodeRxGen(tIap* pIap, tIapItem* pRxItem);t_player_state IAP_DecodeRxExt(tIap* pIap, tIapItem* pRxItem);t_player_state IAP_DecodeRxAud(tIap* pIap, tIapItem* pRxItem);t_player_state IAP_DecodeAcp(tIap* pIap, tIapAcp* pIapAcp);t_player_state IAP_DecodeCmd(tIap* pIap, tIapReq* pIapReq);/*t_player_state IAP_DecodeCmdGen(tIap* pIap, tIapItem* pCmdItem);t_player_state IAP_DecodeCmdExt(tIap* pIap, tIapItem* pCmdItem);t_player_state IAP_DecodeCmdAud(tIap* pIap, tIapItem* pCmdItem);*///void IAP_Refresh(tIap* pIap);void IAP_ConsolidateArchive(tIapArchive* pArchive, uint8 bReset);t_player_state IAP_CheckArchive(tIapArchive* pArchive);t_bool IAP_IsArchiveEmpty(tIapArchive* pArchive);t_player_state IAP_PushOntoArchive(tIapArchive* pArchive, uint8* pData, uint16 DataLength);t_player_state IAP_PopArchive(tIapArchive* pArchive, tIapItem** ppRxItem);t_player_state IAP_ParsePacket(tIapItem* pRxItem, 	uint8* pPosition, uint16* pPositionOffset, 	uint8** ppPacket, uint16* pPacketSize, 	uint32 AvailableLen);void IAP_PrepareRefreshPacket(tIapTx* pIapTx);t_player_state IAP_PreparePacket(tIapTx* pIapTx, tIapItem* pTxItem);	//LL//uint16 IAP_FillPacketHeaderAndChecksum(uint8* pPacket, uint8 LingoId, uint16 CmdId, /*uint8* pCmdData,*/ //	uint16 RemainDataLen, uint16 ChunkDataLen, teIapItemState ComplState);uint16 IAP_FillPacketHeader(uint8* pPacket, tIapItem* pTxItem, uint8* pCheckSum);uint16 IAP_FillPacketData(uint8* pPacket, tIapItem* pTxItem, uint8* pCheckSum, uint16 MaxLenToCopy);uint16 IAP_OmitPacketData(uint8* pPacket, tIapItem* pTxItem, uint8* pCheckSum, uint16 MaxLenToCopy);uint16 IAP_FillPacketChecksum(uint8* pPacket, tIapItem* pTxItem, uint8 CheckSum);t_player_state IAP_SetCmd(tIap* pIap, tIapItem* pCmd, uint8* pCmdData, uint8 bIsRemoteCmd);/****************************** PATCHING **********************************//****************************** FUNCTIONS **********************************//*** buffer handling ***/void IAP_ConsolidateArchive(tIapArchive* pArchive, uint8 bReset){	uint8 count;	tIapItem* pItem0 = &(pArchive->aIapArchiveItem[0]);	tIapItem* pItem;	if(bReset)	{		pArchive->pPosition = gIapArchiveBuffer;		for(count=0; count<C_IAP_ARCHIVE_MAX_LEN; count++)		{			pItem = &(pArchive->aIapArchiveItem[count]);			pItem->CompleteState = IAP_ARCHIVE_ITEM_FREE;		}	}	else	{		if((pArchive->bIncomplete) && 			(pItem0->CompleteState != IAP_ARCHIVE_ITEM_INCOMPLETE))		{			for(count=1; count<C_IAP_ARCHIVE_MAX_LEN; count++)			{				pItem = &(pArchive->aIapArchiveItem[count]);				if(pItem->CompleteState == IAP_ARCHIVE_ITEM_INCOMPLETE)				{					memcpy(pItem0, pItem, sizeof(tIapItem));					memcpy(gIapArchiveBuffer, pItem->pData, pItem->RemainLen);					pItem0->pData = gIapArchiveBuffer;				}				pItem->CompleteState = IAP_ARCHIVE_ITEM_FREE;			}		}	}}t_player_state IAP_CheckArchive(tIapArchive* pArchive){	t_player_state err = IAP_OK;	uint8 count;	uint32 LengthSum = 0;	uint8 bIncomplete = pArchive->bIncomplete ? 1 : 0;		if((pArchive->Count + bIncomplete > C_IAP_ARCHIVE_MAX_LEN) ||		(pArchive->Count < 0))	{		err = E_IAP;		DBG_REPORT_ERROR(err);	}	for(count=0; count<C_IAP_ARCHIVE_MAX_LEN; count++)	{		if(pArchive->aIapArchiveItem[count].CompleteState != IAP_ARCHIVE_ITEM_FREE)		{			LengthSum += pArchive->aIapArchiveItem[count].RemainLen;		}	}	if ((LengthSum > C_IAP_ARCHIVE_BUFFER_SIZE) /*||		(LengthSum > pArchive->pPosition - gIapArchiveBuffer)*/)	{		err = E_IAP;		DBG_REPORT_ERROR(err);	}	return err;}t_bool IAP_IsArchiveEmpty(tIapArchive* pArchive){	t_player_state err;	err = IAP_CheckArchive(pArchive);	if(M_IS_IAP_ERROR(err))	{		DBG_REPORT_ERROR(err);		DBG_PRINTF("iap: *E - Archive error!\r\n");	}	if((err == IAP_OK) && (pArchive->Count))	{		return FALSE;	}	return TRUE;}t_player_state IAP_PushOntoArchive(tIapArchive* pArchive, uint8* pData, uint16 DataLength){	t_player_state err = IAP_OK;	uint8 Count = 0;	uint8* pPosition;	/* local pointer to the first free buffer position */	uint8* pDataTmp;	/* pointer to the packet remaining data */	uint16 DataLen;	/* pointer to the packet remaining length */	uint16 PositionOffset;	uint32 AvailableLen;	tIapItem* pRxItem;	DataLen = DataLength;	pPosition = pArchive->pPosition;	pDataTmp = pData;	while(DataLen)	{		if(Count == C_IAP_ARCHIVE_MAX_LEN)		{			DBG_PRINTF("iap: *W - data doesn't fit into the Archive");			break;		}		AvailableLen = C_IAP_ARCHIVE_BUFFER_SIZE - (gIapArchiveBuffer-pPosition);//		if(!AvailableLen)//			break;	/* nothing to parse anymore */		pRxItem = &(pArchive->aIapArchiveItem[Count]);		err = IAP_ParsePacket(pRxItem, 			pPosition, &PositionOffset, 			&pDataTmp, &DataLen, 			AvailableLen);		if(M_IS_IAP_ERROR(err))		{			//TBD			DBG_REPORT_ERROR(err);			break;		}		else		{//			if(PositionOffset != 0)//			{				if (err == W_IAP_INCOMPLETE)				{					M_SET_FLAG(pArchive->bIncomplete);					pRxItem->CompleteState = IAP_ARCHIVE_ITEM_INCOMPLETE;					break;				}				else				{					M_CLEAR_FLAG(pArchive->bIncomplete);					pRxItem->CompleteState = IAP_ARCHIVE_ITEM_COMPLETE;					Count++;				}				pPosition += PositionOffset;//			}//			else//			{//				break; /* nothing to parse anymore *///			}		}	}	pArchive->pPosition = pPosition;	pArchive->Count = Count;	return err;}t_player_state IAP_PopArchive(tIapArchive* pArchive, tIapItem** ppRxItem){	uint8 count;	tIapItem* pRxItem;	for(count=0; count<C_IAP_ARCHIVE_MAX_LEN; count++)	{		pRxItem = &(pArchive->aIapArchiveItem[count]);		if( (IAP_ARCHIVE_ITEM_COMPLETE == pRxItem->CompleteState) )		{			*ppRxItem = pRxItem;			pRxItem->CompleteState = IAP_ARCHIVE_ITEM_FREE;	/* clear slot anyway before data provessing */			/* (writing to slot will be available later after command processing) */			pArchive->Count--;			if(pArchive->Count == 0)			{				return IAP_RX_DONE;			}			else				return IAP_OK;		}	}	return E_IAP;	/* no item found */ }t_iap_handler iap_open(void){	tIap* pIap = &gIap;	teIapFsmState* pFsmState = &(pIap->FsmState);	IAP_Init(pIap);	*pFsmState = IAP_FSM_INIT;	return (t_iap_handler)pIap;}void iap_close(t_iap_handler hIap){	tIap* pIap = (tIap*)hIap;	teIapFsmState* pFsmState = &(pIap->FsmState);	IAP_Close(pIap);	*pFsmState = IAP_FSM_DONE;}t_bool iap_is_transition_required(t_iap_handler hIap){	tIap* pIap = (tIap*)hIap;	if( (pIap->InEvent.flags) || (pIap->OutEvent.flags) )		return TRUE;	else		return FALSE;}t_player_state iap_pop_transition_required(t_iap_handler hIap){	tIap* pIap = (tIap*)hIap;	tuIapInEvent* pInEvent = &(pIap->InEvent);	tuIapOutEvent* pOutEvent = &(pIap->OutEvent);	if(M_IS_SET(pInEvent->flag.Rx))	{		M_CLEAR_FLAG(pInEvent->flag.Rx);		return IAP_REP_RX;	}	if(M_IS_SET(pInEvent->flag.TxAck))	{		M_CLEAR_FLAG(pInEvent->flag.TxAck);		return IAP_REP_TX;	}	if(M_IS_SET(pInEvent->flag.RxAcp))	{		M_CLEAR_FLAG(pInEvent->flag.RxAcp);		return IAP_REP_RX_ACP;	}	if(M_IS_SET(pOutEvent->flag.RxAck))	{		M_CLEAR_FLAG(pOutEvent->flag.RxAck);		return IAP_RX_DONE;	}	if(M_IS_SET(pOutEvent->flag.Tx))	{		M_CLEAR_FLAG(pOutEvent->flag.Tx);		return IAP_REQ_TX;	}	if(M_IS_SET(pOutEvent->flag.TxCP))	{		M_CLEAR_FLAG(pOutEvent->flag.TxCP);		return IAP_REQ_ACP;	}	else		return IAP_OK;}//t_player_state IAP_SetCmd(tIap* pIap, tIapCmdCode CmdCode, //	uint16 CmdRemainLen, uint16 CmdChunkLen, uint8* pCmdData, teIapItemState CmdState, //	uint8 bIsRemoteCmd)t_player_state IAP_SetCmd(tIap* pIap, tIapItem* pCmd, uint8* pCmdData, uint8 bIsRemoteCmd){	t_player_state err = IAP_OK;	tIapItem* pIapCmd = &(pIap->Req.Item);	/* to check up user command meaning */	if( (pIap->FsmState != IAP_FSM_DONE) || (!pCmdData) )	{		if( (pCmd->CompleteState == IAP_ARCHIVE_ITEM_FREE) ||			(pCmd->RemainLen < pCmd->ChunkLen) )		{			err = E_IAP_CMD;		}		else if//( ((pIap->FsmState == IAP_FSM_IDLE) || (pIap->FsmState == IAP_FSM_CMD)) && 			( (pIap->FsmState == IAP_FSM_IDLE) && 			(pIap->bReady) && 			(!(pIap->InEvent.flags)) )		{			if(bIsRemoteCmd)			{	/* remote command */				if(pCmd->Code.LingoId == IAP_LINGO_EXT_INTERF)				{					switch(pCmd->Code.CmdId)					{	/* supported remote commands below */					case IAP_EXT_SET_DISP_IMG:					case IAP_EXT_GET_MONO_DISP_IMG_LIM:					case IAP_EXT_GET_COLORDISP_IMG_LIM:						break;					default:						err = E_IAP_CMD;						break;					}				}				else					err = E_IAP_CMD;			}		}		else			err = IAP_BUSY;	}	else		err = E_IAP;	/* to check up the user command basic consistency */	if( !(M_IS_IAP_ERROR(err)) )	{		if( (M_IS_SET(pIap->Req.bSemifinished)) &&			(pCmd->CompleteState == IAP_ARCHIVE_ITEM_START) || (pCmd->CompleteState == IAP_ARCHIVE_ITEM_INCOMPLETE) )		{			err = E_IAP_CMD;		}		else if( (pCmd->CompleteState == IAP_ARCHIVE_ITEM_END) || (pCmd->CompleteState == IAP_ARCHIVE_ITEM_COMPLETE) )		{			if(pCmd->RemainLen != pCmd->ChunkLen)				err = E_IAP_CMD;			else				M_CLEAR_FLAG(pIap->Req.bSemifinished);		}		else		{			M_SET_FLAG(pIap->Req.bSemifinished);		}	}	if(M_IS_IAP_ERROR(err))	{		if(M_IS_SET(pIap->Req.bSemifinished))		{	/* in the case of pending transfer relinquish it and refresh downstream pipe */			M_CLEAR_FLAG(pIap->Req.bSemifinished);			pIap->FsmState = IAP_FSM_REFRESH_TX;			DBG_PRINTF("iap: *W - REFRESHING");		}		DBG_REPORT_ERROR(err);	}	else	{		tuIapInEvent* pInEvent = &(pIap->InEvent);		/* command should be of correct form -> store it for processing */		memcpy(pIapCmd, pCmd, sizeof(t_iap_cmd));		memcpy(pIapCmd->pData, pCmdData, pCmd->ChunkLen);		M_CLEAR_FLAG(pIap->bReady);	/* nobody can set new command request until bit is set */		M_SET_FLAG(pInEvent->flag.Cmd);	}	return err;}/******************************************************************************//* Function:  iap_remote_cmd                                                  *//*                                                                            *//*! \brief    used to send remote iPod command*  \param*  \return*  \remark    only small portion of the extended lingo commands are supported*******************************************************************************/t_player_state iap_set_remote_cmd(t_iap_handler hIap, t_iap_cmd* pRemoteCmd, uint8* pRemoteCmdData)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -