?? iap.c
字號:
/************************************************** * * 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 + -