source: svn/trunk/newcon3bcm2_21bu/dta/src/app/image_recv.c @ 2

Last change on this file since 2 was 2, checked in by phkim, 11 years ago

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 10.7 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2003-2008, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: $
11 * $brcm_Revision: $
12 * $brcm_Date: $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log: $
19 *
20 *
21 ***************************************************************************/
22
23#include "bsettop_smessage.h"
24#include "dsmcc.h"
25
26#include "bstd.h"
27#include "bdbg.h"
28
29#include "image_recv.h"
30
31#include "bapp_util.h"
32
33BDBG_MODULE(image_recv);
34
35#define MSG_VERBOSE 1
36#if MSG_VERBOSE & 1
37#define BDBG_MSG_0(x) BDBG_MSG(x)
38#else
39#define BDBG_MSG_0(x) BDBG_NOP()
40#endif
41
42#if MSG_VERBOSE & 2
43#define BDBG_MSG_2(x) BDBG_MSG(x)
44#else
45#define BDBG_MSG_2(x) BDBG_NOP()
46#endif
47
48#define MSG_BUFFER_SIZE 0x1000
49#define MAX_MSG_EVENTS 1
50#define MSG_TIMEOUT (60000)
51#define DDB_TIMEOUT (5*60000)
52
53static uint8_t msg_buffer[MSG_BUFFER_SIZE];
54
55#define MAX_BITS (0x200*8)
56struct bitmap_t {
57    uint32_t bits[0x200]; /* support 4096 DDB */
58};
59
60struct image_state_t {
61    b_queue_t msg_evt;
62    b_event_t msg_evt_data[MAX_MSG_EVENTS];
63    struct bitmap_t bitmap;
64    uint32_t blocks_count;
65    uint32_t blocks_received;
66    struct dii_info_t dii_data;
67    struct dii_module_t dii_module;
68    struct image_t * im;
69};
70
71struct abs_path_t {
72    uint8_t abs_path_length;
73    uint8_t abs_path_byte[0x100];
74};
75
76static struct image_state_t image_state;
77
78static void * msg_callback(void * c, size_t msg_size);
79static void * msg_callback_ddb(void * c, size_t msg_size);
80static void * overflow_callback(void * c, size_t msg_size);
81
82static void bitmap_clear(struct bitmap_t * bm);
83static void bitmap_set_bit(struct bitmap_t * bm, uint32_t bit);
84static uint32_t bitmap_get_bit(struct bitmap_t * bm, uint32_t bit);
85
86
87bresult image_init(void)
88{
89    bresult bres;
90    memset(&image_state, 0, sizeof(struct image_state_t));
91    bres = bos_create_queue(&image_state.msg_evt, image_state.msg_evt_data, MAX_MSG_EVENTS);
92    BDBG_SetModuleLevel("image_recv", BDBG_eMsg);
93    return bres;
94}
95/***************************************************************************
96Summary: receive image from dsm-cc pid
97Description:
98Input:
99Output:
100Returns:
101SeeAlso:
102None
103***************************************************************************/
104/*
105   - Setup filter to capture dii
106   - discover module number and all releated attributes
107   - initialize storage and bitmap
108   - setup filter to capture module data
109   - capture module blocks and store them in to image_t structure
110 */
111
112bresult image_receive(bband_t band, uint16_t pid, struct image_t ** image, uint8_t name_length, uint8_t * name)
113{
114    smessage_stream_t dii, ddb;
115    smessage_stream_params_t params;
116    bresult bres;
117    size_t msg_size;
118    size_t idx;
119    size_t i;
120#if 0
121    struct abs_path_t * ap;
122#endif
123    *image = NULL;
124
125    dii = smessage_open(smessage_format_psi);
126    BDBG_ASSERT(NULL != dii);
127
128    smessage_stream_params_init(&params, dii);
129    params.band = band;
130    params.pid = pid;
131    params.buffer_size = MSG_BUFFER_SIZE;
132    params.buffer = msg_buffer;
133    params.data_ready_callback = msg_callback;
134    params.overflow = overflow_callback;
135    params.callback_context = &image_state;
136    params.filter.coef[0] = 0x3b;
137    params.filter.mask[0] = 0x00;
138    params.filter.coef[8] = 0x11;
139    params.filter.mask[8] = 0x00;
140    params.filter.coef[9] = 0x03;
141    params.filter.mask[9] = 0x00;
142    params.filter.coef[10] = 0x10;
143    params.filter.mask[10] = 0x00;
144    params.filter.coef[11] = 0x02;
145    params.filter.mask[11] = 0x00;
146    BDBG_MSG_0(("dii on pid 0x%x.", pid));
147    while(1){
148        bres = smessage_start(&params, dii);
149        BDBG_ASSERT(b_ok == bres);
150
151        msg_size = (size_t)bos_pend_event(image_state.msg_evt, MSG_TIMEOUT);
152        bres = smessage_stop(dii);
153        BDBG_ASSERT(b_ok == bres);
154
155        if(0 == msg_size){
156            smessage_close(dii);
157            bres = berr_timeout;
158            goto ExitFunc;
159        }
160        bres = dsmcc_dii_parse(msg_buffer, msg_size, &image_state.dii_data);
161        if(0 == bres){
162            BDBG_MSG_0(("got dii %u nom:%u", msg_size, image_state.dii_data.number_of_modules));
163            for(i = 0; i < image_state.dii_data.number_of_modules; i++){
164                bres = dsmcc_dii_next_module(&image_state.dii_data, &image_state.dii_module);
165                if(0 == bres){
166#if 0
167                    ap = (struct abs_path_t *)(&image_state.dii_module.module_info_byte[0]);
168                    if(name_length != ap->abs_path_length){
169                        BDBG_MSG_0(("abs_path_length mismatch %d %d.", name_length, ap->abs_path_length));
170                        continue;
171                    }
172                    for(idx = 0; idx < name_length; idx++){
173                        if(ap->abs_path_byte[idx] != name[idx]){
174                            BDBG_MSG_0(("abs_path_byte mismatch."));
175                            break;
176                        }
177                    }
178#else
179                    if(name_length != image_state.dii_module.module_info_length){
180                        BDBG_MSG_0(("module_info_length mismatch %d %d.", name_length, image_state.dii_module.module_info_length));
181                        continue;
182                    }
183                    for(idx = 0; idx < name_length; idx++){
184                        if(image_state.dii_module.module_info_byte[idx] != name[idx]){
185                            BDBG_MSG_0(("module_info_byte mismatch."));
186                            break;
187                        }
188                    }
189#endif
190                    if(idx == name_length){
191                        break;
192                    }
193                }
194            }
195            if(i < image_state.dii_data.number_of_modules){
196                break;          /* found one we are looking for */
197            }
198        }else{
199            BDBG_ERR(("got dii parser failed %u", bres));
200        }
201    }
202    smessage_close(dii);
203
204    bitmap_clear(&image_state.bitmap);
205    image_state.blocks_count = image_state.dii_module.module_size/image_state.dii_data.block_size + 
206                (((image_state.dii_module.module_size%image_state.dii_data.block_size == 0))?0:1);
207    image_state.blocks_received = 0;
208    image_state.im = malloc(sizeof(struct image_t) + image_state.dii_module.module_size + (image_state.dii_data.block_size*2));
209    BDBG_ASSERT(NULL != image_state.im);
210    memset((image_state.im->data + image_state.dii_module.module_size), 0x55, (image_state.dii_data.block_size*2));
211    image_state.im->size = image_state.dii_module.module_size;
212
213    ddb = smessage_open(smessage_format_psi);
214    BDBG_ASSERT(NULL != ddb);
215
216    smessage_stream_params_init(&params, dii);
217    params.band = band;
218    params.pid = pid;
219    params.buffer_size = MSG_BUFFER_SIZE;
220    params.buffer = msg_buffer;
221    params.data_ready_callback = msg_callback_ddb;
222    params.overflow = overflow_callback;
223    params.callback_context = &image_state;
224    params.filter.coef[0] = 0x3c;
225    params.filter.mask[0] = 0x00;
226    params.filter.coef[3] = (image_state.dii_module.module_id >> 8) & 0xff;
227    params.filter.mask[3] = 0;
228    params.filter.coef[4] = image_state.dii_module.module_id & 0xff;
229    params.filter.mask[4] = 0;
230    params.filter.coef[8] = 0x11;
231    params.filter.mask[8] = 0x00;
232    params.filter.coef[9] = 0x03;
233    params.filter.mask[9] = 0x00;
234    params.filter.coef[10] = 0x10;
235    params.filter.mask[10] = 0x00;
236    params.filter.coef[11] = 0x03;
237    params.filter.mask[11] = 0x00;
238
239    bres = smessage_start(&params, ddb);
240    BDBG_ASSERT(b_ok == bres);
241
242    msg_size = (size_t)bos_pend_event(image_state.msg_evt, DDB_TIMEOUT);
243
244    bres = smessage_stop(ddb);
245    BDBG_ASSERT(b_ok == bres);
246
247    if(0 == msg_size){
248        BDBG_ERR(("ddb timeout"));
249        free(image_state.im);
250        bres = berr_timeout;
251    }else{
252        *image = image_state.im;
253        bres = b_ok;
254    }
255    smessage_close(ddb);
256
257ExitFunc:
258    return bres;
259}
260
261void * msg_callback(void * c, size_t msg_size)
262{
263    struct image_state_t * is;
264    is = (struct image_state_t *)c;
265    bos_post_event(is->msg_evt, (b_event_t*)msg_size);
266    return NULL;
267}
268
269void * msg_callback_ddb(void * c, size_t msg_size)
270{
271    bresult bres;
272    struct image_state_t * is;
273    struct ddb_info_t ddb_data;
274    is = (struct image_state_t *)c;
275
276    bres = dsmcc_ddb_parse(msg_buffer, msg_size, &ddb_data);
277    if(0 == bres){
278        uint32_t have_block;
279                BDBG_MSG_0(("got ddb %u %hu %hu", msg_size, ddb_data.module_id, ddb_data.block_number));
280        have_block = bitmap_get_bit(&is->bitmap, ddb_data.block_number);
281        if(0 == have_block){
282            uint8_t * p_block;
283            size_t copy_size;
284            size_t block_offset;
285
286            BDBG_MSG_2(("%hx %hx %hx %hx", ddb_data.data_bytes[0], ddb_data.data_bytes[1], ddb_data.data_bytes[2], ddb_data.data_bytes[3]));
287            block_offset = ddb_data.block_number * is->dii_data.block_size;
288            p_block = is->im->data + block_offset;
289            copy_size = (is->dii_module.module_size - block_offset) > is->dii_data.block_size ? is->dii_data.block_size : (is->dii_module.module_size - block_offset);
290            memcpy(p_block, ddb_data.data_bytes, copy_size);
291
292            is->blocks_received++;
293                        BDBG_MSG_0(("Copied %u (%d, %d)", copy_size, is->blocks_received, is->blocks_count));
294            bitmap_set_bit(&is->bitmap, ddb_data.block_number);
295            if(is->blocks_count == is->blocks_received){
296                BDBG_MSG_0(("Received all blocks"));
297                bos_post_event(is->msg_evt, (b_event_t*)msg_size);
298            }
299        }else{
300            BDBG_MSG_0(("Have block %u", ddb_data.block_number));
301        }
302    }
303    return msg_buffer;
304}
305
306void * overflow_callback(void * c, size_t msg_size)
307{
308    return NULL;
309}
310
311void bitmap_clear(struct bitmap_t * bm)
312{
313    memset(bm, 0, sizeof(struct bitmap_t));
314}
315
316void bitmap_set_bit(struct bitmap_t * bm, uint32_t bit)
317{
318    uint32_t word;
319    uint32_t word_bit;
320
321    BDBG_ASSERT(MAX_BITS > bit);
322    word = bit >> 5;
323    word_bit = bit & 0x1f;
324    bm->bits[word] |= (0x1 << word_bit);
325}
326
327uint32_t bitmap_get_bit(struct bitmap_t * bm, uint32_t bit)
328{
329    uint32_t word;
330    uint32_t word_bit;
331
332    BDBG_ASSERT(MAX_BITS > bit);
333    word = bit >> 5;
334    word_bit = bit & 0x1f;
335    return ((bm->bits[word] >> word_bit) & 1);
336}
337
338void image_get_status(struct image_status_t * status)
339{
340    status->blocks_count = image_state.blocks_count;
341    status->blocks_received = image_state.blocks_received;
342    status->module_version = image_state.dii_module.module_version;
343    status->module_info_length = image_state.dii_module.module_info_length;
344    status->module_info_bytes = &image_state.dii_module.module_info_byte[0];
345}
346
Note: See TracBrowser for help on using the repository browser.