📄 dvb_eit.c
字号:
(int)pstEitHeader, (int)pstEventInfo));
return EN_EITDB_ERROR;
}
//check database exists a present event or not
if((pstEitHeader->u8PF_S_Flag & PRESENT_MASK) != 0 )
{
if(pstEitHeader->u8PF_Ver == u8SecVer)
{
if(b8ExistExtended == TRUE)
{
}
else
{
return EN_EITDB_EXIST; // version is the same, doesn't save it.
}
}
else //version is not the same, need to update it.
{
// Extended descriptor must has event body first.
if(b8ExistExtended == TRUE)
{
return EN_EITDB_ERROR;
}
//update present event
if (dvb_EitGetDbByIdx(pstEitHeader->u16HeadEventIdx, &stTmpEitDb) != EN_EITDB_NO_ERROR)
{
return EN_EITDB_ERROR;
}
//update header PF version
pstEitHeader->u8PF_Ver = u8SecVer;
//EIT_DBG( ("free old p event\n"));
eitbkfreeeventmemory (&(stTmpEitDb.stEitEvent));
memcpy(&(stTmpEitDb.stEitEvent), pstEventInfo, sizeof(ST_EIT_EVENT));
dvb_EitSaveDbByIdx(pstEitHeader->u16HeadEventIdx, &stTmpEitDb);
// if this service exists a following event, need to delete it.
// because present and following event share a version in header
if((pstEitHeader->u8PF_S_Flag & FOLLOWING_MASK) != 0 )
{
//delete following event
u8ClearMask = FOLLOWING_MASK;
pstEitHeader->u16AllEventNum--;
pstEitHeader->u8PF_S_Flag &= ~u8ClearMask; //clear following mask
//EIT_DBG (("delete following event\n"));
dvb_EitDelOneEvent(pstEitHeader, stTmpEitDb.u16NextEventIdx);
}
//update header info
//SaveHeader2Dram(u16HeaderIdx, pstEitHeader);
return EN_EITDB_ADD;
}
}
else // present event doesn't exist, need to create it
{
// Extended descriptor must has event body first.
if(b8ExistExtended == TRUE)
return EN_EITDB_ERROR;
// if this service exists a following event
if((pstEitHeader->u8PF_S_Flag & FOLLOWING_MASK) != 0)
{
//if version isn't the same, need to delete it.
// because present and following event share a version in header
if(pstEitHeader->u8PF_Ver != u8SecVer)
{
//update header info
u8ClearMask = FOLLOWING_MASK;
pstEitHeader->u16AllEventNum--;
pstEitHeader->u8PF_S_Flag &= ~u8ClearMask; //clear following mask
pstEitHeader->u8PF_Ver = u8SecVer;
//del following event
//EIT_DBG (("delete following event\n"));
dvb_EitDelOneEvent(pstEitHeader, pstEitHeader->u16HeadEventIdx);
//SaveHeader2Dram(u16HeaderIdx, pstEitHeader);
}
}
//create a present event
enRetError = dvb_CreateP_Event(pstEitHeader, pstEventInfo);
if(enRetError != EN_EITDB_NO_ERROR)
return enRetError;
//update header info
pstEitHeader->u16AllEventNum++;
pstEitHeader->u8PF_S_Flag |= PRESENT_MASK;
pstEitHeader->u8PF_Ver = u8SecVer;
//save header to dram
//SaveHeader2Dram(u16HeaderIdx, pstEitHeader);
return EN_EITDB_ADD;
}
return EN_EITDB_NO_ERROR;
}
/******************************************************************************************/
// event will be save to dram here
static EN_EITDB_STATUS dvb_CreateF_Event(ST_EIT_HEADER_T *pstEitHeader, ST_EIT_EVENT *pstEventInfo)
{
u16 u16FollowingIdx;
u16 u16KeepNextIdx;
ST_EIT_DB stTmpEitDb;
if (!pstEitHeader || !pstEventInfo)
return EN_EITDB_ERROR;
if(SearchEmptySpace(EN_EIT_EVENT_FLAG, &u16FollowingIdx) == FALSE)
{
// Todo: del expired or some events to acquire empty event
EIT_DBG(("%s,%d> Memory full when create f event.\n", __FFLL__));
//event full, try to del event
if(dvb_EitDelEvent4DbFull(pstEitHeader->u16HeadEventIdx, EN_EIT_EVENT_FLAG) == FALSE)
return EN_EITDB_MEMORY_FULL;
//search empty space again
if(SearchEmptySpace(EN_EIT_EVENT_FLAG, &u16FollowingIdx) == FALSE)
return EN_EITDB_MEMORY_FULL;
}
// if no present, H->?
if((pstEitHeader->u8PF_S_Flag & PRESENT_MASK) == 0 )
{
memcpy(&(stTmpEitDb.stEitEvent), pstEventInfo, sizeof(ST_EIT_EVENT));
//update header and db info, H->F->?
stTmpEitDb.u16NextEventIdx = pstEitHeader->u16HeadEventIdx;
pstEitHeader->u16HeadEventIdx = u16FollowingIdx;
stTmpEitDb.u16PreEventIdx = INVALID_LINK_IDX;
// save the event to dram
dvb_EitSaveDbByIdx(u16FollowingIdx, &stTmpEitDb);
// if H->F->Next != NULL, update H->F->NEXT info
if(stTmpEitDb.u16NextEventIdx != INVALID_LINK_IDX)
{
// u16KeepNextIdx is P->next
u16KeepNextIdx = stTmpEitDb.u16NextEventIdx;
if (dvb_EitGetDbByIdx(u16KeepNextIdx, &stTmpEitDb) != EN_EITDB_NO_ERROR)
{
return EN_EITDB_ERROR;
}
// set u16KeepNextIdx->previous = F
stTmpEitDb.u16PreEventIdx = u16FollowingIdx;
// save u16CurIdx
dvb_EitSaveDbByIdx(u16KeepNextIdx, &stTmpEitDb);
}
}
else //H->P->?
{
//get present event db, now stTmpEitDb is present
if (dvb_EitGetDbByIdx(pstEitHeader->u16HeadEventIdx, &stTmpEitDb) != EN_EITDB_NO_ERROR)
{
return EN_EITDB_ERROR;
}
// update present event db
//set u16KeepNextIdx = present->next.
u16KeepNextIdx = stTmpEitDb.u16NextEventIdx;
// set presetn->next = following.
stTmpEitDb.u16NextEventIdx = u16FollowingIdx;
dvb_EitSaveDbByIdx(pstEitHeader->u16HeadEventIdx, &stTmpEitDb);
//update following event and db, now stTmpEitDb is following
//set following->previous = present.
stTmpEitDb.u16PreEventIdx = pstEitHeader->u16HeadEventIdx;
//set following->next = u16KeepNextIdx.
stTmpEitDb.u16NextEventIdx = u16KeepNextIdx;
memcpy(&(stTmpEitDb.stEitEvent), pstEventInfo, sizeof(ST_EIT_EVENT));
//save following db
dvb_EitSaveDbByIdx(u16FollowingIdx, &stTmpEitDb);
if(u16KeepNextIdx != INVALID_LINK_IDX)
{
//now stTmpEitDb is following->next
if (dvb_EitGetDbByIdx(u16KeepNextIdx, &stTmpEitDb) != EN_EITDB_NO_ERROR)
{
return EN_EITDB_ERROR;
}
//set following->next->previous = following
stTmpEitDb.u16PreEventIdx = u16FollowingIdx;
//save following->next
dvb_EitSaveDbByIdx(u16KeepNextIdx, &stTmpEitDb);
}
}
return EN_EITDB_NO_ERROR;
}
/******************************************************************************************/
static EN_EITDB_STATUS dvb_EitSetF_Event(ST_EIT_HEADER_T *pstEitHeader, u8 u8SecVer, ST_EIT_EVENT *pstEventInfo, bool8 b8ExistExtended)
{
u8 u8ClearMask;
EN_EITDB_STATUS enRetError = EN_EITDB_NO_ERROR;
ST_EIT_DB stTmpEitDb;
if ((!pstEitHeader) || (!pstEventInfo))
{
EIT_DBG (("fail {dvb_EitSetF_Event} pstEitHeader[0x%x] pstEventInfo[0x%x]\n",
(int)pstEitHeader, (int)pstEventInfo));
return EN_EITDB_ERROR;
}
//check database exists a following event or not
if((pstEitHeader->u8PF_S_Flag & FOLLOWING_MASK) != 0 )
{
if(pstEitHeader->u8PF_Ver == u8SecVer)
{
if(b8ExistExtended == TRUE)
{
}
else
{
return EN_EITDB_EXIST; // version is the same, doesn't save it.
}
}
else //version is not the same, need to update it.
{
// Extended descriptor must has event body first.
if(b8ExistExtended == TRUE)
return EN_EITDB_ERROR;
//update header PF version
pstEitHeader->u8PF_Ver = u8SecVer;
// if this service exists a present event, need to delete it.
// because present and following event share a version in header
if((pstEitHeader->u8PF_S_Flag & PRESENT_MASK) != 0 )
{
//update header info
u8ClearMask = PRESENT_MASK;
pstEitHeader->u16AllEventNum--;
pstEitHeader->u8PF_S_Flag &= ~u8ClearMask; //clear following mask
//delete present event
//EIT_DBG (("F delete present event\n"));
dvb_EitDelOneEvent(pstEitHeader, pstEitHeader->u16HeadEventIdx);
}
//update following event
if (dvb_EitGetDbByIdx(pstEitHeader->u16HeadEventIdx, &stTmpEitDb) != EN_EITDB_NO_ERROR)
{
return EN_EITDB_ERROR;
}
//EIT_DBG(("F delete following event\n"));
eitbkfreeeventmemory (&(stTmpEitDb.stEitEvent));
memcpy(&(stTmpEitDb.stEitEvent), pstEventInfo, sizeof(ST_EIT_EVENT));
dvb_EitSaveDbByIdx(pstEitHeader->u16HeadEventIdx, &stTmpEitDb);
return EN_EITDB_ADD;
}
}
else // following event doesn't exist, need to create it
{
// Extended descriptor must has event body first.
if(b8ExistExtended == TRUE)
return EN_EITDB_ERROR;
// if this service exists a present event
if((pstEitHeader->u8PF_S_Flag & PRESENT_MASK) != 0)
{
// if the version isn't the same, need to present event.
// because present and following event share a version in header
if(pstEitHeader->u8PF_Ver != u8SecVer)
{
//update header info
u8ClearMask = PRESENT_MASK;
pstEitHeader->u16AllEventNum--;
pstEitHeader->u8PF_S_Flag &= ~u8ClearMask; //clear following mask
pstEitHeader->u8PF_Ver = u8SecVer;
//del present event
//EIT_DBG (("F delete present event\n"));
dvb_EitDelOneEvent(pstEitHeader, pstEitHeader->u16HeadEventIdx);
}
}
//create a following event
enRetError = dvb_CreateF_Event(pstEitHeader, pstEventInfo);
if(enRetError != EN_EITDB_NO_ERROR)
return enRetError;
//update header info
pstEitHeader->u16AllEventNum++;
pstEitHeader->u8PF_S_Flag |= FOLLOWING_MASK;
pstEitHeader->u8PF_Ver = u8SecVer;
return EN_EITDB_ADD;
}
return EN_EITDB_NO_ERROR;
}
/******************************************************************************************/
static EN_EITDB_STATUS dvb_EitDelAll_S_Event(ST_EIT_HEADER_T *pstEitHeader)
{
u8 u8OffsetIdx=0, u8ClearMask;
u16 u16CurIdx=0, u16NextIdx= 0, u16DelNum=0;
ST_EIT_DB stTmpEitDb;
if((pstEitHeader->u8PF_S_Flag & PRESENT_MASK) != 0)
u8OffsetIdx++; //This service exists a present event
if((pstEitHeader->u8PF_S_Flag & FOLLOWING_MASK) != 0)
u8OffsetIdx++; //This service exists a following event
if(u8OffsetIdx==0)
{
u16NextIdx = pstEitHeader->u16HeadEventIdx; // next = H->S
pstEitHeader->u16HeadEventIdx = INVALID_LINK_IDX; // H->NULL
}
else if(u8OffsetIdx==1)
{
if (dvb_EitGetDbByIdx(pstEitHeader->u16HeadEventIdx, &stTmpEitDb) != EN_EITDB_NO_ERROR)
{
return EN_EITDB_ERROR;
}
u16CurIdx = pstEitHeader->u16HeadEventIdx; //current = H->P or current = H->F
u16NextIdx = stTmpEitDb.u16NextEventIdx; //next = H->P->S or next = H->F->S
stTmpEitDb.u16NextEventIdx = INVALID_LINK_IDX; // H->P->NULL or H->F->NULL
//update p or f database, because it changed next idx.
dvb_EitSaveDbByIdx(u16CurIdx, &stTmpEitDb);
}
else if(u8OffsetIdx==2) // next = H->P->F->S
{
//dvb_EitGetDbByIdx(pstEitHeader->u16HeadEventIdx, &stTmpEitDb);
if (GetEitDbFirst16Bytes(pstEitHeader->u16HeadEventIdx, &stTmpEitDb) != EN_EITDB_NO_ERROR)
{
return EN_EITDB_ERROR;
}
u16CurIdx = stTmpEitDb.u16NextEventIdx; // current = H->P->F
if (dvb_EitGetDbByIdx(u16CurIdx, &stTmpEitDb) != EN_EITDB_NO_ERROR)
{
return EN_EITDB_ERROR;
}
u16NextIdx = stTmpEitDb.u16NextEventIdx; // next = H->P->F->S
stTmpEitDb.u16NextEventIdx = INVALID_LINK_IDX; //H->P->F->NULL
//update f database, because it changed next idx.
dvb_EitSaveDbByIdx(u16CurIdx, &stTmpEitDb);
}
while(u16NextIdx != INVALID_LINK_IDX)
{
u16CurIdx = u16NextIdx;
//dvb_EitGetDbByIdx(u16CurIdx, &stTmpEitDb);
if (GetEitDbFirst16Bytes(u16CurIdx, &stTmpEitDb) != EN_EITDB_NO_ERROR)
{
return EN_EITDB_ERROR;
}
//clear event flag, means the space is free now.
EditDbFlag(u16CurIdx, EN_EIT_EVENT_FLAG, EN_CLEAR_FLAG);
u16DelNum++;
u16NextIdx = stTmpEitDb.u16NextEventIdx;
// This just a prevent process falling into while loop
if(u16DelNum > 1200) //It's impossible has a service over 1200 events in 7 days.
{
EIT_DBG(("%s,%d> Del Eit error, no event->next=INVALID\n", __FFLL__));
break;
}
}
//update header info
u8ClearMask = SCHEDULE_MASK;
pstEitHeader->u16AllEventNum -= u16DelNum;
pstEitHeader->u8PF_S_Flag &= ~u8ClearMask; //clear schedule mask
//EIT_DBG (("XXXXX{dvb_EitDelAll_S_Event} after delall event count[0x%x]\n", pstEitHeader->u16AllEventNum));
return EN_EITDB_NO_ERROR;
}
/******************************************************************************************/
static EN_EITDB_STATUS GetEitDbFirst16Bytes(u16 u16DbIdx, ST_EIT_DB *pstDb)
{
u32 dwStart;
u32 dwAddrOffset;
if (b8EitBuffInit != TRUE)
{
return EN_EITDB_MEMORY_NULL;
}
if(u16DbIdx >= EIT_MAX_EVENT_NUM)
return EN_EITDB_WRONG_PARAMETER;
if(EditDbFlag(u16DbIdx, EN_EIT_EVENT_FLAG, EN_CHECK_FLAG) == FALSE)
return EN_EITDB_EVENT_NOT_EXIST;
//dwStart = EIT_EVENT_BUFFER_START_ADDR<<2;
dwStart = EIT_EVENT_BUFFER_START_ADDR;
dwAddrOffset = (u32)u16DbIdx * EIT_DB_LENGTH;
//W99AV_ReadDRAMBurst(dwStart+dwAddrOffset, (u32 *)pstDb, 4); //4*4 = 16 Bytes
//DVB_DramRead(dwStart+dwAddrOffset, (u8 *)pstDb, 16);
memcpy((u8 *)pstDb, (u8*)(dwStart+dwAddrOffset), 16);
return EN_EITDB_NO_ERROR;
}
/******************************************************************************************/
// For schedule event, find a location to insert
static bool8 FindInsertLocation(u16 u16StartIdx, u16 *pu16TargetPreIdx, u16 *pu16TargetNextIdx, ST_EIT_EVENT *pstEventInfo)
{
u16 u16Count = 0;
ST_EIT_DB stTmpEitDb;
if(u16StartIdx==INVALID_LINK_IDX)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -