00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "hdhomerun.h"
00034
00035 #define FREQUENCY_RESOLUTION 62500
00036
00037 struct hdhomerun_channel_entry_t {
00038 struct hdhomerun_channel_entry_t *next;
00039 struct hdhomerun_channel_entry_t *prev;
00040 uint32_t frequency;
00041 uint8_t channel_number;
00042 char name[16];
00043 };
00044
00045 struct hdhomerun_channel_list_t {
00046 struct hdhomerun_channel_entry_t *head;
00047 struct hdhomerun_channel_entry_t *tail;
00048 };
00049
00050 struct hdhomerun_channelmap_range_t {
00051 uint8_t channel_range_start;
00052 uint8_t channel_range_end;
00053 uint32_t frequency;
00054 uint32_t spacing;
00055 };
00056
00057 struct hdhomerun_channelmap_record_t {
00058 const char *channelmap_prefix;
00059 const char *channelmap;
00060 const struct hdhomerun_channelmap_range_t *range_list;
00061 const char *channelmap_scan_group;
00062 const char *countrycodes;
00063 };
00064
00065
00066 static const struct hdhomerun_channelmap_range_t hdhomerun_channelmap_range_au_bcast[] = {
00067 { 2, 2, 48500000, 7000000},
00068 { 3, 4, 59500000, 7000000},
00069 { 5, 12, 177500000, 7000000},
00070 { 28, 69, 529500000, 7000000},
00071 { 0, 0, 0, 0}
00072 };
00073
00074
00075 static const struct hdhomerun_channelmap_range_t hdhomerun_channelmap_range_au_cable[] = {
00076 { 0, 0, 0, 0}
00077 };
00078
00079
00080 static const struct hdhomerun_channelmap_range_t hdhomerun_channelmap_range_eu_bcast[] = {
00081 { 2, 4, 50500000, 7000000},
00082 { 5, 12, 177500000, 7000000},
00083 { 21, 69, 474000000, 8000000},
00084 { 0, 0, 0, 0}
00085 };
00086
00087
00088 static const struct hdhomerun_channelmap_range_t hdhomerun_channelmap_range_eu_cable[] = {
00089 { 6, 7, 113000000, 8000000},
00090 { 9, 100, 138000000, 8000000},
00091 { 0, 0, 0, 0}
00092 };
00093
00094
00095 static const struct hdhomerun_channelmap_range_t hdhomerun_channelmap_range_us_bcast[] = {
00096 { 2, 4, 57000000, 6000000},
00097 { 5, 6, 79000000, 6000000},
00098 { 7, 13, 177000000, 6000000},
00099 { 14, 69, 473000000, 6000000},
00100 { 0, 0, 0, 0}
00101 };
00102
00103
00104 static const struct hdhomerun_channelmap_range_t hdhomerun_channelmap_range_us_cable[] = {
00105 { 2, 4, 57000000, 6000000},
00106 { 5, 6, 79000000, 6000000},
00107 { 7, 13, 177000000, 6000000},
00108 { 14, 22, 123000000, 6000000},
00109 { 23, 94, 219000000, 6000000},
00110 { 95, 99, 93000000, 6000000},
00111 {100, 135, 651000000, 6000000},
00112 { 0, 0, 0, 0}
00113 };
00114
00115
00116 static const struct hdhomerun_channelmap_range_t hdhomerun_channelmap_range_us_hrc[] = {
00117 { 2, 4, 55752700, 6000300},
00118 { 5, 6, 79753900, 6000300},
00119 { 7, 13, 175758700, 6000300},
00120 { 14, 22, 121756000, 6000300},
00121 { 23, 94, 217760800, 6000300},
00122 { 95, 99, 91754500, 6000300},
00123 {100, 135, 649782400, 6000300},
00124 { 0, 0, 0, 0}
00125 };
00126
00127
00128 static const struct hdhomerun_channelmap_range_t hdhomerun_channelmap_range_us_irc[] = {
00129 { 2, 4, 57012500, 6000000},
00130 { 5, 6, 81012500, 6000000},
00131 { 7, 13, 177012500, 6000000},
00132 { 14, 22, 123012500, 6000000},
00133 { 23, 41, 219012500, 6000000},
00134 { 42, 42, 333025000, 6000000},
00135 { 43, 94, 339012500, 6000000},
00136 { 95, 97, 93012500, 6000000},
00137 { 98, 99, 111025000, 6000000},
00138 {100, 135, 651012500, 6000000},
00139 { 0, 0, 0, 0}
00140 };
00141
00142 static const struct hdhomerun_channelmap_record_t hdhomerun_channelmap_table[] = {
00143 {"au", "au-bcast", hdhomerun_channelmap_range_au_bcast, "au-bcast", "AU"},
00144 {"au", "au-cable", hdhomerun_channelmap_range_au_cable, "au-cable", "AU"},
00145 {"eu", "eu-bcast", hdhomerun_channelmap_range_eu_bcast, "eu-bcast", "EU"},
00146 {"eu", "eu-cable", hdhomerun_channelmap_range_eu_cable, "eu-cable", "EU"},
00147 {"tw", "tw-bcast", hdhomerun_channelmap_range_us_bcast, "tw-bcast", "TW"},
00148 {"tw", "tw-cable", hdhomerun_channelmap_range_us_cable, "tw-cable", "TW"},
00149 {"us", "us-bcast", hdhomerun_channelmap_range_us_bcast, "us-bcast", "CA US"},
00150 {"us", "us-cable", hdhomerun_channelmap_range_us_cable, "us-cable us-hrc us-irc", "CA US"},
00151 {"us", "us-hrc", hdhomerun_channelmap_range_us_hrc , "us-cable us-hrc us-irc", "CA US"},
00152 {"us", "us-irc", hdhomerun_channelmap_range_us_irc, "us-cable us-hrc us-irc", "CA US"},
00153 {NULL, NULL, NULL, NULL, NULL}
00154 };
00155
00156 const char *hdhomerun_channelmap_convert_countrycode_to_channelmap_prefix(const char *countrycode)
00157 {
00158 const struct hdhomerun_channelmap_record_t *record = hdhomerun_channelmap_table;
00159 while (record->channelmap) {
00160 if (strstr(record->countrycodes, countrycode)) {
00161 return record->channelmap_prefix;
00162 }
00163 record++;
00164 }
00165
00166 return "eu";
00167 }
00168
00169 const char *hdhomerun_channelmap_get_channelmap_scan_group(const char *channelmap)
00170 {
00171 const struct hdhomerun_channelmap_record_t *record = hdhomerun_channelmap_table;
00172 while (record->channelmap) {
00173 if (strstr(channelmap, record->channelmap)) {
00174 return record->channelmap_scan_group;
00175 }
00176 record++;
00177 }
00178
00179 return NULL;
00180 }
00181
00182 uint8_t hdhomerun_channel_entry_channel_number(struct hdhomerun_channel_entry_t *entry)
00183 {
00184 return entry->channel_number;
00185 }
00186
00187 uint32_t hdhomerun_channel_entry_frequency(struct hdhomerun_channel_entry_t *entry)
00188 {
00189 return entry->frequency;
00190 }
00191
00192 const char *hdhomerun_channel_entry_name(struct hdhomerun_channel_entry_t *entry)
00193 {
00194 return entry->name;
00195 }
00196
00197 struct hdhomerun_channel_entry_t *hdhomerun_channel_list_first(struct hdhomerun_channel_list_t *channel_list)
00198 {
00199 return channel_list->head;
00200 }
00201
00202 struct hdhomerun_channel_entry_t *hdhomerun_channel_list_last(struct hdhomerun_channel_list_t *channel_list)
00203 {
00204 return channel_list->tail;
00205 }
00206
00207 struct hdhomerun_channel_entry_t *hdhomerun_channel_list_next(struct hdhomerun_channel_list_t *channel_list, struct hdhomerun_channel_entry_t *entry)
00208 {
00209 return entry->next;
00210 }
00211
00212 struct hdhomerun_channel_entry_t *hdhomerun_channel_list_prev(struct hdhomerun_channel_list_t *channel_list, struct hdhomerun_channel_entry_t *entry)
00213 {
00214 return entry->prev;
00215 }
00216
00217 uint32_t hdhomerun_channel_list_total_count(struct hdhomerun_channel_list_t *channel_list)
00218 {
00219 uint32_t count = 0;
00220
00221 struct hdhomerun_channel_entry_t *entry = hdhomerun_channel_list_first(channel_list);
00222 while (entry) {
00223 count++;
00224 entry = hdhomerun_channel_list_next(channel_list, entry);
00225 }
00226
00227 return count;
00228 }
00229
00230 uint32_t hdhomerun_channel_list_frequency_count(struct hdhomerun_channel_list_t *channel_list)
00231 {
00232 uint32_t count = 0;
00233 uint32_t last_frequency = 0;
00234
00235 struct hdhomerun_channel_entry_t *entry = hdhomerun_channel_list_first(channel_list);
00236 while (entry) {
00237 if (entry->frequency != last_frequency) {
00238 last_frequency = entry->frequency;
00239 count++;
00240 }
00241
00242 entry = hdhomerun_channel_list_next(channel_list, entry);
00243 }
00244
00245 return count;
00246 }
00247
00248 uint32_t hdhomerun_channel_frequency_truncate(uint32_t frequency)
00249 {
00250 return (frequency / FREQUENCY_RESOLUTION) * FREQUENCY_RESOLUTION;
00251 }
00252
00253 uint32_t hdhomerun_channel_number_to_frequency(struct hdhomerun_channel_list_t *channel_list, uint8_t channel_number)
00254 {
00255 struct hdhomerun_channel_entry_t *entry = hdhomerun_channel_list_first(channel_list);
00256 while (entry) {
00257 if (entry->channel_number == channel_number) {
00258 return entry->frequency;
00259 }
00260
00261 entry = hdhomerun_channel_list_next(channel_list, entry);
00262 }
00263
00264 return 0;
00265 }
00266
00267 uint8_t hdhomerun_channel_frequency_to_number(struct hdhomerun_channel_list_t *channel_list, uint32_t frequency)
00268 {
00269 frequency = hdhomerun_channel_frequency_truncate(frequency);
00270
00271 struct hdhomerun_channel_entry_t *entry = hdhomerun_channel_list_first(channel_list);
00272 while (entry) {
00273 if (entry->frequency == frequency) {
00274 return entry->channel_number;
00275 }
00276 if (entry->frequency > frequency) {
00277 return 0;
00278 }
00279
00280 entry = hdhomerun_channel_list_next(channel_list, entry);
00281 }
00282
00283 return 0;
00284 }
00285
00286 static void hdhomerun_channel_list_build_insert(struct hdhomerun_channel_list_t *channel_list, struct hdhomerun_channel_entry_t *entry)
00287 {
00288 struct hdhomerun_channel_entry_t *prev = NULL;
00289 struct hdhomerun_channel_entry_t *next = channel_list->head;
00290
00291 while (next) {
00292 if (next->frequency > entry->frequency) {
00293 break;
00294 }
00295
00296 prev = next;
00297 next = next->next;
00298 }
00299
00300 entry->prev = prev;
00301 entry->next = next;
00302
00303 if (prev) {
00304 prev->next = entry;
00305 } else {
00306 channel_list->head = entry;
00307 }
00308
00309 if (next) {
00310 next->prev = entry;
00311 } else {
00312 channel_list->tail = entry;
00313 }
00314 }
00315
00316 static void hdhomerun_channel_list_build_range(struct hdhomerun_channel_list_t *channel_list, const char *channelmap, const struct hdhomerun_channelmap_range_t *range)
00317 {
00318 uint8_t channel_number;
00319 for (channel_number = range->channel_range_start; channel_number <= range->channel_range_end; channel_number++) {
00320 struct hdhomerun_channel_entry_t *entry = (struct hdhomerun_channel_entry_t *)calloc(1, sizeof(struct hdhomerun_channel_entry_t));
00321 if (!entry) {
00322 return;
00323 }
00324
00325 entry->channel_number = channel_number;
00326 entry->frequency = range->frequency + ((uint32_t)(channel_number - range->channel_range_start) * range->spacing);
00327 entry->frequency = hdhomerun_channel_frequency_truncate(entry->frequency);
00328 sprintf(entry->name, "%s:%u", channelmap, entry->channel_number);
00329
00330 hdhomerun_channel_list_build_insert(channel_list, entry);
00331 }
00332 }
00333
00334 static void hdhomerun_channel_list_build_ranges(struct hdhomerun_channel_list_t *channel_list, const struct hdhomerun_channelmap_record_t *record)
00335 {
00336 const struct hdhomerun_channelmap_range_t *range = record->range_list;
00337 while (range->frequency) {
00338 hdhomerun_channel_list_build_range(channel_list, record->channelmap, range);
00339 range++;
00340 }
00341 }
00342
00343 void hdhomerun_channel_list_destroy(struct hdhomerun_channel_list_t *channel_list)
00344 {
00345 while (channel_list->head) {
00346 struct hdhomerun_channel_entry_t *entry = channel_list->head;
00347 channel_list->head = entry->next;
00348 free(entry);
00349 }
00350
00351 free(channel_list);
00352 }
00353
00354 struct hdhomerun_channel_list_t *hdhomerun_channel_list_create(const char *channelmap)
00355 {
00356 struct hdhomerun_channel_list_t *channel_list = (struct hdhomerun_channel_list_t *)calloc(1, sizeof(struct hdhomerun_channel_list_t));
00357 if (!channel_list) {
00358 return NULL;
00359 }
00360
00361 const struct hdhomerun_channelmap_record_t *record = hdhomerun_channelmap_table;
00362 while (record->channelmap) {
00363 if (!strstr(channelmap, record->channelmap)) {
00364 record++;
00365 continue;
00366 }
00367
00368 hdhomerun_channel_list_build_ranges(channel_list, record);
00369 record++;
00370 }
00371
00372 if (!channel_list->head) {
00373 free(channel_list);
00374 return NULL;
00375 }
00376
00377 return channel_list;
00378 }