ci.h 4.13 KB
Newer Older
Christophe Massiot's avatar
Christophe Massiot committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
/*****************************************************************************
 * ci.h: ETSI EN 50 221 Common Interface Specification
 *****************************************************************************
 * Copyright (C) 2010 VideoLAN
 * $Id$
 *
 * Authors: Christophe Massiot <massiot@via.ecp.fr>
 *
 * This program is free software. It comes without any warranty, to
 * the extent permitted by applicable law. You can redistribute it
 * and/or modify it under the terms of the Do What The Fuck You Want
 * To Public License, Version 2, as published by Sam Hocevar. See
 * http://sam.zoy.org/wtfpl/COPYING for more details.
 *****************************************************************************/

/*
 * Normative references:
 *  - ETSI EN 50 221 (1997) (Common Interface Specification)
 */

#ifndef __BITSTREAM_DVB_CI_H__
#define __BITSTREAM_DVB_CI_H__

#include <bitstream/mpeg/psi.h>

#ifdef __cplusplus
extern "C"
{
#endif

/*****************************************************************************
 * Conditional Access Program Map Table
 *****************************************************************************
 * Implementation note: the first field here is ca_pmt_list_management,
 * since the previous length field is variable size and is generally put
 * afterwards.
 *****************************************************************************/
#define CAPMT_HEADER_SIZE       6
#define CAPMT_ES_SIZE           5
#define CAPMTI_HEADER_SIZE      3

/* Max theoritical size is PSI_MAX_SIZE + ~100 */
#define CAPMT_DECLARE PSI_PRIVATE_DECLARE
#define capmt_allocate psi_private_allocate

static inline void capmt_init(uint8_t *p_capmt)
{
    p_capmt[3] = 0xc1;
    p_capmt[4] = 0xf0;
}

static inline void capmt_set_listmanagement(uint8_t *p_capmt, uint8_t i_mgt)
{
    p_capmt[0] = i_mgt;
}

static inline void capmt_set_program(uint8_t *p_capmt, uint16_t i_program)
{
    p_capmt[1] = i_program >> 8;
    p_capmt[2] = i_program & 0xff;
}

static inline void capmt_set_version(uint8_t *p_capmt, uint8_t i_version)
{
    p_capmt[3] &= ~0x3e;
    p_capmt[3] |= i_version << 1;
}

static inline uint8_t *capmt_get_infos(uint8_t *p_capmt)
{
    return &p_capmt[4];
}

static inline uint16_t capmt_get_infoslength(const uint8_t *p_capmt)
{
    return ((p_capmt[4] & 0xf) << 8) | p_capmt[5];
}

static inline void capmtn_init(uint8_t *p_capmt_n)
{
    p_capmt_n[1] = 0xe0;
}

static inline void capmtn_set_streamtype(uint8_t *p_capmt_n,
                                         uint8_t i_stream_type)
{
    p_capmt_n[0] = i_stream_type;
}

static inline void capmtn_set_pid(uint8_t *p_capmt_n, uint16_t i_pid)
{
    p_capmt_n[1] &= ~0x1f;
    p_capmt_n[1] |= i_pid >> 8;
    p_capmt_n[2] = i_pid & 0xff;
}

static inline uint16_t capmtn_get_infoslength(const uint8_t *p_capmt_n)
{
    return ((p_capmt_n[3] & 0xf) << 8) | p_capmt_n[4];
}

static inline uint8_t *capmtn_get_infos(uint8_t *p_capmt_n)
{
    return &p_capmt_n[3];
}

static inline uint8_t *capmt_get_es(uint8_t *p_capmt, uint8_t n)
{
    uint8_t *p_capmt_n = p_capmt + CAPMT_HEADER_SIZE
                          + capmt_get_infoslength(p_capmt);

    while (n) {
        p_capmt_n += CAPMT_ES_SIZE + capmtn_get_infoslength(p_capmt_n);
        n--;
    }
    return p_capmt_n;
}

static inline void capmti_init(uint8_t *p_infos)
{
    p_infos[0] = 0xf0;
}

static inline void capmti_set_length(uint8_t *p_infos, uint16_t i_length)
{
    p_infos[0] &= ~0xf;
    p_infos[0] |= i_length >> 8;
    p_infos[1] = i_length & 0xff;
}

static inline uint16_t capmti_get_length(const uint8_t *p_infos)
{
    return ((p_infos[0] & 0xf) << 8) | p_infos[1];
}

static inline void capmti_set_cmd(uint8_t *p_infos, uint8_t i_cmd)
{
    p_infos[2] = i_cmd;
}

static inline uint8_t *capmti_get_info(uint8_t *p_infos, uint16_t n)
{
    uint8_t *p_info = p_infos + CAPMTI_HEADER_SIZE;
    uint16_t i_infos_size = capmti_get_length(p_infos) + DESCS_HEADER_SIZE;

    while (n) {
        if (p_info + DESC_HEADER_SIZE - p_infos > i_infos_size) return NULL;
        p_info += DESC_HEADER_SIZE + desc_get_length(p_info);
        n--;
    }
    if (p_info - p_infos >= i_infos_size) return NULL;
    return p_info;
}

#ifdef __cplusplus
}
#endif

#endif