source: svn/trunk/newcon3bcm2_21bu/dta/src/nexus/bsettop_smessage.c @ 2

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

first commit

  • Property svn:executable set to *
File size: 10.7 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2012, 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#include "nexus_pid_channel.h"
23#include "nexus_parser_band.h"
24#include "nexus_message.h"
25#include "nexus_memory.h"
26
27#include "bsettop_smessage.h"
28
29BDBG_MODULE(smsg);
30
31#define MAX_FILTERS                             32
32
33#define B_INVALID_PID                   0xFFFF
34#define B_INVALID_PID_CHANNEL   0xFFFF
35#define B_INVALID_BAND                  ((int)-1)
36#define FILTER_SIZE                             16
37
38#define SM_MAGIC                                0xBADBABE0
39#define SM_WAIT                                 (-1)
40#define SM_POLL_INTERVAL                50
41
42enum sm_task_state_t {
43        STS_NONE,
44        STS_IDLE,
45        STS_RUN
46};
47
48struct smessage_stream
49{
50        BLST_S_ENTRY(smessage_stream) next;
51        smessage_format         format;
52        uint16_t                        pid;
53        smessage_callback       callback;
54        smessage_callback       overflow;
55        void                            *context;
56        void                            *priv;
57       
58        NEXUS_PidChannelHandle          pidChannel;
59        NEXUS_MessageHandle             msgHandle;
60        NEXUS_MessageStartSettings      startSettings;
61       
62        void *buffer;
63        size_t buffer_size;
64};
65
66BLST_S_HEAD(smessage_stream_list_t, smessage_stream);
67
68
69struct smessage_state
70{
71        uint32_t magic;
72        int band;
73
74        b_task_t task;
75        b_mutex_t lock;
76        enum sm_task_state_t task_state;
77
78        struct smessage_stream_list_t free_filter;
79        struct smessage_stream_list_t started_filter;
80        struct smessage_stream sm[MAX_FILTERS];
81};
82
83
84static struct smessage_state sm_st;
85
86#define SM_STACK_SIZE   0x400
87#define SM_PRIORITY             16
88static unsigned int sm_stack[SM_STACK_SIZE];
89static char * sm_task_name = "msg";
90void sm_parser_task(void *param);
91
92bresult smessage_init(void *decode_cfgs)
93{
94        int i;
95        b_task_params t_param;
96        bresult bres = b_ok;
97
98        BSTD_UNUSED(decode_cfgs);       
99        BKNI_Memset(&sm_st, 0, sizeof(struct smessage_state));
100        BLST_S_INIT(&sm_st.free_filter);
101        BLST_S_INIT(&sm_st.started_filter);
102        for (i=0; i<MAX_FILTERS; i++) {
103                BLST_S_INSERT_HEAD(&sm_st.free_filter, &sm_st.sm[i], next);
104        }
105
106        bres = bos_create_mutex(&sm_st.lock);
107        if (b_ok != bres) {
108                goto ExitFunc;
109        }
110
111        sm_st.task_state = STS_IDLE;
112        t_param.priority = SM_PRIORITY;
113        t_param.stack_size = SM_STACK_SIZE;
114        t_param.stack = sm_stack;
115        t_param.name = sm_task_name;
116        bres = bos_start_task(&sm_st.task, &t_param, sm_parser_task, NULL);
117        sm_st.magic = SM_MAGIC;
118ExitFunc:
119        return bres;           
120}
121
122/*
123 * Summary:
124 * Cleanup the message system
125 */
126bresult smessage_uninit(void)
127{
128        sm_st.magic = 0;
129        return b_ok;
130}
131
132/*
133 * Summary:
134 * Open a message stream for a particular format of data
135 */
136smessage_stream_t smessage_open(smessage_format format)
137{
138        smessage_stream_t st;
139        bresult res;
140
141        st = NULL;
142        switch (format) {
143        case smessage_format_psi:
144        case smessage_format_tsc:
145                res = bos_acquire_mutex(&sm_st.lock, SM_WAIT);
146                if (b_ok != res) break;
147
148                st = BLST_S_FIRST(&sm_st.free_filter);
149                if (NULL != st) {
150                        BLST_S_REMOVE_HEAD(&sm_st.free_filter, next);
151                        st->format = format;
152                }
153                bos_release_mutex(&sm_st.lock);
154                break;
155        case smessage_format_ts:
156                break;
157        default:
158                break;
159        }
160        return st;
161}
162
163/*
164 * Summary:
165 * Close a message stream
166 */
167void smessage_close(smessage_stream_t stream)
168{
169        bresult res;
170        res = smessage_stop(stream);
171        if (b_ok != res)
172                BDBG_ERR(("%s:%d", __FILE__, __LINE__));
173        BLST_S_INSERT_HEAD(&sm_st.free_filter, stream, next);
174}
175
176/*
177 * Summary:
178 * Initialize parameters structure
179 */
180void smessage_stream_params_init(smessage_stream_params_t *params, smessage_stream_t stream)
181{
182        int i;
183
184        BSTD_UNUSED(stream);
185        if (NULL != params) {
186                BKNI_Memset(params, 0, sizeof(smessage_stream_params_t));
187                params->band = B_INVALID_BAND;
188                params->pid = B_INVALID_PID;
189                params->pid_channel = B_INVALID_PID_CHANNEL;
190                for (i=0; i<FILTER_SIZE; i++) {
191                        params->filter.mask[i] = 0xFF;
192                        params->filter.excl[i] = 0xFF;
193                }
194        }
195}
196
197/*
198 * Summary:
199 * Capture message according to the parameters
200 */
201bresult smessage_start(const smessage_stream_params_t *params, smessage_stream_t stream)
202{
203        bresult res;
204        NEXUS_ParserBandSettings parserBandSettings;
205        NEXUS_MessageSettings settings;
206        NEXUS_MemoryAllocationSettings memSettings;
207        NEXUS_PidChannelSettings pidChannelSettings;
208
209        BDBG_ASSERT(stream);
210        BDBG_ASSERT(params);
211        BDBG_ASSERT(params->buffer);
212
213        if (((stream->format != smessage_format_psi) && (stream->format != smessage_format_tsc)) ||
214                (B_INVALID_BAND == params->band) ||
215                (NULL != stream->msgHandle) ||
216                (NULL != stream->pidChannel) ||
217                (0 == params->buffer_size) )
218        {
219                BDBG_ERR(("%s:%d", __FILE__, __LINE__));
220                BDBG_ERR(("stream->msg = 0x%08x", stream->msgHandle));
221                BDBG_ERR(("stream->pidChannel = 0x%08x", stream->pidChannel));
222                BDBG_ERR(("params->pid = 0x%08x", params->pid));
223                BDBG_ERR(("stream->format = %d", stream->format));
224                BDBG_ERR(("params->band = %d", params->band));
225                BDBG_ERR(("params->buffer_size = %d", params->buffer_size));
226                goto ExitFunc;
227        }
228
229        NEXUS_Memory_GetDefaultAllocationSettings(&memSettings);
230       
231        res = bos_acquire_mutex(&sm_st.lock, SM_WAIT); 
232        if (res != b_ok) {
233                BDBG_ERR(("%s:%d", __FILE__, __LINE__));
234                goto ExitFunc;
235        }
236        NEXUS_ParserBand_GetSettings((NEXUS_ParserBand)NEXUS_ParserBand_e0/*params->band*/, &parserBandSettings);
237        parserBandSettings.sourceType = NEXUS_ParserBandSourceType_eInputBand;
238        NEXUS_ParserBand_SetSettings((NEXUS_ParserBand)NEXUS_ParserBand_e0/*params->band*/, &parserBandSettings);
239
240        stream->pid = params->pid;
241        NEXUS_PidChannel_GetDefaultSettings(&pidChannelSettings);
242        stream->pidChannel = NEXUS_PidChannel_Open((NEXUS_ParserBand)NEXUS_ParserBand_e0/*params->band*/, params->pid, &pidChannelSettings);
243        if (stream->pidChannel == NULL) {
244                BDBG_ERR(("%s:%d", __FILE__, __LINE__));
245                goto ExitUnlock;
246        }
247       
248        NEXUS_Message_GetDefaultSettings(&settings);
249//      settings.maxContiguousMessageSize = 4096;
250        settings.bufferSize = 0; /* don't have Message alloc the buffer, recommended for maximum flexibility. */
251
252        stream->msgHandle = NEXUS_Message_Open(&settings);
253        NEXUS_Message_GetDefaultStartSettings(stream->msgHandle, &stream->startSettings);
254
255        memSettings.alignment = 1024; /* HW PID2BUF requires 1024 boundary */
256        if (NEXUS_Memory_Allocate(params->buffer_size, &memSettings, &stream->startSettings.buffer) != BERR_SUCCESS)
257        {
258                BDBG_ERR(("%s:%d", __FILE__, __LINE__));
259                NEXUS_Message_Close(stream->msgHandle);
260                stream->msgHandle = NULL;
261                goto ExitUnlock;
262        }
263
264        stream->buffer = params->buffer;
265        stream->startSettings.bufferSize = params->buffer_size;
266        switch (stream->format)
267        {
268        case smessage_format_tsc:
269                stream->startSettings.format = NEXUS_MessageFormat_eTs;
270                break;
271        case smessage_format_psi:
272        default:
273                stream->startSettings.format = NEXUS_MessageFormat_ePsi;
274                break;
275        }
276
277        stream->startSettings.psfCrcDisabled = true; /* disable CRC check on short packets */
278        stream->buffer_size = params->buffer_size;
279
280        /* use the default filter for any data */
281        BKNI_Memcpy(stream->startSettings.filter.coefficient, params->filter.coef, FILTER_SIZE);
282        BKNI_Memcpy(stream->startSettings.filter.mask, params->filter.mask, FILTER_SIZE);
283        BKNI_Memcpy(stream->startSettings.filter.exclusion, params->filter.excl, FILTER_SIZE);
284
285        stream->startSettings.pidChannel = stream->pidChannel;
286
287        if (NEXUS_Message_Start(stream->msgHandle, &stream->startSettings) != NEXUS_SUCCESS)
288        {
289                BDBG_ERR(("%s:%d", __FILE__, __LINE__));
290                NEXUS_Message_Close(stream->msgHandle);
291                stream->msgHandle = NULL;
292                NEXUS_Memory_Free(stream->startSettings.buffer);
293                stream->startSettings.buffer = NULL;
294                goto ExitUnlock;
295        }
296
297        stream->callback = params->data_ready_callback;
298        stream->overflow = params->overflow;
299        stream->context = params->callback_context;
300        stream->priv = params->priv;
301
302        BLST_S_INSERT_HEAD(&sm_st.started_filter, stream, next);
303        res = b_ok;
304
305ExitUnlock:
306        bos_release_mutex(&sm_st.lock);
307ExitFunc:
308        return res;
309}
310
311bresult smessage_stop(smessage_stream_t stream)
312{
313        bresult res;
314
315        BDBG_ASSERT(stream);   
316        res = bos_acquire_mutex(&sm_st.lock, SM_WAIT);
317        if (res != b_ok) {
318                BDBG_ERR(("%s:%d", __FILE__, __LINE__));
319                goto ExitFunc;
320        }
321
322        if (stream->msgHandle == NULL) { /* already closed */
323                bos_release_mutex(&sm_st.lock);
324                return b_ok;
325        }
326
327       
328        if (stream->msgHandle) {
329                NEXUS_Message_Stop(stream->msgHandle);
330                NEXUS_Message_Close(stream->msgHandle);
331                stream->msgHandle = NULL;
332        }
333
334        if (stream->pidChannel != NULL) {
335                NEXUS_PidChannel_Close(stream->pidChannel);
336                stream->pidChannel = NULL;
337        }
338
339        if (stream->startSettings.buffer) {
340                NEXUS_Memory_Free(stream->startSettings.buffer);
341                stream->startSettings.buffer = NULL;
342        }
343
344        BLST_S_REMOVE(&sm_st.started_filter, stream, smessage_stream, next);
345        res = b_ok;
346
347        bos_release_mutex(&sm_st.lock);
348
349ExitFunc:
350        return res;     
351}
352
353bresult smessage_get_buffer(smessage_stream_t stream, const void ** pbuffer, size_t * plength)
354{
355        bresult res;
356
357        res = bos_acquire_mutex(&sm_st.lock, SM_WAIT);
358        if (res != b_ok) {
359                BDBG_ERR(("%s:%d", __FILE__, __LINE__));
360                goto ExitFunc;
361        }
362
363        if (NEXUS_Message_GetBuffer(stream->msgHandle, (const void **)pbuffer, plength) != NEXUS_SUCCESS) {
364                res = -1;
365        }
366        bos_release_mutex(&sm_st.lock);
367ExitFunc:
368        return res;
369}
370
371bresult smessage_read_complete(smessage_stream_t stream, size_t consumed)
372{
373        bresult res;
374       
375        res = bos_acquire_mutex(&sm_st.lock, SM_WAIT);
376        if (res != b_ok) {
377                BDBG_ERR(("%s:%d", __FILE__, __LINE__));
378                goto ExitFunc;
379        }
380
381        NEXUS_Message_ReadComplete(stream->msgHandle, consumed);
382        bos_release_mutex(&sm_st.lock);
383ExitFunc:
384        return res;
385}
386
387void sm_parser_task(void *param)
388{
389        smessage_stream_t stream;
390        bresult res;
391
392        void *buffer;
393        size_t size;
394
395        BSTD_UNUSED(param);
396        while(1)
397        {
398                res = bos_acquire_mutex(&sm_st.lock, SM_WAIT);
399                if (res == b_ok)       
400                {
401
402                        for (stream = BLST_S_FIRST(&sm_st.started_filter); stream; stream = BLST_S_NEXT(stream, next))
403                        {
404                                if (!stream->callback || !stream->buffer) 
405                                        continue;
406                                size = 0;
407                                if (NEXUS_Message_GetBuffer(stream->msgHandle, (const void **)&buffer, &size) == NEXUS_SUCCESS)
408                                {
409                                        if (size <= 0) 
410                                                continue;
411
412                                        BKNI_Memcpy(stream->buffer, buffer, size); /* use the app-allocated buffer. */
413                                        stream->buffer = stream->callback(stream->context, size);
414                                        NEXUS_Message_ReadComplete(stream->msgHandle, size);
415                                        if (stream->buffer == NULL) {
416                                                bos_release_mutex(&sm_st.lock);
417                                                smessage_stop(stream);
418                                                if (bos_acquire_mutex(&sm_st.lock, SM_WAIT) != b_ok) {
419                                                        BDBG_ERR(("%s:%d", __FILE__, __LINE__));
420                                                        break;
421                                                }
422                                        }
423                                }       
424                        }
425
426                        res = bos_release_mutex(&sm_st.lock);
427                        if (b_ok != res) {
428                                BDBG_ERR(("bos_release_mutex failed! exiting ..."));
429                                break;
430                        }
431                }
432                else {
433                        BDBG_ERR(("%s:%d", __FILE__, __LINE__));
434                }
435                bos_sleep(SM_POLL_INTERVAL);
436        }
437}
438       
Note: See TracBrowser for help on using the repository browser.