/* * section and descriptor parser * * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef _UCSI_SECTION_H #define _UCSI_SECTION_H 1 #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #define CRC_SIZE 4 /** * Generic section header. */ struct section { uint8_t table_id; EBIT4(uint16_t syntax_indicator : 1; , uint16_t private_indicator : 1; , /* 2.4.4.10 */ uint16_t reserved : 2; , uint16_t length :12; ); } __ucsi_packed; /** * Generic extended section header structure. */ struct section_ext { uint8_t table_id; EBIT4(uint16_t syntax_indicator : 1; , uint16_t private_indicator : 1; , /* 2.4.4.10 */ uint16_t reserved : 2; , uint16_t length :12; ); uint16_t table_id_ext; EBIT3(uint8_t reserved1 : 2; , uint8_t version_number : 5; , uint8_t current_next_indicator : 1; ); uint8_t section_number; uint8_t last_section_number; } __ucsi_packed; /** * Structure for keeping track of sections of a PSI table. */ struct psi_table_state { uint8_t version_number; uint16_t next_section_number; uint8_t complete:1; uint8_t new_table:1; } __ucsi_packed; /** * Determine the total length of a section, including the header. * * @param section The parsed section structure. * @return The length. */ static inline size_t section_length(struct section *section) { return section->length + sizeof(struct section); } /** * Determine the total length of an extended section, including the header, * but omitting the CRC. * * @param section The parsed section_ext structure. * @return The length. */ static inline size_t section_ext_length(struct section_ext * section) { return section->length + sizeof(struct section) - CRC_SIZE; } /** * Process a section structure in-place. * * @param buf Pointer to the data. * @param len Length of data. * @return Pointer to the section structure, or NULL if invalid. */ static inline struct section * section_codec(uint8_t * buf, size_t len) { struct section * ret = (struct section *)buf; if (len < 3) return NULL; bswap16(buf+1); if (len != ret->length + 3U) return NULL; return ret; } /** * Some sections have a CRC even though they are not section_exts. * This function is to allow checking of them. * * @param section Pointer to the processed section structure. * @return Nonzero on error, or 0 if the CRC was correct. */ static inline int section_check_crc(struct section *section) { uint8_t * buf = (uint8_t *) section; size_t len = section_length(section); uint32_t crc; /* the crc check has to be performed on the unswapped data */ bswap16(buf+1); crc = crc32(CRC32_INIT, buf, len); bswap16(buf+1); /* the crc check includes the crc value, * the result should therefore be zero. */ if (crc) return -1; return 0; } /** * Decode an extended section structure. * * @param section Pointer to the processed section structure. * @param check_crc If 1, the CRC of the section will also be checked. * @return Pointer to the parsed section_ext structure, or NULL if invalid. */ static inline struct section_ext * section_ext_decode(struct section * section, int check_crc) { if (section->syntax_indicator == 0) return NULL; if (check_crc) { if (section_check_crc(section)) return NULL; } bswap16((uint8_t *)section + sizeof(struct section)); return (struct section_ext *)section; } /** * Encode an extended section structure for transmission. * * @param section Pointer to the section_ext structure. * @param update_crc If 1, the CRC of the section will also be updated. * @return Pointer to the encoded section_ext structure, or NULL if invalid. */ static inline struct section_ext * section_ext_encode(struct section_ext* section, int update_crc) { if (section->syntax_indicator == 0) return NULL; bswap16((uint8_t *)section + sizeof(struct section)); if (update_crc) { uint8_t * buf = (uint8_t *) section; int len = sizeof(struct section) + section->length; uint32_t crc; /* the crc has to be performed on the swapped data */ bswap16(buf+1); crc = crc32(CRC32_INIT, buf, len-4); bswap16(buf+1); /* update the CRC */ *((uint32_t*) (buf+len-4)) = crc; bswap32(buf+len-4); } return (struct section_ext *)section; } /** * Reset a psi_table_state structure. * * @param tstate The structure to reset. */ static inline void psi_table_state_reset(struct psi_table_state *tstate) { tstate->version_number = 0xff; } /** * Check if a supplied section_ext is something we want to process. * * @param section The parsed section_ext structure. * @param tstate The state structure for this PSI table. * @return 0=> not useful. nonzero => useful. */ static inline int section_ext_useful(struct section_ext *section, struct psi_table_state *tstate) { if ((section->version_number == tstate->version_number) && tstate->complete) return 0; if (section->version_number != tstate->version_number) { if (section->section_number != 0) return 0; tstate->next_section_number = 0; tstate->complete = 0; tstate->version_number = section->version_number; tstate->new_table = 1; } else if (section->section_number == tstate->next_section_number) { tstate->new_table = 0; } else { return 0; } tstate->next_section_number++; if (section->last_section_number < tstate->next_section_number) { tstate->complete = 1; } return 1; } #ifdef __cplusplus } #endif #endif 0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
T 666000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE