| 1 | /*************************************************************************** |
|---|
| 2 | * Copyright (c) 2007-2009, 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: bmsglib.h $ |
|---|
| 11 | * $brcm_Revision: Hydra_Software_Devel/11 $ |
|---|
| 12 | * $brcm_Date: 7/8/09 2:57p $ |
|---|
| 13 | * |
|---|
| 14 | * Module Description: |
|---|
| 15 | * |
|---|
| 16 | * Revision History: |
|---|
| 17 | * |
|---|
| 18 | * $brcm_Log: /magnum/syslib/msglib/7401/bmsglib.h $ |
|---|
| 19 | * |
|---|
| 20 | * Hydra_Software_Devel/11 7/8/09 2:57p erickson |
|---|
| 21 | * PR53768: removed BMSGlib_BufferMode. it was never implemented and has |
|---|
| 22 | * no use. |
|---|
| 23 | * |
|---|
| 24 | * Hydra_Software_Devel/10 3/24/09 10:01a erickson |
|---|
| 25 | * PR53516: added BMSGlib_GetStatus |
|---|
| 26 | * |
|---|
| 27 | * Hydra_Software_Devel/9 6/18/08 1:08p erickson |
|---|
| 28 | * PR43730: fix warnings by moving param to size_t |
|---|
| 29 | * |
|---|
| 30 | * Hydra_Software_Devel/8 5/9/08 1:29p erickson |
|---|
| 31 | * PR42456: added BMSGlib_Format_ePES_SAVE_ALL. clarified that |
|---|
| 32 | * maxContiguousMessageSize only applies to PSI messages. |
|---|
| 33 | * |
|---|
| 34 | * Hydra_Software_Devel/7 4/14/08 1:16p erickson |
|---|
| 35 | * PR41730: move user buffer override from Open time to Start time to give |
|---|
| 36 | * maximum flexibility |
|---|
| 37 | * |
|---|
| 38 | * Hydra_Software_Devel/6 3/21/08 11:04a erickson |
|---|
| 39 | * PR40813: added BMSGlib_SessionParams.bank. Removed unimplemented |
|---|
| 40 | * BMSGlib_Format's. Clarified mem alloc design. |
|---|
| 41 | * |
|---|
| 42 | * Hydra_Software_Devel/5 3/10/08 1:27p erickson |
|---|
| 43 | * PR39836: enforce memory allocation rules for group masters. If the |
|---|
| 44 | * group master Closes, all other sessions in the group must be Stopped. |
|---|
| 45 | * Don't allow the group master to restart if there are other sessions |
|---|
| 46 | * still active in the group. |
|---|
| 47 | * |
|---|
| 48 | * Hydra_Software_Devel/4 2/26/08 10:29p erickson |
|---|
| 49 | * PR39781: allow maxContiguousMessageSize == 0 for no data copy on wrap |
|---|
| 50 | * around |
|---|
| 51 | * |
|---|
| 52 | * Hydra_Software_Devel/3 9/13/07 1:42p gmullen |
|---|
| 53 | * PR32868: Changed bmsglib to accept PID channel number, rather than PID |
|---|
| 54 | * and band combo. |
|---|
| 55 | * |
|---|
| 56 | * Hydra_Software_Devel/2 7/26/07 11:11p erickson |
|---|
| 57 | * PR32868: added more debug and verification |
|---|
| 58 | * |
|---|
| 59 | * Hydra_Software_Devel/1 7/26/07 12:35p erickson |
|---|
| 60 | * PR32868: initial checkin of BMSGlib |
|---|
| 61 | * |
|---|
| 62 | ************************************************************************/ |
|---|
| 63 | #ifndef BMSGLIB_H__ |
|---|
| 64 | #define BMSGLIB_H__ |
|---|
| 65 | |
|---|
| 66 | /*=****************************** |
|---|
| 67 | Provide library for message filtering, especially for an efficient, reliable implementation of filter groups. |
|---|
| 68 | |
|---|
| 69 | 740x platforms have a HW restriction which limits a pid/band to be routed to the message filter block only once. |
|---|
| 70 | This creates the requirement to use filter groups if you want to apply more than one filter on a pid. |
|---|
| 71 | This HW restriction does not exist in all chips. For those chips which supports duplicate pid channels, BMSGlib_SessionParams.filterGroup |
|---|
| 72 | defaults to false. |
|---|
| 73 | |
|---|
| 74 | Filter groups allow multiple filters to be applied on a single pid channel, but places all filtered messages into a |
|---|
| 75 | single ring buffer. This requires the application to demux the messages per filter. |
|---|
| 76 | |
|---|
| 77 | BMSGlib supports high-bandwidth message capture. Therfore it minimizes any data copy. |
|---|
| 78 | |
|---|
| 79 | Sample Usage: |
|---|
| 80 | void dataReadyCallback_isr(void *context) |
|---|
| 81 | { |
|---|
| 82 | BKNI_SetEvent((BKNI_EventHandle)context); |
|---|
| 83 | } |
|---|
| 84 | |
|---|
| 85 | main() |
|---|
| 86 | { |
|---|
| 87 | uint16_t pids[]; // given |
|---|
| 88 | BKNI_EventHandle event; |
|---|
| 89 | BMSGlib_Settings settings; |
|---|
| 90 | BMSGlib_Handle msglib; |
|---|
| 91 | BMSGlib_Session_Handle msglib_session; |
|---|
| 92 | |
|---|
| 93 | BMSGlib_GetDefaultSettings(&settings); |
|---|
| 94 | settings.xpt = xpt; |
|---|
| 95 | settings.mem = mem; |
|---|
| 96 | BMSGlib_Open(&msglib, settings); |
|---|
| 97 | |
|---|
| 98 | BKNI_CreateEvent(&event); |
|---|
| 99 | |
|---|
| 100 | BMSGlib_GetDefaultSessionSetting(&session_settings); |
|---|
| 101 | session_settings.bufferSize = 4*1024; // let MSGlib alloc |
|---|
| 102 | session_settings.dataReadyCallback_isr = dataReadyCallback_isr; |
|---|
| 103 | session_settings.callbackContext = event; |
|---|
| 104 | BMSGlib_OpenSession(&msglib_session, &session_settings); |
|---|
| 105 | |
|---|
| 106 | for (i=0;i<total_pids;i++) { |
|---|
| 107 | BMSGlib_SessionParams params; |
|---|
| 108 | |
|---|
| 109 | BMSGlib_GetDefaultSessionParams(msglib_session, ¶ms); |
|---|
| 110 | params.format = BMSGlib_Format_ePSI; |
|---|
| 111 | params.pid = pids[i]; |
|---|
| 112 | params.parserBand = X; |
|---|
| 113 | params.filterGroup = false; // don't need filter groups because this is synchronous |
|---|
| 114 | BMSGlib_StartSession(msglib_session, ¶ms); |
|---|
| 115 | |
|---|
| 116 | // event will fire when data is available. this app assumes it will. |
|---|
| 117 | BKNI_WaitForEvent(event, BKNI_INFINITE); |
|---|
| 118 | rc = BMSGlib_GetBuffer(msglib_session, &buffer, &length); |
|---|
| 119 | if (rc) continue; // error |
|---|
| 120 | |
|---|
| 121 | // buffer is guaranteed to contain at least one whole message |
|---|
| 122 | BDBG_ASSERT(length); |
|---|
| 123 | |
|---|
| 124 | process_message(buffer, length); |
|---|
| 125 | |
|---|
| 126 | BMSGlib_StopSession(msglib_session); |
|---|
| 127 | } |
|---|
| 128 | BMSGlib_CloseSession(msglib_session); |
|---|
| 129 | BMSGlib_Close(msglib); |
|---|
| 130 | BKNI_DestroyEvent(event); |
|---|
| 131 | } |
|---|
| 132 | *********************************/ |
|---|
| 133 | |
|---|
| 134 | #include "bstd.h" |
|---|
| 135 | #include "bmem.h" |
|---|
| 136 | #include "bxpt.h" |
|---|
| 137 | |
|---|
| 138 | #ifdef __cplusplus |
|---|
| 139 | extern "C" { |
|---|
| 140 | #endif |
|---|
| 141 | |
|---|
| 142 | /* A global handle is needed for resource allocation. */ |
|---|
| 143 | typedef struct BMSGlib_Impl *BMSGlib_Handle; |
|---|
| 144 | |
|---|
| 145 | /* A session is one filter for a band/pid combination. */ |
|---|
| 146 | typedef struct BMSGlib_Session_Impl *BMSGlib_Session_Handle; |
|---|
| 147 | |
|---|
| 148 | /* |
|---|
| 149 | Summary: |
|---|
| 150 | The settings needed for opening the BMSGlib singleton. |
|---|
| 151 | */ |
|---|
| 152 | typedef struct BMSGlib_Settings { |
|---|
| 153 | BMEM_Handle mem; |
|---|
| 154 | BXPT_Handle xpt; |
|---|
| 155 | } BMSGlib_Settings; |
|---|
| 156 | |
|---|
| 157 | /* |
|---|
| 158 | Summary: |
|---|
| 159 | Calltype typedef used by the session to notify the caller of state changes or other information. |
|---|
| 160 | */ |
|---|
| 161 | typedef void (*BMSGlib_Callback)(void *context); |
|---|
| 162 | |
|---|
| 163 | /* |
|---|
| 164 | Summary: |
|---|
| 165 | The settings needed for opening a session. |
|---|
| 166 | |
|---|
| 167 | Description: |
|---|
| 168 | If you use filter groups, only the memory from the first filter in the group will be used. |
|---|
| 169 | See BMSGlib_OpenSession for more details on buffer allocation options. |
|---|
| 170 | */ |
|---|
| 171 | typedef struct BMSGlib_SessionSettings { |
|---|
| 172 | unsigned bufferSize; /* Size in bytes. Only certain buffer sizes may be supported by HW. This size will be rounded down to the nearest supported value. |
|---|
| 173 | If you want to control the allocation and use of memory, set this to zero; then set BMSGlib_SessionParams.buffer. */ |
|---|
| 174 | |
|---|
| 175 | void *callbackContext; /* app context pointer passed to all BMSGlib_Callbacks. */ |
|---|
| 176 | BMSGlib_Callback dataReadyCallback_isr; /* Called whenever data is available. |
|---|
| 177 | App should schedule future call to BMSGlib_GetBuffer, but cannot call BMSGlib_GetBuffer in this isr callback. |
|---|
| 178 | This is required for filter groups. |
|---|
| 179 | If a dataReadyCallback is sent, it is possible that GetBuffer may still return no data. */ |
|---|
| 180 | BMSGlib_Callback overflowCallback_isr; /* called if overflow occurs. app should return very quickly. */ |
|---|
| 181 | |
|---|
| 182 | unsigned maxContiguousMessageSize; /* The maximum size PSI message that is guaranteed to be returned as a whole message from BMSGlib_GetBuffer. |
|---|
| 183 | For high bitrate message capture, set this to zero. This will ensure no data copy and GetBuffer will not |
|---|
| 184 | guarantee to return whole messages. |
|---|
| 185 | This does not apply to PES/TS capture. */ |
|---|
| 186 | } BMSGlib_SessionSettings; |
|---|
| 187 | |
|---|
| 188 | /* |
|---|
| 189 | The type of data being captured in a session. |
|---|
| 190 | */ |
|---|
| 191 | typedef enum BMSGlib_Format { |
|---|
| 192 | BMSGlib_Format_ePSI, /* capture PSI sections */ |
|---|
| 193 | BMSGlib_Format_ePES, /* capture entire PES packets, respecting PES packet length */ |
|---|
| 194 | BMSGlib_Format_ePES_SAVE_ALL, /* capture entire TS payload, without reference to PES packet length */ |
|---|
| 195 | BMSGlib_Format_eTS /* capture entire transport stream */ |
|---|
| 196 | } BMSGlib_Format; |
|---|
| 197 | |
|---|
| 198 | /* |
|---|
| 199 | Summary: |
|---|
| 200 | The parameters needed for starting a session. |
|---|
| 201 | */ |
|---|
| 202 | typedef struct BMSGlib_SessionParams { |
|---|
| 203 | BMSGlib_Format format; |
|---|
| 204 | |
|---|
| 205 | int bank; /* Select filter bank 0..3. If -1, MSGlib will automatically select the bank. Default is -1. |
|---|
| 206 | For filter groups, HW requires that all filters in a group be on the same bank. MSGlib will |
|---|
| 207 | attempt to do this. However, depending on the pattern of application filter usage, automatic filter selection may |
|---|
| 208 | not be possible. If you hit this case, your application will need to use explicit filter bank selection. */ |
|---|
| 209 | |
|---|
| 210 | /* Number of the PID channel that carries the data. NOTE: Caller must configure the channel before starting the session. */ |
|---|
| 211 | unsigned PidChannel; |
|---|
| 212 | |
|---|
| 213 | BXPT_Filter filter; /* See bxpt.h for documentation. Be aware that byte 2 is skipped. */ |
|---|
| 214 | bool filterGroup; /* If true, BMSGlib will use filter groups. This value defaults to true only on those platforms |
|---|
| 215 | where filter groups are required for multiple filters on the same pid. */ |
|---|
| 216 | bool psiCrcDisabled; /* Disable CRC checks on PSI information */ |
|---|
| 217 | bool psfCrcDisabled; /* Disable CRC checks on short form private sections */ |
|---|
| 218 | |
|---|
| 219 | void *buffer; /* Optional user-supplied uncached-memory buffer which is bufferSize in length. |
|---|
| 220 | If NULL, MSGlib will use the buffer allocated with BMSGlib_SessionSettings.bufferSize. |
|---|
| 221 | Buffers must be physically contiguous, 1K aligned and BMSGlib_Settings.mem should be able to convert between physical address and cached memory. */ |
|---|
| 222 | unsigned bufferSize; /* Size in bytes. Only certain buffer sizes may be supported by HW. The actual size used will be rounded down to the nearest supported value. */ |
|---|
| 223 | } BMSGlib_SessionParams; |
|---|
| 224 | |
|---|
| 225 | /* |
|---|
| 226 | Summary: |
|---|
| 227 | Get default settings for BMSGlib_Open. |
|---|
| 228 | */ |
|---|
| 229 | void BMSGlib_GetDefaultSettings( |
|---|
| 230 | BMSGlib_Settings *settings /* [out] */ |
|---|
| 231 | ); |
|---|
| 232 | |
|---|
| 233 | /* |
|---|
| 234 | Summary: |
|---|
| 235 | Open the BMSGlib handle singleton. |
|---|
| 236 | |
|---|
| 237 | Description: |
|---|
| 238 | This provides a global resource manager for BMSGlib_Sessions. |
|---|
| 239 | */ |
|---|
| 240 | BERR_Code BMSGlib_Open( |
|---|
| 241 | BMSGlib_Handle *handle, |
|---|
| 242 | const BMSGlib_Settings *settings |
|---|
| 243 | ); |
|---|
| 244 | |
|---|
| 245 | /* |
|---|
| 246 | Summary: |
|---|
| 247 | Close the BMSGlib handle singleton. |
|---|
| 248 | */ |
|---|
| 249 | void BMSGlib_Close( |
|---|
| 250 | BMSGlib_Handle handle |
|---|
| 251 | ); |
|---|
| 252 | |
|---|
| 253 | /* |
|---|
| 254 | Summary: |
|---|
| 255 | Get default settings for BMSGlib_OpenSession |
|---|
| 256 | */ |
|---|
| 257 | void BMSGlib_GetDefaultSessionSettings( |
|---|
| 258 | BMSGlib_Handle handle, |
|---|
| 259 | BMSGlib_SessionSettings *settings /* [out] */ |
|---|
| 260 | ); |
|---|
| 261 | |
|---|
| 262 | /* |
|---|
| 263 | Summary: |
|---|
| 264 | Open a session for capturing messages. Each session can have one filter applied to a parser_band/pid pair at a time. |
|---|
| 265 | |
|---|
| 266 | Description: |
|---|
| 267 | Each session provides control over memory allocation and callback management. |
|---|
| 268 | Memory will be allocated from BMEM if BMSGlib_SessionSettings.bufferSize is non-zero. |
|---|
| 269 | You can restart sessions multiple times with different SessionParams without reallocating memory. |
|---|
| 270 | |
|---|
| 271 | If you are using filter groups, the first session which is started for the PID is considered the group master. |
|---|
| 272 | The buffer memory of the group master is used for message capture. The buffer memory for the other sessions in the group is not used. |
|---|
| 273 | The group master's buffer memory remains in use by the group until all sessions in the group are stopped. |
|---|
| 274 | If the group master is closed before the other sessions in the group are stopped, the group master must stop any other sessions in the group. |
|---|
| 275 | If the group master is started on another pid before the other sessions in the group are stopped, the group master start will fail. |
|---|
| 276 | |
|---|
| 277 | If you want the flexibility to switch any filter in and out of a group, without stopping the other filters, you should allocate your |
|---|
| 278 | own memory with BMEM and give it to BMSGlib using BMSGlib_SessionParams.buffer. |
|---|
| 279 | If you do, MSGlib will not automatically stop filters, regardless of any Close or pid switch. |
|---|
| 280 | The user must ensure the following: |
|---|
| 281 | 1) that all message filters that use a buffer are stoppped before the buffer is deallocated. |
|---|
| 282 | 2) that all message filters that use a buffer are filtering on the same pid. |
|---|
| 283 | */ |
|---|
| 284 | BERR_Code BMSGlib_OpenSession( |
|---|
| 285 | BMSGlib_Handle msglib, |
|---|
| 286 | BMSGlib_Session_Handle *session, |
|---|
| 287 | const BMSGlib_SessionSettings *settings |
|---|
| 288 | ); |
|---|
| 289 | |
|---|
| 290 | /* |
|---|
| 291 | Summary: |
|---|
| 292 | Close this session |
|---|
| 293 | |
|---|
| 294 | Description: |
|---|
| 295 | If this is the group master, this will cause all other sessions in the group to be stopped. |
|---|
| 296 | See BMSGlib_OpenSession for details. |
|---|
| 297 | */ |
|---|
| 298 | void BMSGlib_CloseSession( |
|---|
| 299 | BMSGlib_Session_Handle session |
|---|
| 300 | ); |
|---|
| 301 | |
|---|
| 302 | /* |
|---|
| 303 | Summary: |
|---|
| 304 | Get default session parameters for BMSGlib_StartSession. |
|---|
| 305 | */ |
|---|
| 306 | void BMSGlib_GetDefaultSessionParams( |
|---|
| 307 | BMSGlib_Session_Handle session, |
|---|
| 308 | BMSGlib_SessionParams *params /* [out] */ |
|---|
| 309 | ); |
|---|
| 310 | |
|---|
| 311 | /* |
|---|
| 312 | Summary: |
|---|
| 313 | Start capturing data with this session. |
|---|
| 314 | |
|---|
| 315 | Description: |
|---|
| 316 | If this is the group master, you cannot start on another PID before all other sessions in the group are stopped. |
|---|
| 317 | See BMSGlib_OpenSession for details. |
|---|
| 318 | */ |
|---|
| 319 | BERR_Code BMSGlib_StartSession( |
|---|
| 320 | BMSGlib_Session_Handle session, |
|---|
| 321 | const BMSGlib_SessionParams *params |
|---|
| 322 | ); |
|---|
| 323 | |
|---|
| 324 | /* |
|---|
| 325 | Summary: |
|---|
| 326 | Stop capturing messages with this session. |
|---|
| 327 | |
|---|
| 328 | Description: |
|---|
| 329 | You can restart this session with different SessionParams. |
|---|
| 330 | */ |
|---|
| 331 | void BMSGlib_StopSession( |
|---|
| 332 | BMSGlib_Session_Handle session |
|---|
| 333 | ); |
|---|
| 334 | |
|---|
| 335 | /** |
|---|
| 336 | Summary: |
|---|
| 337 | Get a pointer to a message captured for this session. |
|---|
| 338 | |
|---|
| 339 | Description: |
|---|
| 340 | Guaranteed to return whole PSI messages if maxContiguousMessageSize is non-zero. Wrap around is handled internally. |
|---|
| 341 | You can call BMSGlib_GetBuffer multiple times without changing BMSGlib state. It is not destructive. |
|---|
| 342 | You cannot call BMSGlib_GetBuffer after calling BMSGlib_StopSession. |
|---|
| 343 | **/ |
|---|
| 344 | BERR_Code BMSGlib_GetBuffer( |
|---|
| 345 | BMSGlib_Session_Handle handle, |
|---|
| 346 | const void **buffer, /* [out] cached memory. |
|---|
| 347 | may not come from SessionSettings.buffer. may come from internal buffer if maxContiguousMessageSize > 0, |
|---|
| 348 | or may come from a group buffer (another session in the same filter group). |
|---|
| 349 | Returns NULL if no data is available. |
|---|
| 350 | This is rightly marked as const because the user should not modify the data. If the user does, another BMSGlib_SessionHandle might |
|---|
| 351 | get invalid results. */ |
|---|
| 352 | size_t *length /* [out] number of bytes pointed to by buffer. returns 0 if no data is available. */ |
|---|
| 353 | ); |
|---|
| 354 | |
|---|
| 355 | /* |
|---|
| 356 | Summary: |
|---|
| 357 | Notify MSGlib of how much data was consumed from the last BMSGlib_GetBuffer call. |
|---|
| 358 | |
|---|
| 359 | Description: |
|---|
| 360 | It must be <= the length returned by BMSGlib_GetBuffer. |
|---|
| 361 | If < length, you must call BMSGlib_GetBuffer again to reobtain the pointer to the buffer. |
|---|
| 362 | That is, you cannot call BMSGlib_ReadComplete more than once after each BMSGlib_GetBuffer. |
|---|
| 363 | You cannot call BMSGlib_ReadComplete after calling BMSGlib_StopSession. |
|---|
| 364 | */ |
|---|
| 365 | BERR_Code BMSGlib_ReadComplete( |
|---|
| 366 | BMSGlib_Session_Handle handle, |
|---|
| 367 | unsigned amount_consumed /* number of bytes the caller has processed. Must be <= the length returned by last call to BMSGlib_GetBuffer. */ |
|---|
| 368 | ); |
|---|
| 369 | |
|---|
| 370 | /* |
|---|
| 371 | Summary: |
|---|
| 372 | Status information returned by BMSGlib_GetStatus |
|---|
| 373 | */ |
|---|
| 374 | typedef struct BMSGlib_Status |
|---|
| 375 | { |
|---|
| 376 | unsigned groupMembers; /* total number of filters in the filter group, including this session */ |
|---|
| 377 | bool isGroupMaster; /* true if this session is the group master */ |
|---|
| 378 | } BMSGlib_Status; |
|---|
| 379 | |
|---|
| 380 | /* |
|---|
| 381 | Summary: |
|---|
| 382 | Get status information about the session |
|---|
| 383 | */ |
|---|
| 384 | BERR_Code BMSGlib_GetStatus( |
|---|
| 385 | BMSGlib_Session_Handle handle, |
|---|
| 386 | BMSGlib_Status *pStatus /* [out] */ |
|---|
| 387 | ); |
|---|
| 388 | |
|---|
| 389 | #ifdef __cplusplus |
|---|
| 390 | } |
|---|
| 391 | #endif |
|---|
| 392 | |
|---|
| 393 | #endif /* BMSGLIB_H__ */ |
|---|