| OLD | NEW |
| (Empty) | |
| 1 /* |
| 2 * Copyright 2012 Cisco Systems, Inc. and/or its affiliates. All rights reserved
. |
| 3 * Author: Konke Radlow <koradlow@gmail.com> |
| 4 * |
| 5 * This program is free software; you can redistribute it and/or modify |
| 6 * it under the terms of the GNU Lesser General Public License as published by |
| 7 * the Free Software Foundation; either version 2.1 of the License, or |
| 8 * (at your option) any later version. |
| 9 * |
| 10 * This program is distributed in the hope that it will be useful, |
| 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 * GNU General Public License for more details. |
| 14 * |
| 15 * You should have received a copy of the GNU General Public License |
| 16 * along with this program; if not, write to the Free Software |
| 17 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
| 18 */ |
| 19 |
| 20 #ifndef __LIBV4L2RDS |
| 21 #define __LIBV4L2RDS |
| 22 |
| 23 |
| 24 #include <stdbool.h> |
| 25 #include <stdint.h> |
| 26 |
| 27 #include <linux/videodev2.h> |
| 28 |
| 29 #ifdef __cplusplus |
| 30 extern "C" { |
| 31 #endif /* __cplusplus */ |
| 32 |
| 33 #if HAVE_VISIBILITY |
| 34 #define LIBV4L_PUBLIC __attribute__ ((visibility("default"))) |
| 35 #else |
| 36 #define LIBV4L_PUBLIC |
| 37 #endif |
| 38 |
| 39 /* used to define the current version (version field) of the v4l2_rds struct */ |
| 40 #define V4L2_RDS_VERSION (2) |
| 41 |
| 42 /* Constants used to define the size of arrays used to store RDS information */ |
| 43 #define MAX_ODA_CNT 18 /* there are 16 groups each with type a or b. Of these |
| 44 * 32 distinct groups, 18 can be used for ODA purposes *
/ |
| 45 #define MAX_AF_CNT 25 /* AF Method A allows a maximum of 25 AFs to be defined |
| 46 * AF Method B does not impose a limit on the number of
AFs |
| 47 * but it is not fully supported at the moment and will |
| 48 * not receive more than 25 AFs */ |
| 49 #define MAX_TMC_ADDITIONAL 28 /* 28 is the maximal possible number of fields. |
| 50 * Additional data is limited to 112 bit, and the smalles
t |
| 51 * optional tuple has a size of 4 bit (4 bit identifier + |
| 52 * 0 bits of data) */ |
| 53 #define MAX_TMC_ALT_STATIONS 32 /* defined by ISO 14819-1:2003, 7.5.3.3 */ |
| 54 #define MAX_TMC_AF_CNT 4 /* limit for the numbers of AFs stored per alter
native TMC |
| 55 * station. This value is not defined by the standard, bu
t based on observation |
| 56 * of real-world RDS-TMC streams. The maximum encountered
number of AFs per |
| 57 * station during testing was 2 */ |
| 58 #define MAX_EON_CNT 20 /* Maximal number of entries in the EON table (for stori
ng |
| 59 * information about other radio stations, broadcasted by
the current station). |
| 60 * This value is not defined by the standard, but based o
n observation |
| 61 * of real-world RDS-TMC streams. EON doesn't seem to be
a widely used feature |
| 62 * and the maximum number of EON encountered during testi
ng was 8 */ |
| 63 |
| 64 /* Define Constants for the possible types of RDS information |
| 65 * used to address the relevant bit in the valid_fields bitmask */ |
| 66 #define V4L2_RDS_PI 0x01 /* Program Identification */ |
| 67 #define V4L2_RDS_PTY 0x02 /* Program Type */ |
| 68 #define V4L2_RDS_TP 0x04 /* Traffic Program */ |
| 69 #define V4L2_RDS_PS 0x08 /* Program Service Name */ |
| 70 #define V4L2_RDS_TA 0x10 /* Traffic Announcement */ |
| 71 #define V4L2_RDS_DI 0x20 /* Decoder Information */ |
| 72 #define V4L2_RDS_MS 0x40 /* Music / Speech flag */ |
| 73 #define V4L2_RDS_PTYN 0x80 /* Program Type Name */ |
| 74 #define V4L2_RDS_RT 0x100 /* Radio-Text */ |
| 75 #define V4L2_RDS_TIME 0x200 /* Date and Time information */ |
| 76 #define V4L2_RDS_TMC 0x400 /* TMC availability */ |
| 77 #define V4L2_RDS_AF 0x800 /* AF (alternative freq) available */ |
| 78 #define V4L2_RDS_ECC 0x1000 /* Extended County Code */ |
| 79 #define V4L2_RDS_LC 0x2000 /* Language Code */ |
| 80 #define V4L2_RDS_TMC_SG 0x4000 /* RDS-TMC single group */ |
| 81 #define V4L2_RDS_TMC_MG 0x8000 /* RDS-TMC multi group */ |
| 82 #define V4L2_RDS_TMC_SYS 0x10000 /* RDS-TMC system information */ |
| 83 #define V4L2_RDS_EON 0x20000 /* Enhanced Other Network Info */ |
| 84 #define V4L2_RDS_LSF 0x40000 /* Linkage information */ |
| 85 #define V4L2_RDS_TMC_TUNING 0x80000 /* RDS-TMC tuning information */ |
| 86 |
| 87 /* Define Constants for the state of the RDS decoding process |
| 88 * used to address the relevant bit in the decode_information bitmask */ |
| 89 #define V4L2_RDS_GROUP_NEW 0x01 /* New group received */ |
| 90 #define V4L2_RDS_ODA 0x02 /* Open Data Group announced */ |
| 91 |
| 92 /* Decoder Information (DI) codes |
| 93 * used to decode the DI information according to the RDS standard */ |
| 94 #define V4L2_RDS_FLAG_STEREO 0x01 |
| 95 #define V4L2_RDS_FLAG_ARTIFICIAL_HEAD 0x02 |
| 96 #define V4L2_RDS_FLAG_COMPRESSED 0x04 |
| 97 #define V4L2_RDS_FLAG_DYNAMIC_PTY 0x08 |
| 98 |
| 99 /* TMC related codes |
| 100 * used to extract TMC fields from RDS-TMC groups |
| 101 * see ISO 14819-1:2003, Figure 2 - RDS-TMC single-grp full message structure */ |
| 102 #define V4L2_TMC_TUNING_INFO 0x10 /* Bit 4 indicates Tuning Info / User ms
g */ |
| 103 #define V4L2_TMC_SINGLE_GROUP 0x08 /* Bit 3 indicates Single / Multi-group
msg */ |
| 104 |
| 105 /* struct to encapsulate one complete RDS group */ |
| 106 /* This structure is used internally to store data until a complete RDS |
| 107 * group was received and group id dependent decoding can be done. |
| 108 * It is also used to provide external access to uninterpreted RDS groups |
| 109 * when manual decoding is required (e.g. special ODA types) */ |
| 110 struct v4l2_rds_group { |
| 111 uint16_t pi; /* Program Identification */ |
| 112 char group_version; /* group version ('A' / 'B') */ |
| 113 uint8_t group_id; /* group number (0..16) */ |
| 114 |
| 115 /* uninterpreted data blocks for decoding (e.g. ODA) */ |
| 116 uint8_t data_b_lsb; |
| 117 uint8_t data_c_msb; |
| 118 uint8_t data_c_lsb; |
| 119 uint8_t data_d_msb; |
| 120 uint8_t data_d_lsb; |
| 121 }; |
| 122 |
| 123 /* struct to encapsulate some statistical information about the decoding process
*/ |
| 124 struct v4l2_rds_statistics { |
| 125 uint32_t block_cnt; /* total amount of received blocks */ |
| 126 uint32_t group_cnt; /* total amount of successfully |
| 127 * decoded groups */ |
| 128 uint32_t block_error_cnt; /* blocks that were marked as erroneous |
| 129 * and had to be dropped */ |
| 130 uint32_t group_error_cnt; /* group decoding processes that had to
be |
| 131 * aborted because of erroneous blocks |
| 132 * or wrong order of blocks */ |
| 133 uint32_t block_corrected_cnt; /* blocks that contained 1-bit errors |
| 134 * which were corrected */ |
| 135 uint32_t group_type_cnt[16]; /* number of occurrence for each |
| 136 * defined RDS group */ |
| 137 }; |
| 138 |
| 139 /* struct to encapsulate the definition of one ODA (Open Data Application) type
*/ |
| 140 struct v4l2_rds_oda { |
| 141 uint8_t group_id; /* RDS group used to broadcast this ODA */ |
| 142 char group_version; /* group version (A / B) for this ODA */ |
| 143 uint16_t aid; /* Application Identification for this ODA, |
| 144 * AIDs are centrally administered by the |
| 145 * RDS Registration Office (rds.org.uk) */ |
| 146 }; |
| 147 |
| 148 /* struct to encapsulate an array of all defined ODA types for a channel */ |
| 149 /* This structure will grow with ODA announcements broadcasted in type 3A |
| 150 * groups, that were verified not to be no duplicates or redefinitions */ |
| 151 struct v4l2_rds_oda_set { |
| 152 uint8_t size; /* number of ODAs defined by this channel */ |
| 153 struct v4l2_rds_oda oda[MAX_ODA_CNT]; |
| 154 }; |
| 155 |
| 156 /* struct to encapsulate an array of Alternative Frequencies for a channel */ |
| 157 /* Every channel can send out AFs for his program. The number of AFs that |
| 158 * will be broadcasted is announced by the channel */ |
| 159 struct v4l2_rds_af_set { |
| 160 uint8_t size; /* size of the set (might be smaller |
| 161 * than the announced size) */ |
| 162 uint8_t announced_af; /* number of announced AF */ |
| 163 uint32_t af[MAX_AF_CNT]; /* AFs defined in Hz */ |
| 164 }; |
| 165 |
| 166 /* struct to encapsulate one entry in the EON table (Enhanced Other Network) */ |
| 167 struct v4l2_rds_eon { |
| 168 uint32_t valid_fields; |
| 169 uint16_t pi; |
| 170 uint8_t ps[9]; |
| 171 uint8_t pty; |
| 172 bool ta; |
| 173 bool tp; |
| 174 uint16_t lsf; /* Linkage Set Number */ |
| 175 struct v4l2_rds_af_set af; |
| 176 }; |
| 177 |
| 178 /* struct to encapsulate a table of EON information */ |
| 179 struct v4l2_rds_eon_set { |
| 180 uint8_t size; /* size of the table */ |
| 181 uint8_t index; /* current position in the table */ |
| 182 struct v4l2_rds_eon eon[MAX_EON_CNT]; /* Information about other |
| 183 * radio channels */ |
| 184 }; |
| 185 |
| 186 /* struct to encapsulate alternative frequencies (AFs) for RDS-TMC stations. |
| 187 * AFs listed in af[] can be used unconditionally. |
| 188 * AFs listed in mapped_af[n] should only be used if the current |
| 189 * tuner frequency matches the value in mapped_af_tuning[n] */ |
| 190 struct v4l2_tmc_alt_freq { |
| 191 uint8_t af_size; /* number of known AFs */ |
| 192 uint8_t af_index; |
| 193 uint8_t mapped_af_size; /* number of mapped AFs */ |
| 194 uint8_t mapped_af_index; |
| 195 uint32_t af[MAX_TMC_AF_CNT]; /* AFs defined in Hz */ |
| 196 uint32_t mapped_af[MAX_TMC_AF_CNT]; /* mapped AFs defined in
Hz */ |
| 197 uint32_t mapped_af_tuning[MAX_TMC_AF_CNT]; /* mapped AFs defined in
Hz */ |
| 198 }; |
| 199 |
| 200 /* struct to encapsulate information about stations carrying RDS-TMC services */ |
| 201 struct v4l2_tmc_station { |
| 202 uint16_t pi; |
| 203 uint8_t ltn; /* database-ID of ON */ |
| 204 uint8_t msg; /* msg parameters of ON */ |
| 205 uint8_t sid; /* service-ID of ON */ |
| 206 struct v4l2_tmc_alt_freq afi; |
| 207 }; |
| 208 |
| 209 /* struct to encapsulate tuning information for TMC */ |
| 210 struct v4l2_tmc_tuning { |
| 211 uint8_t station_cnt; /* number of announced alternative stations */ |
| 212 uint8_t index; |
| 213 struct v4l2_tmc_station station[MAX_TMC_ALT_STATIONS]; /* information |
| 214 * about other stations c
arrying the same RDS-TMC service */ |
| 215 }; |
| 216 |
| 217 /* struct to encapsulate an additional data field in a TMC message */ |
| 218 struct v4l2_tmc_additional { |
| 219 uint8_t label; |
| 220 uint16_t data; |
| 221 }; |
| 222 |
| 223 /* struct to encapsulate an arbitrary number of additional data fields |
| 224 * belonging to one TMC message */ |
| 225 struct v4l2_tmc_additional_set { |
| 226 uint8_t size; |
| 227 struct v4l2_tmc_additional fields[MAX_TMC_ADDITIONAL]; |
| 228 }; |
| 229 |
| 230 /* struct to encapsulate a decoded TMC message with optional additional |
| 231 * data field (in case of a multi-group TMC message) */ |
| 232 struct v4l2_rds_tmc_msg { |
| 233 uint8_t length; /* length of multi-group message (0..4) */ |
| 234 uint8_t sid; /* service identifier at time of reception */ |
| 235 uint8_t extent; |
| 236 uint8_t dp; /* duration and persistence */ |
| 237 uint16_t event; /* TMC event code */ |
| 238 uint16_t location; /* TMC event location */ |
| 239 bool follow_diversion; /* indicates if the driver is adviced to |
| 240 * follow the diversion */ |
| 241 bool neg_direction; /* indicates negative / positive direction */ |
| 242 |
| 243 /* decoded additional information (only available in multi-group |
| 244 * messages) */ |
| 245 struct v4l2_tmc_additional_set additional; |
| 246 }; |
| 247 |
| 248 /* struct to encapsulate all TMC related information, including TMC System |
| 249 * Information, TMC Tuning information and a buffer for the last decoded |
| 250 * TMC messages */ |
| 251 struct v4l2_rds_tmc { |
| 252 uint8_t ltn; /* location_table_number */ |
| 253 bool afi; /* alternative frequency indicator */ |
| 254 bool enhanced_mode; /* mode of transmission, |
| 255 * if false -> basic => gaps between tmc groups |
| 256 * gap defines timing behavior |
| 257 * if true -> enhanced => t_a, t_w and t_d |
| 258 * define timing behavior of tmc groups */ |
| 259 uint8_t mgs; /* message geographical scope */ |
| 260 uint8_t sid; /* service identifier (unique ID on national lev
el) */ |
| 261 uint8_t gap; /* Gap parameters */ |
| 262 uint8_t t_a; /* activity time (only if mode = enhanced) */ |
| 263 uint8_t t_w; /* window time (only if mode = enhanced */ |
| 264 uint8_t t_d; /* delay time (only if mode = enhanced */ |
| 265 uint8_t spn[9]; /* service provider name */ |
| 266 struct v4l2_rds_tmc_msg tmc_msg; |
| 267 |
| 268 /* tuning information for alternative service providers */ |
| 269 struct v4l2_tmc_tuning tuning; |
| 270 }; |
| 271 |
| 272 /* struct to encapsulate state and RDS information for current decoding process
*/ |
| 273 /* This is the structure that will be used by external applications, to |
| 274 * communicate with the library and get access to RDS data */ |
| 275 struct v4l2_rds { |
| 276 /** state information **/ |
| 277 uint32_t decode_information; /* state of decoding process */ |
| 278 uint32_t valid_fields; /* currently valid info fields |
| 279 * of this structure */ |
| 280 |
| 281 /** RDS info fields **/ |
| 282 bool is_rbds; /* use RBDS standard version of LUTs */ |
| 283 uint16_t pi; /* Program Identification */ |
| 284 uint8_t ps[9]; /* Program Service Name, UTF-8 encoding, |
| 285 * '\0' terminated */ |
| 286 uint8_t pty; /* Program Type */ |
| 287 uint8_t ptyn[9]; /* Program Type Name, UTF-8 encoding, |
| 288 * '\0' terminated */ |
| 289 bool ptyn_ab_flag; /* PTYN A/B flag (toggled), to signal |
| 290 * change of PTYN */ |
| 291 uint8_t rt_length; /* length of RT string */ |
| 292 uint8_t rt[65]; /* Radio-Text string, UTF-8 encoding, |
| 293 * '\0' terminated */ |
| 294 bool rt_ab_flag; /* RT A/B flag (toggled), to signal |
| 295 * transmission of new RT */ |
| 296 bool ta; /* Traffic Announcement */ |
| 297 bool tp; /* Traffic Program */ |
| 298 bool ms; /* Music / Speech flag */ |
| 299 uint8_t di; /* Decoder Information */ |
| 300 uint8_t ecc; /* Extended Country Code */ |
| 301 uint8_t lc; /* Language Code */ |
| 302 time_t time; /* local time and date of transmission */ |
| 303 |
| 304 struct v4l2_rds_statistics rds_statistics; |
| 305 struct v4l2_rds_oda_set rds_oda; /* Open Data Services */ |
| 306 struct v4l2_rds_af_set rds_af; /* Alternative Frequencies */ |
| 307 struct v4l2_rds_eon_set rds_eon; /* EON information */ |
| 308 struct v4l2_rds_tmc tmc; /* TMC information */ |
| 309 }; |
| 310 |
| 311 /* v4l2_rds_init() - initializes a new decoding process |
| 312 * @is_rbds: defines which standard is used: true=RBDS, false=RDS |
| 313 * |
| 314 * initialize a new instance of the RDS-decoding struct and return |
| 315 * a handle containing state and RDS information, used to interact |
| 316 * with the library functions */ |
| 317 LIBV4L_PUBLIC struct v4l2_rds *v4l2_rds_create(bool is_rbds); |
| 318 |
| 319 /* frees all memory allocated for the RDS-decoding struct */ |
| 320 LIBV4L_PUBLIC void v4l2_rds_destroy(struct v4l2_rds *handle); |
| 321 |
| 322 /* resets the RDS information in the handle to initial values |
| 323 * e.g. can be used when radio channel is changed |
| 324 * @reset_statistics: true = set all statistic values to 0, false = keep them
untouched */ |
| 325 LIBV4L_PUBLIC void v4l2_rds_reset(struct v4l2_rds *handle, bool reset_statistics
); |
| 326 |
| 327 /* adds a raw RDS block to decode it into RDS groups |
| 328 * @return: bitmask with with updated fields set to 1 |
| 329 * @rds_data: 3 bytes of raw RDS data, obtained by calling read() |
| 330 * on RDS capable V4L2 devices */ |
| 331 LIBV4L_PUBLIC uint32_t v4l2_rds_add(struct v4l2_rds *handle, struct v4l2_rds_dat
a *rds_data); |
| 332 |
| 333 /* |
| 334 * group of functions to translate numerical RDS data into strings |
| 335 * |
| 336 * return program description string defined in the RDS/RBDS Standard |
| 337 * ! return value depends on selected Standard !*/ |
| 338 LIBV4L_PUBLIC const char *v4l2_rds_get_pty_str(const struct v4l2_rds *handle); |
| 339 LIBV4L_PUBLIC const char *v4l2_rds_get_language_str(const struct v4l2_rds *handl
e); |
| 340 LIBV4L_PUBLIC const char *v4l2_rds_get_country_str(const struct v4l2_rds *handle
); |
| 341 LIBV4L_PUBLIC const char *v4l2_rds_get_coverage_str(const struct v4l2_rds *handl
e); |
| 342 |
| 343 /* returns a pointer to the last decoded RDS group, in order to give raw |
| 344 * access to RDS data if it is required (e.g. ODA decoding) */ |
| 345 LIBV4L_PUBLIC const struct v4l2_rds_group *v4l2_rds_get_group |
| 346 (const struct v4l2_rds *handle); |
| 347 |
| 348 |
| 349 #ifdef __cplusplus |
| 350 } |
| 351 #endif /* __cplusplus */ |
| 352 #endif |
| OLD | NEW |