/** @file DMW_PsiSdds.c @brief PSI MW SDDS implementation Copyright 2010 Digital STREAM Technology, Inc. All Rights Reserved */ #include "DHL_OSAL.h" #include "DHL_DBG.h" #include "DHL_Timer.h" #include "DLIB_SDDS_Monitor.h" #include "DLIB_SDDS_Parser.h" #include "DMW_Status.h" #include "DMW_PsiSdds.h" //#include // memcmp /* ¸ðµç Çì´õ ÆÄÀÏÀ» Æ÷ÇÔÇÏÁö´Â ¾ÊÀ¸¸ç, compile timeÀ» ÁÙÀ̱â À§ÇØ °¢ ¸ðµâÀº ÇÊ¿äÇÑ ¸¸Å­ÀÇ Çì´õ¸¦ ¼±¾ðÇϵµ·Ï ÇÔ. */ /* DHL µð¹ö±× ¸ðµâ À̸§ Á¤ÀÇ ·ê Âü°í: DHL ¸ðµâµéÀº ¸ðµÎ * ·Î ½ÃÀÛ. API´Â ´ë¹®ÀÚ, Platform ¹× ±âŸ´Â ¼Ò¹®ÀÚ »ç¿ë. µðÆúÆ® ·¹º§Àº 0À¸·Î ¼³Á¤ÇÑ´Ù. (0: ¿¡·¯ ¸Þ½ÃÁö¸¸ Ãâ·Â) */ DHL_MODULE("$sds", 0); #if COMMENT ____Config____(){} #endif /* ÀÌ ¸ðµâ ³»ºÎ¿¡¼­ »ç¿ëµÇ´Â °¢Á¾ configuration Á¤ÀÇ. */ #define DMW_SDDS_TEST 0 // Å×½ºÆ® ÄÚµå Æ÷ÇÔ. #define SDDS_ENABLE_SECTION_SYNTAX_CHECK 1 // ¼½¼Ç syntax¿¡ ¹®Á¦°¡ ¾ø´Â °ÍÀÎÁö MW ·¹º§¿¡¼­ ´Ù½Ã üũ. // DLIB ¿¡¼­µµ ÀÏ´Ü ±âº»ÀûÀΠüũ´Â ÇØ ÁÖ¾î¾ß °ÚÁö¸¸.. #define SDDS_ENABLE_DDB_RX_INTERLEAVING 1 // 1À̸é ddb ¼ö½ÅÀ²À» ³ôÀ̱â À§ÇØ ÀÎÅ͸®ºù ¸ðµå·Î µ¿ÀÛÇÑ´Ù. // ´ë½Å ddb ÇÊÅ͸¦ µÎ¹è·Î ¼Ò¸ðÇÏ´Â ´ÜÁ¡ÀÌ ÀÖ´Ù. #define SDDS_ENABLE_GLOBAL_DDB_RX 1 // 1 ÀÌ¸é °¢ ¸ðµâº° ddb ÇÊÅ͸¦ »ç¿ëÇÏÁö ¾Ê°í, // group ³»ÀÇ ¸ðµç ¸ðµâ blockÀ» ¼ö½Å°¡´ÉÇϵµ·Ï ddb ÇÊÅ͸¦ ¼³Á¤ÇÏ¿© »ç¿ëÇÑ´Ù. #if COMMENT ____Types____(){} #endif /* ÀÌ ¸ðµâ ³»ºÎ¿¡¼­ »ç¿ëµÇ´Â structure ¹× enumerations. */ typedef struct { //---- sddsDiiModule_t Á¤º¸ÀÇ copy UINT16 moduleId; UINT32 moduleSize; // ¸ðµâ ÀüüÀÇ Å©±â. //---- sddsModuleInfoDesc_t Á¤º¸ÀÇ backup UINT8 *moduleName; UINT8 *moduleSignature; BOOL bNeedToDownload; // ´Ù¿î·Îµå ÇÊ¿äÇÔÀ» ÀǹÌ. // ¹öÆÛ °ü¸®¸¦ app ÂÊÀ¸·Î ³Ñ°åÀ½. #if 0 // ´Ù¿î·Îµå ¹ÞÀ» ºí·°ÀÌ ÀúÀåµÉ ¹öÆÛ °ø°£. Å©±â´Â moduleSize ¹ÙÀÌÆ®. UINT8 *moduleBuffer; #endif // ºí·°ÀÇ °¹¼ö´Â (moduleSize+dii->blockSize-1)/dii->blockSize ÀÌ´Ù. // ¸Ç ¸¶Áö¸· blockÀÇ Å©±â´Â blockSize º¸´Ù ÀûÀ» ¼ö ÀÖ´Ù. UINT16 numberOfBlocks; // DDBÀÇ blockNumberÀÇ °ªÀÇ ¹üÀ§´Â 16bit·Î¼­ 0 ºÎÅÍ 65535 ÀÌ´Ù. // blockSize´Â 16 bitÀÌÁö¸¸, ÃÖ´ë Å©±â´Â 4066 ÀÌ´Ù. // µû¶ó¼­ ¸ðµâÀÇ ÃÖ´ë Å©±â´Â 4066 * 65536 = 266,469,376 ÀÌ´Ù. ¾à 254MB. // °¢ DDBÀÇ ¼ö½ÅÀÌ ¿Ï·á µÇ¾ú´ÂÁö¸¦ ±â·ÏÇÏ´Â Ç÷¡±×. // // DDB°¡ ¼ø¼­´ë·Î ¼ö½ÅµÇÁö ¾ÊÀ» ¼ö ÀÖ°í, ¶Ç ½ÅÈ£ »óÅ¿¡ µû¶ó Áß°£¿¡ ºüÁö´Â °æ¿ìµµ ÀÖÀ¸¹Ç·Î // °¢ DDB º°·Î ¼ö½Å »óŸ¦ °ü¸®ÇØ¾ß ÇÑ´Ù. // // ÇØ´ç bit°¡ 1À̸é complete µÇ¾ú´Ù´Â ÀǹÌÀÌ´Ù. // flags[blockIndex/8] & (1 << blockIndex%8) ¿Í °°ÀÌ »ç¿ë. // UINT8 completedFlags[65536/8]; // <-- ³Ê¹« Å©´Ù. µ¿Àû ÇÒ´çÀ¸·Î ÇÒ±î? // ¸Þ¸ð¸®°¡ ºÎÁ·ÇÏÁö¸¸ ¾Ê´Ù¸é »ó°ü ¾ø´Ù. ÀÌ ModuleInfo ÀÚüµµ µ¿Àû ÇÒ´ç ¹ÞÀº °ÍÀÓ. // ÀÌ ÆÄÀÏ ´Ù¿î·Îµå°¡ ´Ù ³¡³ª¸é true. BOOL bDownloadCompleted; // ddb¸¦ ¼ö½ÅÇϱâ À§ÇÑ psi control ÇÚµé. // ÀÎÅ͸®ºù ¼ö½Å ¿É¼ÇÀÌ enable À̸é 0, 1 ¸ðµÎ »ç¿ëÇϰí // ±×·¸Áö ¾Ê´Ù¸é 0 ¸¸ »ç¿ëÇÑ´Ù. tDHL_PSI_ControlHandle hDdbCtl0; // even block number tDHL_PSI_ControlHandle hDdbCtl1; // odd block number } S_SDDS_ModuleInfo; typedef struct { UINT32 groupId; // copy of ctx->dsi->group[ctx->iGroup].groupId; // compatibility µî ±âŸ Á¤º¸¸¦ Ã¼Å©ÇØ º» °á°ú, ó¸®ÇÒ Çʿ䰡 ¾ø´Â group ÀÎ °æ¿ì // ÀÌ flag¸¦ true·Î ÇÏ¿© skip Çϵµ·Ï ÇÑ´Ù. //BOOL bNotUsed; // ¸Ç ¸¶Áö¸· blockÀ» Á¦¿ÜÇÑ ¸ðµç blockÀÇ Å©±â. UINT16 blockSize; // copy of ctx->dii->blockSize // dii¸¦ ¼ö½ÅÇϱâ À§ÇÑ psi control ÇÚµé. tDHL_PSI_ControlHandle hDiiCtl; // download µÈ dii ¼½¼Ç. NULL if not downloaded yet. // ¸ðµç diiÀÇ transaction id´Â groupId¿Í µ¿ÀÏÇØ¾ß ÇÑ´Ù. sddsDiiPtr_t dii; // ¸ðµâ °¹¼öÀÇ Á¦ÇÑÀº µüÈ÷ ¾øÀ¸¹Ç·Î, µ¿ÀûÀ¸·Î ÇÒ´ç ¹Þ´Â´Ù. int numModules; // same as dii->numberOfModules S_SDDS_ModuleInfo *mi; // this is moduleinfo array. } S_SDDS_GroupInfo; #if COMMENT ____Types____(){} #endif typedef struct { tDHL_TSD tsd; UINT16 pid; // dsi¸¦ ¼ö½ÅÇϱâ À§ÇÑ psi control ÇÚµé. tDHL_PSI_ControlHandle hDsiCtl; // download µÈ dsi ¼½¼Ç. NULL if not downloaded yet. sddsDsiPtr_t dsi; int iGroup; // dsi¿¡¼­ ¿ì¸®°¡ ó¸®ÇÒ group index S_SDDS_GroupInfo *gi; } S_SDDS_Context; typedef enum { //--------------------------- eSDDS_Cmd_BEGIN = 0x20, eSDDS_Cmd_Init, // param1: task info.. eSDDS_Cmd_Start, // param1: tsd // param2: pid eSDDS_Cmd_Stop, // no param eSDDS_Cmd_Delete, // no param eSDDS_Cmd_GetStatus, // param1: SddsStatusStructure * // param2: Ack semaphore eSDDS_Cmd_PrintStatus, // param1: detail level eSDDS_Cmd_UserAction, // param1: user param eSDDS_Cmd_Shutdown, //--------------------------- eSDDS_Evt_BEGIN = 0x40, // À̺¥Æ® °øÅë // param1: tDHL_PSI_ControlHandle // param2: tDHL_PSI_DataArray * eSDDS_Evt_DSI, // DSI ¼ö½Å eSDDS_Evt_DII, // DII ¼ö½Å eSDDS_Evt_DDB, // DDB ¼ö½Å eSDDS_Evt_DC, // DC ¼ö½Å } E_SDDS_Command; typedef struct { E_SDDS_Command cmd; UINT32 param[4]; } S_SDDS_TaskMessage; #if COMMENT ____Variables____(){} #endif /* global·Î Àû¿ëµÇ´Â variable Á¤ÀÇ. °¢ function º°·Î Ư¼öÇÑ ¿ëµµÀÇ variableÀº °¢ functionX block ¿¡¼­ Á¤ÀÇ °¡´É. */ static S_SDDS_Context s_sdds_context; /* user callback */ F_SDDS_CALLBACK s_sdds_user_cb; /* Å×½ºÆ®¸¦ À§ÇÑ º¯¼öµé.. */ BOOL s_sdds_force_pidchange; #if COMMENT ____Function____(){} #endif STATUS sdds_task_send_cmd(E_SDDS_Command cmd, UINT32 p0, UINT32 p1, BOOL bWait); STATUS sdds_task_send_event(E_SDDS_Command evt, UINT32 p0, UINT32 p1); #if COMMENT ____Group1____(){} #endif S_SDDS_Context *sdds_get_context(void) { return &s_sdds_context; } void sdds_check_task(void *handle) { } /** return TRUE if two dsi is same. */ BOOL sdds_is_same_dsi(sddsDsiPtr_t dsi1, sddsDsiPtr_t dsi2) { int i; sddsDsiGroup_t *g1, *g2; if (!dsi1 || !dsi2) return FALSE; if (dsi1->transactionId != dsi2->transactionId) return FALSE; // transactionId ¿¡ ¹öÀü Á¤º¸°¡ Æ÷ÇԵǾî ÀÖÀ¸¹Ç·Î // À̰͸¸ ºñ±³Çصµ ¹«¹æÇÒ µí ÇÔ. #if 0 if (memcmp(&dsi1->compat, &dsi2->compat, sizeof(sddsCompatDesc_t))) return FALSE; if (dsi1->numberOfGroups != dsi2->numberOfGroups) return FALSE; for (i=0; inumberOfGroups; i++) { g1 = &dsi1->groups[i]; g2 = &dsi2->groups[i]; if (g1->groupId != g2->groupId) return FALSE; if (g1->groupSize != g2->groupSize) return FALSE; if (memcmp(&g1->compat, &g2->compat, sizeof(sddsCompatDesc_t))) return FALSE; // ÀÌ ºÎºÐÀº ¹ö±×ÀÓ. compat ¾È¿¡ malloc Æ÷ÀÎÅͰ¡ ÀÖÀ¸¹Ç·Î ±×³É memcmp ÇÏ¸é ¾ÈµÊ. if (g1->groupInfoLength != g2->groupInfoLength) return FALSE; if (memcmp(&g1->groupDescriptors, &g2->groupDescriptors, g1->groupInfoLength)) return FALSE; } if (dsi1->groupInfoPrivateDataLength != dsi2->groupInfoPrivateDataLength) return FALSE; if (memcmp(&dsi1->groupInfoPrivateDataBytes, &dsi2->groupInfoPrivateDataBytes, dsi1->groupInfoPrivateDataLength)) return FALSE; #endif if (dsi1->checksum_CRC32 != dsi2->checksum_CRC32) return FALSE; return TRUE; // all data same.. } BOOL sdds_is_same_dii(sddsDiiPtr_t dii1, sddsDiiPtr_t dii2) { if (!dii1 || !dii2) return FALSE; if (dii1->transactionId != dii2->transactionId) return FALSE; // todo.. if (dii1->checksum_CRC32 != dii2->checksum_CRC32) return FALSE; return TRUE; } void sdds_stop_monitor(tDHL_PSI_ControlHandle *pHandle) { if (pHandle == NULL || *pHandle == (tDHL_PSI_ControlHandle)0) return; DLIB_SDDS_StopMonitor(*pHandle); *pHandle = (tDHL_PSI_ControlHandle)0; } void sdds_free_section(void *ppSection) { void **pp = (void **)ppSection; if (pp == NULL || *pp == NULL) return; DLIB_SDDS_FreeSection(*pp); *pp = (void *)NULL; } void sdds_free_module_info(int index, S_SDDS_ModuleInfo *mi) { if (!mi) return; dprint(3, " free module info [%d] 0x%x..\n", index, mi); #if 0 if (mi->moduleBuffer) { dprint(3, " free module buf 0x%x\n", mi->moduleBuffer); DHL_OS_Free((void **)&mi->moduleBuffer); } #endif sdds_stop_monitor(&mi->hDdbCtl0); sdds_stop_monitor(&mi->hDdbCtl1); memset(mi, 0, sizeof(S_SDDS_ModuleInfo)); } void sdds_free_all_module_info(S_SDDS_GroupInfo *gi) { int iModule; if (!gi) return; dprint(3, " free all %d module info\n", gi->numModules); for (iModule=0; iModulenumModules; iModule++) sdds_free_module_info(iModule, &gi->mi[iModule]); DHL_OS_Free((void **)&gi->mi); gi->numModules = 0; } void sdds_free_group_info(S_SDDS_GroupInfo *gi) { int iModule; if (!gi) return; dprint(3, " free group info %x..\n", gi); sdds_stop_monitor(&gi->hDiiCtl); sdds_free_section(&gi->dii); for (iModule=0; iModulenumModules; iModule++) sdds_free_module_info(iModule, &gi->mi[iModule]); DHL_OS_Free((void **)&gi->mi); memset(gi, 0, sizeof(S_SDDS_GroupInfo)); } void sdds_free_all_group_info(S_SDDS_Context *ctx) { if (ctx->gi == NULL) return; dprint(3, " free all group info..\n"); sdds_free_group_info(ctx->gi); DHL_OS_Free((void **)&ctx->gi); // ctx->dsi ¹× hDsiCtlÀº °Çµå¸®Áö ¾Ê´Â´Ù. À̰ÍÀº GroupInfo°¡ ¾Æ´Ï´Ù. } void sdds_stop_all_monitor(S_SDDS_Context *ctx) { int i; if (ctx->hDsiCtl) { dprint(3, " stop dsi ctl..\n"); sdds_stop_monitor(&ctx->hDsiCtl); } if (ctx->gi && ctx->gi->hDiiCtl) { dprint(3, " stop dii ctl..\n"); sdds_stop_monitor(&ctx->gi->hDiiCtl); } for (i=0; ctx->gi && igi->numModules; i++) { if (ctx->gi->mi[i].hDdbCtl0) { dprint(3, " stop ddb0[%u] ctl..\n", i); sdds_stop_monitor(&ctx->gi->mi[i].hDdbCtl0); } if (ctx->gi->mi[i].hDdbCtl1) { dprint(3, " stop ddb1[%u] ctl..\n", i); sdds_stop_monitor(&ctx->gi->mi[i].hDdbCtl1); } } } /* user callbackÀ» È£Ãâ. */ void sdds_user_call(E_SDDS_CB_TYPE cbtype, void *param) { if (!s_sdds_user_cb) return; dprint(2, "--> user callback (cbtype %u, param 0x%x)\n", cbtype, param); (*s_sdds_user_cb)(cbtype, param); } /* ¼±ÅÃµÈ group index¸¦ ¸®ÅÏ. ¾ø´Ù¸é -1À» ¸®ÅÏÇÑ´Ù. */ int sdds_choose_group_from_dsi(sddsDsiPtr_t dsi) { int iGroup; for (iGroup=0; iGroupnumberOfGroups; iGroup++) { // ¿©±â¼­ callbackÀ» º¸³»¼­ Á¦Á¶»ç°¡ ¸Â´ÂÁö üũ.. S_SDDS_CBPARAM_GET_OUI cbp = {0, }; sdds_user_call(eSDDS_CB_TYPE_GetOUI, &cbp); if (cbp.oui == 0) // user°¡ ±¸ÇöÇÏÁö ¾Ê¾ÒÀ½. ; // user not specifed oui. // group descriptor°¡ ¾ø´Ù¸é, manufacturere¸¦ ãÀ» ¼ö ¾øÀ¸¹Ç·Î, // ÀÌ dsi ±×·ìÀº »ç¿ë ºÒ°¡. if (dsi->groups[iGroup].compat.descriptorCount == 0) continue; if (cbp.oui == 0x80000000) { dprint(2, "test mode: accept any group..\n"); break; } if (cbp.oui) { // oui Á¤º¸¸¦ ¾Ë°í ÀÖ´Â °æ¿ì.. µÎ °³ÀÇ desc¸¸ üũÇÑ´Ù. sddsCompatDescEntry_t *d; d = &dsi->groups[iGroup].compat.desc[0]; if (d->specifierType == compatSpecifierType_IEEE_OUI && (d->specifierData == cbp.oui || 0x80000000 == cbp.oui)) dprint(2, "group[%d] desc0 oui matched 0x%x\n", iGroup, cbp.oui); else continue; // oui not matched. try next group.. if (d->model == cbp.model || 0xFFFF == cbp.model) dprint(2, "group[%d] desc0 model matched 0x%x\n", iGroup, cbp.model); else continue; if (d->version == cbp.version || 0xFFFF == cbp.version) dprint(2, "group[%d] desc0 version matched 0x%x\n", iGroup, cbp.version); else continue; #if 0 // ±×³É ¸Ç ¾ÕÀÇ ÇϳªÀÇ compat descriptor¸¸ Á¶»çÇÏÀÚ. d = &dsi->groups[iGroup].compat.desc[1]; if (dsi->groups[iGroup].compat.descriptorCount > 1 && d->specifierType == compatSpecifierType_IEEE_OUI && d->specifierData == cbp.oui) { dprint(2, "found group[%d] desc1 oui matched 0x%x\n", iGroup, cbp.oui); break; } .. #endif } else { // oui Á¤º¸¸¦ ¸ð¸£´Â °æ¿ì. user¿¡°Ô callbackÀ¸·Î Çϳª¾¿ query.. S_SDDS_CBPARAM_CHECK_DESC cbp2; cbp2.desc = &dsi->groups[iGroup].compat; cbp2.isOk = FALSE; sdds_user_call(eSDDS_CB_TYPE_CheckCompatDesc, &cbp2); if (cbp2.isOk) { dprint(2, "user choosed group[%d].\n", iGroup); break; } } } if (iGroup >= dsi->numberOfGroups) { dprint(0, "!! cannot find group in dsi!!\n"); return -1; } // iGroup ¼±ÅÃÀº ¿Ï·á. return iGroup; } int sdds_rx_blk_count(S_SDDS_ModuleInfo *mi) { int count, i; for (count=0, i=0; inumberOfBlocks; i++) { if (mi->completedFlags[i/8] & (1<numberOfBlocks); return count; } void sdds_prepare_module_info(int index, sddsDiiModule_t *m, S_SDDS_CBPARAM_CHECK_FILE *f) { memset(f, 0, sizeof(*f)); //f->index = index; //-------- ¸ðµâ »óÅ º¯¼ö ÃʱâÈ­.. f->id = m->moduleId; f->size = m->moduleSize; // ¸ðµâ ÀüüÀÇ Å©±â. // module info µð½ºÅ©¸³ÅÍ Á¤º¸ º¹»ç. if (m->moduleInfoDesc) { sddsModuleInfoDesc_t *mid = m->moduleInfoDesc; sddsDstModuleInfoDesc_t *di = &mid->dstinfo; f->name = di->moduleName; f->version = di->moduleVer; f->type = di->moduleType; f->numSupportedHwVersions = di->numSupportedHwVersions; f->supportedHwVersions = di->supportedHwVersions; f->crc32 = di->fileCRC32; } end: return; } #if COMMENT ____Group1____(){} #endif void SDDS_PsiRxCallback(tDHL_PSI_Event event, tDHL_PSI_ControlHandle psiCtl, E_SDDS_Command cmd, UINT32 userParam) { DHL_RESULT dhr; STATUS err; tDHL_PSI_DataArray *desc; if (event != ePSIEVENT_DATARECEIVED) { dprint(0, "!! psicallback err %d\n", event); return; } if (cmd == eSDDS_Evt_DSI || cmd == eSDDS_Evt_DII || cmd == eSDDS_Evt_DDB || cmd == eSDDS_Evt_DC) { dprint(2, "sdds psi rx, cmd %d, psictl %x\n", cmd, psiCtl); // race condition À¸·ÎºÎÅÍÀÇ º¸È£°¡ ¾ÆÁ÷ ¿Ïº®ÇÏÁö ¾ÊÀ¸¹Ç·Î, // desc detach ÀÛ¾÷À» ÀÌ callback task¿¡¼­ ¼öÇàÇϵµ·Ï ÇÏÀÚ. // dhr = DHL_PSI_ReadPSIData(psiCtl, &desc); if (dhr) { dprint(0, "!! %s: DHL_PSI_ReadPSIData err %x\n", __FUNCTION__, dhr); return; } err = sdds_task_send_event(cmd, (UINT32)psiCtl, (UINT32)desc); // jump to.. // SDDS_HandleEvtProcessDsi // SDDS_HandleEvtProcessDii // SDDS_HandleEvtProcessDdb // SDDS_HandleEvtProcessDc if (err) { dprint(0, "!! %s: send dpc event err %d\n", __FUNCTION__, err); // detach ÇÑ desc¸¦ ÇØÁ¦ ÇØ Áà¾ß ¸Þ¸ð¸® leak°¡ ¾ø´Ù. DHL_PSI_FreePSIData(desc); } } else { dprint(0, "!! %s: unknown evt msg %d\n", __FUNCTION__, cmd); goto errexit; } errexit: // psiCtl clean up?? return; } void SDDS_DsiCallback(tDHL_PSI_Event event, tDHL_PSI_ControlHandle psiCtl, UINT32 userParam) { SDDS_PsiRxCallback(event, psiCtl, eSDDS_Evt_DSI, userParam); } void SDDS_DiiCallback(tDHL_PSI_Event event, tDHL_PSI_ControlHandle psiCtl, UINT32 userParam) { SDDS_PsiRxCallback(event, psiCtl, eSDDS_Evt_DII, userParam); } void SDDS_DdbCallback(tDHL_PSI_Event event, tDHL_PSI_ControlHandle psiCtl, UINT32 userParam) { SDDS_PsiRxCallback(event, psiCtl, eSDDS_Evt_DDB, userParam); } void SDDS_DcCallback(tDHL_PSI_Event event, tDHL_PSI_ControlHandle psiCtl, UINT32 userParam) { SDDS_PsiRxCallback(event, psiCtl, eSDDS_Evt_DC, userParam); } void SDDS_HandleCmdInit(void *handle) { S_SDDS_Context *ctx; //-------- get context ctx = sdds_get_context(); //-------- init context memset(ctx, 0, sizeof(*ctx)); dprint(2, "sdds init.. handle %x.. \n", handle); // iGroupÀº ctx->dsi°¡ ÀÖÀ» ¶§¿¡¸¸ Àǹ̰¡ ÀÖ´Ù. ctx->iGroup = -1; } /* Start APIÀÇ Çڵ鷯 */ void SDDS_HandleCmdStart(tDHL_TSD tsd, UINT16 pid) { DHL_RESULT dhr; S_SDDS_Context *ctx; //-------- parameter checking // tsd, pid.. //-------- get context ctx = sdds_get_context(); // check task is valid. //sdds_check_task(ctx->task); //-------- ±âÁ¸¿¡ µ¿ÀÛ ÁßÀÎÁö ¸ÕÀú üũ. // /* tsd³ª pid°¡ ´Þ¶óÁö¸é ÀÏ´Ü ¸ðµÎ resetÇÏ°í ´Ù½Ã ½ÃÀÛÇÏ´Â °ÍÀ¸·Î ÇÑ´Ù. ´ÙÀ½°ú °°Àº ½Ã³ª¸®¿À¿¡¼­ ÀÌ·± °æ¿ì°¡ ¹ß»ýÇÑ´Ù. 1. ÇÑ RF ³»¿¡ ¿©·¯ sdds °¡»ó ä³Î ¼­ºñ½º°¡ Á¸ÀçÇÏ´Â °æ¿ì. 2. ´Ù¸¥ ¹æ¼Û±¹(´Ù¸¥ RF)¿¡¼­ sdds ¼­ºñ½º¸¦ ½Ç½ÃÇÏ´Â °æ¿ì. 3. ±âÁ¸¿¡ µ¿ÀÛ ÁßÀÌ´ø sdds ¼­ºñ½º°¡ ¿Ï·áµÇÁö ¾ÊÀº »óÅ¿¡¼­, ³ªÁß¿¡ ½Ã°£ÀÌ È帥 ÈÄ¿¡ ´Ù¸¥ pid·Î »õ sdds ¼­ºñ½º °³½Ã.. ±¹³» ±Ô°Ý»ó, ÀÌ·± °æ¿ì´Â ¹ß»ýÇÏÁö ¾Ê°ÚÁö¸¸ ½ÇÇè½Ç µî¿¡¼­ÀÇ ½Ç¼ö/Àǵµ µîÀ¸·Î ÀÌ·± »óȲÀÌ ¹ß»ýµÇ¸é ÃÖ´ëÇÑ ¹®Á¦°¡ ¾ø°Ô ÇØ¾ß ÇÑ´Ù. 2¹ø °°Àº °æ¿ì´Â ´Ù¸¥ RF¿¡¼­ "µ¿ÀÏÇÑ" pid·Î ¼­ºñ½º¸¦ ÇÏ´Â °æ¿ì¿¡, ÀÌ µÑÀÇ ±¸ºÐÀÌ ºÒ°¡´ÉÇÏ´Ù´Â Á¡Àε¥, º°µµÀÇ rf_id µîÀÌ Ãß°¡µÇ¾î¾ß ÇÒ °Í °°´Ù. ¹æ¹ý 1) ±âÁ¸ sdds µ¿ÀÛÀÌ ¿Ï·á µÉ ¶§ ±îÁö »õ sdds ¼­ºñ½º reject. --> 3¹ø °°Àº °æ¿ì´Â ±âÁ¸ sdds´Â ÀÌ¹Ì ¹°°Ç³Ê °£ °æ¿ì. µû¶ó¼­ »ç¿ë ºÒ°¡!! ¹æ¹ý 2) ±âÁ¸ sdds µ¿ÀÛÀ» ÁßÁöÇϰí, »õ·Î ½ÃÀÛ --> ÀÌ ¹æ¹ýÀ» »ç¿ëÇÒ ¼ö ¹Û¿¡ ¾øÀ½. ºó¹øÇÏ°Ô ÀÚ²Ù pid °¡ º¯°æµÇ¾î restart µÇ´õ¶óµµ ¾ÈÁ¤¼º¿¡ ¹®Á¦°¡ ¾ø´ÂÁö ÃæºÐÈ÷ Å×½ºÆ® ÇÊ¿äÇÏ´Ù. Å×½ºÆ® ¹æ¹ý: A. pid ´Ù¸¥ µÎ°³ÀÇ ½ºÆ®¸²À» ¸¸µé¾î ½ºÆ®¸² Àåºñ¿¡¼­ ¹Ýº¹ Àç»ý. B. ½Ã¹Ä·¹À̼Ç. */ if (s_sdds_force_pidchange || (ctx->pid != pid || ctx->tsd != tsd)) { if (s_sdds_force_pidchange) dprint(0, "-- pid change simul..\n"); else if (ctx->pid) dprint(2, "!! warning: pid %x tsd %x changed\n", pid, tsd); dprint(2, "reset all..\n"); sdds_free_all_group_info(ctx); // ÀÌ ¾È¿¡¼­ reset ¾ÈµÇ´Â °ÍµéÀº hDsiCtl, dsi »ÓÀÌ´Ù. sdds_free_section(&ctx->dsi); sdds_user_call(eSDDS_CB_TYPE_ResetDownload, NULL); } //-------- ÆÄ¶ó¹ÌÅ͵é ÃʱâÈ­ ctx->tsd = tsd; ctx->pid = pid; dprint(2, "start sdds, tsd %x, pid 0x%x\n", tsd, pid); //-------- dsi ¸ð´ÏÅÍ ½ÃÀÛ. // óÀ½¿¡´Â table_id_extension ÇÊÅÍ ¾øÀÌ ¸ðµÎ ¹Þ´Â´Ù. // /* ÀÌ¹Ì ½ÃÀÛ ÁßÀε¥ ´Ù½Ã Start api°¡ ºÒ¸®´Â °Íµµ Çã¿ëÇÑ´Ù. Áï, app ¿¡¼­ ä³Î º¯°æ½Ã ¸Å¹ø Stop ÇÔ¼ö¸¦ ºÎ¸£Áö ¾Ê¾Æµµ MW µ¿ÀÛÀº µÇµµ·Ï ¼³°è ÇÑ´Ù. ±×·¯³ª ±ÇÀåÇÏ´Â °ÍÀº ¾Æ´Ô. 1. ±âÁ¸ ¸ð´ÏÅͰ¡ ÀÖÀ¸´Ï ±×³É skip ÇÏ´Â ¹æ¹ý Ȥ½Ã ±× µÞ´ÜÀÇ dii, ddb µî¿¡ ¹®Á¦°¡ À־ ´Ù½Ã ½ÃÀÛ½ÃŰ°í ½ÍÀº °æ¿ì¶ó¸é ÀÌ ¹æ¹ýÀº È¿°ú°¡ ¾øÀ½.. dii, ddb¿¡ ¹®Á¦°¡ ÀÖÀ» °¡´É¼ºÀº?? 2. filter¸¦ ´Ù½Ã ½ÃÀÛÇÏ´Â ¹æ¹ý ¹«Á¶°Ç dsi¸¦ Çѹø ´õ ¹Þ°Ô µÉ °ÍÀÓ.. ¾îÂ÷ÇÇ Ã¤³Î º¯°æ ÇÏ´Ù°¡ sdds RF·Î °¡¸é ¹«Á¶°Ç dsi¸¦ ´Ù½Ã ¹Þ°Ô µÇ¹Ç·Î º° ºÎ´ãÀº ¾Æ´Ô.. --> ÀÌ ¹æ¹ý »ç¿ë. */ #if 0 // method 1 if (ctx->hDsiCtl) { dprint(2, "prev dsi ctl %x active. skip dsi monitor..\n", ctx->hDsiCtl); } else #else // method 2 if (ctx->hDsiCtl) { dprint(2, "prev dsi ctl %x active.. restart..\n", ctx->hDsiCtl); sdds_stop_monitor(&ctx->hDsiCtl); } #endif { dprint(2, "start monitor dsi..\n"); dhr = DLIB_SDDS_MonitorDsi(tsd, pid, (UINT32)-1, ePSIUPDATE_CONTINEOUS, SDDS_DsiCallback, 0, &ctx->hDsiCtl); DHL_ASSERT(dhr == DHL_OK, ""); } /* ctxÀÇ groupinfo µî¿¡ ´ëÇØ¼­´Â üũÇÏÁö ¸»ÀÚ. ÀÏ´Ü dsi ¼ö½Å ÀÌÈÄ¿¡ °í·ÁÇÏÀÚ. */ } /* ´ÙÀ½°ú °°Àº °æ¿ì¿¡ È£Ã⠵ȴÙ. 1. app ¿¡¼­ sdds ä³ÎÀ» ¹þ¾î³ª ´Ù¸¥ ä³Î·Î À̵¿ÇÒ ¶§.. 2. ´ë±â¸ðµå¿¡¼­ sdds ´Ù¿î·Îµå ÁßÀε¥ »ç¿ëÀÚ°¡ Àü¿øÀ» ÄѼ­ ½Ãû ä³Î·Î °¡¾ß ÇÒ ¶§.. (1¹øÀÇ Æ¯¼ö ÄÉÀ̽º) µ¥ÀÌÅÍ´Â ±×´ë·Î µÎ°í, monitorµé¸¸ ÁßÁö (stop) ÇÑ´Ù. */ void SDDS_HandleCmdStop(void) { S_SDDS_Context *ctx; int i; //-------- parameter checking // none //-------- get context ctx = sdds_get_context(); dprint(2, "stop sdds rx\n"); // check task is valid. //sdds_check_task(ctx->task); sdds_stop_all_monitor(ctx); sdds_user_call(eSDDS_CB_TYPE_DownloadStopped, NULL); } /* sdds °ü·Ã µ¥ÀÌÅ͸¦ ¸ðµÎ Áö¿î´Ù. Áö¿î ÈÄ¿¡µµ °è¼Ó ¹Þ¾ÆÁö¸é ¾ÈµÇ¹Ç·Î, ³»ºÎ¿¡¼­ ´ç¿¬È÷ ¸ÕÀú stop ºÎÅÍ ÇÑ´Ù. ´ÙÀ½°ú °°Àº °æ¿ì¿¡ È£Ã⠵ȴÙ. 1. flash update ±îÁö ¿Ï·á µÈ ÈÄ(??) 2. app ¿¡¼­´Â delete ÇÑ ÀÌÈÄ¿¡µµ ä³Î º¯°æ½Ã ¸¶´Ù start¸¦ ´Ù½Ã È£ÃâÇÒ °ÍÀÌ´Ù. ¼ÂžÀº update°¡ ³¡³µ´Ù°í ÇÏ´õ¶óµµ ä³Î º¯°æ½Ã ¸¶´Ù sdds ¼­ºñ½º¸¦ ´Ù½Ã ¹ß°ßÇÒ °ÍÀ̴ϱî. ±×·¡¼­ sdds RFÀÇ Ã¤³ÎÀ» Æ©´× ÇÒ ¶§ ¸¶´Ù ÃÖ¼ÒÇÑ dsi, dii´Â ¹Þ°Ô µÈ´Ù. (dsi ¸¸ ¹Þ¾Æ¼­´Â ÀÌ¹Ì updateµÈ sdds ½ºÆ®¸²ÀÎÁö ±¸ºÐ ºÒ°¡À̹ǷΠdiiµµ ¹ÞÀ½. ´õºÒ¾î groupinfo ¹öÆÛ, moduleinfo array buffer µîµµ ¸Å¹ø ÇÒ´ç µÈ´Ù.) µû¶ó¼­ flash update ÀÌÈÄ¿¡µµ delete¸¦ ÇÒ Çʿ䰡 º°·Î ¾ø´Ù. firmware¿ë ¹öÆÛ´Â app¿¡¼­ °ü¸®ÇϹǷÎ, ÀÌ delete api ¾øÀ̵µ ½±°Ô free ÇÒ ¼ö ÀÖÀ» °ÍÀÓ. ¹°·Ð app¿¡¼­ sdds download¸¦ ´ë±â¸ðµå¿¡¼­¸¸ ¼öÇàÇÏ°Ô ÇѴٵ簡 ÇÏ´Â ¹æ½ÄÀ» ¾²¸é Á» ´úÇÒ °ÍÀÓ. Ãß°¡: flash update°¡ ¿Ï·á µÇ¸é ¾îÂ÷ÇÇ rebootÀ» ÇÑ´Ù. ±×·¯¸é ±»ÀÌ delete¸¦ ºÎ¸¦ Çʿ䵵 ¾ø´Ù. Áï ÀÌ api´Â Å×½ºÆ® ¿ëµµ À̿ܿ¡´Â º° ÀÇ¹Ì ¾ø´Ù´Â °Í.. */ void SDDS_HandleCmdDelete(void) { S_SDDS_Context *ctx; //-------- parameter checking // none //-------- get context ctx = sdds_get_context(); dprint(2, "delete all sdds data\n"); // delete ÇÏ·Á¸é ¸ÕÀú stop ºÎÅÍ.. sdds_stop_all_monitor(ctx); // group Á¤º¸¸¦ Áö¿ì°í sdds_free_all_group_info(ctx); sdds_stop_monitor(&ctx->hDsiCtl); sdds_free_section(&ctx->dsi); ctx->iGroup = -1; sdds_user_call(eSDDS_CB_TYPE_ResetDownload, NULL); } void SDDS_HandleCmdPrintStatus(int level) { S_SDDS_Context *ctx; S_SDDS_GroupInfo *gi; S_SDDS_ModuleInfo *mi; int k; //-------- parameter checking // none //-------- get context ctx = sdds_get_context(); #define print DHL_OS_Printf // dsi info print("--------------------------------\n"); print(" tsd 0x%x, pid 0x%x (%u)\n", ctx->tsd, ctx->pid, ctx->pid); print(" dsi 0x%x, selected group idx %d\n", ctx->dsi, ctx->iGroup); print(" dsictl 0x%x, groupinfo 0x%x\n", ctx->hDsiCtl, ctx->gi); DLIB_SDDS_PrintDsiSection(ctx->dsi, 5); // group info gi = ctx->gi; if (gi == NULL) goto label_end; print(" group id 0x%x, blksz %d (0x%x)\n", gi->groupId, gi->blockSize, gi->blockSize); print(" dii 0x%x, %d modules\n", gi->dii, gi->numModules); print(" diictl 0x%x, moduleinfo list 0x%x\n", gi->hDiiCtl, gi->mi); DLIB_SDDS_PrintDiiSection(gi->dii, 5); // module info list if (gi->mi == NULL) goto label_end; for (k=0; knumModules; k++) { mi = &gi->mi[k]; print(" (%d) module id 0x%x, size %d (0x%x)\n", k, mi->moduleId, mi->moduleSize, mi->moduleSize); print(" ddbctl0 0x%x, ddbctl1 0x%x, active %d, completed %d\n", mi->hDdbCtl0, mi->hDdbCtl1, mi->bNeedToDownload, mi->bDownloadCompleted); print(" %d/%u received\n", sdds_rx_blk_count(mi), mi->numberOfBlocks); } label_end: print("--------------------------------\n"); #undef print } void SDDS_HandleCmdUserAction(UINT32 userparam) { sdds_user_call(eSDDS_CB_TYPE_UserAction, (void *)userparam); } /* */ void SDDS_HandleEvtProcessDsi(tDHL_PSI_ControlHandle psiCtl, tDHL_PSI_DataArray *desc) { DHL_RESULT dhr; int iGroup; S_SDDS_Context *ctx; sddsDsiPtr_t dsi = NULL; int i, k; dprint(2, "%s\n", __FUNCTION__); //-------- parameter checking //-------- get context ctx = sdds_get_context(); //-------- check if we are too late // check psictl is valid // todo /* ¾Æ·¡¿Í °°Àº °æ¿ì´Â psi event Àü´ÞÀÌ ³Ê¹« ´Ê°Ô µÇ¾ú°í, ±× »çÀÌ¿¡ stop api°¡ ºÒ¸° °æ¿ìÀÌ´Ù. (¶Ç´Â ±× ÀÌÈÄ¿¡ ´Ù½Ã start api È£Ãâ..) desc´Â ÀÌ¹Ì Çڵ鿡¼­ detach µÇ¾ú±â ¶§¹®¿¡ ¿ì¸® ¼Ò°üÀÌ´Ù. free ÇØÁà¾ß ÇÑ´Ù. */ if (ctx->hDsiCtl != psiCtl) { // ÀÌ psictlÀº ÀÌ¹Ì stop µÈ invalid handle ÀÏ °ÍÀÓ. dprint(0, "!! dsi received, but psictl mismatch ours %x event %x\n", ctx->hDsiCtl, psiCtl); psiCtl = (tDHL_PSI_ControlHandle)0; goto label_end; } //-------- ÆÄ½Ì.. dprint(2, " parse dsi..\n"); if (dprintable(2)) { // dsi dump int size = ((desc->sectPtr[0][1] & 0xf)<<8UL) | desc->sectPtr[0][2]; memdump(desc->sectPtr[0], size+3, ""); } dhr = DLIB_SDDS_ParseDsiSection(desc->sectPtr[0], &dsi); DHL_ASSERT(dhr == DHL_OK && dsi != NULL, ""); DHL_PSI_FreePSIData(desc); desc = NULL; //-------- ³»¿ë Ç¥½Ã.. if (dprintable(2)) { DLIB_SDDS_PrintDsiSection(dsi, 0); } // dsi sanity check. // ¸ðµç table consistency´Â MW ·¹º§¿¡¼­ ´Ù½Ã üũÇϵµ·Ï ÇÑ´Ù. #if SDDS_ENABLE_SECTION_SYNTAX_CHECK DHL_ASSERT(dsi->numberOfGroups > 0, ""); DHL_ASSERT(dsi->groups != NULL, ""); if (!dsi->groups || dsi->numberOfGroups <= 0) { dprint(0, "!! invalid dsi, num_group %d\n", dsi->numberOfGroups); // ´Ù½Ã ¹Þ¾Æµµ ¸¶Âù°¡Áö ÀÏ °ÍÀ̹ǷΠ±×³É Áß´Ü. // dsi ¸ð´ÏÅÍ´Â continuous ¸ðµå·Î ¹Þ°í ÀÖÀ¸¹Ç·Î »¡¸® Áß´Ü. sdds_stop_monitor(&ctx->hDsiCtl); goto label_end; } #endif // SDDS_ENABLE_SECTION_SYNTAX_CHECK //------- ÀÌ¹Ì ¹ÞÀº dsi¿Í µ¿ÀÏÇÑ °ÍÀ» ¶Ç ¼ö½Å ÇßÀ» ¼öµµ ÀÖÀ¸¹Ç·Î üũ. if (ctx->dsi) { do { /* ¾î´À Á¤µµ ±îÁö ÀÚ¼¼È÷ ºñ±³ÇØ¾ß ÇÒ±î? ±×³É ¹öÀü ºñ±³¸¸À¸·Î µÇ´ÂÁö ¾Æ´Ï¸é byte compare°¡ ÇÊ¿äÇÑÁö.. todo.. */ if (!sdds_is_same_dsi(ctx->dsi, dsi)) { dprint(2, " dsi changed\n"); break; } dprint(2, " new dsi is same as old one\n"); // pause µÇ¾ú´Ù°¡ Àç½ÃÀÛ ÇÑ °æ¿ìÀ̰ųª, // ¹º°¡ ÇÊÅͰ¡ À߸ø µÇ¾î µ¿ÀÏÇÑ ¼½¼ÇÀÌ ¼ö½ÅµÈ °æ¿ìÀÌ´Ù. // ctx->dsi °¡ non-null À̶ó¸é ¹Ýµå½Ã ´ÙÀ½ Á¶°ÇÀÌ ¸¸Á·µÇ¾î¾ß ÇÑ´Ù. // 1. ctx->iGroup ÀÌ valid. // 2. ctx->groups ¹öÆÛ ÇÒ´ç ¿Ï·á // ÀÌ Á¶°ÇÀÌ ¸¸Á·µÇÁö ¾ÊÀ¸¸é ´Ù½Ã ½ÃÀÛÇØ¾ß ÇÔ. if (ctx->iGroup < 0 || ctx->iGroup >= ctx->dsi->numberOfGroups) { dprint(0, "!! iGroup %d invalid!\n", ctx->iGroup); break; } if (ctx->gi == NULL) { dprint(0, "!! ctx groupinfo null!\n"); break; } // dsi ¸¦ ´õ ÀÌ»ó ó¸®ÇÒ Çʿ䰡 ¾ø´Â °æ¿ìÀÌ´Ù. sdds_free_section(&dsi); // »õ·Î ¹ÞÀº dsi´Â ctx->dsi¿Í Áߺ¹µÈ °ÍÀ̹ǷΠfreeÇϰí // dii 󸮺ηΠ°£´Ù. goto monitor_dii; } while (0); /* dsi°¡ º¯°æ µÉ ¼ö ÀÖ´Â »óȲ: 1. ½ºÆ®¸²ÀÌ Áß°£¿¡ º¯°æ. (½ÇÇè½Ç »óȲ) 2. ¿À·¡Àü¿¡ ½Ç½Ã µÇ¾ú´ø sdds°¡ ¿Ï·á µÇÁö ¸øÇÏ°í ³²¾Æ ÀÖ´Ù°¡ ³ªÁßÀÇ »õ sdds ¹ß°ß. (°¡´É¼ºÀº Èñ¹Ú) */ // dsi°¡ º¯°æ µÈ °æ¿ì.. ¶Ç´Â ¹º°¡ ¹®Á¦°¡ »ý°Ü¼­ ´Ù½Ã reset ÇØ¾ß ÇÏ´Â °æ¿ì.. // ÀÌ ¸ðµç °æ¿ì°¡ »ç½Ç»ó ºñÁ¤»ó »óȲÀÌ´Ù. dprint(0, "!!!! dsi is changed. clean up first..\n"); // µ¿ÀÛ ÁßÀÎ ¸ðµç ÇÊÅ͸¦ ´Ù stop Çϰí, // ³»ºÎ¸¦ ¿ÏÀüÈ÷ reset ÇÑ´Ù. sdds_free_all_group_info(ctx); // ÀÌ ¾È¿¡¼­ reset ¾ÈµÇ´Â °ÍµéÀº hDsiCtl, dsi »ÓÀÌ´Ù. sdds_free_section(&ctx->dsi); //ctx->dsi = dsi; // group Á¤º¸¸¦ ´Ù ó¸®ÇÑ ÈÄ ¸Ç ³ªÁß¿¡ µî·ÏÇØ¾ß ÇÑ´Ù. // µÎ°³ÀÇ Áߺ¹ Æ÷ÀÎÅÍ´Â ÀÚÁ¦ÇÏ´Â °ÍÀÌ ¹Ù¶÷Á÷. sdds_user_call(eSDDS_CB_TYPE_ResetDownload, NULL); } else { // dsi¸¦ óÀ½ ¼ö½Å ÇÑ °æ¿ì.. dprint(2, " first dsi\n"); // Ȥ½Ã ³²¾Æ ÀÖÀ» Áö ¸ð¸£´Â ¸ðµç µ¥ÀÌÅ͸¦ »èÁ¦.. sdds_free_all_group_info(ctx); //ctx->dsi = dsi; // group Á¤º¸¸¦ ´Ù ó¸®ÇÑ ÈÄ ¸Ç ³ªÁß¿¡ µî·ÏÇØ¾ß ÇÑ´Ù. // µÎ°³ÀÇ Áߺ¹ Æ÷ÀÎÅÍ´Â ÀÚÁ¦ÇÏ´Â °ÍÀÌ ¹Ù¶÷Á÷. } //------------- ±×·ì ¼±Åà ---------- DHL_ASSERT(ctx->dsi == NULL && dsi != NULL, ""); /* */ iGroup = sdds_choose_group_from_dsi(dsi); if (iGroup < 0) { // ±×·ìÀÌ ¾ø´Ù¸é ÀÌ dsi´Â ¾µ¸ð ¾ø´Â µ¥ÀÌÅÍÀÌ´Ù. // ±×·¯³ª »èÁ¦¸¦ ÇÏ¸é »õ·Î¿î dsi ¼ö½ÅÀ» ÇÒ ¼ö ¾øÀ¸¹Ç·Î (trid) // ÀÏ´Ü keepÇÑ´Ù. //sdds_free_section(&dsi); ctx->dsi = dsi; dsi = NULL; sdds_free_all_group_info(ctx); goto monitor_dsi_change; } // iGroup ¼±ÅÃÀº ¿Ï·á. DHL_ASSERT(iGroup >= 0 && iGroup < dsi->numberOfGroups, ""); //-------- ±×·ì ±¸Á¶Ã¼ ¸Þ¸ð¸® ÇÒ´ç ¹× ÃʱâÈ­.. if (1) { // ¿ì¸®°¡ °ü½ÉÀÖ´Â ±×·ì Çϳª¸¸ ó¸®.. ctx->gi = DHL_OS_Malloc(sizeof(S_SDDS_GroupInfo)); DHL_ASSERT(ctx->gi != NULL, ""); dprint(2, " groupinfo: 0x%x\n", ctx->gi); ctx->gi->groupId = dsi->groups[iGroup].groupId; } //-------- dsi ó¸® ¿Ï·á ------------ ctx->dsi = dsi; dsi = NULL; // °ü¸® ÆíÀǸ¦ À§ÇØ ÇϳªÀÇ Æ÷ÀÎÅ͸¸ »ç¿ë. ctx->iGroup = iGroup; //-------- dsi ±âŸ Á¤º¸ ------------ if (ctx->dsi->groups[iGroup].scheduleDescriptor.numSchedules > 0) { // schedule Á¤º¸ ¾Ë·ÁÁÜ. sdds_user_call(eSDDS_CB_TYPE_NotifySchedules, &ctx->dsi->groups[iGroup].scheduleDescriptor); // schedule Á¤º¸¿Í »ó°ü ¾øÀÌ, Ç×»ó ´ÙÀ½ ´Ü°è·Î ÁøÇàÇÑ´Ù. // schedule Á¤º¸´Â standby »óÅ¿¡¼­ app¿¡¼­ »ç¿ëÇÒ °ÍÀÓ. } //-------- dii ¸ð´ÏÅÍ ½ÃÀÛ --------- monitor_dii: // ÀÌ ½ÃÁ¡ºÎÅÍ´Â dsi ´Â »ç¿ëÇÏÁö ¾Ê°í, ctx->dsi ¸¸ »ç¿ëÇϵµ·Ï ÇÏÀÚ. (°ü¸® ÆíÀÇ) DHL_ASSERT(dsi == NULL, ""); DHL_ASSERT(ctx->gi != NULL, ""); if (1) { S_SDDS_GroupInfo *gi = ctx->gi; dprint(2, " processing group id 0x%x..\n", gi->groupId); //-------- ±âÁ¸ dii ¸ð´ÏÅÍ stop. /* comment »õ dsi°¡ ¼ö½ÅµÇ¸é ¹«Á¶°Ç ±âÁ¸ monitor´Â restart Çϵµ·Ï ÇÏÀÚ. groupId µîÀÇ º¯°æ ¿©ºÎ¸¦ Ã¼Å©ÇØ¼­ ¼±ÅÃÀûÀ¸·Î restart ÇØµµ µÇÁö¸¸, ¸Å¹ø restart ÇØµµ Å©°Ô ¹®Á¦µÇÁö ¾ÊÀ» µí ÇÔ. ³í¸®ÀûÀ¸·Î dii ctlÀÌ ³²¾Æ ÀÖÀ» ¼öµµ ÀÖ´Ù. stop ¾øÀÌ start api¸¦ ¿¬¼Ó ºÎ¸£¸é.. */ if (gi->hDiiCtl) { dprint(0, "!! cancel old dii monitor.. %x\n", gi->hDiiCtl); sdds_stop_monitor(&gi->hDiiCtl); } //-------- dii ¸ð´ÏÅÍ ½ÃÀÛ. // óÀ½¿¡´Â table_id_extension ÇÊÅÍ ¾øÀÌ ¸ðµÎ ¹Þ´Â´Ù. // dprint(2, " monitor dii with groupid 0x%x..\n", gi->groupId); dhr = DLIB_SDDS_MonitorDii(ctx->tsd, ctx->pid, gi->groupId, ePSIUPDATE_ONESHOT, SDDS_DiiCallback, 0, &gi->hDiiCtl); DHL_ASSERT(dhr == DHL_OK, ""); } monitor_dsi_change: /* comment dsi change¸¦ hardwareÀûÀ¸·Î filtering Çϸé ÁÁÀºµ¥ top-level dsi´Â ¸¹Àº bit°¡ 0À¸·Î °íÁ¤À̹ǷΠtable_id_extension ¸¸À» »ç¿ëÇÒ °æ¿ì LSB 1bit ¹Û¿¡ »ç¿ëÇÒ ¼ö ¾ø´Ù. ¸¸¾à dsi1 --> dsi2 --> dsi3 °ú °°ÀÌ ¼¼¹ø º¯°æÀÌ µÇ°í Àִµ¥, dsi2 ºÎºÐ¿¡ ½ÅÈ£ »óÅ µîÀÌ ¾ÊÁÁ¾Æ¼­ dsi2¸¦ ¹ÞÁö ¸øÇß´Ù¸é dsi3´Â ¸ø¹ÞÀ» ¼öµµ ÀÖ´Ù. Á¦´ë·Î ÇÏ·Á¸é transaction_id ÀÇ version field(14bit)¸¦ filter·Î °É¸é µÈ´Ù. HAL¿¡¼­ Áö¿øµÇ´ÂÁö¿¡ µû¶ó »ç¿ë °¡´É ¿©ºÎ°¡ ´Þ¶óÁø´Ù. ÇÏÁö¸¸ À§ ¿¹¿¡¼­¿Í °°ÀÌ dsi3¸¦ ¸ø¹Þ´Â »óȲ¿¡¼­µµ stop & start¸¦ ÇÏ¸é ´Ù½Ã ¹Þ°Ô µÈ´Ù. (´Ù¸¥ ä³Î¿¡ ´Ù³à¿À¸é ¹Þ´Â ´Ù´Â ÀǹÌ) µû¶ó¼­ 1 bit ¸¸ monitorÇØµµ µÉ µí ÇÏ´Ù. */ // ÇöÀçÀÇ dsi¸¦ ±âÁØÀ¸·Î »õ·Î¿î dsi¸¦ monitorÇÑ´Ù. DHL_ASSERT(ctx->dsi != NULL, ""); sdds_stop_monitor(&ctx->hDsiCtl); //-------- »õ·Î¿î dsi ¸ð´ÏÅÍ. // dsi´Â ¹öÀüÀÌ ¿Ã¶ó°¥ ¶§ ¸¶´Ù transactionIdÀÇ ¸¶Áö¸· LSB°¡ toggleµÈ´Ù. dprint(2, " monitor dsi with new trid %x..\n", ctx->dsi->transactionId ^ 1); dhr = DLIB_SDDS_MonitorDsi(ctx->tsd, ctx->pid, ctx->dsi->transactionId ^ 1, ePSIUPDATE_CONTINEOUS, SDDS_DsiCallback, 0, &ctx->hDsiCtl); DHL_ASSERT(dhr == DHL_OK, ""); label_end: if (dsi){ // ¿©±â±îÁö dsi°¡ Èê·¯¿Â °Å¸é Á¤»ó »óȲÀÌ ¾Æ´Ô. sdds_free_section(&dsi); } if (desc) { DHL_PSI_FreePSIData(desc); desc = NULL; } } /* */ void SDDS_HandleEvtProcessDii(tDHL_PSI_ControlHandle psiCtl, tDHL_PSI_DataArray *desc) { DHL_RESULT dhr; int iModule; int nModuleToDownload; int nModuleCompleted; int nBlocksToDownload; S_SDDS_Context *ctx; S_SDDS_GroupInfo *gi = NULL; sddsDiiPtr_t dii = NULL; int i; dprint(2, "%s\n", __FUNCTION__); //-------- parameter checking //-------- get context ctx = sdds_get_context(); gi = ctx->gi; //-------- check if we are too late //if ( ) return; // check psictl is valid /* event󸮰¡ ´Ê¾îÁø »óȲ¿¡¼­: reset api°¡ È£ÃâµÇ¾ú´Ù¸é gi°¡ null stop api°¡ È£ÃâµÇ¾ú´Ù¸é psictlÀÌ ´Þ¶óÁü. */ if (gi == NULL) { dprint(0, "!! dii without groupinfo\n"); // app ¿¡¼­ ResetÀ» ÇßÀ» ¼öµµ ÀÖÀ½. goto label_end; // ±×³É Á¶¿ëÈ÷ ¹«½Ã.. } if (gi->hDiiCtl != psiCtl) { // app ¿¡¼­ Reset ¶Ç´Â Stop À» ÇßÀ» ¼öµµ ÀÖÀ½. // ÀÌ psictlÀº ÀÌ¹Ì stop µÈ invalid handle ÀÏ °ÍÀÓ. dprint(0, "!! dii received, but psictl mismatch %x %x\n", gi->hDiiCtl, psiCtl); psiCtl = (tDHL_PSI_ControlHandle)0; goto label_end; // ±×³É Á¶¿ëÈ÷ ¹«½Ã.. } //-------- ÆÄ½Ì.. dprint(2, " parse dii..\n"); if (dprintable(2)) { int size = ((desc->sectPtr[0][1] & 0xf)<<8UL) | desc->sectPtr[0][2]; memdump(desc->sectPtr[0], size+3, ""); } dhr = DLIB_SDDS_ParseDiiSection(desc->sectPtr[0], &dii); DHL_ASSERT(dhr == DHL_OK && dii != NULL, ""); DHL_PSI_FreePSIData(desc); desc = NULL; //-------- ³»¿ë Ç¥½Ã.. if (dprintable(2)) { DLIB_SDDS_PrintDiiSection(dii, 0); } #if SDDS_ENABLE_SECTION_SYNTAX_CHECK DHL_ASSERT(dii->numberOfModules > 0, ""); DHL_ASSERT(dii->modules != NULL, ""); if (!dii->modules || dii->numberOfModules == 0) { dprint(0, "!! invalid dii, num module %d\n", dii->numberOfModules); // ÀÌ dii´Â invalid ÇϹǷÎ, ´ÙÀ½ ¹öÀü upµÇ±â¸¦ ±â´Ù·Á¾ß ÇÔ. // ¹öÀü º¯°æÀº dsi ºÎÅÍ ´Ù½Ã ½ÃÀÛÇϹǷÎ, ÀÌ dii psictlÀº Áß´Ü. sdds_stop_monitor(&gi->hDiiCtl); goto label_end; } #endif // SDDS_ENABLE_SECTION_SYNTAX_CHECK //-------- ÇöÀçÀÇ context »óȲ üũ. // ¾Æ·¡ °¢Á¾ ¸Þ½ÃÁöµéÀº ÀϹÝÀûÀÎ »óȲ¿¡¼­´Â ¹ß»ýµÇÁö ¾Ê¾Æ¾ß ÇÏÁö¸¸, // °úºÎÇÏ »óÅ¿¡¼­´Â ÃæºÐÈ÷ ¹ß»ý °¡´ÉÇÑ °ÍµéÀÓ. // // ¿¹·Î continuous ¸ðµå·Î ¼ö½ÅÇϸ鼭 (dii callback ÀÌ °è¼Ó ºÒ¸²) // ÀÌ taskÀÇ Ã³¸®°¡ ´Ê¾îÁö¸é (ÀÌ task ¿¡¼­ dii psictl stop) // queue ¿¡ ½×¿© ÀÖ´ø dii callbackÀÌ µÚ´Ê°Ô ¿Ã ¼ö ÀÖ´Ù. if (ctx->dsi == NULL) { dprint(0, "!! dii without dsi\n"); // app ¿¡¼­ ResetÀ» ÇßÀ» ¼öµµ ÀÖÀ½. goto label_end; // ±×³É Á¶¿ëÈ÷ ¹«½Ã.. } if (gi->groupId != dii->transactionId) { // ÀÌ·± °æ¿ì´Â µå¹°´Ù.. dii´Â ƯÁ¤ trid·Î ÁöÁ¤ ¼ö½ÅÇÔ. dprint(0, "!! new dii's trid %x not matched of group id %x\n", dii->transactionId, gi->groupId); // 󸮰¡ ´Ê¾îÁ®¼­ ¹ß»ýÇÑ °æ¿ì¶ó¸é ±×³É Á¶¿ëÈ÷ ¹«½ÃÇÏ¸é µÇ´Âµ¥, ±×·² °¡´É¼º ³·À½. // ±× ÀÌ¿ÜÀÇ °æ¿ì¶ó¸é, ´õ ¹Þ¾Æ ºÃÀÚ ¶È°°À¸´Ï psictl Áß´Ü. sdds_stop_monitor(&gi->hDiiCtl); goto label_end; } //-------- dii filtering // no filtering required. //-------- ±âÁ¸ dii ¿ÍÀÇ ºñ±³. º¯°æ »çÇ× Ã¼Å©. if (gi->dii) { do { if (!sdds_is_same_dii(gi->dii, dii)) break; // Á¤¸»·Î ¸ðµç °ÍÀÌ ´Ù µ¿ÀÏÇÑÁö Çϳª¾¿ ´Ù½Ã üũ.. if (gi->numModules != dii->numberOfModules) { dprint(0, "!! num module changed %u %u\n", gi->numModules, dii->numberOfModules); break; } for (i=0; inumModules; i++) { //if (gi->mi[i].moduleBuffer == NULL) break; if (gi->mi[i].moduleId != dii->modules[i].moduleId) break; if (gi->mi[i].moduleSize != dii->modules[i].moduleSize) break; } if (inumModules) { dprint(0, "!! module info [%d] changed\n", i); break; } dprint(2, " new dii is same as old one\n"); // ok. dii ¿Í mi Á¤º¸´Â ¿ÏÀüÈ÷ µ¿ÀÏÇÏ´Ù°í º¼ ¼ö ÀÖÀ½. // dii ´Â gi->dii ¿Í Áߺ¹µÈ´Ù°í º¸°í »èÁ¦ Çϰí ddb ¸ð´ÏÅÍ·Î jump.. sdds_free_section(&dii); goto download_start; } while(0); dprint(0, " module info or dii changed. reset!\n"); sdds_free_all_module_info(gi); sdds_free_section(&gi->dii); // user¿¡°Ôµµ ÀÌ »ç½ÇÀ» ¾Ë·ÁÁÜ. sdds_user_call(eSDDS_CB_TYPE_ResetDownload, NULL); } else { dprint(2, " first dii\n"); sdds_free_all_module_info(gi); } //-------- ¸ðµâ ±¸Á¶Ã¼ ¸Þ¸ð¸® ÇÒ´ç ¹× ÃʱâÈ­.. DHL_ASSERT(gi->dii == NULL && dii != NULL, ""); DHL_ASSERT(gi->mi == NULL, ""); dprint(2, " alloc %d module info..\n", dii->numberOfModules); gi->mi = DHL_OS_Malloc(dii->numberOfModules * sizeof(S_SDDS_ModuleInfo)); DHL_ASSERT(gi->mi != NULL, ""); gi->blockSize = dii->blockSize; gi->numModules = dii->numberOfModules; for (iModule=0; iModulenumModules; iModule++) { S_SDDS_CBPARAM_CHECK_FILE fileinfo; S_SDDS_ModuleInfo *mi = &gi->mi[iModule]; dprint(2, " processing module[%d]..\n", iModule); // application query callback sdds_prepare_module_info(iModule, &dii->modules[iModule], &fileinfo); //-------- module Á¤º¸ callback. accept ¿©ºÎ query. fileinfo.isOk = FALSE; sdds_user_call(eSDDS_CB_TYPE_CheckModuleInfo, &fileinfo); if (fileinfo.isOk) { dprint(2, " module accepted\n"); mi->bNeedToDownload = TRUE; } else { dprint(2, " !! user denied this module\n"); mi->bNeedToDownload = FALSE; } //-------- ¸ðµâ »óÅ º¯¼ö mi->moduleId = fileinfo.id; mi->moduleSize = fileinfo.size; mi->moduleName = fileinfo.name; mi->moduleSignature = fileinfo.version; // ºí·°ÀÇ °¹¼ö´Â (moduleSize+dii->blockSize-1)/dii->blockSize ÀÌ´Ù. // ¸Ç ¸¶Áö¸· blockÀÇ Å©±â´Â blockSize º¸´Ù ÀûÀ» ¼ö ÀÖ´Ù. mi->numberOfBlocks = (mi->moduleSize + dii->blockSize-1)/dii->blockSize; mi->bDownloadCompleted = FALSE; /* ¹öÆÛ °ü¸®´Â app ¿¡¼­ Çϵµ·Ï Á¤Ã¥ º¯°æ. ¹öÆÛ¸¦ MW¿¡¼­ ÇÏ°Ô µÇ¸é ³ªÁß¿¡ buffer free¸¦ À§ÇÑ º°µµÀÇ api°¡ ÇÊ¿äÇÏ°Ô µÊ. */ #if 0 //-------- ¸ðµâ ¹öÆÛ ¸Þ¸ð¸® ÇÒ´ç.. // ´Ù¿î·Îµå ¹ÞÀ» ºí·°ÀÌ ÀúÀåµÉ ¹öÆÛ °ø°£. Å©±â´Â moduleSize ¹ÙÀÌÆ®. dprint(2, " alloc module buffers.. %u bytes..\n", mi->moduleSize); // todo.. // ¿ä±¸ ÇÏ´Â ¸Þ¸ð¸® Å©±â°¡ ¾öû Ŭ ¼öµµ ÀÖÀ½.. üũ ¿ä¸Á.. if (mi->moduleSize > SDDS_MAX_MODULE_SIZE) { dprint(2, "!! module size exceed max\n"); } else { mi->moduleBuffer = DHL_OS_Malloc(mi->moduleSize); DHL_ASSERT(mi->moduleBuffer != NULL, ""); } #endif //mi->completedFlags[65536/8]; memset(mi->completedFlags, 0, sizeof(mi->completedFlags)); } //-------- dii ó¸® ¿Ï·á ------------ gi->dii = dii; dii = NULL; download_start: DHL_ASSERT(gi->dii != NULL && dii == NULL, ""); //-------- ddb ¸ð´ÏÅÍ Áغñ.. for (iModule=0, nModuleToDownload=0, nBlocksToDownload=0; iModulenumModules; iModule++) { S_SDDS_ModuleInfo *mi = &gi->mi[iModule]; //-------- ±âÁ¸ ddb ¸ð´ÏÅÍ ÁßÁö. // »õ dii°¡ ¼ö½ÅµÇ¸é ¹«Á¶°Ç ±âÁ¸ monitor´Â restart Çϵµ·Ï ÇÏÀÚ. if (mi->hDdbCtl0) { dprint(2, " cancel old ddb0 monitor[%d] 0x%x..\n", iModule, mi->hDdbCtl0); sdds_stop_monitor(&mi->hDdbCtl0); } if (mi->hDdbCtl1) { dprint(2, " cancel old ddb1 monitor[%d] 0x%x..\n", iModule, mi->hDdbCtl1); sdds_stop_monitor(&mi->hDdbCtl1); } /* ¹öÀü µîÀ» È®ÀÎÇÏ¿© download°¡ ÇÊ¿ä ¾ø´Â ÆÄÀϵéÀº º°µµ·Î check¸¦ ÇØ µÎ¾úÀ½. */ if (!mi->bNeedToDownload) continue; if (mi->bDownloadCompleted) { nModuleCompleted++; continue; } nModuleToDownload ++; nBlocksToDownload += mi->numberOfBlocks; } if (nModuleToDownload > 0) { // ÀÌÁ¦ ddb monitor¸¦ ½ÃÀÛÇÏ¸é ¹Ù·Î blonk ¼ö½ÅÀÌ ½ÃÀ۵ȴÙ. // ÀÌ ½ÃÁ¡¿¡¼­ download start callback ¾Ë¸². S_SDDS_CBPARAM_DOWNLOAD_START param; param.total_blocks = nBlocksToDownload; sdds_user_call(eSDDS_CB_TYPE_DownloadStarted, ¶m); } else if (nModuleCompleted > 0) { dprint(2, " all modules downloaded already\n"); sdds_user_call(eSDDS_CB_TYPE_DownloadCompleted, (void *)(-1)); goto monitor_dii_change; } else { dprint(2, " no modules to download\n"); sdds_user_call(eSDDS_CB_TYPE_DownloadNotRequired, NULL); goto monitor_dii_change; } //-------- ddb ¸ð´ÏÅÍ ½ÃÀÛ. for (iModule=0; iModulenumModules; iModule++) { S_SDDS_ModuleInfo *mi = &gi->mi[iModule]; //-------- ±âÁ¸ ddb ¸ð´ÏÅÍ ÁßÁö. // »õ dii°¡ ¼ö½ÅµÇ¸é ¹«Á¶°Ç ±âÁ¸ monitor´Â restart Çϵµ·Ï ÇÏÀÚ. if (mi->hDdbCtl0) sdds_stop_monitor(&mi->hDdbCtl0); if (mi->hDdbCtl1) sdds_stop_monitor(&mi->hDdbCtl1); if (!mi->bNeedToDownload) { dprint(2, " module[%d] download skipped\n", iModule); continue; } #if SDDS_ENABLE_DDB_RX_INTERLEAVING dprint(2, " start monitor ddb_0 [%d]..\n", iModule); dhr = DLIB_SDDS_MonitorDdb(ctx->tsd, ctx->pid, mi->moduleId, eDDB_RIM_Even, ePSIUPDATE_CONTINEOUS, SDDS_DdbCallback, 0, &mi->hDdbCtl0); DHL_ASSERT(dhr == DHL_OK, ""); dprint(2, " start monitor ddb_1 [%d]..\n", iModule); dhr = DLIB_SDDS_MonitorDdb(ctx->tsd, ctx->pid, mi->moduleId, eDDB_RIM_Odd, ePSIUPDATE_CONTINEOUS, SDDS_DdbCallback, 0, &mi->hDdbCtl1); DHL_ASSERT(dhr == DHL_OK, ""); #else dprint(2, " start monitor ddb[%d]..\n", iModule); dhr = DLIB_SDDS_MonitorDdb(ctx->tsd, ctx->pid, mi->moduleId, eDDB_RIM_All, ePSIUPDATE_CONTINEOUS, SDDS_DdbCallback, 0, &mi->hDdbCtl0); DHL_ASSERT(dhr == DHL_OK, ""); // ÀÎÅ͸®ºù ¼ö½ÅÀ» ÇÏÁö ¾Ê´Â´Ù¸é hDdbCtl1 Àº »ç¿ëÇÏÁö ¾Ê´Â´Ù. #endif } monitor_dii_change: DHL_ASSERT(gi->dii != NULL, ""); sdds_stop_monitor(&gi->hDiiCtl); // dii°¡ ¹Ù²î¸é dsiµµ °°ÀÌ ¹Ù²î´Ï±î ±»ÀÌ ¸ð´ÏÅ͸¦ °ÉÁö ¾Ê¾Æµµ µÉ µí ÇÔ.. label_end: if (dii) { // ctx¿¡ µî·ÏµÇÁö ¾Ê°í ¿©±â±îÁö Èê·¯¿Â dii´Â ¹ö·Á¾ß ÇÔ. sdds_free_section(&dii); } if (desc) { // ¿¡·¯ ¹ß»ý½Ã ¿©±â¼­ desc°¡ free µÊ. DHL_PSI_FreePSIData(desc); desc = NULL; } } /* */ void SDDS_HandleEvtProcessDdb(tDHL_PSI_ControlHandle psiCtl, tDHL_PSI_DataArray *desc) { DHL_RESULT dhr; S_SDDS_Context *ctx; S_SDDS_GroupInfo *gi = NULL; S_SDDS_ModuleInfo *mi = NULL; sddsDdbPtr_t ddb = NULL; int i, iModule; UINT32 received_blocks; dprint(2, "%s\n", __FUNCTION__); //-------- parameter checking //-------- get context ctx = sdds_get_context(); //-------- check if we are too late //if ( ) return; // check psictl is valid gi = ctx->gi; if (gi == NULL) { dprint(0, "!! ddb without groupinfo\n"); goto label_end; } if (gi->mi == NULL || gi->numModules <= 0) { dprint(0, "!! ddb without moduleinfo\n"); goto label_end; } /* psictlÀÌ À¯È¿ÇÑ °ÍÀÎÁö¸¦ °Ë»çÇØ¾ß Çϴµ¥, mi->hDdbCtl ¿¡ ÀúÀµÇ¾?ÀÖ´Ù. ±×·¯³ª ÀÌ ½ÃÁ¡¿¡¼­ mi¸¦ ãÀ» ¼ö´Â ¾ø´Ù. ¾î´À module ÀÇ µ¥ÀÌÅÍÀÎÁö¸¦ ¾Ë·Á¸é ddb¸¦ parsing ÇØ¼­ ddb->moduleId ¿Í ÀÏÄ¡ÇÏ´Â moduleÀ» ã¾Æ¾ß ÇÑ´Ù. ±×·¡¼­ ¼ø¼­°¡ ´Ù¸¥ handler¿Í Á» ´Ù¸£´Ù. ÀÏ´Ü parsing ºÎÅÍ ÇØ ºÁ¾ß ÇÑ´Ù. ÀÌ¹Ì À߸øµÈ psictlÀ̶ó¸é ¾û¶×ÇÑ µ¥ÀÌÅÍÀÏ ¼ö ÀÖ´Ù. (ddb°¡ ¾Æ´Ï¶ó pat ¶óµç°¡..) HAL¿¡¼­ handleÀ» validate check ÇÏ´Â api¸¦ Á¦°øÇØ ÁÖ¸é ÁÁ´Ù. */ //-------- ÆÄ½Ì.. dprint(2, " parse ddb..\n"); dhr = DLIB_SDDS_ParseDdbSection(desc->sectPtr[0], &ddb); // ¿¡·¯°¡ ¹ß»ýÇÒ ¼öµµ ÀÖÀ½.. ´ëÃ¥ ÇÊ¿ä.. DHL_ASSERT(dhr == DHL_OK && ddb != NULL, ""); //-------- ³»¿ë Ç¥½Ã.. if (dprintable(2)) { DLIB_SDDS_PrintDdbSection(ddb, 0); } //-------- ÇöÀçÀÇ context »óȲ üũ. // ¾î´À ¸ðµâ¿¡ ¼ÓÇÑ ºí·°ÀÎÁö ã´Â´Ù. for (mi=NULL, iModule=0; iModulenumModules; iModule++) { if (gi->mi[iModule].moduleId == ddb->moduleId) { mi = &gi->mi[iModule]; break; } } if (mi == NULL) { dprint(0, "!! cannot find related module\n"); goto label_end; } if (mi->hDdbCtl0 != psiCtl && mi->hDdbCtl1 != psiCtl) { dprint(0, "!! ddb received, but psictl mismatch 0:%x 1:%x this:%x\n", mi->hDdbCtl0, mi->hDdbCtl1, psiCtl); psiCtl = (tDHL_PSI_ControlHandle)0; // ÀÌ¹Ì stop µÈ ÇÚµéÀÓ. goto label_end; // ±×³É Á¶¿ëÈ÷ ¹«½Ã.. } dprint(2, " this block is from module[%d], moduleId 0x%x, ddbctl %d\n", iModule, mi->moduleId, psiCtl==mi->hDdbCtl0 ? 0 : 1); //------- block °Ë»ç ¹× ó¸®.. // ¾î¶² °æ¿ì? // ÀÌ¹Ì reset µÈ °æ¿ì ¹Û¿¡ ¾øÀ» µí ÇÔ.. resetÀº À§¿¡¼­ °É·¯Áö´Âµ¥. ÀÏ´Ü Ã¼Å©ÇÏÀÚ. if (mi->bNeedToDownload == FALSE) { dprint(0, "!! ddb with non-necessary module?\n"); //DHL_ASSERT(FALSE, ""); goto label_end; } // block number ¹üÀ§ üũ. if (ddb->blockNumber >= mi->numberOfBlocks) { dprint(0, "!! ddb block# %u exceed max %u. moduleSize %u\n", ddb->blockNumber, mi->numberOfBlocks, mi->moduleSize); goto label_end; } // block data size üũ. ¸ðµâÀÇ ¸¶Áö¸· blockÀ» Á¦¿ÜÇϰí´Â ¸ðµÎ ¹Ì¸® ¾Ë·ÁÁø Á¤º¸¿Í ÀÏÄ¡ÇØ¾ß ÇÔ. if ((ddb->blockNumber < mi->numberOfBlocks-1 && ddb->blockDataLength != gi->blockSize) || (ddb->blockNumber == mi->numberOfBlocks-1 && ddb->blockDataLength > 4066)) { dprint(0, "!! ddb block (blk# %u) data len %u invalid\n", ddb->blockNumber, ddb->blockDataLength); goto label_end; } // ±â ¼ö½Å ¿©ºÎ üũ. if (mi->completedFlags[ddb->blockNumber/8] & (1 << ddb->blockNumber%8)) { dprint(1, " block #%u (moduleId %u) already received, %d/%u\n", ddb->blockNumber, mi->moduleId, sdds_rx_blk_count(mi), mi->numberOfBlocks); // cafrii 100819 fix // ÀÌ¹Ì ¼ö½Å ¿Ï·á »óÅ¿¡¼­ caller°¡ ´Ù½Ã start ÇßÀ» ¼öµµ ÀÖÀ¸¹Ç·Î // ¸Å block ¼ö½Å ¸¶´Ù complete üũ¸¦ Çϵµ·Ï ÇÏÀÚ. received_blocks = sdds_rx_blk_count(mi); goto label_check_complete; } mi->completedFlags[ddb->blockNumber/8] |= (1 << ddb->blockNumber%8); // ¼ö½Å Á¤µµ Ç¥½Ã.. received_blocks = sdds_rx_blk_count(mi); dprint(1, " %d/%u ddb blks received\n", received_blocks, mi->numberOfBlocks); //------- application callback if (1) { S_SDDS_CBPARAM_BLOCK_RECEIVED cbp; memset(&cbp, 0, sizeof(cbp)); cbp.ddb = ddb; cbp.idxblk = ddb->blockNumber; cbp.offset = ddb->blockNumber*gi->blockSize; cbp.received_blocks = received_blocks; cbp.total_blocks = mi->numberOfBlocks; sdds_user_call(eSDDS_CB_TYPE_BlockReceived, &cbp); } label_check_complete: // ´Ù ¼ö½Å µÈ °Å¶ó¸é ¿Ï·á. if (received_blocks == mi->numberOfBlocks) { dprint(2, " module[%d] download completed\n", iModule); sdds_stop_monitor(&mi->hDdbCtl0); sdds_stop_monitor(&mi->hDdbCtl1); mi->bDownloadCompleted = TRUE; sdds_user_call(eSDDS_CB_TYPE_DownloadCompleted, (void *)(UINT32)mi->moduleId); } // ¸ðµç module ÀÌ ´Ù¿î·Îµå ¿Ï·á µÇ¸é callback. if (1) { BOOL bAllCompleted = TRUE; for (i=0; inumModules; i++) { // Çϳª¶óµµ ´Ù ¾È¹ÞÀº ¸ðµâÀÌ ÀÖ´Ù¸é ¾Æ´Ô.. if (gi->mi[i].bNeedToDownload && !gi->mi[i].bDownloadCompleted) { bAllCompleted = FALSE; break; } } if (bAllCompleted) { dprint(2, " all modules are completed\n"); sdds_user_call(eSDDS_CB_TYPE_DownloadCompleted, (void *)-1); } } label_end: //-------- ¸¶¹«¸®.. // ddb ¼½¼ÇÀÇ Æ÷ÀÎÅÍ´Â ½ÇÁ¦·Î´Â ÀÌ desc ¾ÈÀÇ µ¥ÀÌÅ͸¦ ±×³É pointing ¸¸ ÇÑ °ÍÀÌ´Ù. // µû¶ó¼­ ddb ¼½¼ÇÀ» ´Ù Ȱ¿ëÇϱâ Àü±îÁö´Â ÀÌ desc¸¦ free ÇÏ¸é ¾ÈµÈ´Ù. // ²À ÇÊ¿äÇÏ´Ù¸é memcpy¸¦ ÇØ µÎ¾î¾ß Çϴµ¥, ±ÇÀåÇÏÁö ¾ÊÀ½.. if (desc) DHL_PSI_FreePSIData(desc); sdds_free_section(&ddb); } void SDDS_HandleEvtProcessDc(tDHL_PSI_ControlHandle psiCtl, tDHL_PSI_DataArray *desc) { dprint(2, "%s\n", __FUNCTION__); DHL_PSI_FreePSIData(desc); } #if COMMENT ____TaskWrapper____(){} #endif DHL_TMHANDLE g_sdds_task; #define DMW_SDDS_TASK_PRIO TASK_PRI_DMW_PSI #define DMW_SDDS_TASK_STACK 16384 /* proxy´Â timer stubµéÀ» º¸ÀÌÁö ¾Ê°Ô ÇØ ÁÖ´Â thin layer. command ¿Í event¸¦ ºÐ¸®Çϴ Ưº°ÇÑ ÀÌÀ¯´Â ¾øÀ½. ¸ðµç command/event¸¦ ´Ù ºÐ¸®ÇÒ ¼öµµ ÀÖ°í, (°¢°¢ÀÇ timer callback »ç¿ë) (--> Äڵ尡 ÁöÀúºÐ..) ¸ðµç command/event¸¦ ÇϳªÀÇ callback¿¡¼­ ó¸®ÇÒ ¼öµµ ÀÖ´Ù. (--> ¼º´É »óÀÇ ¼ÕÇØ..) ±×³É µÎ ±Ø´Ü ¿É¼ÇÀÇ Áß°£ Á¤µµ¸¦ »ç¿ëÇÔ.. */ void _sdds_task_proxy_cmd(UINT32 idTimer, UINT32 *param) { if (0); else if (idTimer == eSDDS_Cmd_Init) { dprint(2, "cmd init\n"); SDDS_HandleCmdInit((void *)param[0]); } else if (idTimer == eSDDS_Cmd_Start) { dprint(2, "cmd start\n"); SDDS_HandleCmdStart((tDHL_TSD)param[0], param[1]); } else if (idTimer == eSDDS_Cmd_Stop) { dprint(2, "cmd stop\n"); SDDS_HandleCmdStop(); } else if (idTimer == eSDDS_Cmd_Delete) { //dprint(2, "cmd delete\n"); SDDS_HandleCmdDelete(); } else if (idTimer == eSDDS_Cmd_GetStatus) { //dprint(2, "cmd get status\n"); //SDDS_HandleCmdGetStatus(param[0], param[1]); } else if (idTimer == eSDDS_Cmd_PrintStatus) { //dprint(2, "cmd print status\n"); SDDS_HandleCmdPrintStatus(param[0]); } else if (idTimer == eSDDS_Cmd_UserAction) { SDDS_HandleCmdUserAction(param[0]); } else if (idTimer == eSDDS_Cmd_Shutdown) { //dprint(2, "cmd shutdown\n"); //SDDS_HandleCmdShutdown(param[0], param[1]); } else dprint(0, "!! unknown cmd 0x%x\n", idTimer); } void _sdds_task_proxy_event(UINT32 idTimer, UINT32 *param) { if (0); else if (idTimer == eSDDS_Evt_DSI) { dprint(2, "dsi msg\n"); SDDS_HandleEvtProcessDsi((tDHL_PSI_ControlHandle)param[0], (tDHL_PSI_DataArray *)param[1]); } else if (idTimer == eSDDS_Evt_DII) { dprint(2, "dii msg\n"); SDDS_HandleEvtProcessDii((tDHL_PSI_ControlHandle)param[0], (tDHL_PSI_DataArray *)param[1]); } else if (idTimer == eSDDS_Evt_DDB) { dprint(2, "ddb msg\n"); SDDS_HandleEvtProcessDdb((tDHL_PSI_ControlHandle)param[0], (tDHL_PSI_DataArray *)param[1]); } else if (idTimer == eSDDS_Evt_DC) { dprint(2, "dc msg\n"); SDDS_HandleEvtProcessDc((tDHL_PSI_ControlHandle)param[0], (tDHL_PSI_DataArray *)param[1]); } else dprint(0, "!! unknown evt 0x%x\n", idTimer); } STATUS sdds_task_send_cmd(E_SDDS_Command cmd, UINT32 p0, UINT32 p1, BOOL bWait) { DHL_RESULT dhr; UINT32 params[4]; params[0] = p0; params[1] = p1; dhr = DHL_TIMER_StartEx( g_sdds_task, cmd, 0, /* zero period ==> dpc */ _sdds_task_proxy_cmd, 2, params, eTIMER_FLAG_OneShot); if (bWait) DHL_TIMER_Sync(g_sdds_task); return dhr ? statusError : statusOK; } STATUS sdds_task_send_event(E_SDDS_Command evt, UINT32 p0, UINT32 p1) { DHL_RESULT dhr; UINT32 params[4]; params[0] = p0; params[1] = p1; dhr = DHL_TIMER_StartEx( g_sdds_task, evt, 0, /* zero period ==> dpc */ _sdds_task_proxy_event, 2, params, eTIMER_FLAG_OneShot); return dhr ? statusError : statusOK; } void sdds_task_init(void) { DHL_RESULT dhr; DHL_TIMER_INIT_PARAM param; //dhl_timer_module_init(); // DHL_SYS_Timer ´Â ¹Ì¸® ÃʱâÈ­ µÇ¾ú´Ù°í °¡Á¤. if (g_sdds_task) return; // dhl timer already initialized. memset(¶m, 0, sizeof(DHL_TIMER_INIT_PARAM)); param.max_timer_entry = 2; // ÇöÀç´Â ¸ðµÎ dpc ·Î¸¸ »ç¿ëÇϹǷÎ, ¸¹ÀÌ ÇÊ¿ä ¾øÀ½. param.name = "sdds"; param.task_priority = DMW_SDDS_TASK_PRIO; param.stack_size = DMW_SDDS_TASK_STACK; param.use_mutex_lock = 0; // we should support ISR!! param.num_user_param = 2; param.msg_que_size = 32; dhr = DHL_TIMER_Initialize(¶m, &g_sdds_task); DHL_ASSERT(dhr == DHL_OK, ""); dprint(2, "sdds task init..\n"); } #if COMMENT ____Debug____(){} #endif #if COMMENT ____Symbol____(){} #endif #if DHL_REGISTER_DEUBG_SYMBOLS static DHL_SymbolTable _symbols[] = { /* however, if you want typing short-cut, it is good usage. DHL_FNC_SYM_ENTRY2("epg_start", App_EpgUpdateStart), DHL_FNC_SYM_ENTRY2("epg_stop", App_EpgUpdateCancel), DHL_FNC_SYM_ENTRY2("epg_list", Dmc_EpgPrintAllTables), DHL_FNC_SYM_ENTRY2("epg_delete", App_EpgDeleteAll), DHL_VAR_SYM_ENTRY(g_XX_TestMode), */ 0, }; #endif /* DHL_REGISTER_DEUBG_SYMBOLS */ #if COMMENT ____Init____(){} #endif void DMW_SDDS_Init(void) { //STATUS status; #if DHL_REGISTER_DEUBG_SYMBOLS DHL_DBG_RegisterSymbols(_symbols, DHL_NUMSYMBOLS(_symbols)); #endif /* °¢Á¾ init code.. */ sdds_task_init(); // bwait ¸ðµå »ç¿ë½Ã ÁÖÀÇ. user action command (flashing) ÀÛ¾÷Àº ¿À·¡ °É¸± ¼ö ÀÖÀ¸¹Ç·Î.. // sdds init Àº óÀ½ init task ¿¡¼­ 1ȸ¸¸ ºÒ¸®¹Ç·Î ±¦ÂúÀ½. sdds_task_send_cmd(eSDDS_Cmd_Init, 0, 0, TRUE); // jump to SDDS_HandleCmdInit } void DMW_SDDS_RegisterCallback(F_SDDS_CALLBACK cb) { s_sdds_user_cb = cb; } void DMW_SDDS_Start(int pid) { sdds_task_send_cmd(eSDDS_Cmd_Start, (UINT32)DHL_DMX_GetTsd(), pid, FALSE); // jump to SDDS_HandleCmdStart } void DMW_SDDS_Stop(void) { sdds_task_send_cmd(eSDDS_Cmd_Stop, 0, 0, FALSE); // jump to SDDS_HandleCmdStop } void DMW_SDDS_Reset(void) { sdds_task_send_cmd(eSDDS_Cmd_Delete, 0, 0, FALSE); // jump to SDDS_HandleCmdDelete } void DMW_SDDS_PrintStatus(int level) { sdds_task_send_cmd(eSDDS_Cmd_PrintStatus, level, 0, FALSE); // jump to SDDS_HandleCmdPrintStatus } void DMW_SDDS_UserAction(UINT32 userparam) { sdds_task_send_cmd(eSDDS_Cmd_UserAction, 0, 0, FALSE); } #if COMMENT ____Test____(){} #endif #if DMW_SDDS_TEST /* test procedure m2_init m2_chtype 0 m2_scan 18 18 // ¶Ç´Â KBS-2 live.. sdds ¼­ºñ½º°¡ Æ÷ÇԵǾî ÀÖ¾î¾ß ÇÔ. //m2_tune 7 sml $sds 4 DMW_SDDS_Init DWM_SDDS_Start 0x1200 // vct/pmt ¿¡¼­ pid´Â ã¾Æ¾ß Çϴµ¥, // ±¹³» KBS sdds´Â Áö±Ý 0x1200 À¸·Î °íÁ¤ µÈ µí ÇÔ.. // ³ªÁß¿¡ ¹Ù²ð ¼ö ÀÖÀ½. */ void sdt_callback(E_SDDS_CB_TYPE cbtype, void *param) { dprint(0, "------- callback, type %d, param %x\n", cbtype, param); if (0); #if 0 else if (cbtype == eSDDS_CB_TYPE_GetOUI) { S_SDDS_CBPARAM_GET_OUI *cbp = (S_SDDS_CBPARAM_GET_OUI *)param; cbp->oui = IEEE_OUI_DST; //cbp->oui = 0x80000000; // special marker.. meaning accept anyone. /* ÁÖÀÇ !!!!!!!! ÀÌ ½ºÆä¼È ¸¶Ä¿´Â °³¹ß¿ëÀ¸·Î¸¸ »ç¿ëµÇ¾î¾ß ÇÔ!!!! OUI´Â 24ºñÆ® À̹ǷÎ, À§ °ªÀº ½ÇÁ¦·Î´Â »ç¿ëµÇÁö ¾Ê´Â ¹üÀ§ÀÓ. */ cbp->model = 0x01; // NEWBY cbp->version = 0xFFFF; // any version. } #else else if (cbtype == eSDDS_CB_TYPE_CheckCompatDesc) { S_SDDS_CBPARAM_CHECK_DESC *cbp = (S_SDDS_CBPARAM_CHECK_DESC *)param; int i; for (i=0; idesc->descriptorCount; i++) { sddsCompatDescEntry_t *desc = &cbp->desc->desc[i]; if (desc->descriptorType != eSystemHardwareDescriptor && desc->descriptorType != eSystemSoftwareDescriptor) continue; if (desc->specifierType != compatSpecifierType_IEEE_OUI) continue; if (desc->specifierData != IEEE_OUI_DST) continue; if (desc->model != 0x01) // NEWBY continue; // DST ±Ô°Ý, NEWBY ±ÔÁ¤¿¡¼­´Â versionÀº ¹Ì»ç¿ë. // desc->subDescriptorCount ¿¡´Â urgency mode °¡ µé¾î ÀÖÀ»ÅÙµ¥, // ÀÏ´Ü »ç¿ëÇÏÁö ¾Ê´Â´Ù. cbp->isOk = TRUE; break; } } #endif else if (cbtype == eSDDS_CB_TYPE_NotifySchedules) { int i; sddsScheduleDesc_t *sch = (sddsScheduleDesc_t *)param; for (i=0; sch && sch->schedules && inumSchedules; i++) { dprint(2, " sched[%d] %x, %d seconds\n", sch->schedules[i].startTime, sch->schedules[i].lengthInSeconds); } } else if (cbtype == eSDDS_CB_TYPE_CheckModuleInfo) { S_SDDS_CBPARAM_CHECK_FILE *cbp = (S_SDDS_CBPARAM_CHECK_FILE *)param; dprint(2, " [%d] check file: mid %u, '%s'", cbp->id, cbp->name); cbp->isOk = TRUE; } else if (cbtype == eSDDS_CB_TYPE_BlockReceived) { S_SDDS_CBPARAM_BLOCK_RECEIVED *cbp = (S_SDDS_CBPARAM_BLOCK_RECEIVED *)param; dprint(2, " %u/%u blocks received\n", cbp->received_blocks, cbp->total_blocks); } } void sdt_init(void) { void m2_init(void); void m2_chtype(int); void m2_scan(int,int); DHL_DBG_SetModuleLevel("$sds", 4); m2_init(); m2_chtype(0); m2_scan(18, 18); // ¶Ç´Â KBS-2 live.. sdds ¼­ºñ½º°¡ Æ÷ÇԵǾî ÀÖ¾î¾ß ÇÔ. DMW_SDDS_Init(); DMW_SDDS_RegisterCallback(sdt_callback); } void sdt_start(UINT16 pid) { DMW_SDDS_Start(pid); } #endif // DMW_SDDS_TEST /* end of file */