source: svn/newcon3bcm2_21bu/dst/dmw/src/EPG/DMW_RfDownload.c @ 22

Last change on this file since 22 was 22, checked in by phkim, 11 years ago
  1. phkim
  2. newcon3sk 를 kctv 로 브랜치 함
  • Property svn:executable set to *
File size: 29.5 KB
Line 
1/********************************************************************
2
3        DMW_RfDownload.c
4       
5        EPG Middleware utility API implementation
6
7        Copyright 2004 Digital STREAM Technology, Inc.
8        All Rights Reserved
9       
10        import from rf_FlashUpdate.c
11
12        $Id: DMW_RfDownload.c  v1.00 2004/04 cafrii Exp $
13       
14********************************************************************/
15
16/*_____ I N C L U D E __________________________________________*/
17
18#include "DMW_Platform.h"
19
20//#include "DHL_PsiFilter.h"
21
22#include "DMW_Channel.h"
23#include "DMW_RfDownload.h"
24
25//#include <string.h>
26
27#define USER_HEADER_SIZE 16
28
29#define GETUpperByte(y) (((y)>>8)&0xff)
30#define GETLowerByte(y) ((y)&0xff)
31
32
33/* cafrii 070214, boot code size is now 64KB */
34/*
35#define BOOTCODE_SIZE (64*1024)
36#define STAGE2_SIZE  8192
37*/
38
39
40
41/* MonitorPrvt()¿Í ±×ÀÇ procedure°£ÀÇ argument·Î »ç¿ë */
42typedef struct PrvtEventProcData
43{
44        int                             index;
45        DHL_RESULT                              err;                                    /*ouput*/
46        DHL_OS_SEMA_ID          waitsem;        /*input*/
47        UINT8                           receiveOk;
48        UINT8                           receiveCheckOk;
49        tDHL_PSI_ControlHandle hPsiCtl;
50        tDHL_PSI_DataArray              *desc;
51       
52} PrvtEventProcData;
53
54
55
56DHL_RESULT RfDownload_MonitorPrvt(tDHL_TSD tsd, tDHL_PSI_Mode psiMode ,tDHL_PSI_Update updateMode, 
57                        tDHL_PSI_EventProc eventProc, UINT16 pid, UINT8 tableId, 
58                        int tableIdExt, UINT32 userParam,  tDHL_PSI_ControlHandle *psiCtl);
59
60DHL_RESULT RfDownload_ParsePrvt(const tDHL_PSI_DataArray *desc, prvtPtr_t *prvtPtr);
61               
62
63
64
65#if COMMENT
66______________(){}
67#endif
68
69
70int g_Trace_bRfUpdate = 1;
71 
72static int RfUpdate_DebugPrint(char *fmt, ...)
73{
74        DHL_OS_TASK_INFO tInfo;
75        char msgPrefix[50], sTaskName[20];
76    va_list v;
77    int n;
78        int priority;
79
80        DHL_OS_GetTaskInfo(DHL_OS_GetTaskID(), &tInfo);
81        if (g_Trace_bRfUpdate == 0) return 0;
82
83        priority = tInfo.priority;
84       
85#if SUPPORT_THREADX     
86        if (1) {
87                char *s;
88                strncpy(sTaskName, tInfo.name, 10);
89                if (sTaskName[2]==':') {
90                        sTaskName[7] = 0;               /* ¾ÕÀÇ ¼¼ÀÚ¸® »©°í 4 ÀÚ¸® Ç¥½Ã */
91                        s = sTaskName + 3;
92                }
93                else {
94                        sTaskName[4] = 0;               /* 4 ÀÚ¸® Ç¥½Ã */
95                        s = sTaskName;
96                }
97                sprintf(msgPrefix, "[RFUPDATE %02x %s] ", priority, s);
98        }
99
100#else
101        strncpy(sTaskName, tInfo.name, 6);
102        sTaskName[6] = 0;
103        sprintf(msgPrefix, "[RFUPDATE %d %s] ", priority, sTaskName);
104#endif
105       
106        va_start(v, fmt);
107        n = DHL_OS_Printf(msgPrefix, fmt, v);
108        va_end(v);
109       
110        return n;
111}
112
113#define dprint RfUpdate_DebugPrint
114
115
116
117
118/* ========================================================================= */
119/* CRC32 - refer to /drivers/graphics/ZLIB/crc32.c*/
120/*static int FLASH_crc_table_empty = 1;*/
121
122static UINT32 crc_table_rf_update[256];
123
124/* memory size¸¦ ÁÙÀ̱âÀ§Çؼ­ dynamic ÀÌ¿ëÇϵµ·Ï ÇÔ. Çѹø¸¸ È£ÃâµÊ */
125
126static void ConstructCRCTable()
127{
128        unsigned int c;
129        unsigned int n;
130        int k;
131        unsigned int poly;                      /* polynomial exclusive-or pattern  */
132        /* terms of polynomial defining this crc (except x^32): */
133        static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
134
135        /* make exclusive-or pattern from polynomial (0xedb88320L) */
136        poly = 0L;
137        for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
138                poly |= 1L << (31 - p[n]);
139
140        for (n = 0; n < 256; n++)
141        {
142                c = (unsigned int)n;
143                for (k = 0; k < 8; k++)
144                        c = c & 1 ? poly ^ (c >> 1) : c >> 1;
145                crc_table_rf_update[n] = c;
146        }
147
148        /* for (n=0; n<256; n++)
149                        dprint("%08x %s", FLASH_crc_table[n], n%5==4 ? "\n" : "");
150        */
151}
152
153
154
155/* DST ÀÚüÀûÀÎ CRC üũ ·çƾ. */
156static UINT32 CalculateCRC32(UINT32 out_crc, const UINT8 *buf, UINT32 len)
157{
158        #define CRC32DO1(buf)   out_crc = \
159                                                crc_table_rf_update[((int)out_crc ^ (*buf++)) & 0xff]\
160                                                 ^ (out_crc >> 8);
161        #define CRC32DO2(buf)  CRC32DO1(buf); CRC32DO1(buf);
162        #define CRC32DO4(buf)  CRC32DO2(buf); CRC32DO2(buf);
163        #define CRC32DO8(buf)  CRC32DO4(buf); CRC32DO4(buf);
164
165        if (buf == NULL) return 0L;
166
167        if (crc_table_rf_update[1] == 0)
168                ConstructCRCTable();
169
170        out_crc = out_crc ^ 0xffffffffL;
171        while (len >= 8)
172        {
173                CRC32DO8(buf);
174                len -= 8;
175        }
176        if (len) {
177                do {
178                        CRC32DO1(buf);
179                } while (--len);
180        }
181       
182        return out_crc ^ 0xffffffffL;
183}
184
185
186
187
188
189#if COMMENT
190______________(){}
191#endif
192
193
194/* caller°¡ Ưº°È÷ memory allocator¸¦ ÁöÁ¤ÇÏÁö ¾Ê¾ÒÀ» °æ¿ì »ç¿ëµÇ´Â µðÆúÆ® handlerÀÌ´Ù. */
195static void *_Default_MemAlloc(UINT32 size)
196{
197        void *ptr = DHL_OS_Malloc(size);
198        return ptr;
199}
200
201static void _Default_MemFree(void *ptr)
202{
203        /* ptr´Â free ÇÒ mem blockÀÇ ÁÖ¼ÒÀÌ´Ù. */
204        if (ptr)
205                DHL_OS_Free((void**)&ptr);
206}
207
208
209MEM_ALLOC_FN RfDownload_AllocLargeMem = _Default_MemAlloc;
210MEM_FREE_FN RfDownload_FreeLargeMem = _Default_MemFree;
211
212
213
214
215#if COMMENT
216______________(){}
217#endif
218
219
220void PrvtSyncEventProc(tDHL_PSI_Event event, tDHL_PSI_ControlHandle psiCtl, UINT32 userParam)
221{
222        PrvtEventProcData               *procData = (PrvtEventProcData *)userParam;
223        tDHL_PSI_DataArray                      *desc;
224        DHL_RESULT                                      err;
225
226        /* dprint("@@ PrvtSyncEventProc[%d]...\n", procData->index); */
227       
228        switch (event) 
229        {
230                case ePSIEVENT_DATARECEIVED:
231                        err = DHL_PSI_ReadPSIData(psiCtl, &desc);
232                       
233                        if (err) {
234                                dprint("!! DHL_PSI_ReadPSIData returned %s, %d\n", ErrorString(err), err);
235                                procData->desc = NULL;
236                        }
237                        else {
238                                procData->desc = desc;
239                        }
240
241                        if (procData->hPsiCtl != psiCtl)
242                                dprint("@@ !! psiCtl mismatch?\n");
243                       
244                        procData->receiveOk = 1;                /* ¿¡·¯°¡ ³µ´Â ¾È³µµç ¼ö½ÅÀº µÈ °ÍÀÌ´Ù. */
245                        procData->err = err;
246                        dprint("@@ table[%d] data received\n", procData->index);
247                        DHL_OS_GiveSemaphore(procData->waitsem);
248                        break;
249
250                case ePSIEVENT_SCRAMBLEDERROR:
251                        dprint("@@ ePSIEVENT_SCRAMBLEDERROR\n");
252                        procData->err = DHL_FAIL_SCRAMBLED;
253                        procData->receiveOk = 1;
254                        DHL_OS_GiveSemaphore(procData->waitsem);
255                        break;
256                       
257                default: 
258                        if (event != ePSIEVENT_LOSTPACKET && event != ePSIEVENT_SYNCERR)
259                                dprint("!! unknown event %s, %d\n",DHL_PSIEventString(event), event);
260                        break;
261        }
262}
263
264
265
266
267/*==============================================================================
268DHL_RESULT MonitorPrvt(tDHL_PSI_Update updateMode, tDHL_PSI_EventProc eventProc, UINT32 pid , UINT8 iTableId , UINT32 userParam, tDHL_PSI_ControlHandle *psiCtl)
269
270        updateMode:             Update mode (ePSIUPDATE_ONESHOT,psiVersionChange,psiContinuous).
271        eventProc:              Callback function to catch monitor events.
272        userParam:              Passed back to the eventProc.
273        psiCtl:                 PSI Object for PSI layer.
274
275Configures the TID & PID filters for Privaet secions with a given TableId.
276==============================================================================*/
277
278DHL_RESULT RfDownload_MonitorPrvt(tDHL_TSD tsd, tDHL_PSI_Mode psiMode ,tDHL_PSI_Update updateMode, 
279                        tDHL_PSI_EventProc eventProc, UINT16 pid, UINT8 tableId, 
280                        int tableIdExt, UINT32 userParam,  tDHL_PSI_ControlHandle *psiCtl)
281{
282        tDHL_PSI_Filter *pref = NULL;
283        DHL_RESULT              err;
284        UINT32          maxSections;
285
286        /* Set up the Table ID filter */
287        if (tableIdExt >= 0) {
288                dprint("%s: tidex 0x%04x\n", __FUNCTION__, tableId);
289                err = DHL_PSI_AllocFilterWithTidEx(&pref, tableId, tableIdExt, TRUE);
290        }
291        else {
292                err = DHL_PSI_AllocFilterWithTid(&pref, tableId, TRUE);
293                        /* ignore table id extension. */
294        }
295        if (err) {
296                return(err);
297        }
298       
299        maxSections = (psiMode == ePSIMODE_TABLE) ? 256 : 1;
300
301        /* Set up PID Filter */ 
302        if ((err = DHL_PSI_StartMonitor(tsd,
303                                                pid,
304                                                psiMode, 
305                                                updateMode,
306                                                pref,
307                                                4096,
308                                                maxSections,
309                                                eventProc,
310                                                userParam,
311                                                psiCtl))) {
312
313                dprint("!! %s: DHL_PSI_StartMonitor() err %d\n", __FUNCTION__, err);
314
315                /* ÁÖÀÇ: pref´Â OS_Malloc¿¡ ÀÇÇØ¼­ ÇÒ´çµÈ °ÍÀ̹ǷΠOS_Free·Î Ç®¾î¾ß ÇÑ´Ù. */
316                /* OS_Free((void *)&pref); */
317                DHL_PSI_FreeFilter(pref);
318        }
319
320        return(err);
321}
322
323
324void RfDownload_FreePrvt(prvtPtr_t prvt)
325{
326        if (prvt == NULL)
327                return;
328
329        if (prvt->private_data_byte) {
330                (*RfDownload_FreeLargeMem)(prvt->private_data_byte);
331                prvt->private_data_byte = NULL;
332        }
333
334        DHL_OS_Free((void**)&prvt);
335}
336
337
338
339/*==============================================================================
340DHL_RESULT RfDownload_ParsePrvt (UINT8 **sectionArr, prvtPtr_t *prvtPtr)
341
342        **sectionArr:   Array of pointers to all TVCT sections.
343        *prvtPtr:               Returned pointer to the parsed PRVT.
344
345Parses an PRVT and returns the parsed table via the return pointer.
346==============================================================================*/
347
348DHL_RESULT RfDownload_ParsePrvt(const tDHL_PSI_DataArray *desc, prvtPtr_t *prvtPtr)
349{
350        UINT16                          numSections;
351        UINT32                          i;
352        DHL_RESULT                              err = DHL_OK;
353
354        UINT32  section_length;
355        UINT16  table_id_extension = 0;
356        UINT8   version_number = 0;
357//      UINT8   current_next_indicator = 0;
358//      UINT8   section_number = 0;
359//      UINT8   last_section_number = 0;
360        UINT32  private_data_length = 0;
361
362        UINT32  sizeDataBytes;
363        UINT8 *const *sectionArr;
364        prvtPtr_t prvt = NULL;
365       
366        dprint("%s:\n", __FUNCTION__);
367        if (desc == NULL || desc->sectPtr == NULL || prvtPtr == NULL) {
368                dprint("!! invalid argument (desc %x, prvtptr %x)\n", desc, prvtPtr);   
369                return (DHL_FAIL_INVALID_PARAM);
370        }
371
372        sectionArr = desc->sectPtr;
373        *prvtPtr = NULL;
374       
375        numSections = get_last_section_number(sectionArr[0]) + 1;
376        dprint("\t num sections = %d\n" , (int)numSections);
377
378        /* now verify all other sections are present
379                  and calculate total payload data byte size.. */
380        sizeDataBytes = 0;
381        for (i=0; i<numSections; i++) 
382        {
383                if (sectionArr[i] == NULL) {
384                        dprint("!! desc section[%d] ptr NULL\n", i);
385                        return (DHL_FAIL_BAD_FORMAT);
386                }
387                section_length = get_section_length(sectionArr[i]);
388                sizeDataBytes += (section_length - 5 - 4);
389                        /* ¾ÕÀÇ 5´Â header ºÎºÐÀÇ overhead (section lengthÀÌÈÄ last section number±îÁö)
390                                 µÚÀÇ 4´Â CRC ºÎºÐ.. */
391        }
392        dprint("\t total payload size: %d\n", sizeDataBytes);
393
394        prvt = (prvtPtr_t) DHL_OS_Malloc(sizeof(prvt_t));
395        checkMemoryError(prvt);
396
397        /* note!
398                  data¸¦ À§ÇÑ ¸Þ¸ð¸®´Â Ưº°È÷ special memory allocator¸¦ »ç¿ëÇÑ´Ù.
399        */
400        prvt->private_data_byte = (*RfDownload_AllocLargeMem)(sizeDataBytes);
401        checkMemoryError(prvt->private_data_byte);
402       
403        prvt->private_data_length = 0;
404        /* ÀÌ °ªÀº µ¥ÀÌÅ͸¦ ¹ÞÀ¸¸é¼­ Á¡Â÷ÀûÀ¸·Î Áõ°¡ÇÑ´Ù. */
405       
406        for (i=0; i<numSections; i++)
407        {
408                section_length = get_section_length(sectionArr[i]);
409                table_id_extension = ((UINT16)((sectionArr[i][3])<<8) | (UINT16)sectionArr[i][4]);
410                version_number = 0;
411//              current_next_indicator = 1;
412//              section_number          = (sectionArr[i][6]);
413//              last_section_number = (sectionArr[i][7]);
414                private_data_length = section_length-5-4;       /* header + CRC */
415
416                if (i == 0) {
417                        /* duplicate fields copied once */
418                        prvt->version_number = version_number;
419                        prvt->table_id_extension = table_id_extension; 
420                }
421                else if (prvt->version_number != version_number ||
422                        prvt->table_id_extension != table_id_extension) {
423                        dprint("!! warning: sect[%d]'s (ver %d, tidex %d) != sect[0]'s (v %d, t %d)\n",
424                                        version_number, table_id_extension,
425                                        prvt->version_number, prvt->table_id_extension);
426                }
427               
428                /* section_length max = 12bit = 4095.
429                         header frame after section length = 5 bytes. (without protocol version)
430                         crc = 4 bytes.
431                         total maximum payload size = 4095 - 5 - 4 = 4086
432                       
433                         --> ÀÌ·ÐÀûÀ¸·Î ÃÖ´ë 4086±îÁö °¡´ÉÇѵ¥,
434                             encodingÀ» ÇÒ ¶§ ÃÖ´ë 4084·Î ÇÑ °Í °°´Ù.
435                */
436                if (private_data_length > 0 && private_data_length <= 4084) 
437                {
438                        memcpy(prvt->private_data_byte+prvt->private_data_length, 
439                                        &(sectionArr[i][8]), private_data_length);
440
441                        /* update private_data_length field. */
442                        prvt->private_data_length += private_data_length;       
443                }
444                else {
445                        dprint("!! data length %d invalid range\n", private_data_length);
446                }
447                       
448        }       /* for( i = 0 ; i < numSections ; i++ ) */
449       
450        dprint("\tParsePrtv end. byte length %d\n", prvt->private_data_length);
451
452
453        /* parsing complete */
454        /* *(((memId_t *)(*prvtPtr))-1) = memId; */
455        /* memId = NULL;                // so memChain not deleted */
456
457        *prvtPtr = prvt;
458
459        return DHL_OK;
460
461ParseExit:
462
463        if (prvt && prvt->private_data_byte) {
464                (*RfDownload_FreeLargeMem)(prvt->private_data_byte);
465                prvt->private_data_byte = NULL;
466        }
467
468        if (prvt)
469                DHL_OS_Free((void**)&prvt);
470               
471        return (err);
472}
473
474
475
476/*==============================================================================
477DHL_RESULT GetPrvtEx tDHL_TSD tsd, prvtPtr_t *prvtPtr, int timeOut)
478
479        *tsd                    Pointer to a TSD structure from which this stream is coming
480        *tvctPtr:               Return pointer to a PRVT.
481        timeOut:                Synchronous wait timeout for PRVT.
482
483Synchronous function which waits (up to the timeout specified) for the
484arrival of a PRVT.  If the PRVT arrives before the timeout, the table is
485parsed and returned to the caller.
486==============================================================================*/
487
488STATUS RfDownload_GetPrvt(tDHL_TSD tsd, prvtPtr_t *prvtPtr, UINT16 pid, UINT16 tableid, 
489                                        UINT16 iTableNumber, int timeOut, BOOL (*checkfn)(void))
490{
491        PrvtEventProcData               procData;
492        tDHL_PSI_ControlHandle  psiCtl = (tDHL_PSI_ControlHandle)0;
493        int                                             semErr;
494        STATUS                                  err = (STATUS)DHL_OK;
495        UINT32                                  tickStart;
496
497        if (prvtPtr == NULL)
498                return statusInvalidArgument;
499               
500        memset(&procData, 0, sizeof(procData));
501
502        procData.index = 0;
503        procData.desc = NULL;
504        procData.err = DHL_OK;
505        procData.waitsem = DHL_OS_CreateCountingSemaphore("GetPrvt", OS_SEM_PRIO, 0);
506        if (!procData.waitsem) {
507                err = statusOutOfResource;
508                goto GetSectionExit;
509        }
510       
511        err = (STATUS)RfDownload_MonitorPrvt(tsd, ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, PrvtSyncEventProc, 
512                        pid, tableid, iTableNumber, (UINT32)&procData, &psiCtl);
513       
514        if (err) {
515                dprint("!! %s: MonitorPrvt err %d\n", __FUNCTION__, err);
516                goto GetSectionExit;
517        }
518
519        procData.hPsiCtl = psiCtl;
520       
521        tickStart = DHL_OS_GetMsCount();
522        while (1) {
523                semErr = DHL_OS_TakeSemaphore(procData.waitsem, 1000/10);
524               
525                if (semErr == DHL_OK) 
526                        break;
527
528                if (checkfn && checkfn()) {
529                        err = statusCancelled;
530                        goto GetSectionExit;
531                }
532               
533                if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) {
534                        err = statusTimeout;
535                        dprint("!! %s: timeout err\n", __FUNCTION__);
536                        goto GetSectionExit;
537                }
538        }
539
540        if ((err = (STATUS)procData.err)) {
541                dprint("!! %s: procData.err err %d\n", __FUNCTION__, procData.err);
542                goto GetSectionExit;
543        }
544
545        err = (STATUS)RfDownload_ParsePrvt(procData.desc, prvtPtr);
546        if (err) {
547                dprint("!! %s: Parse err %d, prvt 0x%x\n", err, *prvtPtr);
548        }
549       
550GetSectionExit:
551
552        if (psiCtl)
553                DHL_PSI_StopMonitor(psiCtl);
554       
555        if (procData.desc)
556                DHL_PSI_FreePSIData(procData.desc);     
557
558        if (procData.waitsem)
559                DHL_OS_DeleteSemaphore(procData.waitsem);
560
561        return (err);
562}
563
564
565
566void TestGetPrvt(int idx)
567{
568        int err;
569        tDHL_TSD tsd = DHL_DMX_GetTsd();
570
571        prvtPtr_t prvt;
572
573        int pid = 0x1FEF;                       /* 8175 */
574        int table_id = 0xFD;    /* 253 */
575
576        printf("Get prvt idx %d, pid 0x%x, tid 0x%x\n", idx, pid, table_id);
577       
578        /* Get iTableNumber 0.. first table. */
579        err = (DHL_RESULT)RfDownload_GetPrvt(tsd, &prvt, pid, table_id, idx, 1000*10, NULL);
580
581        if (err) {
582                printf("!! RfDownload_GetPrvt err %d\n", err);
583                return;
584        }
585        printf("Prvt rx ok. ver %d, tidex 0x%x, data len %d, p 0x%x\n", 
586                        prvt->version_number, prvt->table_id_extension, 
587                        prvt->private_data_length, prvt->private_data_byte);
588
589        RfDownload_FreePrvt(prvt);
590       
591}
592
593
594
595
596#if COMMENT
597______________(){}
598#endif
599
600
601/*--------------------------
602         RfUpdate_VerifyHeader
603       
604         INPUT: pInfo
605         OUTPUT: list
606       
607         ´Ù¿î·Îµå°¡ ¿Ï·áµÈ µ¥ÀÌÅÍ (pInfo)¸¦ verifyÇÑ´Ù.
608         header Á¤º¸¸¦ ÀÌ¿ëÇÏ¿© Á¦´ë·Î ¼ö½Å µÈ °ÍÀÎÁö È®ÀÎÇϰí
609         ½ÇÁ¦·Î Á¤È®ÇÑ µ¥ÀÌÅÍ Å©±â·Î Á¶Á¤µµ ÇÑ´Ù.
610       
611         ¹®Á¦°¡ ¾øÀ¸¸é PRVT Å×À̺í Á¤º¸¸¦ ÀÌ¿ëÇÏ¿© data list¸¦ »ý¼ºÇØ ³½´Ù.
612*/
613int RfDownload_VerifyHeader(RfDownloadInfo *pInfo, DataChunkList *list)
614{
615        UINT8   headerChecksum = 0;
616        UINT32  dataChecksum = 0;
617        UINT32  givenDataChecksum = 0;
618        int i = 0;
619        UINT8 *pImagePart =NULL;
620        int             iImagePartSize = 0;
621       
622        UINT32 nRealImageSize = 0, tmpSize = 0;
623        BOOL bFirst = TRUE;
624
625        int tableCount = pInfo->NumPrvts;
626        prvtPtr_t *pPrvts = pInfo->PrvtList;
627       
628        dprint("%s: (%d tables)\n", __FUNCTION__, tableCount);
629
630
631        if (!pPrvts || tableCount == 0) {
632                dprint("!! Null PRVT list or 0 count\n");
633                return -1;
634        }
635
636        for (i=0; i<tableCount; i++) {
637                if (pPrvts[i] == NULL) {
638                        dprint("!! PRVT[%d] NULL\n", i);
639                        return -2;
640                }
641        }
642
643        dprint("\t DST chars check...\n");
644       
645        pImagePart = pPrvts[0]->private_data_byte;
646
647
648/*  16 bytes DST header
649        +------+------+------+------+
650        |  AA  | 'D'  | 'S'  | 'T'  |
651        +------+------+------+------+
652        | Type | SZ_0 | SZ_1 | SZ_2 |
653        +------+------+------+------+
654        | SZ_3 | CHK  |      |      | 
655        +------+------+------+------+
656        | CRC0 | CRC1 | CRC2 | CRC3 |
657        +------+------+------+------+
658
659        "\xAADST": marker
660        Type: flash type
661        SZ_X: total image size in byte
662        CHK : Header checksum. sum from 'Type' to 'SZ_3'
663        CRCX: CRC32 of total image bytes
664
665*/
666
667        /* first verification... */
668
669        memdump3(pImagePart, 16, "Image Header", 0, 0);
670       
671        if( !(  pImagePart[0] == 0xAA && 
672                        pImagePart[1] == 0x44 &&                /*D*/
673                        pImagePart[2] == 0x53 &&                /*S*/
674                        pImagePart[3] == 0x54 ) )               /*T*/
675        {
676                dprint("!! header marker err\n");
677                return -1;     
678        }
679
680        /* second verifiction... */
681       
682        dprint("\t User header checsum check...\n");
683        for (i = 4 ; i < 9 ; i++)
684                headerChecksum += pImagePart[i];
685
686        if (headerChecksum != pImagePart[9]) {
687                dprint("!! header checksum err\n");
688                return -1;
689        }
690               
691        dprint("\t image flash type %d\n", ((pImagePart[4]>>6)&0x03));
692               
693        nRealImageSize = ((pImagePart[5] << 24 ) & 0xFF000000) |
694                                ((pImagePart[6] << 16 ) & 0x00FF0000) |
695                                ((pImagePart[7] << 8 )  & 0x0000FF00) |
696                                ( pImagePart[8]         & 0x000000FF);
697
698        dprint("\t image size: %d (0x%x)\n", nRealImageSize, nRealImageSize);
699               
700        dprint("\t data checksum check...\n");
701        givenDataChecksum = (( pImagePart[12] << 24 ) &  0xff000000 ) |
702                                                (( pImagePart[13] << 16 ) &  0x00ff0000 ) |
703                                                (( pImagePart[14] << 8  ) &  0x0000ff00 ) |
704                                                (  pImagePart[15]                 & 0x000000ff );
705       
706        /* ù ¹øÂ° table byte calculation for checksum..... */
707        iImagePartSize = pPrvts[0]->private_data_length - 16;
708        dataChecksum = CalculateCRC32(0/*seed*/,pPrvts[0]->private_data_byte+16,iImagePartSize);
709
710        if (bFirst == TRUE && (unsigned int)iImagePartSize > nRealImageSize)
711        {
712                /* PRVT ÇѰ³¹Û¿¡ ¾ø´Â °æ¿ì.. */
713                pPrvts[0]->private_data_length = nRealImageSize + 16;   
714                bFirst = FALSE;
715        }
716        tmpSize = iImagePartSize;
717
718        /* ¸¶Áö¸· tableÀÇ °æ¿ì dummy data¸¦ Æ÷ÇÔÇϰí Àֱ⠶§¹®¿¡
719                 Çì´õ¿¡¼­ ÃßÃâÇÑ ½ÇÁ¦ µ¥ÀÌÅÍ Å©±â Á¤º¸¸¦ ÀÌ¿ëÇÏ¿©
720                 data length¸¦ Á¶ÀýÇØ Áà¾ß ÇÑ´Ù.
721                 ÀÌ ºÎºÐÀÇ Äڵ尡 Àß ´«¿¡ µé¾î¿ÀÁö ¾Ê´Â´Ù. ÁÖÀÇÇØ¼­ º¸ÀÚ.
722        */
723        for (i = 1; i < tableCount; i++)
724        {
725                pImagePart = pPrvts[i]->private_data_byte;
726                iImagePartSize = pPrvts[i]->private_data_length;
727               
728                dataChecksum = CalculateCRC32(dataChecksum, pImagePart,iImagePartSize);
729
730                if( bFirst == TRUE && tmpSize + iImagePartSize > nRealImageSize )
731                {
732                        pPrvts[i]->private_data_length = nRealImageSize - tmpSize;      /* Á¶Á¤! */
733                        bFirst = FALSE;
734                }
735                tmpSize += iImagePartSize;
736        }
737
738        dprint("\tCRC given: 0x%x, calculated: 0x%x\n", givenDataChecksum, dataChecksum);
739       
740        if (dataChecksum != givenDataChecksum) {
741                dprint("!! CRC mismatch\n");
742                return -1;
743        }
744
745        list->NumChunk = pInfo->NumPrvts;
746        list->ChunkSize = DHL_OS_Malloc(list->NumChunk * sizeof(int));
747        list->ChunkList = DHL_OS_Malloc(list->NumChunk * sizeof(UINT8 *));
748        list->TotalPayloadSize = nRealImageSize;
749
750        if (list->ChunkSize == NULL || list->ChunkList == NULL) {
751                dprint("!! out of memory for data list\n");
752                return -2;
753        }
754       
755        nRealImageSize = 0;
756        for (i=0; i<list->NumChunk; i++) 
757        {
758                if (i == 0) {
759                        /* ¸Ç ¾ÕÀÇ header ºÎºÐÀº Á¦¿ÜÇÑ´Ù. */
760                        list->ChunkList[0] = pInfo->PrvtList[0]->private_data_byte + USER_HEADER_SIZE;
761                        list->ChunkSize[0] = pInfo->PrvtList[0]->private_data_length - USER_HEADER_SIZE;
762                }
763                else {
764                        list->ChunkList[i] = pInfo->PrvtList[i]->private_data_byte;
765                        list->ChunkSize[i] = pInfo->PrvtList[i]->private_data_length;
766                }
767                nRealImageSize += list->ChunkSize[i];
768                dprint("\t  [%d] ChunkSize: %d\n", i, list->ChunkSize[i]);
769        }
770
771        dprint("\t%d PRVTs, actual image size %d, calc %d\n", 
772                                list->NumChunk, list->TotalPayloadSize, nRealImageSize);
773
774        if (list->TotalPayloadSize != nRealImageSize)
775                dprint("!! warning! image size mismatch\n");
776
777        return 0;       
778}
779
780
781
782void RfDownload_CleanUp(RfDownloadInfo *pInfo, DataChunkList *list)
783{
784        int i;
785       
786        if (pInfo == NULL) return;
787
788        dprint("RfUpdate_CleanUp:\n");
789       
790        dprint("  free all prvts..\n");
791        for (i=0; i<pInfo->NumPrvts && pInfo->PrvtList; i++) 
792        {
793                if (pInfo->PrvtList[i]) {
794                        RfDownload_FreePrvt(pInfo->PrvtList[i]);
795                        pInfo->PrvtList[i] = NULL;
796                }
797        }
798        DHL_OS_Free((void**)&pInfo->PrvtList);
799        DHL_OS_Free((void**)&list->ChunkList);
800        DHL_OS_Free((void**)&list->ChunkSize);
801}
802
803
804
805STATUS RfDownload_Download(RfDownloadInfo *pInfo, UINT32 nRxTimeOutSec, 
806                                                RFDOWNLOAD_CALLBACK callback, BOOL (*checkfn)())
807{
808        tDHL_TSD tsd = 0;
809        prvtPtr_t prvt = 0;                                             /* temporary PRVT pointer */
810        prvtPtr_t *pPrvtsList = NULL;   /* PRVT list */
811        PrvtEventProcData *pProcData = NULL;
812        DHL_OS_SEMA_ID waitsem = 0;     /* sema4 for notify table received */
813
814        DHL_RESULT err = DHL_OK;
815        int i, result;
816        STATUS status = statusOK;
817       
818        int iCurrentTable = 0, iLastTable = 0;
819        int nReceivedCount = 0;                         /* number of received tables */
820        int nPrvtMonitor = 0;                                   /* number of monitor */
821       
822        int _second = 1000;
823        int tickStart = DHL_OS_GetMsCount(); 
824
825        dprint("%s: rx timeout %d\n", __FUNCTION__, nRxTimeOutSec);
826
827        waitsem = DHL_OS_CreateCountingSemaphore("GetPrvt", OS_SEM_PRIO, 0);
828        if (waitsem == (DHL_OS_SEMA_ID)NULL) {
829                dprint("!! %s: sema4 create err\n", __FUNCTION__);
830                return statusOutOfMemory;               /* outOfCPUMemoryError; */
831        }
832       
833        tsd = DHL_DMX_GetTsd();
834        if (!tsd) {
835                dprint("!! TSD NULL\n");
836                return statusInvalidState;      /* illegalOperationError;       */
837        }
838
839        dprint("  Get first prvt table..\n");
840       
841        /* Get iTableNumber 0.. first table. */
842        err = (DHL_RESULT)RfDownload_GetPrvt(tsd, &prvt, pInfo->Pid, pInfo->TableId, 0, 
843                                nRxTimeOutSec*1000, checkfn);
844        if (err != DHL_OK)
845        {
846                dprint("!! GetPrvt() err %d\n", err);
847                return statusError;                                     /* err; */
848        }
849
850        iCurrentTable = GETUpperByte(prvt->table_id_extension);
851        iLastTable  = GETLowerByte(prvt->table_id_extension);
852       
853        dprint("  PRVT: ver %d, tidex 0x%x (cur %d, last %d), len %d\n",
854                                (int)prvt->version_number, (int)prvt->table_id_extension, 
855                                iCurrentTable, iLastTable,
856                                prvt->private_data_length);
857
858        dprint("  total %d tables (0 ~ %d)\n", iLastTable+1, iLastTable);
859
860
861        if (callback)
862                callback(RFDOWNLOAD_REPORT_DOWNLOAD, (iCurrentTable+1)*100/(iLastTable+1));
863
864        /* PRVT array ¸Þ¸ð¸® ÇÒ´ç. */
865        pPrvtsList = DHL_OS_Malloc((iLastTable+1) * sizeof(prvtPtr_t *));
866        if (pPrvtsList == NULL)
867                return statusOutOfMemory;               /* outOfCPUMemoryError; */
868
869        pPrvtsList[0] = prvt;
870        prvt = NULL;
871
872        if (iLastTable <= 0) {
873                dprint("  only 1 table exist. receive complete..\n");
874                nReceivedCount = 1;
875                goto label_prvts_received;
876        }
877
878        pProcData = (PrvtEventProcData *) DHL_OS_Malloc(sizeof(PrvtEventProcData) * (iLastTable+1));
879        if (pProcData == NULL)
880        {
881                dprint("!! pProcData allocation failed...\n");
882                /* err = outOfCPUMemoryError; */
883                status = statusOutOfMemory;
884                goto label_exit;
885        }
886
887        memset(pProcData, 0, sizeof(PrvtEventProcData)*(iLastTable+1));
888
889        /* ÀÌÁ¦ ³ª¸ÓÁö´Â monitoringÀ» °ÉÀÚ... */
890        for (i = 0 ; i <= iLastTable; i++)
891        {
892                if (i == iCurrentTable) {
893                        dprint("  monitor[%d] skip! already exist\n", i);
894                        pProcData[i].receiveOk = 1;
895                        pProcData[i].receiveCheckOk = 1;
896                        continue;
897                }
898               
899                pProcData[i].index = i;
900                pProcData[i].err = DHL_OK;
901                pProcData[i].receiveOk = 0;
902                pProcData[i].receiveCheckOk = 0;
903                pProcData[i].waitsem = waitsem;
904
905                dprint("  monitor[%d] start\n", i);
906               
907                err = RfDownload_MonitorPrvt(tsd, ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, PrvtSyncEventProc, 
908                                                pInfo->Pid, pInfo->TableId, (UINT16)i, 
909                                                (UINT32)&pProcData[i], &pProcData[i].hPsiCtl);
910               
911                if (err == DHL_OK) {
912                        nPrvtMonitor++;
913                }
914                else { 
915                        dprint("!! PrvtMonitor[%d] err %d.. total %d monitors\n", i, err, nPrvtMonitor);
916                        status = statusInvalidVCT;
917                        goto label_exit;
918                }
919        }
920       
921        dprint("  total %d monitors ok. now wait..\n", nPrvtMonitor);   
922       
923
924        if (checkfn && checkfn())
925                goto label_cancelled;
926               
927        nReceivedCount = 1;             /* ÀÌ¹Ì ÇѰ³¸¦ ¹ÞÀº »óÅÂÀ̹ǷΠ1ºÎÅÍ ½ÃÀÛ. */
928       
929        while (nReceivedCount <= iLastTable)
930        {
931                int nLeftTimeTick = (int)nRxTimeOutSec*_second - (int)(DHL_OS_GetMsCount()-tickStart);
932
933                if (checkfn && checkfn())
934                        goto label_cancelled;
935
936
937                if (nLeftTimeTick <= 0) {       
938                        /* err = timeoutError; */
939                        status = statusTimeout;
940                        dprint("!! timeout %d seconds\n" , nRxTimeOutSec);
941                        goto label_exit;
942                }
943
944                result = DHL_OS_TakeSemaphore(waitsem, 100);
945               
946                if (checkfn && checkfn())
947                        goto label_cancelled;
948
949                if (result == DHL_OK)
950                        dprint("  some tables may be received\n");
951               
952                for (i = 0; i < iLastTable+1; i++)
953                {
954                        if (pProcData[i].receiveOk == 0)                        /* ¾ÆÁ÷ ¼ö½Å ¾ÈµÈ table. */
955                                continue;
956
957                        if (pProcData[i].receiveCheckOk == 1)   /* ¼ö½Å µÇ°í ó¸® ´Ù µÈ table. */
958                                continue;
959
960                #if DEVELOPMENT_BUILD
961                        DHL_ASSERT(pProcData[i].receiveOk == 1 && pProcData[i].receiveCheckOk == 0, "");
962                #endif
963                       
964                        if (pProcData[i].err) {
965                                dprint("!! PRVT[%d] received err %d\n", pProcData[i].err);
966                                break;
967                        }
968
969                        if (pProcData[i].hPsiCtl == (tDHL_PSI_ControlHandle)0) {
970                                dprint("!! PRVT[%d] received but no psictl !!\n", i);
971                        }
972
973                        if (pPrvtsList[i])
974                                dprint("!! warning! PRVT[%d] non-NULL before parsing..\n", i);
975
976                        dprint("  PRVT[%d] received. parsing..\n", i);
977                       
978                        err = RfDownload_ParsePrvt(pProcData[i].desc, &pPrvtsList[i]);
979                        if (err) {
980                                dprint("!! PRVT[%d] parsing err %d\n", i, err);
981                                status = statusInvalidVCT;
982                                goto label_exit;
983                        }
984                       
985                        DHL_PSI_StopMonitor(pProcData[i].hPsiCtl);
986                        pProcData[i].hPsiCtl = (tDHL_PSI_ControlHandle)0;
987                       
988                        if (pProcData[i].desc) {
989                                DHL_PSI_FreePSIData(pProcData[i].desc);
990                                pProcData[i].desc = NULL;
991                        }
992
993                        pProcData[i].hPsiCtl = (tDHL_PSI_ControlHandle)0;
994                        pProcData[i].desc = NULL;
995                        pProcData[i].receiveCheckOk = 1;
996                       
997                        nReceivedCount++;
998               
999                        dprint("  PRVT[%d] parsed. total rx count %d\n", i, nReceivedCount);
1000               
1001                        iCurrentTable = GETUpperByte(pPrvtsList[i]->table_id_extension);
1002                        iLastTable  = GETLowerByte(pPrvtsList[i]->table_id_extension);
1003                       
1004                        dprint("  PRVT: ver %d, tidex 0x%x (cur %d, last %d), len %d\n",
1005                                                (int)pPrvtsList[i]->version_number, (int)pPrvtsList[i]->table_id_extension, 
1006                                                iCurrentTable, iLastTable,
1007                                                pPrvtsList[i]->private_data_length);
1008
1009                        if (callback)
1010                                callback(RFDOWNLOAD_REPORT_DOWNLOAD, (iCurrentTable+1)*100/(iLastTable+1));
1011
1012                }       /* for( i = 0 ; i < iLastTable + 1 ; i++ ) */
1013
1014                if (nReceivedCount == iLastTable+1)
1015                {
1016                        dprint("  all %d tables received\n", nReceivedCount);
1017                        break;         
1018                }
1019        }
1020       
1021
1022label_prvts_received:
1023
1024        if (nReceivedCount != iLastTable+1) {
1025                dprint("!! only %d tables received !!\n", nReceivedCount);
1026                /* err = generalError; */
1027                status = statusNotFound;
1028                goto label_exit;
1029        }
1030       
1031        pInfo->PrvtList = pPrvtsList;
1032        pInfo->NumPrvts = iLastTable+1;
1033
1034        dprint("  download completed. num prvts %d\n", pInfo->NumPrvts);
1035        /* err = DHL_OK; */
1036        status = statusOK;
1037        goto label_exit;
1038
1039
1040label_cancelled:
1041        /* err = userCancelError; */
1042        status = statusCancelled;
1043
1044label_exit:
1045
1046        dprint("  cancel all remaining monitors..\n");
1047        for (i = 0; pProcData && i < iLastTable+1; i++)
1048        {
1049                if (pProcData[i].hPsiCtl) {
1050                        dprint("    DHL_PSI_StopMonitor(%d)\n", i);
1051                        DHL_PSI_StopMonitor(pProcData[i].hPsiCtl);
1052                        pProcData[i].hPsiCtl = (tDHL_PSI_ControlHandle)0;
1053                }
1054        }
1055
1056        if (pProcData) {
1057                DHL_OS_Free((void**)&pProcData);
1058                pProcData = NULL;
1059        }
1060       
1061        if (waitsem) {
1062                DHL_OS_DeleteSemaphore(waitsem);       
1063                waitsem = (DHL_OS_SEMA_ID)NULL;
1064        }
1065
1066        return status;
1067}
1068
1069
1070
1071
1072#if 0
1073
1074int RfUpdate_Vprint(const char *format, va_list va)
1075{
1076        char buff[100];
1077        int n;
1078       
1079        n = vsprintf(buff, format, va);
1080       
1081        dprint(buff);
1082
1083        return n;
1084}
1085
1086
1087/*
1088         Çϳª ÀÌ»óÀÇ chunk·Î ÀÌ·ç¾î Á®¼­ flash write°¡ ÀÌ·ç¾îÁö¹Ç·Î
1089         driver¿¡¼­ reportµÇ´Â percentage´Â ÀüüÀûÀÎ progress percentage°¡ ¾Æ´Ï´Ù.
1090         µû¶ó¼­ ÇöÀç ¾î´À chunk°¡ ÁøÇàÁßÀÎÁö ¾Ë°í ÀÖ¾î¾ß ÇÑ´Ù.
1091*/
1092int g_RfUpdate_CurrentChunkIdx; /* ÇöÀç ÁøÇàÁßÀÎ chunk index (0 ~ ..) */
1093int g_RfUpdate_NumChunk;                                /* Àüü chunk °¹¼ö. */
1094
1095void (*g_RfUpdate_ReportFn)(RfUpdateReport msg, UINT32 value);
1096
1097static void RfUpdate_FlashStatusCallback(enum SFlashReport msg, UINT32 value)
1098{
1099        if (msg == SFLASH_REPORT_ERASE)
1100        {
1101                if (value <= 100)
1102                        g_RfUpdate_ReportFn(RFUPDATE_REPORT_ERASE, value);
1103        }
1104        else if (msg == SFLASH_REPORT_BLANKCHECK)
1105        {
1106                if (value <= 100)
1107                        g_RfUpdate_ReportFn(RFUPDATE_REPORT_BLANKCHECK, value);
1108        }
1109        else if (msg == SFLASH_REPORT_WRITE)
1110        {
1111                int percentage = (100*g_RfUpdate_CurrentChunkIdx + value)/g_RfUpdate_NumChunk;
1112               
1113                if (value <= 100)
1114                        g_RfUpdate_ReportFn(RFUPDATE_REPORT_WRITE, percentage);
1115        }
1116        else if (msg == SFLASH_REPORT_VERIFY)
1117        {
1118                if (value <= 100)
1119                        g_RfUpdate_ReportFn(RFUPDATE_REPORT_VERIFY, value);
1120        }
1121        else {
1122                /* dprint("---- report: msg [%d], value [%d]\n", msg, value); */
1123                /* g_RfUpdate_ReportFn(msg, value); */
1124        }
1125       
1126        OS_Delay(1000/10);
1127}
1128
1129
1130static int SafeUpdateStage2Code(UINT8 *buf)
1131{
1132        int err = 0;
1133        int i;
1134
1135        for (i=0; i<5; i++)
1136        {
1137                if (!err)
1138                        err = SFlash_Erase(0, STAGE2_SIZE);
1139                if (!err)
1140                        err = SFlash_BlankCheck(0, STAGE2_SIZE);
1141                if (!err)
1142                        err = SFlash_Write(0, buf, STAGE2_SIZE);
1143                if (!err)
1144                        err = SFlash_Verify(0, buf, STAGE2_SIZE);
1145               
1146                if (err == 0) {
1147                        dprint("## stage2 updated successfully\n");
1148                        return 0;
1149                }
1150                dprint("## stage2 update err, retry..\n");
1151                OS_Delay(1000/4);
1152        }
1153        dprint("## stage2 update failed !!\n");
1154       
1155        return -1;
1156}
1157
1158#endif  /* #if 0 */
1159
1160
1161
1162/* end of file */
Note: See TracBrowser for help on using the repository browser.