Ticket #6138: 132-hdhr.20081231.patch
File 132-hdhr.20081231.patch, 243.2 KB (added by , 17 years ago) |
---|
-
mythtv/libs/libmythtv/hdhomerun/README
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/README release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/README
1 /* 2 * README 3 * 4 * Copyright © 2005-2006 Silicondust Engineering Ltd. <www.silicondust.com>. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 3 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 31 */ 1 32 2 This directory contains Silicondust Engineering's hdhomerun 3 library used for communicating with the HDHomeRun hardware. 33 Top level include file: hdhomerun.h 4 34 5 The files in this directory are released under the GNU LESSER GENERAL PUBLIC LICENSE 6 For details see the lgpl.txt file which should be located in this directory. 7 If you can not find it, it can also be seen at http://www.gnu.org/licenses/lgpl.txt 35 Top level API: hdhomerun_device. See hdhomerun_device.h for documentation. 36 37 The hdhomerun_device API should be used rather than the low level control and video APIs required with previous versions. 38 39 Additional libraries required: 40 - pthread 41 - iphlpapi (windows only) -
mythtv/libs/libmythtv/hdhomerun/README.MythTV
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/README.MythTV release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/README.MythTV
1 2 This directory contains Silicondust Engineering's hdhomerun 3 library used for communicating with the HDHomeRun hardware. 4 5 The files in this directory are released under the GNU LESSER GENERAL PUBLIC LICENSE 6 For details see the lgpl.txt file which should be located in this directory. 7 If you can not find it, it can also be seen at http://www.gnu.org/licenses/lgpl.txt -
mythtv/libs/libmythtv/hdhomerun/hdhomerun.h
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun.h release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun.h
1 1 /* 2 * hdhomerun _device.h2 * hdhomerun.h 3 3 * 4 * Copyright © 2006Silicondust Engineering Ltd. <www.silicondust.com>.4 * Copyright © 2006-2008 Silicondust Engineering Ltd. <www.silicondust.com>. 5 5 * 6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU Lesser General Public 8 8 * License as published by the Free Software Foundation; either 9 * version 2.1of the License, or (at your option) any later version.9 * version 3 of the License, or (at your option) any later version. 10 10 * 11 11 * This library is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of … … 14 14 * Lesser General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 19 31 */ 20 32 21 33 #include "hdhomerun_os.h" 34 #include "hdhomerun_types.h" 22 35 #include "hdhomerun_pkt.h" 36 #include "hdhomerun_debug.h" 23 37 #include "hdhomerun_discover.h" 24 38 #include "hdhomerun_control.h" 25 39 #include "hdhomerun_video.h" 40 #include "hdhomerun_channels.h" 41 #include "hdhomerun_channelscan.h" 26 42 #include "hdhomerun_device.h" -
mythtv/libs/libmythtv/hdhomerun/hdhomerun_channels.c
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun_channels.c release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun_channels.c
1 /* 2 * hdhomerun_channels.c 3 * 4 * Copyright © 2007-2008 Silicondust Engineering Ltd. <www.silicondust.com>. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 3 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 31 */ 32 33 #include "hdhomerun.h" 34 35 #define FREQUENCY_RESOLUTION 62500 36 37 struct hdhomerun_channel_entry_t { 38 struct hdhomerun_channel_entry_t *next; 39 struct hdhomerun_channel_entry_t *prev; 40 uint32_t frequency; 41 uint8_t channel_number; 42 char name[16]; 43 }; 44 45 struct hdhomerun_channel_list_t { 46 struct hdhomerun_channel_entry_t *head; 47 struct hdhomerun_channel_entry_t *tail; 48 }; 49 50 struct hdhomerun_channelmap_range_t { 51 uint8_t channel_range_start; 52 uint8_t channel_range_end; 53 uint32_t frequency; 54 uint32_t spacing; 55 }; 56 57 struct hdhomerun_channelmap_record_t { 58 const char *channelmap_prefix; 59 const char *channelmap; 60 const struct hdhomerun_channelmap_range_t *range_list; 61 const char *channelmap_scan_group; 62 const char *countrycodes; 63 }; 64 65 /* AU antenna channels. Channels {0, 1, 2, 6, 7, 8, 9, 9A} are numbered {2, 3, 4, 5, 6, 7, 8, 9} by the HDHomeRun. */ 66 static const struct hdhomerun_channelmap_range_t hdhomerun_channelmap_range_au_bcast[] = { 67 { 2, 2, 48500000, 7000000}, 68 { 3, 4, 59500000, 7000000}, 69 { 5, 12, 177500000, 7000000}, 70 { 28, 69, 529500000, 7000000}, 71 { 0, 0, 0, 0} 72 }; 73 74 /* AU cable channels. TBD. */ 75 static const struct hdhomerun_channelmap_range_t hdhomerun_channelmap_range_au_cable[] = { 76 { 0, 0, 0, 0} 77 }; 78 79 /* EU antenna channels. */ 80 static const struct hdhomerun_channelmap_range_t hdhomerun_channelmap_range_eu_bcast[] = { 81 { 2, 4, 50500000, 7000000}, 82 { 5, 12, 177500000, 7000000}, 83 { 21, 69, 474000000, 8000000}, 84 { 0, 0, 0, 0} 85 }; 86 87 /* EU cable channels. Channels do not have simple numbers - the HDHomeRun uses its own numbering scheme (subject to change). */ 88 static const struct hdhomerun_channelmap_range_t hdhomerun_channelmap_range_eu_cable[] = { 89 { 6, 7, 113000000, 8000000}, 90 { 9, 100, 138000000, 8000000}, 91 { 0, 0, 0, 0} 92 }; 93 94 /* US antenna channels. */ 95 static const struct hdhomerun_channelmap_range_t hdhomerun_channelmap_range_us_bcast[] = { 96 { 2, 4, 57000000, 6000000}, 97 { 5, 6, 79000000, 6000000}, 98 { 7, 13, 177000000, 6000000}, 99 { 14, 69, 473000000, 6000000}, 100 { 0, 0, 0, 0} 101 }; 102 103 /* US cable channels. */ 104 static const struct hdhomerun_channelmap_range_t hdhomerun_channelmap_range_us_cable[] = { 105 { 2, 4, 57000000, 6000000}, 106 { 5, 6, 79000000, 6000000}, 107 { 7, 13, 177000000, 6000000}, 108 { 14, 22, 123000000, 6000000}, 109 { 23, 94, 219000000, 6000000}, 110 { 95, 99, 93000000, 6000000}, 111 {100, 135, 651000000, 6000000}, 112 { 0, 0, 0, 0} 113 }; 114 115 /* US cable channels (HRC). */ 116 static const struct hdhomerun_channelmap_range_t hdhomerun_channelmap_range_us_hrc[] = { 117 { 2, 4, 55752700, 6000300}, 118 { 5, 6, 79753900, 6000300}, 119 { 7, 13, 175758700, 6000300}, 120 { 14, 22, 121756000, 6000300}, 121 { 23, 94, 217760800, 6000300}, 122 { 95, 99, 91754500, 6000300}, 123 {100, 135, 649782400, 6000300}, 124 { 0, 0, 0, 0} 125 }; 126 127 /* US cable channels (IRC). */ 128 static const struct hdhomerun_channelmap_range_t hdhomerun_channelmap_range_us_irc[] = { 129 { 2, 4, 57012500, 6000000}, 130 { 5, 6, 81012500, 6000000}, 131 { 7, 13, 177012500, 6000000}, 132 { 14, 22, 123012500, 6000000}, 133 { 23, 41, 219012500, 6000000}, 134 { 42, 42, 333025000, 6000000}, 135 { 43, 94, 339012500, 6000000}, 136 { 95, 97, 93012500, 6000000}, 137 { 98, 99, 111025000, 6000000}, 138 {100, 135, 651012500, 6000000}, 139 { 0, 0, 0, 0} 140 }; 141 142 static const struct hdhomerun_channelmap_record_t hdhomerun_channelmap_table[] = { 143 {"au", "au-bcast", hdhomerun_channelmap_range_au_bcast, "au-bcast", "AU"}, 144 {"au", "au-cable", hdhomerun_channelmap_range_au_cable, "au-cable", "AU"}, 145 {"eu", "eu-bcast", hdhomerun_channelmap_range_eu_bcast, "eu-bcast", "EU"}, 146 {"eu", "eu-cable", hdhomerun_channelmap_range_eu_cable, "eu-cable", "EU"}, 147 {"tw", "tw-bcast", hdhomerun_channelmap_range_us_bcast, "tw-bcast", "TW"}, 148 {"tw", "tw-cable", hdhomerun_channelmap_range_us_cable, "tw-cable", "TW"}, 149 {"us", "us-bcast", hdhomerun_channelmap_range_us_bcast, "us-bcast", "CA US"}, 150 {"us", "us-cable", hdhomerun_channelmap_range_us_cable, "us-cable us-hrc us-irc", "CA US"}, 151 {"us", "us-hrc", hdhomerun_channelmap_range_us_hrc , "us-cable us-hrc us-irc", "CA US"}, 152 {"us", "us-irc", hdhomerun_channelmap_range_us_irc, "us-cable us-hrc us-irc", "CA US"}, 153 {NULL, NULL, NULL, NULL, NULL} 154 }; 155 156 const char *hdhomerun_channelmap_convert_countrycode_to_channelmap_prefix(const char *countrycode) 157 { 158 const struct hdhomerun_channelmap_record_t *record = hdhomerun_channelmap_table; 159 while (record->channelmap) { 160 if (strstr(record->countrycodes, countrycode)) { 161 return record->channelmap_prefix; 162 } 163 record++; 164 } 165 166 return "eu"; 167 } 168 169 const char *hdhomerun_channelmap_get_channelmap_scan_group(const char *channelmap) 170 { 171 const struct hdhomerun_channelmap_record_t *record = hdhomerun_channelmap_table; 172 while (record->channelmap) { 173 if (strstr(channelmap, record->channelmap)) { 174 return record->channelmap_scan_group; 175 } 176 record++; 177 } 178 179 return NULL; 180 } 181 182 uint8_t hdhomerun_channel_entry_channel_number(struct hdhomerun_channel_entry_t *entry) 183 { 184 return entry->channel_number; 185 } 186 187 uint32_t hdhomerun_channel_entry_frequency(struct hdhomerun_channel_entry_t *entry) 188 { 189 return entry->frequency; 190 } 191 192 const char *hdhomerun_channel_entry_name(struct hdhomerun_channel_entry_t *entry) 193 { 194 return entry->name; 195 } 196 197 struct hdhomerun_channel_entry_t *hdhomerun_channel_list_first(struct hdhomerun_channel_list_t *channel_list) 198 { 199 return channel_list->head; 200 } 201 202 struct hdhomerun_channel_entry_t *hdhomerun_channel_list_last(struct hdhomerun_channel_list_t *channel_list) 203 { 204 return channel_list->tail; 205 } 206 207 struct hdhomerun_channel_entry_t *hdhomerun_channel_list_next(struct hdhomerun_channel_list_t *channel_list, struct hdhomerun_channel_entry_t *entry) 208 { 209 return entry->next; 210 } 211 212 struct hdhomerun_channel_entry_t *hdhomerun_channel_list_prev(struct hdhomerun_channel_list_t *channel_list, struct hdhomerun_channel_entry_t *entry) 213 { 214 return entry->prev; 215 } 216 217 uint32_t hdhomerun_channel_list_total_count(struct hdhomerun_channel_list_t *channel_list) 218 { 219 uint32_t count = 0; 220 221 struct hdhomerun_channel_entry_t *entry = hdhomerun_channel_list_first(channel_list); 222 while (entry) { 223 count++; 224 entry = hdhomerun_channel_list_next(channel_list, entry); 225 } 226 227 return count; 228 } 229 230 uint32_t hdhomerun_channel_list_frequency_count(struct hdhomerun_channel_list_t *channel_list) 231 { 232 uint32_t count = 0; 233 uint32_t last_frequency = 0; 234 235 struct hdhomerun_channel_entry_t *entry = hdhomerun_channel_list_first(channel_list); 236 while (entry) { 237 if (entry->frequency != last_frequency) { 238 last_frequency = entry->frequency; 239 count++; 240 } 241 242 entry = hdhomerun_channel_list_next(channel_list, entry); 243 } 244 245 return count; 246 } 247 248 uint32_t hdhomerun_channel_frequency_truncate(uint32_t frequency) 249 { 250 return (frequency / FREQUENCY_RESOLUTION) * FREQUENCY_RESOLUTION; 251 } 252 253 uint32_t hdhomerun_channel_number_to_frequency(struct hdhomerun_channel_list_t *channel_list, uint8_t channel_number) 254 { 255 struct hdhomerun_channel_entry_t *entry = hdhomerun_channel_list_first(channel_list); 256 while (entry) { 257 if (entry->channel_number == channel_number) { 258 return entry->frequency; 259 } 260 261 entry = hdhomerun_channel_list_next(channel_list, entry); 262 } 263 264 return 0; 265 } 266 267 uint8_t hdhomerun_channel_frequency_to_number(struct hdhomerun_channel_list_t *channel_list, uint32_t frequency) 268 { 269 frequency = hdhomerun_channel_frequency_truncate(frequency); 270 271 struct hdhomerun_channel_entry_t *entry = hdhomerun_channel_list_first(channel_list); 272 while (entry) { 273 if (entry->frequency == frequency) { 274 return entry->channel_number; 275 } 276 if (entry->frequency > frequency) { 277 return 0; 278 } 279 280 entry = hdhomerun_channel_list_next(channel_list, entry); 281 } 282 283 return 0; 284 } 285 286 static void hdhomerun_channel_list_build_insert(struct hdhomerun_channel_list_t *channel_list, struct hdhomerun_channel_entry_t *entry) 287 { 288 struct hdhomerun_channel_entry_t *prev = NULL; 289 struct hdhomerun_channel_entry_t *next = channel_list->head; 290 291 while (next) { 292 if (next->frequency > entry->frequency) { 293 break; 294 } 295 296 prev = next; 297 next = next->next; 298 } 299 300 entry->prev = prev; 301 entry->next = next; 302 303 if (prev) { 304 prev->next = entry; 305 } else { 306 channel_list->head = entry; 307 } 308 309 if (next) { 310 next->prev = entry; 311 } else { 312 channel_list->tail = entry; 313 } 314 } 315 316 static void hdhomerun_channel_list_build_range(struct hdhomerun_channel_list_t *channel_list, const char *channelmap, const struct hdhomerun_channelmap_range_t *range) 317 { 318 uint8_t channel_number; 319 for (channel_number = range->channel_range_start; channel_number <= range->channel_range_end; channel_number++) { 320 struct hdhomerun_channel_entry_t *entry = (struct hdhomerun_channel_entry_t *)calloc(1, sizeof(struct hdhomerun_channel_entry_t)); 321 if (!entry) { 322 return; 323 } 324 325 entry->channel_number = channel_number; 326 entry->frequency = range->frequency + ((uint32_t)(channel_number - range->channel_range_start) * range->spacing); 327 entry->frequency = hdhomerun_channel_frequency_truncate(entry->frequency); 328 sprintf(entry->name, "%s:%u", channelmap, entry->channel_number); 329 330 hdhomerun_channel_list_build_insert(channel_list, entry); 331 } 332 } 333 334 static void hdhomerun_channel_list_build_ranges(struct hdhomerun_channel_list_t *channel_list, const struct hdhomerun_channelmap_record_t *record) 335 { 336 const struct hdhomerun_channelmap_range_t *range = record->range_list; 337 while (range->frequency) { 338 hdhomerun_channel_list_build_range(channel_list, record->channelmap, range); 339 range++; 340 } 341 } 342 343 void hdhomerun_channel_list_destroy(struct hdhomerun_channel_list_t *channel_list) 344 { 345 while (channel_list->head) { 346 struct hdhomerun_channel_entry_t *entry = channel_list->head; 347 channel_list->head = entry->next; 348 free(entry); 349 } 350 351 free(channel_list); 352 } 353 354 struct hdhomerun_channel_list_t *hdhomerun_channel_list_create(const char *channelmap) 355 { 356 struct hdhomerun_channel_list_t *channel_list = (struct hdhomerun_channel_list_t *)calloc(1, sizeof(struct hdhomerun_channel_list_t)); 357 if (!channel_list) { 358 return NULL; 359 } 360 361 const struct hdhomerun_channelmap_record_t *record = hdhomerun_channelmap_table; 362 while (record->channelmap) { 363 if (!strstr(channelmap, record->channelmap)) { 364 record++; 365 continue; 366 } 367 368 hdhomerun_channel_list_build_ranges(channel_list, record); 369 record++; 370 } 371 372 if (!channel_list->head) { 373 free(channel_list); 374 return NULL; 375 } 376 377 return channel_list; 378 } -
mythtv/libs/libmythtv/hdhomerun/hdhomerun_channels.h
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun_channels.h release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun_channels.h
1 /* 2 * hdhomerun_channels.h 3 * 4 * Copyright © 2007-2008 Silicondust Engineering Ltd. <www.silicondust.com>. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 3 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 31 */ 32 33 #ifdef __cplusplus 34 extern "C" { 35 #endif 36 37 struct hdhomerun_channel_entry_t; 38 struct hdhomerun_channel_list_t; 39 40 extern LIBTYPE const char *hdhomerun_channelmap_convert_countrycode_to_channelmap_prefix(const char *countrycode); 41 extern LIBTYPE const char *hdhomerun_channelmap_get_channelmap_scan_group(const char *channelmap); 42 43 extern LIBTYPE uint8_t hdhomerun_channel_entry_channel_number(struct hdhomerun_channel_entry_t *entry); 44 extern LIBTYPE uint32_t hdhomerun_channel_entry_frequency(struct hdhomerun_channel_entry_t *entry); 45 extern LIBTYPE const char *hdhomerun_channel_entry_name(struct hdhomerun_channel_entry_t *entry); 46 47 extern LIBTYPE struct hdhomerun_channel_list_t *hdhomerun_channel_list_create(const char *channelmap); 48 extern LIBTYPE void hdhomerun_channel_list_destroy(struct hdhomerun_channel_list_t *channel_list); 49 50 extern LIBTYPE struct hdhomerun_channel_entry_t *hdhomerun_channel_list_first(struct hdhomerun_channel_list_t *channel_list); 51 extern LIBTYPE struct hdhomerun_channel_entry_t *hdhomerun_channel_list_last(struct hdhomerun_channel_list_t *channel_list); 52 extern LIBTYPE struct hdhomerun_channel_entry_t *hdhomerun_channel_list_next(struct hdhomerun_channel_list_t *channel_list, struct hdhomerun_channel_entry_t *entry); 53 extern LIBTYPE struct hdhomerun_channel_entry_t *hdhomerun_channel_list_prev(struct hdhomerun_channel_list_t *channel_list, struct hdhomerun_channel_entry_t *entry); 54 extern LIBTYPE uint32_t hdhomerun_channel_list_total_count(struct hdhomerun_channel_list_t *channel_list); 55 extern LIBTYPE uint32_t hdhomerun_channel_list_frequency_count(struct hdhomerun_channel_list_t *channel_list); 56 57 extern LIBTYPE uint32_t hdhomerun_channel_frequency_truncate(uint32_t frequency); 58 extern LIBTYPE uint32_t hdhomerun_channel_number_to_frequency(struct hdhomerun_channel_list_t *channel_list, uint8_t channel_number); 59 extern LIBTYPE uint8_t hdhomerun_channel_frequency_to_number(struct hdhomerun_channel_list_t *channel_list, uint32_t frequency); 60 61 #ifdef __cplusplus 62 } 63 #endif -
mythtv/libs/libmythtv/hdhomerun/hdhomerun_channelscan.c
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun_channelscan.c release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun_channelscan.c
1 /* 2 * hdhomerun_channelscan.c 3 * 4 * Copyright © 2007-2008 Silicondust Engineering Ltd. <www.silicondust.com>. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 3 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 31 */ 32 33 #include "hdhomerun.h" 34 35 struct hdhomerun_channelscan_t { 36 struct hdhomerun_device_t *hd; 37 uint32_t scanned_channels; 38 struct hdhomerun_channel_list_t *channel_list; 39 struct hdhomerun_channel_entry_t *next_channel; 40 }; 41 42 struct hdhomerun_channelscan_t *channelscan_create(struct hdhomerun_device_t *hd, const char *channelmap) 43 { 44 struct hdhomerun_channelscan_t *scan = (struct hdhomerun_channelscan_t *)calloc(1, sizeof(struct hdhomerun_channelscan_t)); 45 if (!scan) { 46 return NULL; 47 } 48 49 scan->hd = hd; 50 51 scan->channel_list = hdhomerun_channel_list_create(channelmap); 52 if (!scan->channel_list) { 53 free(scan); 54 return NULL; 55 } 56 57 scan->next_channel = hdhomerun_channel_list_last(scan->channel_list); 58 return scan; 59 } 60 61 void channelscan_destroy(struct hdhomerun_channelscan_t *scan) 62 { 63 free(scan); 64 } 65 66 static int channelscan_execute_find_lock(struct hdhomerun_channelscan_t *scan, uint32_t frequency, struct hdhomerun_channelscan_result_t *result) 67 { 68 /* Set channel. */ 69 char channel_str[64]; 70 sprintf(channel_str, "auto:%ld", (unsigned long)frequency); 71 72 int ret = hdhomerun_device_set_tuner_channel(scan->hd, channel_str); 73 if (ret <= 0) { 74 return ret; 75 } 76 77 /* Wait for lock. */ 78 ret = hdhomerun_device_wait_for_lock(scan->hd, &result->status); 79 if (ret <= 0) { 80 return ret; 81 } 82 if (!result->status.lock_supported) { 83 return 1; 84 } 85 86 /* Wait for symbol quality = 100%. */ 87 int i; 88 for (i = 0; i < 5 * 4; i++) { 89 usleep(250000); 90 91 ret = hdhomerun_device_get_tuner_status(scan->hd, NULL, &result->status); 92 if (ret <= 0) { 93 return ret; 94 } 95 96 if (result->status.symbol_error_quality == 100) { 97 return 1; 98 } 99 } 100 101 /* Timeout. */ 102 return 1; 103 } 104 105 static void channelscan_extract_name(struct hdhomerun_channelscan_program_t *program, const char *line) 106 { 107 /* Find start of name. */ 108 const char *start = strchr(line, ' '); 109 if (!start) { 110 return; 111 } 112 start++; 113 114 start = strchr(start, ' '); 115 if (!start) { 116 return; 117 } 118 start++; 119 120 /* Find end of name. */ 121 const char *end = strstr(start, " ("); 122 if (!end) { 123 end = strchr(line, 0); 124 } 125 126 if (end <= start) { 127 return; 128 } 129 130 /* Extract name. */ 131 size_t length = (size_t)(end - start); 132 if (length > sizeof(program->name) - 1) { 133 length = sizeof(program->name) - 1; 134 } 135 136 strncpy(program->name, start, length); 137 program->name[length] = 0; 138 } 139 140 static int channelscan_execute_detect_programs(struct hdhomerun_channelscan_t *scan, struct hdhomerun_channelscan_result_t *result, int *pchanged) 141 { 142 *pchanged = FALSE; 143 144 char *streaminfo; 145 int ret = hdhomerun_device_get_tuner_streaminfo(scan->hd, &streaminfo); 146 if (ret <= 0) { 147 return ret; 148 } 149 150 char *line = streaminfo; 151 int program_count = 0; 152 153 while (1) { 154 char *end = strchr(line, '\n'); 155 if (!end) { 156 break; 157 } 158 159 *end = 0; 160 161 struct hdhomerun_channelscan_program_t program; 162 memset(&program, 0, sizeof(program)); 163 164 strncpy(program.program_str, line, sizeof(program.program_str)); 165 program.program_str[sizeof(program.program_str) - 1] = 0; 166 167 unsigned int program_number; 168 unsigned int virtual_major, virtual_minor; 169 if (sscanf(line, "%u: %u.%u", &program_number, &virtual_major, &virtual_minor) != 3) { 170 continue; 171 } 172 173 program.program_number = program_number; 174 program.virtual_major = virtual_major; 175 program.virtual_minor = virtual_minor; 176 177 channelscan_extract_name(&program, line); 178 179 program.type = HDHOMERUN_CHANNELSCAN_PROGRAM_NORMAL; 180 if (strstr(line, "(no data)")) { 181 program.type = HDHOMERUN_CHANNELSCAN_PROGRAM_NODATA; 182 } 183 if (strstr(line, "(control)")) { 184 program.type = HDHOMERUN_CHANNELSCAN_PROGRAM_CONTROL; 185 } 186 if (strstr(line, "(encrypted)")) { 187 program.type = HDHOMERUN_CHANNELSCAN_PROGRAM_ENCRYPTED; 188 } 189 190 if (memcmp(&result->programs[program_count], &program, sizeof(program)) != 0) { 191 memcpy(&result->programs[program_count], &program, sizeof(program)); 192 *pchanged = TRUE; 193 } 194 195 program_count++; 196 if (program_count >= HDHOMERUN_CHANNELSCAN_MAX_PROGRAM_COUNT) { 197 break; 198 } 199 200 line = end + 1; 201 } 202 203 if (result->program_count != program_count) { 204 result->program_count = program_count; 205 *pchanged = TRUE; 206 } 207 208 return 1; 209 } 210 211 int channelscan_advance(struct hdhomerun_channelscan_t *scan, struct hdhomerun_channelscan_result_t *result) 212 { 213 memset(result, 0, sizeof(struct hdhomerun_channelscan_result_t)); 214 215 struct hdhomerun_channel_entry_t *entry = scan->next_channel; 216 if (!entry) { 217 return 0; 218 } 219 220 /* Combine channels with same frequency. */ 221 result->frequency = hdhomerun_channel_entry_frequency(entry); 222 strncpy(result->channel_str, hdhomerun_channel_entry_name(entry), sizeof(result->channel_str) - 1); 223 result->channel_str[sizeof(result->channel_str) - 1] = 0; 224 225 while (1) { 226 entry = hdhomerun_channel_list_prev(scan->channel_list, entry); 227 if (!entry) { 228 scan->next_channel = NULL; 229 break; 230 } 231 232 if (hdhomerun_channel_entry_frequency(entry) != result->frequency) { 233 scan->next_channel = entry; 234 break; 235 } 236 237 char *ptr = strchr(result->channel_str, 0); 238 sprintf(ptr, ", %s", hdhomerun_channel_entry_name(entry)); 239 } 240 241 return 1; 242 } 243 244 int channelscan_detect(struct hdhomerun_channelscan_t *scan, struct hdhomerun_channelscan_result_t *result) 245 { 246 scan->scanned_channels++; 247 248 /* Find lock. */ 249 int ret = channelscan_execute_find_lock(scan, result->frequency, result); 250 if (ret <= 0) { 251 return ret; 252 } 253 if (!result->status.lock_supported) { 254 return 1; 255 } 256 257 /* Detect programs. */ 258 result->program_count = 0; 259 260 int changed; 261 ret = channelscan_execute_detect_programs(scan, result, &changed); 262 if (ret <= 0) { 263 return ret; 264 } 265 266 int same_count = 0; 267 int i; 268 for (i = 0; i < 5 * 4; i++) { 269 usleep(250000); 270 271 ret = channelscan_execute_detect_programs(scan, result, &changed); 272 if (ret <= 0) { 273 return ret; 274 } 275 276 if (changed) { 277 same_count = 0; 278 continue; 279 } 280 281 same_count++; 282 if (same_count >= 8) { 283 break; 284 } 285 } 286 287 /* Complete. */ 288 return 1; 289 } 290 291 uint8_t channelscan_get_progress(struct hdhomerun_channelscan_t *scan) 292 { 293 struct hdhomerun_channel_entry_t *entry = scan->next_channel; 294 if (!entry) { 295 return 100; 296 } 297 298 uint32_t channels_remaining = 1; 299 uint32_t frequency = hdhomerun_channel_entry_frequency(entry); 300 301 while (1) { 302 entry = hdhomerun_channel_list_prev(scan->channel_list, entry); 303 if (!entry) { 304 break; 305 } 306 307 if (hdhomerun_channel_entry_frequency(entry) != frequency) { 308 channels_remaining++; 309 frequency = hdhomerun_channel_entry_frequency(entry); 310 } 311 } 312 313 return scan->scanned_channels * 100 / (scan->scanned_channels + channels_remaining); 314 } -
mythtv/libs/libmythtv/hdhomerun/hdhomerun_channelscan.h
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun_channelscan.h release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun_channelscan.h
1 /* 2 * hdhomerun_channelscan.h 3 * 4 * Copyright © 2007-2008 Silicondust Engineering Ltd. <www.silicondust.com>. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 3 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 31 */ 32 33 #ifdef __cplusplus 34 extern "C" { 35 #endif 36 37 #define HDHOMERUN_CHANNELSCAN_PROGRAM_NORMAL 0 38 #define HDHOMERUN_CHANNELSCAN_PROGRAM_NODATA 1 39 #define HDHOMERUN_CHANNELSCAN_PROGRAM_CONTROL 2 40 #define HDHOMERUN_CHANNELSCAN_PROGRAM_ENCRYPTED 3 41 42 struct hdhomerun_channelscan_t; 43 44 extern LIBTYPE struct hdhomerun_channelscan_t *channelscan_create(struct hdhomerun_device_t *hd, const char *channelmap); 45 extern LIBTYPE void channelscan_destroy(struct hdhomerun_channelscan_t *scan); 46 47 extern LIBTYPE int channelscan_advance(struct hdhomerun_channelscan_t *scan, struct hdhomerun_channelscan_result_t *result); 48 extern LIBTYPE int channelscan_detect(struct hdhomerun_channelscan_t *scan, struct hdhomerun_channelscan_result_t *result); 49 extern LIBTYPE uint8_t channelscan_get_progress(struct hdhomerun_channelscan_t *scan); 50 51 #ifdef __cplusplus 52 } 53 #endif -
mythtv/libs/libmythtv/hdhomerun/hdhomerun_config.c
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun_config.c release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun_config.c
1 1 /* 2 2 * hdhomerun_config.c 3 3 * 4 * Copyright © 2006Silicondust Engineering Ltd. <www.silicondust.com>.4 * Copyright © 2006-2008 Silicondust Engineering Ltd. <www.silicondust.com>. 5 5 * 6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU Lesser General Public 8 8 * License as published by the Free Software Foundation; either 9 * version 2.1of the License, or (at your option) any later version.9 * version 3 of the License, or (at your option) any later version. 10 10 * 11 11 * This library is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of … … 14 14 * Lesser General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 19 31 */ 20 32 21 33 #include "hdhomerun.h" 22 34 35 /* 36 * The console output format should be set to UTF-8, however in XP and Vista this breaks batch file processing. 37 * Attempting to restore on exit fails to restore if the program is terminated by the user. 38 * Solution - set the output format each printf. 39 */ 40 #if defined(__WINDOWS__) 41 #define printf console_printf 42 #define vprintf console_vprintf 43 #endif 44 23 45 static const char *appname; 24 46 25 47 struct hdhomerun_device_t *hd; … … 31 53 printf("\t%s <id> get help\n", appname); 32 54 printf("\t%s <id> get <item>\n", appname); 33 55 printf("\t%s <id> set <item> <value>\n", appname); 34 printf("\t%s <id> scan <tuner> <starting channel>\n", appname); 56 printf("\t%s <id> scan <tuner> [<filename>]\n", appname); 57 printf("\t%s <id> save <tuner> <filename>\n", appname); 35 58 printf("\t%s <id> upgrade <filename>\n", appname); 36 59 return -1; 37 60 } … … 68 91 return FALSE; 69 92 } 70 93 71 static int discover_print(void) 94 static uint32_t parse_ip_addr(const char *str) 95 { 96 unsigned long a[4]; 97 if (sscanf(str, "%lu.%lu.%lu.%lu", &a[0], &a[1], &a[2], &a[3]) != 4) { 98 return 0; 99 } 100 101 return (uint32_t)((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | (a[3] << 0)); 102 } 103 104 static int discover_print(char *target_ip_str) 72 105 { 106 uint32_t target_ip = 0; 107 if (target_ip_str) { 108 target_ip = parse_ip_addr(target_ip_str); 109 if (target_ip == 0) { 110 fprintf(stderr, "invalid ip address: %s\n", target_ip_str); 111 return -1; 112 } 113 } 114 73 115 struct hdhomerun_discover_device_t result_list[64]; 74 int count = hdhomerun_discover_find_devices (HDHOMERUN_DEVICE_TYPE_TUNER, result_list, 64);116 int count = hdhomerun_discover_find_devices_custom(target_ip, HDHOMERUN_DEVICE_TYPE_TUNER, HDHOMERUN_DEVICE_ID_WILDCARD, result_list, 64); 75 117 if (count < 0) { 76 118 fprintf(stderr, "error sending discover request\n"); 77 119 return -1; … … 94 136 return count; 95 137 } 96 138 97 static bool_t parse_device_id_str(const char *s, uint32_t *pdevice_id, uint32_t *pdevice_ip)98 {99 unsigned long a[4];100 if (sscanf(s, "%lu.%lu.%lu.%lu", &a[0], &a[1], &a[2], &a[3]) == 4) {101 *pdevice_id = HDHOMERUN_DEVICE_ID_WILDCARD;102 *pdevice_ip = (uint32_t)((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | (a[3] << 0));103 return TRUE;104 }105 106 unsigned long device_id_raw;107 if (sscanf(s, "%lx", &device_id_raw) != 1) {108 fprintf(stderr, "invalid device id: %s\n", s);109 return FALSE;110 }111 112 uint32_t device_id = (uint32_t)device_id_raw;113 if (!hdhomerun_discover_validate_device_id(device_id)) {114 fprintf(stderr, "invalid device id: %s\n", s);115 return FALSE;116 }117 118 *pdevice_id = device_id;119 *pdevice_ip = 0;120 return TRUE;121 }122 123 139 static int cmd_get(const char *item) 124 140 { 125 141 char *ret_value; … … 138 154 return 1; 139 155 } 140 156 141 static int cmd_set (const char *item, const char *value)157 static int cmd_set_internal(const char *item, const char *value) 142 158 { 143 159 char *ret_error; 144 160 if (hdhomerun_device_set_var(hd, item, value, NULL, &ret_error) < 0) { … … 154 170 return 1; 155 171 } 156 172 157 static int cmd_s treaminfo(const char *tuner_str)173 static int cmd_set(const char *item, const char *value) 158 174 { 159 fprintf(stderr, "streaminfo: use \"get /tuner<n>/streaminfo\"\n"); 160 return -1; 175 if (strcmp(value, "-") == 0) { 176 char *buffer = NULL; 177 size_t pos = 0; 178 179 while (1) { 180 buffer = (char *)realloc(buffer, pos + 1024); 181 if (!buffer) { 182 fprintf(stderr, "out of memory\n"); 183 return -1; 184 } 185 186 int size = fread(buffer + pos, 1, 1024, stdin); 187 pos += size; 188 189 if (size < 1024) { 190 break; 191 } 192 } 193 194 buffer[pos] = 0; 195 196 int ret = cmd_set_internal(item, buffer); 197 198 free(buffer); 199 return ret; 200 } 201 202 return cmd_set_internal(item, value); 161 203 } 162 204 163 static int cmd_scan(const char *tuner_str, const char *start_value)205 static void cmd_scan_printf(FILE *fp, const char *fmt, ...) 164 206 { 165 unsigned int tuner; 166 if (sscanf(tuner_str, "%u", &tuner) != 1) { 167 fprintf(stderr, "invalid tuner number\n"); 168 return -1; 169 } 207 va_list ap; 208 va_start(ap, fmt); 170 209 171 hdhomerun_device_set_tuner(hd, tuner); 210 if (fp) { 211 va_list apc; 212 va_copy(apc, ap); 172 213 173 char channel_str[64]; 174 strncpy(channel_str, start_value, sizeof(channel_str)); 175 channel_str[sizeof(channel_str) - 8] = 0; 176 177 char *channel_number_ptr = strrchr(channel_str, ':'); 178 if (!channel_number_ptr) { 179 channel_number_ptr = channel_str; 180 } else { 181 channel_number_ptr++; 214 vfprintf(fp, fmt, apc); 215 fflush(fp); 216 217 va_end(apc); 182 218 } 183 219 184 unsigned int channel_number = atol(channel_number_ptr); 185 if (channel_number == 0) { 186 fprintf(stderr, "invalid starting channel\n"); 220 vprintf(fmt, ap); 221 fflush(stdout); 222 223 va_end(ap); 224 } 225 226 static int cmd_scan(const char *tuner_str, const char *filename) 227 { 228 if (hdhomerun_device_set_tuner_from_str(hd, tuner_str) <= 0) { 229 fprintf(stderr, "invalid tuner number\n"); 187 230 return -1; 188 231 } 189 232 190 /* Test starting channel. */ 191 int ret = hdhomerun_device_set_tuner_channel(hd, channel_str); 192 if (ret < 0) { 193 fprintf(stderr, "communication error sending request to hdhomerun device\n"); 233 char *channelmap; 234 if (hdhomerun_device_get_tuner_channelmap(hd, &channelmap) <= 0) { 235 fprintf(stderr, "failed to query channelmap from device\n"); 194 236 return -1; 195 237 } 196 if (ret == 0) { 197 fprintf(stderr, "invalid starting channel\n"); 238 239 const char *channelmap_scan_group = hdhomerun_channelmap_get_channelmap_scan_group(channelmap); 240 if (!channelmap_scan_group) { 241 fprintf(stderr, "unknown channelmap '%s'\n", channelmap); 198 242 return -1; 199 243 } 200 244 201 while (1) { 202 /* Update channel value */ 203 sprintf(channel_number_ptr, "%u", channel_number); 245 if (hdhomerun_device_channelscan_init(hd, channelmap_scan_group) <= 0) { 246 fprintf(stderr, "failed to initialize channel scan\n"); 247 return -1; 248 } 204 249 205 /* Set channel. */ 206 ret = hdhomerun_device_set_tuner_channel(hd, channel_str); 207 if (ret < 0) { 208 fprintf(stderr, "communication error sending request to hdhomerun device\n"); 250 FILE *fp = NULL; 251 if (filename) { 252 fp = fopen(filename, "w"); 253 if (!fp) { 254 fprintf(stderr, "unable to create file: %s\n", filename); 209 255 return -1; 210 256 } 211 if (ret == 0) { 212 return 0; 257 } 258 259 int ret; 260 while (1) { 261 struct hdhomerun_channelscan_result_t result; 262 ret = hdhomerun_device_channelscan_advance(hd, &result); 263 if (ret <= 0) { 264 break; 213 265 } 214 266 215 /* Wait 1.5s for lock (qam auto is the slowest to lock). */ 216 usleep(HDHOMERUN_DEVICE_MAX_TUNE_TO_LOCK_TIME * 1000); 267 cmd_scan_printf(fp, "SCANNING: %lu (%s)\n", 268 result.frequency, result.channel_str 269 ); 217 270 218 /* Get status to check for signal. Quality numbers will not be valid yet. */ 219 struct hdhomerun_tuner_status_t status; 220 if (hdhomerun_device_get_tuner_status(hd, &status) < 0) { 221 fprintf(stderr, "communication error sending request to hdhomerun device\n"); 222 return -1; 271 ret = hdhomerun_device_channelscan_detect(hd, &result); 272 if (ret <= 0) { 273 break; 223 274 } 224 275 225 /* If no signal then advance to next channel. */ 226 if (status.signal_strength == 0) { 227 printf("%s: no signal\n", channel_str); 228 channel_number++; 229 continue; 276 cmd_scan_printf(fp, "LOCK: %s (ss=%u snq=%u seq=%u)\n", 277 result.status.lock_str, result.status.signal_strength, 278 result.status.signal_to_noise_quality, result.status.symbol_error_quality 279 ); 280 281 int i; 282 for (i = 0; i < result.program_count; i++) { 283 struct hdhomerun_channelscan_program_t *program = &result.programs[i]; 284 cmd_scan_printf(fp, "PROGRAM %s\n", program->program_str); 230 285 } 286 } 287 288 if (fp) { 289 fclose(fp); 290 } 291 if (ret < 0) { 292 fprintf(stderr, "communication error sending request to hdhomerun device\n"); 293 } 294 return ret; 295 } 296 297 static void cmd_save_abort(int junk) 298 { 299 struct hdhomerun_video_stats_t stats; 300 hdhomerun_device_get_video_stats(hd, &stats); 301 hdhomerun_device_stream_stop(hd); 302 hdhomerun_device_destroy(hd); 303 304 fprintf(stderr, "\n"); 305 fprintf(stderr, "-- Video statistics --\n"); 306 fprintf(stderr, "%u packets received, %u network errors, %u transport errors, %u sequence errors\n", 307 (unsigned)stats.packet_count, 308 (unsigned)stats.network_error_count, 309 (unsigned)stats.transport_error_count, 310 (unsigned)stats.sequence_error_count); 311 312 exit(0); 313 } 231 314 232 /* Wait for 2s. */ 233 usleep(HDHOMERUN_DEVICE_MAX_LOCK_TO_DATA_TIME * 1000); 315 static int cmd_save(const char *tuner_str, const char *filename) 316 { 317 if (hdhomerun_device_set_tuner_from_str(hd, tuner_str) <= 0) { 318 fprintf(stderr, "invalid tuner number\n"); 319 return -1; 320 } 234 321 235 /* Get status to check quality numbers. */ 236 if (hdhomerun_device_get_tuner_status(hd, &status) < 0) { 237 fprintf(stderr, "communication error sending request to hdhomerun device\n"); 322 FILE *fp; 323 if (strcmp(filename, "null") == 0) { 324 fp = NULL; 325 } else if (strcmp(filename, "-") == 0) { 326 fp = stdout; 327 } else { 328 fp = fopen(filename, "wb"); 329 if (!fp) { 330 fprintf(stderr, "unable to create file %s\n", filename); 238 331 return -1; 239 332 } 240 if (status.signal_strength == 0) { 241 printf("%s: no signal\n", channel_str); 242 channel_number++; 243 continue; 244 } 245 printf("%s: ss=%u snq=%u seq=%u\n", channel_str, status.signal_strength, status.signal_to_noise_quality, status.symbol_error_quality); 333 } 334 335 int ret = hdhomerun_device_stream_start(hd); 336 if (ret <= 0) { 337 fprintf(stderr, "unable to start stream\n"); 338 return ret; 339 } 340 341 signal(SIGINT, cmd_save_abort); 342 signal(SIGPIPE, cmd_save_abort); 246 343 247 /* Detect sub channels. */ 248 usleep(4 * 1000000); 249 char *streaminfo; 250 if (hdhomerun_device_get_tuner_streaminfo(hd, &streaminfo) <= 0) { 251 channel_number++; 344 struct hdhomerun_video_stats_t stats_old, stats_cur; 345 hdhomerun_device_get_video_stats(hd, &stats_old); 346 347 uint64_t next_progress = getcurrenttime() + 1000; 348 while (1) { 349 usleep(64000); 350 351 size_t actual_size; 352 uint8_t *ptr = hdhomerun_device_stream_recv(hd, VIDEO_DATA_BUFFER_SIZE_1S, &actual_size); 353 if (!ptr) { 252 354 continue; 253 355 } 254 while (1) { 255 char *end = strchr(streaminfo, '\n'); 256 if (!end) { 257 break; 356 357 if (fp) { 358 if (fwrite(ptr, 1, actual_size, fp) != actual_size) { 359 fprintf(stderr, "error writing output\n"); 360 return -1; 258 361 } 362 } 259 363 260 *end++ = 0; 261 printf("program %s\n", streaminfo); 364 uint64_t current_time = getcurrenttime(); 365 if (current_time >= next_progress) { 366 next_progress = current_time + 1000; 367 368 hdhomerun_device_get_video_stats(hd, &stats_cur); 369 370 if (stats_cur.network_error_count > stats_old.network_error_count) { 371 fprintf(stderr, "n"); 372 } else if (stats_cur.transport_error_count > stats_old.transport_error_count) { 373 fprintf(stderr, "t"); 374 } else if (stats_cur.sequence_error_count > stats_old.sequence_error_count) { 375 fprintf(stderr, "s"); 376 } else { 377 fprintf(stderr, "."); 378 } 262 379 263 streaminfo = end; 380 stats_old = stats_cur; 381 fflush(stderr); 264 382 } 265 266 /* Advance to next channel. */267 channel_number++;268 383 } 269 384 } 270 385 … … 276 391 return -1; 277 392 } 278 393 394 printf("uploading firmware...\n"); 279 395 if (hdhomerun_device_upgrade(hd, fp) <= 0) { 280 396 fprintf(stderr, "error sending upgrade file to hdhomerun device\n"); 281 397 fclose(fp); 282 398 return -1; 283 399 } 400 sleep(2); 401 402 printf("upgrading firmware...\n"); 403 sleep(8); 404 405 printf("rebooting...\n"); 406 int count = 0; 407 char *version_str; 408 while (1) { 409 if (hdhomerun_device_get_version(hd, &version_str, NULL) >= 0) { 410 break; 411 } 412 413 count++; 414 if (count > 30) { 415 fprintf(stderr, "error finding device after firmware upgrade\n"); 416 fclose(fp); 417 return -1; 418 } 419 420 sleep(1); 421 } 284 422 285 printf("upgrade complete \n");423 printf("upgrade complete - now running firmware %s\n", version_str); 286 424 return 0; 287 425 } 288 426 … … 308 446 return cmd_set(argv[0], argv[1]); 309 447 } 310 448 311 if (contains(cmd, "s treaminfo")) {449 if (contains(cmd, "scan")) { 312 450 if (argc < 1) { 313 451 return help(); 314 452 } 315 return cmd_streaminfo(argv[0]); 453 if (argc < 2) { 454 return cmd_scan(argv[0], NULL); 455 } else { 456 return cmd_scan(argv[0], argv[1]); 457 } 316 458 } 317 459 318 if (contains(cmd, "s can")) {460 if (contains(cmd, "save")) { 319 461 if (argc < 2) { 320 462 return help(); 321 463 } 322 return cmd_s can(argv[0], argv[1]);464 return cmd_save(argv[0], argv[1]); 323 465 } 324 466 325 467 if (contains(cmd, "upgrade")) { … … 335 477 static int main_internal(int argc, char *argv[]) 336 478 { 337 479 #if defined(__WINDOWS__) 338 //Start pthreads 339 pthread_win32_process_attach_np(); 340 341 // Start WinSock 480 /* Initialize network socket support. */ 342 481 WORD wVersionRequested = MAKEWORD(2, 0); 343 482 WSADATA wsaData; 344 483 WSAStartup(wVersionRequested, &wsaData); … … 357 496 return help(); 358 497 } 359 498 if (contains(id_str, "discover")) { 360 return discover_print(); 361 } 362 363 /* Device ID. */ 364 uint32_t device_id, device_ip; 365 if (!parse_device_id_str(id_str, &device_id, &device_ip)) { 366 return -1; 499 if (argc < 1) { 500 return discover_print(NULL); 501 } else { 502 return discover_print(argv[0]); 503 } 367 504 } 368 505 369 506 /* Device object. */ 370 hd = hdhomerun_device_create (device_id, device_ip, 0);507 hd = hdhomerun_device_create_from_str(id_str); 371 508 if (!hd) { 372 fprintf(stderr, " unable to create device\n");509 fprintf(stderr, "invalid device id: %s\n", id_str); 373 510 return -1; 374 511 } 375 512 376 /* Connect to device and check firmware version. */ 377 int ret = hdhomerun_device_firmware_version_check(hd, 0); 378 if (ret < 0) { 513 /* Device ID check. */ 514 uint32_t device_id_requested = hdhomerun_device_get_device_id_requested(hd); 515 if (!hdhomerun_discover_validate_device_id(device_id_requested)) { 516 fprintf(stderr, "invalid device id: %08lX\n", (unsigned long)device_id_requested); 517 } 518 519 /* Connect to device and check model. */ 520 const char *model = hdhomerun_device_get_model_str(hd); 521 if (!model) { 379 522 fprintf(stderr, "unable to connect to device\n"); 380 523 hdhomerun_device_destroy(hd); 381 524 return -1; 382 525 } 383 if (ret == 0) {384 fprintf(stderr, "WARNING: firmware upgrade needed for all operations to function\n");385 }386 526 387 527 /* Command. */ 388 ret = main_cmd(argc, argv);528 int ret = main_cmd(argc, argv); 389 529 390 530 /* Cleanup. */ 391 531 hdhomerun_device_destroy(hd); -
mythtv/libs/libmythtv/hdhomerun/hdhomerun_control.c
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun_control.c release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun_control.c
1 1 /* 2 2 * hdhomerun_control.c 3 3 * 4 * Copyright © 2006 Silicondust Engineering Ltd. <www.silicondust.com>.4 * Copyright © 2006 Silicondust Engineering Ltd. <www.silicondust.com>. 5 5 * 6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU Lesser General Public 8 8 * License as published by the Free Software Foundation; either 9 * version 2.1of the License, or (at your option) any later version.9 * version 3 of the License, or (at your option) any later version. 10 10 * 11 11 * This library is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of … … 14 14 * Lesser General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 19 31 */ 20 32 21 #include "hdhomerun_os.h" 22 #include "hdhomerun_pkt.h" 23 #include "hdhomerun_discover.h" 24 #include "hdhomerun_control.h" 33 #include "hdhomerun.h" 34 35 #define HDHOMERUN_CONTROL_SEND_TIMEOUT 5000 36 #define HDHOMERUN_CONTROL_RECV_TIMEOUT 5000 37 #define HDHOMERUN_CONTROL_UPGRADE_TIMEOUT 20000 25 38 26 39 struct hdhomerun_control_sock_t { 27 uint32_t device_id; 28 uint32_t device_ip; 40 uint32_t desired_device_id; 41 uint32_t desired_device_ip; 42 uint32_t actual_device_id; 43 uint32_t actual_device_ip; 29 44 int sock; 30 uint8_t buffer[16384]; 45 struct hdhomerun_debug_t *dbg; 46 struct hdhomerun_pkt_t tx_pkt; 47 struct hdhomerun_pkt_t rx_pkt; 31 48 }; 32 49 50 static void hdhomerun_control_close_sock(struct hdhomerun_control_sock_t *cs) 51 { 52 if (cs->sock == -1) { 53 return; 54 } 55 56 close(cs->sock); 57 cs->sock = -1; 58 } 59 60 void hdhomerun_control_set_device(struct hdhomerun_control_sock_t *cs, uint32_t device_id, uint32_t device_ip) 61 { 62 hdhomerun_control_close_sock(cs); 63 64 cs->desired_device_id = device_id; 65 cs->desired_device_ip = device_ip; 66 cs->actual_device_id = 0; 67 cs->actual_device_ip = 0; 68 } 69 33 70 struct hdhomerun_control_sock_t *hdhomerun_control_create(uint32_t device_id, uint32_t device_ip) 34 71 { 35 struct hdhomerun_control_sock_t *cs = (struct hdhomerun_control_sock_t *) malloc(sizeof(struct hdhomerun_control_sock_t));72 struct hdhomerun_control_sock_t *cs = (struct hdhomerun_control_sock_t *)calloc(1, sizeof(struct hdhomerun_control_sock_t)); 36 73 if (!cs) { 37 74 return NULL; 38 75 } 39 40 cs->device_id = device_id; 41 cs->device_ip = device_ip; 76 42 77 cs->sock = -1; 78 hdhomerun_control_set_device(cs, device_id, device_ip); 43 79 44 80 return cs; 45 81 } 46 82 47 83 void hdhomerun_control_destroy(struct hdhomerun_control_sock_t *cs) 48 84 { 49 if (cs->sock != -1) { 50 close(cs->sock); 51 } 85 hdhomerun_control_close_sock(cs); 52 86 free(cs); 53 87 } 54 88 55 static void hdhomerun_control_close_sock(struct hdhomerun_control_sock_t *cs)89 void hdhomerun_control_set_debug(struct hdhomerun_control_sock_t *cs, struct hdhomerun_debug_t *dbg) 56 90 { 57 close(cs->sock); 58 cs->sock = -1; 91 cs->dbg = dbg; 59 92 } 60 93 61 94 static bool_t hdhomerun_control_connect_sock(struct hdhomerun_control_sock_t *cs) … … 64 97 return TRUE; 65 98 } 66 99 67 /* Find ip address. */ 68 uint32_t device_ip = cs->device_ip; 69 if (device_ip == 0) { 70 struct hdhomerun_discover_device_t result; 71 if (hdhomerun_discover_find_device(cs->device_id, &result) <= 0) { 72 return FALSE; 73 } 74 device_ip = result.ip_addr; 100 if ((cs->desired_device_id == 0) && (cs->desired_device_ip == 0)) { 101 hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_connect_sock: no device specified\n"); 102 return FALSE; 103 } 104 105 /* Find device. */ 106 struct hdhomerun_discover_device_t result; 107 if (hdhomerun_discover_find_devices_custom(cs->desired_device_ip, HDHOMERUN_DEVICE_TYPE_WILDCARD, cs->desired_device_id, &result, 1) <= 0) { 108 hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_connect_sock: device not found\n"); 109 return FALSE; 75 110 } 111 cs->actual_device_ip = result.ip_addr; 112 cs->actual_device_id = result.device_id; 76 113 77 114 /* Create socket. */ 78 115 cs->sock = (int)socket(AF_INET, SOCK_STREAM, 0); 79 116 if (cs->sock == -1) { 117 hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_connect_sock: failed to create socket (%d)\n", sock_getlasterror); 80 118 return FALSE; 81 119 } 82 120 83 121 /* Set timeouts. */ 84 setsocktimeout(cs->sock, SOL_SOCKET, SO_SNDTIMEO, 1000);85 setsocktimeout(cs->sock, SOL_SOCKET, SO_RCVTIMEO, 1000);122 setsocktimeout(cs->sock, SOL_SOCKET, SO_SNDTIMEO, HDHOMERUN_CONTROL_SEND_TIMEOUT); 123 setsocktimeout(cs->sock, SOL_SOCKET, SO_RCVTIMEO, HDHOMERUN_CONTROL_RECV_TIMEOUT); 86 124 87 125 /* Initiate connection. */ 88 126 struct sockaddr_in sock_addr; 89 127 memset(&sock_addr, 0, sizeof(sock_addr)); 90 128 sock_addr.sin_family = AF_INET; 91 sock_addr.sin_addr.s_addr = htonl( device_ip);129 sock_addr.sin_addr.s_addr = htonl(cs->actual_device_ip); 92 130 sock_addr.sin_port = htons(HDHOMERUN_CONTROL_TCP_PORT); 93 131 if (connect(cs->sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) { 132 hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_connect_sock: failed to connect (%d)\n", sock_getlasterror); 94 133 hdhomerun_control_close_sock(cs); 95 134 return FALSE; 96 135 } … … 99 138 return TRUE; 100 139 } 101 140 141 uint32_t hdhomerun_control_get_device_id(struct hdhomerun_control_sock_t *cs) 142 { 143 if (!hdhomerun_control_connect_sock(cs)) { 144 hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_get_device_id: connect failed\n"); 145 return 0; 146 } 147 148 return cs->actual_device_id; 149 } 150 151 uint32_t hdhomerun_control_get_device_ip(struct hdhomerun_control_sock_t *cs) 152 { 153 if (!hdhomerun_control_connect_sock(cs)) { 154 hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_get_device_ip: connect failed\n"); 155 return 0; 156 } 157 158 return cs->actual_device_ip; 159 } 160 161 uint32_t hdhomerun_control_get_device_id_requested(struct hdhomerun_control_sock_t *cs) 162 { 163 return cs->desired_device_id; 164 } 165 166 uint32_t hdhomerun_control_get_device_ip_requested(struct hdhomerun_control_sock_t *cs) 167 { 168 return cs->desired_device_ip; 169 } 170 102 171 uint32_t hdhomerun_control_get_local_addr(struct hdhomerun_control_sock_t *cs) 103 172 { 104 173 if (!hdhomerun_control_connect_sock(cs)) { 174 hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_get_local_addr: connect failed\n"); 105 175 return 0; 106 176 } 107 177 108 178 struct sockaddr_in sock_addr; 109 179 socklen_t sockaddr_size = sizeof(sock_addr); 110 180 if (getsockname(cs->sock, (struct sockaddr*)&sock_addr, &sockaddr_size) != 0) { 181 hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_get_local_addr: getsockname failed (%d)\n", sock_getlasterror); 111 182 return 0; 112 183 } 113 184 114 185 return ntohl(sock_addr.sin_addr.s_addr); 115 186 } 116 187 117 static int hdhomerun_control_send (struct hdhomerun_control_sock_t *cs, uint8_t *start, uint8_t *end)188 static int hdhomerun_control_send_sock(struct hdhomerun_control_sock_t *cs, struct hdhomerun_pkt_t *tx_pkt) 118 189 { 119 int length = (int)(end - start); 120 if (send(cs->sock, (char *)start, (int)length, 0) != length) { 190 int length = (int)(tx_pkt->end - tx_pkt->start); 191 if (send(cs->sock, (char *)tx_pkt->start, (int)length, 0) != length) { 192 hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_send_sock: send failed (%d)\n", sock_getlasterror); 193 hdhomerun_control_close_sock(cs); 121 194 return -1; 122 195 } 123 196 124 return length;197 return 1; 125 198 } 126 199 127 static int hdhomerun_control_recv_sock(struct hdhomerun_control_sock_t *cs, uint8_t *buffer, uint8_t *limit)200 static int hdhomerun_control_recv_sock(struct hdhomerun_control_sock_t *cs, struct hdhomerun_pkt_t *rx_pkt, uint16_t *ptype, uint64_t recv_timeout) 128 201 { 129 struct timeval t; 130 t.tv_sec = 0; 131 t.tv_usec = 250000; 132 133 fd_set readfds; 134 FD_ZERO(&readfds); 135 FD_SET(cs->sock, &readfds); 202 uint64_t stop_time = getcurrenttime() + recv_timeout; 203 hdhomerun_pkt_reset(rx_pkt); 136 204 137 if (select(cs->sock+1, &readfds, NULL, NULL, &t) < 0) { 138 return -1; 139 } 205 while (getcurrenttime() < stop_time) { 206 struct timeval t; 207 t.tv_sec = 0; 208 t.tv_usec = 250000; 209 210 fd_set readfds; 211 FD_ZERO(&readfds); 212 FD_SET(cs->sock, &readfds); 213 214 if (select(cs->sock+1, &readfds, NULL, NULL, &t) < 0) { 215 hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_recv_sock: select failed (%d)\n", sock_getlasterror); 216 hdhomerun_control_close_sock(cs); 217 return -1; 218 } 219 220 if (!FD_ISSET(cs->sock, &readfds)) { 221 continue; 222 } 223 224 int rx_length = recv(cs->sock, (char *)rx_pkt->end, (int)(rx_pkt->limit - rx_pkt->end), 0); 225 if (rx_length <= 0) { 226 hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_recv_sock: recv failed (%d)\n", sock_getlasterror); 227 hdhomerun_control_close_sock(cs); 228 return -1; 229 } 230 rx_pkt->end += rx_length; 140 231 141 if (!FD_ISSET(cs->sock, &readfds)) { 142 return 0; 143 } 232 int ret = hdhomerun_pkt_open_frame(rx_pkt, ptype); 233 if (ret < 0) { 234 hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_recv_sock: frame error\n"); 235 hdhomerun_control_close_sock(cs); 236 return -1; 237 } 238 if (ret == 0) { 239 continue; 240 } 144 241 145 int length = recv(cs->sock, (char *)buffer, (int)(limit - buffer), 0); 146 if (length <= 0) { 147 return -1; 242 return 1; 148 243 } 149 244 150 return length; 245 hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_recv_sock: timeout\n"); 246 hdhomerun_control_close_sock(cs); 247 return -1; 151 248 } 152 249 153 static int hdhomerun_control_ recv(struct hdhomerun_control_sock_t *cs, uint8_t *buffer, uint8_t *limit)250 static int hdhomerun_control_send_recv_internal(struct hdhomerun_control_sock_t *cs, struct hdhomerun_pkt_t *tx_pkt, struct hdhomerun_pkt_t *rx_pkt, uint16_t type, uint64_t recv_timeout) 154 251 { 155 uint64_t timeout = getcurrenttime() + 1000; 156 uint8_t *ptr = buffer; 252 hdhomerun_pkt_seal_frame(tx_pkt, type); 157 253 158 while (getcurrenttime() < timeout) { 159 int length = hdhomerun_control_recv_sock(cs, ptr, limit); 160 if (length < 0) { 161 return -1; 254 int i; 255 for (i = 0; i < 2; i++) { 256 if (cs->sock == -1) { 257 if (!hdhomerun_control_connect_sock(cs)) { 258 hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_send_recv: connect failed\n"); 259 return -1; 260 } 162 261 } 163 if (length == 0) { 262 263 if (hdhomerun_control_send_sock(cs, tx_pkt) < 0) { 164 264 continue; 165 265 } 166 ptr += length; 266 if (!rx_pkt) { 267 return 1; 268 } 167 269 168 if (buffer + HDHOMERUN_MIN_PEEK_LENGTH > limit) { 270 uint16_t rsp_type; 271 if (hdhomerun_control_recv_sock(cs, rx_pkt, &rsp_type, recv_timeout) < 0) { 169 272 continue; 170 273 } 171 172 length = (int)hdhomerun_peek_packet_length(buffer);173 if (buffer + length > limit) {274 if (rsp_type != type + 1) { 275 hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_send_recv: unexpected frame type\n"); 276 hdhomerun_control_close_sock(cs); 174 277 continue; 175 278 } 176 279 177 return length;280 return 1; 178 281 } 179 282 283 hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_send_recv: failed\n"); 180 284 return -1; 181 285 } 182 286 183 static int hdhomerun_control_get_set(struct hdhomerun_control_sock_t *cs, const char *name, const char *value, char **pvalue, char **perror) 287 int hdhomerun_control_send_recv(struct hdhomerun_control_sock_t *cs, struct hdhomerun_pkt_t *tx_pkt, struct hdhomerun_pkt_t *rx_pkt, uint16_t type) 288 { 289 return hdhomerun_control_send_recv_internal(cs, tx_pkt, rx_pkt, type, HDHOMERUN_CONTROL_RECV_TIMEOUT); 290 } 291 292 static int hdhomerun_control_get_set(struct hdhomerun_control_sock_t *cs, const char *name, const char *value, uint32_t lockkey, char **pvalue, char **perror) 184 293 { 185 /* Send request. */ 186 uint8_t *ptr = cs->buffer; 187 hdhomerun_write_get_set_request(&ptr, name, value); 188 if (hdhomerun_control_send(cs, cs->buffer, ptr) < 0) { 294 struct hdhomerun_pkt_t *tx_pkt = &cs->tx_pkt; 295 struct hdhomerun_pkt_t *rx_pkt = &cs->rx_pkt; 296 297 /* Request. */ 298 hdhomerun_pkt_reset(tx_pkt); 299 300 int name_len = (int)strlen(name) + 1; 301 if (tx_pkt->end + 3 + name_len > tx_pkt->limit) { 189 302 return -1; 190 303 } 304 hdhomerun_pkt_write_u8(tx_pkt, HDHOMERUN_TAG_GETSET_NAME); 305 hdhomerun_pkt_write_var_length(tx_pkt, name_len); 306 hdhomerun_pkt_write_mem(tx_pkt, (void *)name, name_len); 191 307 192 /* Receive response. */ 193 int length = hdhomerun_control_recv(cs, cs->buffer, cs->buffer + sizeof(cs->buffer)); 194 if (length <= 0) { 195 return -1; 308 if (value) { 309 int value_len = (int)strlen(value) + 1; 310 if (tx_pkt->end + 3 + value_len > tx_pkt->limit) { 311 return -1; 312 } 313 hdhomerun_pkt_write_u8(tx_pkt, HDHOMERUN_TAG_GETSET_VALUE); 314 hdhomerun_pkt_write_var_length(tx_pkt, value_len); 315 hdhomerun_pkt_write_mem(tx_pkt, (void *)value, value_len); 196 316 } 197 317 198 /* Parse response. */ 199 ptr = cs->buffer; 200 uint8_t *end = ptr + length; 201 int type = hdhomerun_process_packet(&ptr, &end); 202 if (type < 0) { 203 return -1; 318 if (lockkey != 0) { 319 if (tx_pkt->end + 6 > tx_pkt->limit) { 320 return -1; 321 } 322 hdhomerun_pkt_write_u8(tx_pkt, HDHOMERUN_TAG_GETSET_LOCKKEY); 323 hdhomerun_pkt_write_var_length(tx_pkt, 4); 324 hdhomerun_pkt_write_u32(tx_pkt, lockkey); 204 325 } 205 if (type != HDHOMERUN_TYPE_GETSET_RPY) { 326 327 /* Send/Recv. */ 328 if (hdhomerun_control_send_recv_internal(cs, tx_pkt, rx_pkt, HDHOMERUN_TYPE_GETSET_REQ, HDHOMERUN_CONTROL_RECV_TIMEOUT) < 0) { 206 329 return -1; 207 330 } 208 331 209 while (ptr < end) { 332 /* Response. */ 333 while (1) { 210 334 uint8_t tag; 211 335 size_t len; 212 uint8_t * val;213 if ( hdhomerun_read_tlv(&ptr, end, &tag, &len, &val) < 0) {336 uint8_t *next = hdhomerun_pkt_read_tlv(rx_pkt, &tag, &len); 337 if (!next) { 214 338 break; 215 339 } 340 216 341 switch (tag) { 217 342 case HDHOMERUN_TAG_GETSET_VALUE: 218 343 if (pvalue) { 219 *pvalue = (char *) val;220 val[len] = 0;344 *pvalue = (char *)rx_pkt->pos; 345 rx_pkt->pos[len] = 0; 221 346 } 222 347 if (perror) { 223 348 *perror = NULL; … … 229 354 *pvalue = NULL; 230 355 } 231 356 if (perror) { 232 *perror = (char *) val;233 val[len] = 0;357 *perror = (char *)rx_pkt->pos; 358 rx_pkt->pos[len] = 0; 234 359 } 235 360 return 0; 236 361 } 362 363 rx_pkt->pos = next; 237 364 } 238 365 366 hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_get_set: missing response tags\n"); 239 367 return -1; 240 368 } 241 369 242 370 int hdhomerun_control_get(struct hdhomerun_control_sock_t *cs, const char *name, char **pvalue, char **perror) 243 371 { 244 if (!hdhomerun_control_connect_sock(cs)) { 245 return -1; 246 } 247 248 int ret = hdhomerun_control_get_set(cs, name, NULL, pvalue, perror); 249 if (ret < 0) { 250 hdhomerun_control_close_sock(cs); 251 return -1; 252 } 253 254 return ret; 372 return hdhomerun_control_get_set(cs, name, NULL, 0, pvalue, perror); 255 373 } 256 374 257 375 int hdhomerun_control_set(struct hdhomerun_control_sock_t *cs, const char *name, const char *value, char **pvalue, char **perror) 258 376 { 259 if (!hdhomerun_control_connect_sock(cs)) { 260 return -1; 261 } 262 263 int ret = hdhomerun_control_get_set(cs, name, value, pvalue, perror); 264 if (ret < 0) { 265 hdhomerun_control_close_sock(cs); 266 return -1; 267 } 377 return hdhomerun_control_get_set(cs, name, value, 0, pvalue, perror); 378 } 268 379 269 return ret; 380 int hdhomerun_control_set_with_lockkey(struct hdhomerun_control_sock_t *cs, const char *name, const char *value, uint32_t lockkey, char **pvalue, char **perror) 381 { 382 return hdhomerun_control_get_set(cs, name, value, lockkey, pvalue, perror); 270 383 } 271 384 272 385 int hdhomerun_control_upgrade(struct hdhomerun_control_sock_t *cs, FILE *upgrade_file) 273 386 { 274 if (!hdhomerun_control_connect_sock(cs)) { 275 return -1; 276 } 277 387 struct hdhomerun_pkt_t *tx_pkt = &cs->tx_pkt; 388 struct hdhomerun_pkt_t *rx_pkt = &cs->rx_pkt; 278 389 uint32_t sequence = 0; 279 uint8_t *ptr;280 390 391 /* Upload. */ 281 392 while (1) { 282 393 uint8_t data[256]; 283 394 size_t length = fread(data, 1, 256, upgrade_file); … … 285 396 break; 286 397 } 287 398 288 ptr = cs->buffer; 289 hdhomerun_write_upgrade_request(&ptr, sequence, data, length); 290 if (hdhomerun_control_send(cs, cs->buffer, ptr) < 0) { 291 hdhomerun_control_close_sock(cs); 399 hdhomerun_pkt_reset(tx_pkt); 400 hdhomerun_pkt_write_u32(tx_pkt, sequence); 401 hdhomerun_pkt_write_mem(tx_pkt, data, length); 402 403 if (hdhomerun_control_send_recv_internal(cs, tx_pkt, NULL, HDHOMERUN_TYPE_UPGRADE_REQ, 0) < 0) { 292 404 return -1; 293 405 } 294 406 … … 300 412 return 0; 301 413 } 302 414 303 ptr = cs->buffer; 304 hdhomerun_write_upgrade_request(&ptr, 0xFFFFFFFF, NULL, 0); 305 if (hdhomerun_control_send(cs, cs->buffer, ptr) < 0) { 306 hdhomerun_control_close_sock(cs); 415 /* Execute upgrade. */ 416 hdhomerun_pkt_reset(tx_pkt); 417 hdhomerun_pkt_write_u32(tx_pkt, 0xFFFFFFFF); 418 419 if (hdhomerun_control_send_recv_internal(cs, tx_pkt, rx_pkt, HDHOMERUN_TYPE_UPGRADE_REQ, HDHOMERUN_CONTROL_UPGRADE_TIMEOUT) < 0) { 307 420 return -1; 308 421 } 309 422 423 /* Check response. */ 424 while (1) { 425 uint8_t tag; 426 size_t len; 427 uint8_t *next = hdhomerun_pkt_read_tlv(rx_pkt, &tag, &len); 428 if (!next) { 429 break; 430 } 431 432 switch (tag) { 433 case HDHOMERUN_TAG_ERROR_MESSAGE: 434 return 0; 435 436 default: 437 break; 438 } 439 440 rx_pkt->pos = next; 441 } 442 310 443 return 1; 311 444 } -
mythtv/libs/libmythtv/hdhomerun/hdhomerun_control.h
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun_control.h release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun_control.h
1 1 /* 2 2 * hdhomerun_control.h 3 3 * 4 * Copyright © 2006 Silicondust Engineering Ltd. <www.silicondust.com>.4 * Copyright © 2006 Silicondust Engineering Ltd. <www.silicondust.com>. 5 5 * 6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU Lesser General Public 8 8 * License as published by the Free Software Foundation; either 9 * version 2.1of the License, or (at your option) any later version.9 * version 3 of the License, or (at your option) any later version. 10 10 * 11 11 * This library is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of … … 14 14 * Lesser General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 19 31 */ 20 32 #ifdef __cplusplus 21 33 extern "C" { … … 36 48 * 37 49 * When no longer needed, the socket should be destroyed by calling hdhomerun_control_destroy. 38 50 */ 39 extern struct hdhomerun_control_sock_t *hdhomerun_control_create(uint32_t device_id, uint32_t device_ip); 40 extern void hdhomerun_control_destroy(struct hdhomerun_control_sock_t *cs); 51 extern LIBTYPE struct hdhomerun_control_sock_t *hdhomerun_control_create(uint32_t device_id, uint32_t device_ip); 52 extern LIBTYPE void hdhomerun_control_destroy(struct hdhomerun_control_sock_t *cs); 53 54 /* 55 * Get the actual device id or ip of the device. 56 * 57 * Returns 0 if the device id cannot be determined. 58 */ 59 extern LIBTYPE uint32_t hdhomerun_control_get_device_id(struct hdhomerun_control_sock_t *cs); 60 extern LIBTYPE uint32_t hdhomerun_control_get_device_ip(struct hdhomerun_control_sock_t *cs); 61 extern LIBTYPE uint32_t hdhomerun_control_get_device_id_requested(struct hdhomerun_control_sock_t *cs); 62 extern LIBTYPE uint32_t hdhomerun_control_get_device_ip_requested(struct hdhomerun_control_sock_t *cs); 63 64 extern LIBTYPE void hdhomerun_control_set_device(struct hdhomerun_control_sock_t *cs, uint32_t device_id, uint32_t device_ip); 41 65 42 66 /* 43 67 * Get the local machine IP address used when communicating with the device. … … 46 70 * 47 71 * Returns 32-bit IP address with native endianness, or 0 on error. 48 72 */ 49 extern uint32_t hdhomerun_control_get_local_addr(struct hdhomerun_control_sock_t *cs); 73 extern LIBTYPE uint32_t hdhomerun_control_get_local_addr(struct hdhomerun_control_sock_t *cs); 74 75 /* 76 * Low-level communication. 77 */ 78 extern LIBTYPE int hdhomerun_control_send_recv(struct hdhomerun_control_sock_t *cs, struct hdhomerun_pkt_t *tx_pkt, struct hdhomerun_pkt_t *rx_pkt, uint16_t type); 50 79 51 80 /* 52 81 * Get/set a control variable on the device. … … 65 94 * Returns 0 if the operation was rejected (pvalue NULL, perror set). 66 95 * Returns -1 if a communication error occurs. 67 96 */ 68 extern int hdhomerun_control_get(struct hdhomerun_control_sock_t *cs, const char *name, char **pvalue, char **perror); 69 extern int hdhomerun_control_set(struct hdhomerun_control_sock_t *cs, const char *name, const char *value, char **pvalue, char **perror); 97 extern LIBTYPE int hdhomerun_control_get(struct hdhomerun_control_sock_t *cs, const char *name, char **pvalue, char **perror); 98 extern LIBTYPE int hdhomerun_control_set(struct hdhomerun_control_sock_t *cs, const char *name, const char *value, char **pvalue, char **perror); 99 extern LIBTYPE int hdhomerun_control_set_with_lockkey(struct hdhomerun_control_sock_t *cs, const char *name, const char *value, uint32_t lockkey, char **pvalue, char **perror); 70 100 71 101 /* 72 102 * Upload new firmware to the device. … … 77 107 * Returns 0 if the upload was rejected. 78 108 * Returns -1 if an error occurs. 79 109 */ 80 extern int hdhomerun_control_upgrade(struct hdhomerun_control_sock_t *cs, FILE *upgrade_file); 110 extern LIBTYPE int hdhomerun_control_upgrade(struct hdhomerun_control_sock_t *cs, FILE *upgrade_file); 111 112 /* 113 * Debug logging. 114 */ 115 extern LIBTYPE void hdhomerun_control_set_debug(struct hdhomerun_control_sock_t *cs, struct hdhomerun_debug_t *dbg); 81 116 82 117 #ifdef __cplusplus 83 118 } -
mythtv/libs/libmythtv/hdhomerun/hdhomerun_debug.c
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun_debug.c release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun_debug.c
1 /* 2 * hdhomerun_debug.c 3 * 4 * Copyright © 2006 Silicondust Engineering Ltd. <www.silicondust.com>. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 3 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 31 */ 32 33 /* 34 * The debug logging includes optional support for connecting to the 35 * Silicondust support server. This option should not be used without 36 * being explicitly enabled by the user. Debug information should be 37 * limited to information useful to diagnosing a problem. 38 * - Silicondust. 39 */ 40 41 #include "hdhomerun.h" 42 43 #if !defined(HDHOMERUN_DEBUG_HOST) 44 #define HDHOMERUN_DEBUG_HOST "debug.silicondust.com" 45 #endif 46 #if !defined(HDHOMERUN_DEBUG_PORT) 47 #define HDHOMERUN_DEBUG_PORT "8002" 48 #endif 49 50 struct hdhomerun_debug_message_t 51 { 52 struct hdhomerun_debug_message_t *next; 53 struct hdhomerun_debug_message_t *prev; 54 char buffer[2048]; 55 }; 56 57 struct hdhomerun_debug_t 58 { 59 pthread_t thread; 60 volatile bool_t enabled; 61 volatile bool_t terminate; 62 char *prefix; 63 64 pthread_mutex_t print_lock; 65 pthread_mutex_t queue_lock; 66 pthread_mutex_t send_lock; 67 68 struct hdhomerun_debug_message_t *queue_head; 69 struct hdhomerun_debug_message_t *queue_tail; 70 uint32_t queue_depth; 71 72 uint64_t connect_delay; 73 74 char *file_name; 75 FILE *file_fp; 76 int sock; 77 }; 78 79 static THREAD_FUNC_PREFIX hdhomerun_debug_thread_execute(void *arg); 80 81 struct hdhomerun_debug_t *hdhomerun_debug_create(void) 82 { 83 struct hdhomerun_debug_t *dbg = (struct hdhomerun_debug_t *)calloc(1, sizeof(struct hdhomerun_debug_t)); 84 if (!dbg) { 85 return NULL; 86 } 87 88 dbg->sock = -1; 89 90 pthread_mutex_init(&dbg->print_lock, NULL); 91 pthread_mutex_init(&dbg->queue_lock, NULL); 92 pthread_mutex_init(&dbg->send_lock, NULL); 93 94 if (pthread_create(&dbg->thread, NULL, &hdhomerun_debug_thread_execute, dbg) != 0) { 95 free(dbg); 96 return NULL; 97 } 98 99 return dbg; 100 } 101 102 /* Send lock held by caller */ 103 static void hdhomerun_debug_close_file(struct hdhomerun_debug_t *dbg) 104 { 105 if (!dbg->file_fp) { 106 return; 107 } 108 109 fclose(dbg->file_fp); 110 dbg->file_fp = NULL; 111 } 112 113 /* Send lock held by caller */ 114 static void hdhomerun_debug_close_sock(struct hdhomerun_debug_t *dbg) 115 { 116 if (dbg->sock == -1) { 117 return; 118 } 119 120 close(dbg->sock); 121 dbg->sock = -1; 122 } 123 124 void hdhomerun_debug_destroy(struct hdhomerun_debug_t *dbg) 125 { 126 dbg->terminate = TRUE; 127 pthread_join(dbg->thread, NULL); 128 129 hdhomerun_debug_close_file(dbg); 130 hdhomerun_debug_close_sock(dbg); 131 132 if (dbg->prefix) { 133 free(dbg->prefix); 134 } 135 136 free(dbg); 137 } 138 139 void hdhomerun_debug_set_prefix(struct hdhomerun_debug_t *dbg, const char *prefix) 140 { 141 pthread_mutex_lock(&dbg->print_lock); 142 143 if (dbg->prefix) { 144 free(dbg->prefix); 145 dbg->prefix = NULL; 146 } 147 148 if (prefix) { 149 dbg->prefix = strdup(prefix); 150 } 151 152 pthread_mutex_unlock(&dbg->print_lock); 153 } 154 155 void hdhomerun_debug_set_filename(struct hdhomerun_debug_t *dbg, const char *filename) 156 { 157 pthread_mutex_lock(&dbg->send_lock); 158 159 if (!filename && !dbg->file_name) { 160 pthread_mutex_unlock(&dbg->send_lock); 161 return; 162 } 163 if (filename && dbg->file_name) { 164 if (strcmp(filename, dbg->file_name) == 0) { 165 pthread_mutex_unlock(&dbg->send_lock); 166 return; 167 } 168 } 169 170 hdhomerun_debug_close_file(dbg); 171 hdhomerun_debug_close_sock(dbg); 172 173 if (dbg->file_name) { 174 free(dbg->file_name); 175 dbg->file_name = NULL; 176 } 177 if (filename) { 178 dbg->file_name = strdup(filename); 179 } 180 181 pthread_mutex_unlock(&dbg->send_lock); 182 } 183 184 void hdhomerun_debug_enable(struct hdhomerun_debug_t *dbg) 185 { 186 pthread_mutex_lock(&dbg->send_lock); 187 188 dbg->enabled = TRUE; 189 190 pthread_mutex_unlock(&dbg->send_lock); 191 } 192 193 void hdhomerun_debug_disable(struct hdhomerun_debug_t *dbg) 194 { 195 pthread_mutex_lock(&dbg->send_lock); 196 197 dbg->enabled = FALSE; 198 hdhomerun_debug_close_file(dbg); 199 hdhomerun_debug_close_sock(dbg); 200 201 pthread_mutex_unlock(&dbg->send_lock); 202 } 203 204 bool_t hdhomerun_debug_enabled(struct hdhomerun_debug_t *dbg) 205 { 206 if (!dbg) { 207 return FALSE; 208 } 209 210 return dbg->enabled; 211 } 212 213 void hdhomerun_debug_flush(struct hdhomerun_debug_t *dbg, uint64_t timeout) 214 { 215 timeout = getcurrenttime() + timeout; 216 217 while (getcurrenttime() < timeout) { 218 pthread_mutex_lock(&dbg->queue_lock); 219 struct hdhomerun_debug_message_t *message = dbg->queue_tail; 220 pthread_mutex_unlock(&dbg->queue_lock); 221 222 if (!message) { 223 return; 224 } 225 226 usleep(10*1000); 227 } 228 } 229 230 void hdhomerun_debug_printf(struct hdhomerun_debug_t *dbg, const char *fmt, ...) 231 { 232 va_list args; 233 va_start(args, fmt); 234 hdhomerun_debug_vprintf(dbg, fmt, args); 235 va_end(args); 236 } 237 238 void hdhomerun_debug_vprintf(struct hdhomerun_debug_t *dbg, const char *fmt, va_list args) 239 { 240 if (!dbg) { 241 return; 242 } 243 if (!dbg->enabled) { 244 return; 245 } 246 247 struct hdhomerun_debug_message_t *message = (struct hdhomerun_debug_message_t *)malloc(sizeof(struct hdhomerun_debug_message_t)); 248 if (!message) { 249 return; 250 } 251 252 char *ptr = message->buffer; 253 char *end = message->buffer + sizeof(message->buffer) - 2; 254 *end = 0; 255 256 /* 257 * Timestamp. 258 */ 259 time_t current_time = time(NULL); 260 ptr += strftime(ptr, end - ptr, "%Y%m%d-%H:%M:%S ", localtime(¤t_time)); 261 if (ptr > end) { 262 ptr = end; 263 } 264 265 /* 266 * Debug prefix. 267 */ 268 pthread_mutex_lock(&dbg->print_lock); 269 270 if (dbg->prefix) { 271 int len = snprintf(ptr, end - ptr, "%s ", dbg->prefix); 272 len = (len <= 0) ? 0 : len; 273 ptr += len; 274 if (ptr > end) { 275 ptr = end; 276 } 277 } 278 279 pthread_mutex_unlock(&dbg->print_lock); 280 281 /* 282 * Message text. 283 */ 284 int len = vsnprintf(ptr, end - ptr, fmt, args); 285 len = (len < 0) ? 0 : len; /* len does not include null */ 286 ptr += len; 287 if (ptr > end) { 288 ptr = end; 289 } 290 291 /* 292 * Force newline. 293 */ 294 if ((ptr[-1] != '\n') && (ptr + 1 <= end)) { 295 *ptr++ = '\n'; 296 } 297 298 /* 299 * Force NULL. 300 */ 301 if (ptr + 1 > end) { 302 ptr = end - 1; 303 } 304 *ptr++ = 0; 305 306 /* 307 * Enqueue. 308 */ 309 pthread_mutex_lock(&dbg->queue_lock); 310 311 message->prev = NULL; 312 message->next = dbg->queue_head; 313 dbg->queue_head = message; 314 if (message->next) { 315 message->next->prev = message; 316 } else { 317 dbg->queue_tail = message; 318 } 319 dbg->queue_depth++; 320 321 pthread_mutex_unlock(&dbg->queue_lock); 322 } 323 324 /* Send lock held by caller */ 325 static bool_t hdhomerun_debug_output_message_file(struct hdhomerun_debug_t *dbg, struct hdhomerun_debug_message_t *message) 326 { 327 if (!dbg->file_fp) { 328 uint64_t current_time = getcurrenttime(); 329 if (current_time < dbg->connect_delay) { 330 return FALSE; 331 } 332 dbg->connect_delay = current_time + 60*1000; 333 334 dbg->file_fp = fopen(dbg->file_name, "a"); 335 if (!dbg->file_fp) { 336 return FALSE; 337 } 338 } 339 340 fprintf(dbg->file_fp, "%s", message->buffer); 341 fflush(dbg->file_fp); 342 343 return TRUE; 344 } 345 346 /* Send lock held by caller */ 347 #if defined(__CYGWIN__) 348 static bool_t hdhomerun_debug_output_message_sock(struct hdhomerun_debug_t *dbg, struct hdhomerun_debug_message_t *message) 349 { 350 return TRUE; 351 } 352 #else 353 static bool_t hdhomerun_debug_output_message_sock(struct hdhomerun_debug_t *dbg, struct hdhomerun_debug_message_t *message) 354 { 355 if (dbg->sock == -1) { 356 uint64_t current_time = getcurrenttime(); 357 if (current_time < dbg->connect_delay) { 358 return FALSE; 359 } 360 dbg->connect_delay = current_time + 60*1000; 361 362 dbg->sock = (int)socket(AF_INET, SOCK_STREAM, 0); 363 if (dbg->sock == -1) { 364 return FALSE; 365 } 366 367 struct addrinfo hints; 368 memset(&hints, 0, sizeof(hints)); 369 hints.ai_family = AF_INET; 370 hints.ai_socktype = SOCK_STREAM; 371 hints.ai_protocol = IPPROTO_TCP; 372 373 struct addrinfo *sock_info; 374 if (getaddrinfo(HDHOMERUN_DEBUG_HOST, HDHOMERUN_DEBUG_PORT, &hints, &sock_info) != 0) { 375 hdhomerun_debug_close_sock(dbg); 376 return FALSE; 377 } 378 if (connect(dbg->sock, sock_info->ai_addr, (int)sock_info->ai_addrlen) != 0) { 379 freeaddrinfo(sock_info); 380 hdhomerun_debug_close_sock(dbg); 381 return FALSE; 382 } 383 freeaddrinfo(sock_info); 384 } 385 386 size_t length = strlen(message->buffer); 387 if (send(dbg->sock, (char *)message->buffer, (int)length, 0) != length) { 388 hdhomerun_debug_close_sock(dbg); 389 return FALSE; 390 } 391 392 return TRUE; 393 } 394 #endif 395 396 static bool_t hdhomerun_debug_output_message(struct hdhomerun_debug_t *dbg, struct hdhomerun_debug_message_t *message) 397 { 398 pthread_mutex_lock(&dbg->send_lock); 399 400 if (!dbg->enabled) { 401 pthread_mutex_unlock(&dbg->send_lock); 402 return TRUE; 403 } 404 405 bool_t ret; 406 if (dbg->file_name) { 407 ret = hdhomerun_debug_output_message_file(dbg, message); 408 } else { 409 ret = hdhomerun_debug_output_message_sock(dbg, message); 410 } 411 412 pthread_mutex_unlock(&dbg->send_lock); 413 return ret; 414 } 415 416 static void hdhomerun_debug_pop_and_free_message(struct hdhomerun_debug_t *dbg) 417 { 418 pthread_mutex_lock(&dbg->queue_lock); 419 420 struct hdhomerun_debug_message_t *message = dbg->queue_tail; 421 dbg->queue_tail = message->prev; 422 if (message->prev) { 423 message->prev->next = NULL; 424 } else { 425 dbg->queue_head = NULL; 426 } 427 dbg->queue_depth--; 428 429 pthread_mutex_unlock(&dbg->queue_lock); 430 431 free(message); 432 } 433 434 static THREAD_FUNC_PREFIX hdhomerun_debug_thread_execute(void *arg) 435 { 436 struct hdhomerun_debug_t *dbg = (struct hdhomerun_debug_t *)arg; 437 438 while (!dbg->terminate) { 439 440 pthread_mutex_lock(&dbg->queue_lock); 441 struct hdhomerun_debug_message_t *message = dbg->queue_tail; 442 uint32_t queue_depth = dbg->queue_depth; 443 pthread_mutex_unlock(&dbg->queue_lock); 444 445 if (!message) { 446 sleep(1); 447 continue; 448 } 449 450 if (queue_depth > 256) { 451 hdhomerun_debug_pop_and_free_message(dbg); 452 continue; 453 } 454 455 if (!hdhomerun_debug_output_message(dbg, message)) { 456 sleep(1); 457 continue; 458 } 459 460 hdhomerun_debug_pop_and_free_message(dbg); 461 } 462 463 return 0; 464 } -
mythtv/libs/libmythtv/hdhomerun/hdhomerun_debug.h
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun_debug.h release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun_debug.h
1 /* 2 * hdhomerun_debug.h 3 * 4 * Copyright © 2006 Silicondust Engineering Ltd. <www.silicondust.com>. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 3 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 31 */ 32 33 /* 34 * The debug logging includes optional support for connecting to the 35 * Silicondust support server. This option should not be used without 36 * being explicitly enabled by the user. Debug information should be 37 * limited to information useful to diagnosing a problem. 38 * - Silicondust. 39 */ 40 41 #ifdef __cplusplus 42 extern "C" { 43 #endif 44 45 struct hdhomerun_debug_t; 46 47 extern LIBTYPE struct hdhomerun_debug_t *hdhomerun_debug_create(void); 48 extern LIBTYPE void hdhomerun_debug_destroy(struct hdhomerun_debug_t *dbg); 49 50 extern LIBTYPE void hdhomerun_debug_set_prefix(struct hdhomerun_debug_t *dbg, const char *prefix); 51 extern LIBTYPE void hdhomerun_debug_set_filename(struct hdhomerun_debug_t *dbg, const char *filename); 52 extern LIBTYPE void hdhomerun_debug_enable(struct hdhomerun_debug_t *dbg); 53 extern LIBTYPE void hdhomerun_debug_disable(struct hdhomerun_debug_t *dbg); 54 extern LIBTYPE bool_t hdhomerun_debug_enabled(struct hdhomerun_debug_t *dbg); 55 56 extern LIBTYPE void hdhomerun_debug_flush(struct hdhomerun_debug_t *dbg, uint64_t timeout); 57 58 extern LIBTYPE void hdhomerun_debug_printf(struct hdhomerun_debug_t *dbg, const char *fmt, ...); 59 extern LIBTYPE void hdhomerun_debug_vprintf(struct hdhomerun_debug_t *dbg, const char *fmt, va_list args); 60 61 #ifdef __cplusplus 62 } 63 #endif -
mythtv/libs/libmythtv/hdhomerun/hdhomerun_device.c
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun_device.c release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun_device.c
1 1 /* 2 * hdhomerun_ record.c2 * hdhomerun_device.c 3 3 * 4 * Copyright © 2006Silicondust Engineering Ltd. <www.silicondust.com>.4 * Copyright © 2006-2008 Silicondust Engineering Ltd. <www.silicondust.com>. 5 5 * 6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU Lesser General Public 8 8 * License as published by the Free Software Foundation; either 9 * version 2.1of the License, or (at your option) any later version.9 * version 3 of the License, or (at your option) any later version. 10 10 * 11 11 * This library is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of … … 14 14 * Lesser General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 19 31 */ 20 32 21 #include "hdhomerun_os.h" 22 #include "hdhomerun_pkt.h" 23 #include "hdhomerun_control.h" 24 #include "hdhomerun_video.h" 25 #include "hdhomerun_device.h" 33 #include "hdhomerun.h" 26 34 27 35 struct hdhomerun_device_t { 28 36 struct hdhomerun_control_sock_t *cs; 29 37 struct hdhomerun_video_sock_t *vs; 38 struct hdhomerun_debug_t *dbg; 39 struct hdhomerun_channelscan_t *scan; 30 40 unsigned int tuner; 31 char result_buffer[1024]; 41 uint32_t lockkey; 42 char name[32]; 43 char model[32]; 32 44 }; 33 45 46 static void hdhomerun_device_set_update(struct hdhomerun_device_t *hd) 47 { 48 /* Clear cached information. */ 49 *hd->model = 0; 50 51 /* New name. */ 52 sprintf(hd->name, "%08lX-%u", (unsigned long)hdhomerun_control_get_device_id(hd->cs), hd->tuner); 53 } 54 55 void hdhomerun_device_set_device(struct hdhomerun_device_t *hd, uint32_t device_id, uint32_t device_ip) 56 { 57 hdhomerun_control_set_device(hd->cs, device_id, device_ip); 58 hdhomerun_device_set_update(hd); 59 } 60 61 void hdhomerun_device_set_tuner(struct hdhomerun_device_t *hd, unsigned int tuner) 62 { 63 hd->tuner = tuner; 64 hdhomerun_device_set_update(hd); 65 } 66 34 67 struct hdhomerun_device_t *hdhomerun_device_create(uint32_t device_id, uint32_t device_ip, unsigned int tuner) 35 68 { 36 69 struct hdhomerun_device_t *hd = (struct hdhomerun_device_t *)calloc(1, sizeof(struct hdhomerun_device_t)); … … 38 71 return NULL; 39 72 } 40 73 41 hd->tuner = tuner; 42 43 hd->cs = hdhomerun_control_create(device_id, device_ip); 74 hd->cs = hdhomerun_control_create(0, 0); 44 75 if (!hd->cs) { 45 76 free(hd); 46 77 return NULL; 47 78 } 48 79 80 hdhomerun_device_set_device(hd, device_id, device_ip); 81 hdhomerun_device_set_tuner(hd, tuner); 82 49 83 return hd; 50 84 } 51 85 52 86 void hdhomerun_device_destroy(struct hdhomerun_device_t *hd) 53 87 { 88 if (hd->scan) { 89 channelscan_destroy(hd->scan); 90 } 91 54 92 if (hd->vs) { 55 93 hdhomerun_video_destroy(hd->vs); 56 94 } … … 60 98 free(hd); 61 99 } 62 100 63 void hdhomerun_device_set_tuner(struct hdhomerun_device_t *hd, unsigned int tuner)101 static bool_t is_hex_char(char c) 64 102 { 65 hd->tuner = tuner; 103 if ((c >= '0') && (c <= '9')) { 104 return TRUE; 105 } 106 if ((c >= 'A') && (c <= 'F')) { 107 return TRUE; 108 } 109 if ((c >= 'a') && (c <= 'f')) { 110 return TRUE; 111 } 112 return FALSE; 113 } 114 115 static struct hdhomerun_device_t *hdhomerun_device_create_from_str_device_id(const char *device_str) 116 { 117 int i; 118 const char *ptr = device_str; 119 for (i = 0; i < 8; i++) { 120 if (!is_hex_char(*ptr++)) { 121 return NULL; 122 } 123 } 124 125 if (*ptr == 0) { 126 unsigned long device_id; 127 if (sscanf(device_str, "%lx", &device_id) != 1) { 128 return NULL; 129 } 130 return hdhomerun_device_create((uint32_t)device_id, 0, 0); 131 } 132 133 if (*ptr == '-') { 134 unsigned long device_id; 135 unsigned int tuner; 136 if (sscanf(device_str, "%lx-%u", &device_id, &tuner) != 2) { 137 return NULL; 138 } 139 return hdhomerun_device_create((uint32_t)device_id, 0, tuner); 140 } 141 142 return NULL; 143 } 144 145 static struct hdhomerun_device_t *hdhomerun_device_create_from_str_ip(const char *device_str) 146 { 147 unsigned long a[4]; 148 if (sscanf(device_str, "%lu.%lu.%lu.%lu", &a[0], &a[1], &a[2], &a[3]) != 4) { 149 return NULL; 150 } 151 152 unsigned long device_ip = (a[0] << 24) | (a[1] << 16) | (a[2] << 8) | (a[3] << 0); 153 return hdhomerun_device_create(HDHOMERUN_DEVICE_ID_WILDCARD, (uint32_t)device_ip, 0); 154 } 155 156 static struct hdhomerun_device_t *hdhomerun_device_create_from_str_dns(const char *device_str) 157 { 158 #if defined(__CYGWIN__) 159 return NULL; 160 #else 161 struct addrinfo hints; 162 memset(&hints, 0, sizeof(hints)); 163 hints.ai_family = AF_INET; 164 hints.ai_socktype = SOCK_STREAM; 165 hints.ai_protocol = IPPROTO_TCP; 166 167 struct addrinfo *sock_info; 168 if (getaddrinfo(device_str, "65001", &hints, &sock_info) != 0) { 169 return NULL; 170 } 171 172 struct sockaddr_in *sock_addr = (struct sockaddr_in *)sock_info->ai_addr; 173 uint32_t device_ip = ntohl(sock_addr->sin_addr.s_addr); 174 freeaddrinfo(sock_info); 175 176 if (device_ip == 0) { 177 return NULL; 178 } 179 180 return hdhomerun_device_create(HDHOMERUN_DEVICE_ID_WILDCARD, (uint32_t)device_ip, 0); 181 #endif 182 } 183 184 struct hdhomerun_device_t *hdhomerun_device_create_from_str(const char *device_str) 185 { 186 struct hdhomerun_device_t *device = hdhomerun_device_create_from_str_device_id(device_str); 187 if (device) { 188 return device; 189 } 190 191 device = hdhomerun_device_create_from_str_ip(device_str); 192 if (device) { 193 return device; 194 } 195 196 device = hdhomerun_device_create_from_str_dns(device_str); 197 if (device) { 198 return device; 199 } 200 201 return NULL; 202 } 203 204 int hdhomerun_device_set_tuner_from_str(struct hdhomerun_device_t *hd, const char *tuner_str) 205 { 206 unsigned int tuner; 207 if (sscanf(tuner_str, "%u", &tuner) == 1) { 208 hdhomerun_device_set_tuner(hd, tuner); 209 return 1; 210 } 211 if (sscanf(tuner_str, "/tuner%u", &tuner) == 1) { 212 hdhomerun_device_set_tuner(hd, tuner); 213 return 1; 214 } 215 216 return -1; 217 } 218 219 void hdhomerun_device_set_debug(struct hdhomerun_device_t *hd, struct hdhomerun_debug_t *dbg) 220 { 221 hd->dbg = dbg; 222 hdhomerun_control_set_debug(hd->cs, dbg); 223 224 if (hd->vs) { 225 hdhomerun_video_set_debug(hd->vs, dbg); 226 } 227 } 228 229 uint32_t hdhomerun_device_get_device_id(struct hdhomerun_device_t *hd) 230 { 231 return hdhomerun_control_get_device_id(hd->cs); 232 } 233 234 uint32_t hdhomerun_device_get_device_ip(struct hdhomerun_device_t *hd) 235 { 236 return hdhomerun_control_get_device_ip(hd->cs); 237 } 238 239 uint32_t hdhomerun_device_get_device_id_requested(struct hdhomerun_device_t *hd) 240 { 241 return hdhomerun_control_get_device_id_requested(hd->cs); 242 } 243 244 uint32_t hdhomerun_device_get_device_ip_requested(struct hdhomerun_device_t *hd) 245 { 246 return hdhomerun_control_get_device_ip_requested(hd->cs); 247 } 248 249 unsigned int hdhomerun_device_get_tuner(struct hdhomerun_device_t *hd) 250 { 251 return hd->tuner; 66 252 } 67 253 68 254 struct hdhomerun_control_sock_t *hdhomerun_device_get_control_sock(struct hdhomerun_device_t *hd) … … 72 258 73 259 struct hdhomerun_video_sock_t *hdhomerun_device_get_video_sock(struct hdhomerun_device_t *hd) 74 260 { 261 if (hd->vs) { 262 return hd->vs; 263 } 264 265 hd->vs = hdhomerun_video_create(0, VIDEO_DATA_BUFFER_SIZE_1S * 2); 75 266 if (!hd->vs) { 76 hd->vs = hdhomerun_video_create(0, VIDEO_DATA_BUFFER_SIZE_1S);267 return NULL; 77 268 } 269 270 hdhomerun_video_set_debug(hd->vs, hd->dbg); 78 271 return hd->vs; 79 272 } 80 273 … … 96 289 return (uint32_t)value; 97 290 } 98 291 99 int hdhomerun_device_get_tuner_status(struct hdhomerun_device_t *hd, struct hdhomerun_tuner_status_t *status) 292 static bool_t hdhomerun_device_get_tuner_status_lock_is_bcast(struct hdhomerun_tuner_status_t *status) 293 { 294 if (strcmp(status->lock_str, "8vsb") == 0) { 295 return TRUE; 296 } 297 if (strncmp(status->lock_str, "t8", 2) == 0) { 298 return TRUE; 299 } 300 if (strncmp(status->lock_str, "t7", 2) == 0) { 301 return TRUE; 302 } 303 if (strncmp(status->lock_str, "t6", 2) == 0) { 304 return TRUE; 305 } 306 307 return FALSE; 308 } 309 310 uint32_t hdhomerun_device_get_tuner_status_ss_color(struct hdhomerun_tuner_status_t *status) 311 { 312 unsigned int ss_yellow_min; 313 unsigned int ss_green_min; 314 315 if (!status->lock_supported) { 316 return HDHOMERUN_STATUS_COLOR_NEUTRAL; 317 } 318 319 if (hdhomerun_device_get_tuner_status_lock_is_bcast(status)) { 320 ss_yellow_min = 50; /* -30dBmV */ 321 ss_green_min = 75; /* -15dBmV */ 322 } else { 323 ss_yellow_min = 80; /* -12dBmV */ 324 ss_green_min = 90; /* -6dBmV */ 325 } 326 327 if (status->signal_strength >= ss_green_min) { 328 return HDHOMERUN_STATUS_COLOR_GREEN; 329 } 330 if (status->signal_strength >= ss_yellow_min) { 331 return HDHOMERUN_STATUS_COLOR_YELLOW; 332 } 333 334 return HDHOMERUN_STATUS_COLOR_RED; 335 } 336 337 uint32_t hdhomerun_device_get_tuner_status_snq_color(struct hdhomerun_tuner_status_t *status) 338 { 339 if (status->signal_to_noise_quality >= 70) { 340 return HDHOMERUN_STATUS_COLOR_GREEN; 341 } 342 if (status->signal_to_noise_quality >= 50) { 343 return HDHOMERUN_STATUS_COLOR_YELLOW; 344 } 345 346 return HDHOMERUN_STATUS_COLOR_RED; 347 } 348 349 uint32_t hdhomerun_device_get_tuner_status_seq_color(struct hdhomerun_tuner_status_t *status) 350 { 351 if (status->symbol_error_quality >= 100) { 352 return HDHOMERUN_STATUS_COLOR_GREEN; 353 } 354 355 return HDHOMERUN_STATUS_COLOR_RED; 356 } 357 358 int hdhomerun_device_get_tuner_status(struct hdhomerun_device_t *hd, char **pstatus_str, struct hdhomerun_tuner_status_t *status) 100 359 { 101 360 memset(status, 0, sizeof(struct hdhomerun_tuner_status_t)); 102 361 … … 109 368 return ret; 110 369 } 111 370 371 if (pstatus_str) { 372 *pstatus_str = status_str; 373 } 374 112 375 char *channel = strstr(status_str, "ch="); 113 376 if (channel) { 114 sscanf(channel + 3, "%s", status->channel); 377 sscanf(channel + 3, "%31s", status->channel); 378 } 379 380 char *lock = strstr(status_str, "lock="); 381 if (lock) { 382 sscanf(lock + 5, "%31s", status->lock_str); 115 383 } 116 384 117 385 status->signal_strength = (unsigned int)hdhomerun_device_get_status_parse(status_str, "ss="); … … 120 388 status->raw_bits_per_second = hdhomerun_device_get_status_parse(status_str, "bps="); 121 389 status->packets_per_second = hdhomerun_device_get_status_parse(status_str, "pps="); 122 390 391 status->signal_present = status->signal_strength >= 45; 392 393 if (strcmp(status->lock_str, "none") != 0) { 394 if (status->lock_str[0] == '(') { 395 status->lock_unsupported = TRUE; 396 } else { 397 status->lock_supported = TRUE; 398 } 399 } 400 123 401 return 1; 124 402 } 125 403 … … 151 429 return hdhomerun_control_get(hd->cs, name, pfilter, NULL); 152 430 } 153 431 154 int hdhomerun_device_get_tuner_program(struct hdhomerun_device_t *hd, uint16_t *pprogram_number)432 int hdhomerun_device_get_tuner_program(struct hdhomerun_device_t *hd, char **pprogram) 155 433 { 156 434 char name[32]; 157 435 sprintf(name, "/tuner%u/program", hd->tuner); 436 return hdhomerun_control_get(hd->cs, name, pprogram, NULL); 437 } 158 438 159 char *program_str; 160 int ret = hdhomerun_control_get(hd->cs, name, &program_str, NULL); 439 int hdhomerun_device_get_tuner_target(struct hdhomerun_device_t *hd, char **ptarget) 440 { 441 char name[32]; 442 sprintf(name, "/tuner%u/target", hd->tuner); 443 return hdhomerun_control_get(hd->cs, name, ptarget, NULL); 444 } 445 446 int hdhomerun_device_get_tuner_plotsample(struct hdhomerun_device_t *hd, struct hdhomerun_plotsample_t **psamples, size_t *pcount) 447 { 448 char name[32]; 449 sprintf(name, "/tuner%u/plotsample", hd->tuner); 450 451 char *result; 452 int ret = hdhomerun_control_get(hd->cs, name, &result, NULL); 161 453 if (ret <= 0) { 162 454 return ret; 163 455 } 164 456 165 *pprogram_number = (uint16_t)atol(program_str); 457 struct hdhomerun_plotsample_t *samples = (struct hdhomerun_plotsample_t *)result; 458 *psamples = samples; 459 size_t count = 0; 460 461 while (1) { 462 char *ptr = strchr(result, ' '); 463 if (!ptr) { 464 break; 465 } 466 *ptr++ = 0; 467 468 unsigned long raw; 469 if (sscanf(result, "%lx", &raw) != 1) { 470 break; 471 } 472 473 uint16_t real = (raw >> 12) & 0x0FFF; 474 if (real & 0x0800) { 475 real |= 0xF000; 476 } 477 478 uint16_t imag = (raw >> 0) & 0x0FFF; 479 if (imag & 0x0800) { 480 imag |= 0xF000; 481 } 482 483 samples->real = (int16_t)real; 484 samples->imag = (int16_t)imag; 485 samples++; 486 count++; 487 488 result = ptr; 489 } 490 491 *pcount = count; 166 492 return 1; 167 493 } 168 494 169 int hdhomerun_device_get_tuner_ target(struct hdhomerun_device_t *hd, char **ptarget)495 int hdhomerun_device_get_tuner_lockkey_owner(struct hdhomerun_device_t *hd, char **powner) 170 496 { 171 497 char name[32]; 172 sprintf(name, "/tuner%u/ target", hd->tuner);173 return hdhomerun_control_get(hd->cs, name, p target, NULL);498 sprintf(name, "/tuner%u/lockkey", hd->tuner); 499 return hdhomerun_control_get(hd->cs, name, powner, NULL); 174 500 } 175 501 176 502 int hdhomerun_device_get_ir_target(struct hdhomerun_device_t *hd, char **ptarget) … … 178 504 return hdhomerun_control_get(hd->cs, "/ir/target", ptarget, NULL); 179 505 } 180 506 507 int hdhomerun_device_get_lineup_location(struct hdhomerun_device_t *hd, char **plocation) 508 { 509 return hdhomerun_control_get(hd->cs, "/lineup/location", plocation, NULL); 510 } 511 181 512 int hdhomerun_device_get_version(struct hdhomerun_device_t *hd, char **pversion_str, uint32_t *pversion_num) 182 513 { 183 514 char *version_str; … … 206 537 { 207 538 char name[32]; 208 539 sprintf(name, "/tuner%u/channel", hd->tuner); 209 return hdhomerun_control_set (hd->cs, name, channel, NULL, NULL);540 return hdhomerun_control_set_with_lockkey(hd->cs, name, channel, hd->lockkey, NULL, NULL); 210 541 } 211 542 212 543 int hdhomerun_device_set_tuner_channelmap(struct hdhomerun_device_t *hd, const char *channelmap) 213 544 { 214 545 char name[32]; 215 546 sprintf(name, "/tuner%u/channelmap", hd->tuner); 216 return hdhomerun_control_set (hd->cs, name, channelmap, NULL, NULL);547 return hdhomerun_control_set_with_lockkey(hd->cs, name, channelmap, hd->lockkey, NULL, NULL); 217 548 } 218 549 219 550 int hdhomerun_device_set_tuner_filter(struct hdhomerun_device_t *hd, const char *filter) 220 551 { 221 552 char name[32]; 222 553 sprintf(name, "/tuner%u/filter", hd->tuner); 223 return hdhomerun_control_set(hd->cs, name, filter, NULL, NULL); 554 return hdhomerun_control_set_with_lockkey(hd->cs, name, filter, hd->lockkey, NULL, NULL); 555 } 556 557 static int hdhomerun_device_set_tuner_filter_by_array_append(char **pptr, char *end, uint16_t range_begin, uint16_t range_end) 558 { 559 char *ptr = *pptr; 560 561 size_t available = end - ptr; 562 size_t required; 563 564 if (range_begin == range_end) { 565 required = snprintf(ptr, available, "0x%04x ", range_begin) + 1; 566 } else { 567 required = snprintf(ptr, available, "0x%04x-0x%04x ", range_begin, range_end) + 1; 568 } 569 570 if (required > available) { 571 return FALSE; 572 } 573 574 *pptr = strchr(ptr, 0); 575 return TRUE; 224 576 } 225 577 226 int hdhomerun_device_set_tuner_ program(struct hdhomerun_device_t *hd, uint16_t program_number)578 int hdhomerun_device_set_tuner_filter_by_array(struct hdhomerun_device_t *hd, unsigned char filter_array[0x2000]) 227 579 { 228 char name[32], value[32]; 580 char filter[1024]; 581 char *ptr = filter; 582 char *end = filter + sizeof(filter); 583 584 uint16_t range_begin = 0xFFFF; 585 uint16_t range_end = 0xFFFF; 586 587 uint16_t i; 588 for (i = 0; i <= 0x1FFF; i++) { 589 if (!filter_array[i]) { 590 if (range_begin == 0xFFFF) { 591 continue; 592 } 593 if (!hdhomerun_device_set_tuner_filter_by_array_append(&ptr, end, range_begin, range_end)) { 594 return 0; 595 } 596 range_begin = 0xFFFF; 597 range_end = 0xFFFF; 598 continue; 599 } 600 601 if (range_begin == 0xFFFF) { 602 range_begin = i; 603 range_end = i; 604 continue; 605 } 606 607 range_end = i; 608 } 609 610 if (range_begin != 0xFFFF) { 611 if (!hdhomerun_device_set_tuner_filter_by_array_append(&ptr, end, range_begin, range_end)) { 612 return 0; 613 } 614 } 615 616 /* Remove trailing space. */ 617 if (ptr > filter) { 618 ptr--; 619 } 620 *ptr = 0; 621 622 return hdhomerun_device_set_tuner_filter(hd, filter); 623 } 624 625 int hdhomerun_device_set_tuner_program(struct hdhomerun_device_t *hd, const char *program) 626 { 627 char name[32]; 229 628 sprintf(name, "/tuner%u/program", hd->tuner); 230 sprintf(value, "%u", program_number); 231 return hdhomerun_control_set(hd->cs, name, value, NULL, NULL); 629 return hdhomerun_control_set_with_lockkey(hd->cs, name, program, hd->lockkey, NULL, NULL); 232 630 } 233 631 234 632 int hdhomerun_device_set_tuner_target(struct hdhomerun_device_t *hd, char *target) 235 633 { 236 634 char name[32]; 237 635 sprintf(name, "/tuner%u/target", hd->tuner); 238 return hdhomerun_control_set (hd->cs, name, target, NULL, NULL);636 return hdhomerun_control_set_with_lockkey(hd->cs, name, target, hd->lockkey, NULL, NULL); 239 637 } 240 638 241 static int hdhomerun_device_set_tuner_target_to_local(struct hdhomerun_device_t *hd)639 int hdhomerun_device_set_tuner_target_to_local_protocol(struct hdhomerun_device_t *hd, const char *protocol) 242 640 { 641 /* Create video socket. */ 642 hdhomerun_device_get_video_sock(hd); 643 if (!hd->vs) { 644 return -1; 645 } 646 647 /* Set target. */ 243 648 char target[64]; 244 649 uint32_t local_ip = hdhomerun_control_get_local_addr(hd->cs); 245 650 uint16_t local_port = hdhomerun_video_get_local_port(hd->vs); 246 sprintf(target, "%u.%u.%u.%u:%u", 651 sprintf(target, "%s://%u.%u.%u.%u:%u", 652 protocol, 247 653 (unsigned int)(local_ip >> 24) & 0xFF, (unsigned int)(local_ip >> 16) & 0xFF, 248 654 (unsigned int)(local_ip >> 8) & 0xFF, (unsigned int)(local_ip >> 0) & 0xFF, 249 655 (unsigned int)local_port … … 252 658 return hdhomerun_device_set_tuner_target(hd, target); 253 659 } 254 660 661 int hdhomerun_device_set_tuner_target_to_local(struct hdhomerun_device_t *hd) 662 { 663 return hdhomerun_device_set_tuner_target_to_local_protocol(hd, HDHOMERUN_TARGET_PROTOCOL_UDP); 664 } 665 255 666 int hdhomerun_device_set_ir_target(struct hdhomerun_device_t *hd, const char *target) 256 667 { 257 668 return hdhomerun_control_set(hd->cs, "/ir/target", target, NULL, NULL); 258 669 } 259 670 671 int hdhomerun_device_set_lineup_location(struct hdhomerun_device_t *hd, const char *location) 672 { 673 return hdhomerun_control_set(hd->cs, "/lineup/location", location, NULL, NULL); 674 } 675 260 676 int hdhomerun_device_get_var(struct hdhomerun_device_t *hd, const char *name, char **pvalue, char **perror) 261 677 { 262 678 return hdhomerun_control_get(hd->cs, name, pvalue, perror); … … 267 683 return hdhomerun_control_set(hd->cs, name, value, pvalue, perror); 268 684 } 269 685 270 int hdhomerun_device_ stream_start(struct hdhomerun_device_t *hd)686 int hdhomerun_device_tuner_lockkey_request(struct hdhomerun_device_t *hd) 271 687 { 272 /* Create video socket. */ 273 hdhomerun_device_get_video_sock(hd); 274 if (!hd->vs) { 275 return -1; 688 uint32_t new_lockkey = (uint32_t)getcurrenttime(); 689 690 char name[32]; 691 sprintf(name, "/tuner%u/lockkey", hd->tuner); 692 693 char new_lockkey_str[64]; 694 sprintf(new_lockkey_str, "%u", (unsigned int)new_lockkey); 695 696 int ret = hdhomerun_control_set_with_lockkey(hd->cs, name, new_lockkey_str, hd->lockkey, NULL, NULL); 697 if (ret <= 0) { 698 hd->lockkey = 0; 699 return ret; 276 700 } 277 701 702 hd->lockkey = new_lockkey; 703 return ret; 704 } 705 706 int hdhomerun_device_tuner_lockkey_release(struct hdhomerun_device_t *hd) 707 { 708 if (hd->lockkey == 0) { 709 return 1; 710 } 711 712 char name[32]; 713 sprintf(name, "/tuner%u/lockkey", hd->tuner); 714 int ret = hdhomerun_control_set_with_lockkey(hd->cs, name, "none", hd->lockkey, NULL, NULL); 715 716 hd->lockkey = 0; 717 return ret; 718 } 719 720 int hdhomerun_device_wait_for_lock(struct hdhomerun_device_t *hd, struct hdhomerun_tuner_status_t *status) 721 { 722 /* Wait for up to 2.5 seconds for lock. */ 723 int i; 724 for (i = 0; i < 10; i++) { 725 usleep(250000); 726 727 /* Get status to check for lock. Quality numbers will not be valid yet. */ 728 int ret = hdhomerun_device_get_tuner_status(hd, NULL, status); 729 if (ret <= 0) { 730 return ret; 731 } 732 733 if (!status->signal_present) { 734 return 1; 735 } 736 if (status->lock_supported || status->lock_unsupported) { 737 return 1; 738 } 739 } 740 741 return 1; 742 } 743 744 int hdhomerun_device_stream_start(struct hdhomerun_device_t *hd) 745 { 278 746 /* Set target. */ 279 int ret = hdhomerun_device_s et_tuner_target_to_local(hd);747 int ret = hdhomerun_device_stream_refresh_target(hd); 280 748 if (ret <= 0) { 281 749 return ret; 282 750 } … … 289 757 return 1; 290 758 } 291 759 760 int hdhomerun_device_stream_refresh_target(struct hdhomerun_device_t *hd) 761 { 762 return hdhomerun_device_set_tuner_target_to_local_protocol(hd, HDHOMERUN_TARGET_PROTOCOL_RTP); 763 } 764 292 765 uint8_t *hdhomerun_device_stream_recv(struct hdhomerun_device_t *hd, size_t max_size, size_t *pactual_size) 293 766 { 767 if (!hd->vs) { 768 return NULL; 769 } 294 770 return hdhomerun_video_recv(hd->vs, max_size, pactual_size); 295 771 } 296 772 773 void hdhomerun_device_stream_flush(struct hdhomerun_device_t *hd) 774 { 775 hdhomerun_video_flush(hd->vs); 776 } 777 297 778 void hdhomerun_device_stream_stop(struct hdhomerun_device_t *hd) 298 779 { 299 780 hdhomerun_device_set_tuner_target(hd, "none"); 300 781 } 301 782 783 int hdhomerun_device_channelscan_init(struct hdhomerun_device_t *hd, const char *channelmap) 784 { 785 if (hd->scan) { 786 channelscan_destroy(hd->scan); 787 } 788 789 hd->scan = channelscan_create(hd, channelmap); 790 if (!hd->scan) { 791 return -1; 792 } 793 794 return 1; 795 } 796 797 int hdhomerun_device_channelscan_advance(struct hdhomerun_device_t *hd, struct hdhomerun_channelscan_result_t *result) 798 { 799 if (!hd->scan) { 800 return 0; 801 } 802 803 int ret = channelscan_advance(hd->scan, result); 804 if (ret <= 0) { 805 channelscan_destroy(hd->scan); 806 hd->scan = NULL; 807 } 808 809 return ret; 810 } 811 812 int hdhomerun_device_channelscan_detect(struct hdhomerun_device_t *hd, struct hdhomerun_channelscan_result_t *result) 813 { 814 if (!hd->scan) { 815 return 0; 816 } 817 818 int ret = channelscan_detect(hd->scan, result); 819 if (ret <= 0) { 820 channelscan_destroy(hd->scan); 821 hd->scan = NULL; 822 } 823 824 return ret; 825 } 826 827 uint8_t hdhomerun_device_channelscan_get_progress(struct hdhomerun_device_t *hd) 828 { 829 if (!hd->scan) { 830 return 0; 831 } 832 833 return channelscan_get_progress(hd->scan); 834 } 835 302 836 int hdhomerun_device_firmware_version_check(struct hdhomerun_device_t *hd, uint32_t features) 303 837 { 304 838 uint32_t version; … … 306 840 return -1; 307 841 } 308 842 309 if (version >= 20061213) { 310 return 1; 843 if (version < 20070219) { 844 return 0; 845 } 846 847 return 1; 848 } 849 850 const char *hdhomerun_device_get_model_str(struct hdhomerun_device_t *hd) 851 { 852 if (*hd->model) { 853 return hd->model; 854 } 855 856 char *model_str; 857 int ret = hdhomerun_control_get(hd->cs, "/sys/model", &model_str, NULL); 858 if (ret < 0) { 859 return NULL; 860 } 861 if (ret == 0) { 862 model_str = "hdhomerun_atsc"; 311 863 } 312 864 313 return 0; 865 strncpy(hd->model, model_str, sizeof(hd->model) - 1); 866 hd->model[sizeof(hd->model) - 1] = 0; 867 868 return hd->model; 314 869 } 315 870 316 871 int hdhomerun_device_upgrade(struct hdhomerun_device_t *hd, FILE *upgrade_file) 317 872 { 873 hdhomerun_control_set(hd->cs, "/tuner0/lockkey", "force", NULL, NULL); 318 874 hdhomerun_control_set(hd->cs, "/tuner0/channel", "none", NULL, NULL); 875 876 hdhomerun_control_set(hd->cs, "/tuner1/lockkey", "force", NULL, NULL); 319 877 hdhomerun_control_set(hd->cs, "/tuner1/channel", "none", NULL, NULL); 878 320 879 return hdhomerun_control_upgrade(hd->cs, upgrade_file); 321 880 } 881 882 void hdhomerun_device_debug_print_video_stats(struct hdhomerun_device_t *hd) 883 { 884 if (!hdhomerun_debug_enabled(hd->dbg)) { 885 return; 886 } 887 888 char name[32]; 889 sprintf(name, "/tuner%u/debug", hd->tuner); 890 891 char *debug_str; 892 char *error_str; 893 int ret = hdhomerun_control_get(hd->cs, name, &debug_str, &error_str); 894 if (ret < 0) { 895 hdhomerun_debug_printf(hd->dbg, "video dev: communication error getting debug stats\n"); 896 return; 897 } 898 899 if (error_str) { 900 hdhomerun_debug_printf(hd->dbg, "video dev: %s\n", error_str); 901 } else { 902 hdhomerun_debug_printf(hd->dbg, "video dev: %s\n", debug_str); 903 } 904 905 if (hd->vs) { 906 hdhomerun_video_debug_print_stats(hd->vs); 907 } 908 } 909 910 void hdhomerun_device_get_video_stats(struct hdhomerun_device_t *hd, struct hdhomerun_video_stats_t *stats) 911 { 912 hdhomerun_video_get_stats(hd->vs, stats); 913 } -
mythtv/libs/libmythtv/hdhomerun/hdhomerun_device.h
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun_device.h release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun_device.h
1 1 /* 2 2 * hdhomerun_device.h 3 3 * 4 * Copyright © 2006Silicondust Engineering Ltd. <www.silicondust.com>.4 * Copyright © 2006-2008 Silicondust Engineering Ltd. <www.silicondust.com>. 5 5 * 6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU Lesser General Public 8 8 * License as published by the Free Software Foundation; either 9 * version 2.1of the License, or (at your option) any later version.9 * version 3 of the License, or (at your option) any later version. 10 10 * 11 11 * This library is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of … … 14 14 * Lesser General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 19 31 */ 20 32 21 33 #ifdef __cplusplus … … 26 38 #define HDHOMERUN_DEVICE_MAX_LOCK_TO_DATA_TIME 2000 27 39 #define HDHOMERUN_DEVICE_MAX_TUNE_TO_DATA_TIME (HDHOMERUN_DEVICE_MAX_TUNE_TO_LOCK_TIME + HDHOMERUN_DEVICE_MAX_LOCK_TO_DATA_TIME) 28 40 29 struct hdhomerun_device_t; 41 #define HDHOMERUN_STATUS_COLOR_NEUTRAL 0xFFFFFFFF 42 #define HDHOMERUN_STATUS_COLOR_RED 0xFFFF0000 43 #define HDHOMERUN_STATUS_COLOR_YELLOW 0xFFFFFF00 44 #define HDHOMERUN_STATUS_COLOR_GREEN 0xFF00C000 30 45 31 struct hdhomerun_tuner_status_t { 32 char channel[32]; 33 unsigned int signal_strength; 34 unsigned int signal_to_noise_quality; 35 unsigned int symbol_error_quality; 36 uint32_t raw_bits_per_second; 37 uint32_t packets_per_second; 38 }; 46 #define HDHOMERUN_TARGET_PROTOCOL_UDP "udp" 47 #define HDHOMERUN_TARGET_PROTOCOL_RTP "rtp" 39 48 40 49 /* 41 50 * Create a device object. … … 57 66 * Returns a pointer to the newly created device object. 58 67 * 59 68 * When no longer needed, the socket should be destroyed by calling hdhomerun_device_destroy. 69 * 70 * The hdhomerun_device_create_from_str function creates a device object from the given device_str. 71 * The device_str parameter can be any of the following forms: 72 * <device id> 73 * <device id>-<tuner index> 74 * <ip address> 75 * If the tuner index is not included in the device_str then it is set to zero. 76 * Use hdhomerun_device_set_tuner or hdhomerun_device_set_tuner_from_str to set the tuner. 77 * 78 * The hdhomerun_device_set_tuner_from_str function sets the tuner from the given tuner_str. 79 * The tuner_str parameter can be any of the following forms: 80 * <tuner index> 81 * /tuner<tuner index> 82 */ 83 extern LIBTYPE struct hdhomerun_device_t *hdhomerun_device_create(uint32_t device_id, uint32_t device_ip, unsigned int tuner); 84 extern LIBTYPE struct hdhomerun_device_t *hdhomerun_device_create_from_str(const char *device_str); 85 extern LIBTYPE void hdhomerun_device_destroy(struct hdhomerun_device_t *hd); 86 87 /* 88 * Get the device id, ip, or tuner of the device instance. 60 89 */ 61 extern struct hdhomerun_device_t *hdhomerun_device_create(uint32_t device_id, uint32_t device_ip, unsigned int tuner); 62 extern void hdhomerun_device_destroy(struct hdhomerun_device_t *hd); 63 extern void hdhomerun_device_set_tuner(struct hdhomerun_device_t *hd, unsigned int tuner); 90 extern LIBTYPE uint32_t hdhomerun_device_get_device_id(struct hdhomerun_device_t *hd); 91 extern LIBTYPE uint32_t hdhomerun_device_get_device_ip(struct hdhomerun_device_t *hd); 92 extern LIBTYPE uint32_t hdhomerun_device_get_device_id_requested(struct hdhomerun_device_t *hd); 93 extern LIBTYPE uint32_t hdhomerun_device_get_device_ip_requested(struct hdhomerun_device_t *hd); 94 extern LIBTYPE unsigned int hdhomerun_device_get_tuner(struct hdhomerun_device_t *hd); 95 96 extern LIBTYPE void hdhomerun_device_set_device(struct hdhomerun_device_t *hd, uint32_t device_id, uint32_t device_ip); 97 extern LIBTYPE void hdhomerun_device_set_tuner(struct hdhomerun_device_t *hd, unsigned int tuner); 98 extern LIBTYPE int hdhomerun_device_set_tuner_from_str(struct hdhomerun_device_t *hd, const char *tuner_str); 64 99 65 100 /* 66 101 * Get the local machine IP address used when communicating with the device. … … 69 104 * 70 105 * Returns 32-bit IP address with native endianness, or 0 on error. 71 106 */ 72 extern uint32_t hdhomerun_device_get_local_machine_addr(struct hdhomerun_device_t *hd);107 extern LIBTYPE uint32_t hdhomerun_device_get_local_machine_addr(struct hdhomerun_device_t *hd); 73 108 74 109 /* 75 110 * Get operations. … … 82 117 * Returns 0 if the operation was rejected. 83 118 * Returns -1 if a communication error occurred. 84 119 */ 85 extern int hdhomerun_device_get_tuner_status(struct hdhomerun_device_t *hd, struct hdhomerun_tuner_status_t *status); 86 extern int hdhomerun_device_get_tuner_streaminfo(struct hdhomerun_device_t *hd, char **pstreaminfo); 87 extern int hdhomerun_device_get_tuner_channel(struct hdhomerun_device_t *hd, char **pchannel); 88 extern int hdhomerun_device_get_tuner_channelmap(struct hdhomerun_device_t *hd, char **pchannelmap); 89 extern int hdhomerun_device_get_tuner_filter(struct hdhomerun_device_t *hd, char **pfilter); 90 extern int hdhomerun_device_get_tuner_program(struct hdhomerun_device_t *hd, uint16_t *pprogram_number); 91 extern int hdhomerun_device_get_tuner_target(struct hdhomerun_device_t *hd, char **ptarget); 92 extern int hdhomerun_device_get_ir_target(struct hdhomerun_device_t *hd, char **ptarget); 93 extern int hdhomerun_device_get_version(struct hdhomerun_device_t *hd, char **pversion_str, uint32_t *pversion_num); 120 extern LIBTYPE int hdhomerun_device_get_tuner_status(struct hdhomerun_device_t *hd, char **pstatus_str, struct hdhomerun_tuner_status_t *status); 121 extern LIBTYPE int hdhomerun_device_get_tuner_streaminfo(struct hdhomerun_device_t *hd, char **pstreaminfo); 122 extern LIBTYPE int hdhomerun_device_get_tuner_channel(struct hdhomerun_device_t *hd, char **pchannel); 123 extern LIBTYPE int hdhomerun_device_get_tuner_channelmap(struct hdhomerun_device_t *hd, char **pchannelmap); 124 extern LIBTYPE int hdhomerun_device_get_tuner_filter(struct hdhomerun_device_t *hd, char **pfilter); 125 extern LIBTYPE int hdhomerun_device_get_tuner_program(struct hdhomerun_device_t *hd, char **pprogram); 126 extern LIBTYPE int hdhomerun_device_get_tuner_target(struct hdhomerun_device_t *hd, char **ptarget); 127 extern LIBTYPE int hdhomerun_device_get_tuner_plotsample(struct hdhomerun_device_t *hd, struct hdhomerun_plotsample_t **psamples, size_t *pcount); 128 extern LIBTYPE int hdhomerun_device_get_tuner_lockkey_owner(struct hdhomerun_device_t *hd, char **powner); 129 extern LIBTYPE int hdhomerun_device_get_ir_target(struct hdhomerun_device_t *hd, char **ptarget); 130 extern LIBTYPE int hdhomerun_device_get_lineup_location(struct hdhomerun_device_t *hd, char **plocation); 131 extern LIBTYPE int hdhomerun_device_get_version(struct hdhomerun_device_t *hd, char **pversion_str, uint32_t *pversion_num); 132 133 extern LIBTYPE uint32_t hdhomerun_device_get_tuner_status_ss_color(struct hdhomerun_tuner_status_t *status); 134 extern LIBTYPE uint32_t hdhomerun_device_get_tuner_status_snq_color(struct hdhomerun_tuner_status_t *status); 135 extern LIBTYPE uint32_t hdhomerun_device_get_tuner_status_seq_color(struct hdhomerun_tuner_status_t *status); 136 137 extern LIBTYPE const char *hdhomerun_device_get_model_str(struct hdhomerun_device_t *hd); 94 138 95 139 /* 96 140 * Set operations. … … 101 145 * Returns 0 if the operation was rejected. 102 146 * Returns -1 if a communication error occurred. 103 147 */ 104 extern int hdhomerun_device_set_tuner_channel(struct hdhomerun_device_t *hd, const char *channel); 105 extern int hdhomerun_device_set_tuner_channelmap(struct hdhomerun_device_t *hd, const char *channelmap); 106 extern int hdhomerun_device_set_tuner_filter(struct hdhomerun_device_t *hd, const char *filter); 107 extern int hdhomerun_device_set_tuner_program(struct hdhomerun_device_t *hd, uint16_t program_number); 108 extern int hdhomerun_device_set_tuner_target(struct hdhomerun_device_t *hd, char *target); 109 extern int hdhomerun_device_set_ir_target(struct hdhomerun_device_t *hd, const char *target); 148 extern LIBTYPE int hdhomerun_device_set_tuner_channel(struct hdhomerun_device_t *hd, const char *channel); 149 extern LIBTYPE int hdhomerun_device_set_tuner_channelmap(struct hdhomerun_device_t *hd, const char *channelmap); 150 extern LIBTYPE int hdhomerun_device_set_tuner_filter(struct hdhomerun_device_t *hd, const char *filter); 151 extern LIBTYPE int hdhomerun_device_set_tuner_filter_by_array(struct hdhomerun_device_t *hd, unsigned char filter_array[0x2000]); 152 extern LIBTYPE int hdhomerun_device_set_tuner_program(struct hdhomerun_device_t *hd, const char *program); 153 extern LIBTYPE int hdhomerun_device_set_tuner_target(struct hdhomerun_device_t *hd, char *target); 154 extern LIBTYPE int hdhomerun_device_set_tuner_target_to_local_protocol(struct hdhomerun_device_t *hd, const char *protocol); 155 extern LIBTYPE int hdhomerun_device_set_tuner_target_to_local(struct hdhomerun_device_t *hd); 156 extern LIBTYPE int hdhomerun_device_set_ir_target(struct hdhomerun_device_t *hd, const char *target); 157 extern LIBTYPE int hdhomerun_device_set_lineup_location(struct hdhomerun_device_t *hd, const char *location); 110 158 111 159 /* 112 160 * Get/set a named control variable on the device. … … 125 173 * Returns 0 if the operation was rejected (pvalue NULL, perror set). 126 174 * Returns -1 if a communication error occurs. 127 175 */ 128 extern int hdhomerun_device_get_var(struct hdhomerun_device_t *hd, const char *name, char **pvalue, char **perror); 129 extern int hdhomerun_device_set_var(struct hdhomerun_device_t *hd, const char *name, const char *value, char **pvalue, char **perror); 176 extern LIBTYPE int hdhomerun_device_get_var(struct hdhomerun_device_t *hd, const char *name, char **pvalue, char **perror); 177 extern LIBTYPE int hdhomerun_device_set_var(struct hdhomerun_device_t *hd, const char *name, const char *value, char **pvalue, char **perror); 178 179 /* 180 * Tuner locking. 181 * 182 * The hdhomerun_device_tuner_lockkey_request function is used to obtain a lock 183 * or to verify that the hdhomerun_device object still holds the lock. 184 * Returns 1 if the lock request was successful and the lock was obtained. 185 * Returns 0 if the lock request was rejected. 186 * Returns -1 if a communication error occurs. 187 * 188 * The hdhomerun_device_tuner_lockkey_release function is used to release a 189 * previously held lock. If locking is used then this function must be called 190 * before destroying the hdhomerun_device object. 191 */ 192 extern LIBTYPE int hdhomerun_device_tuner_lockkey_request(struct hdhomerun_device_t *hd); 193 extern LIBTYPE int hdhomerun_device_tuner_lockkey_release(struct hdhomerun_device_t *hd); 194 195 /* 196 * Wait for tuner lock after channel change. 197 * 198 * The hdhomerun_device_wait_for_lock function is used to detect/wait for a lock vs no lock indication 199 * after a channel change. 200 * 201 * It will return quickly if a lock is aquired. 202 * It will return quickly if there is no signal detected. 203 * Worst case it will time out after 1.5 seconds - the case where there is signal but no lock. 204 */ 205 extern LIBTYPE int hdhomerun_device_wait_for_lock(struct hdhomerun_device_t *hd, struct hdhomerun_tuner_status_t *status); 130 206 131 207 /* 132 208 * Stream a filtered program or the unfiltered stream. … … 144 220 * 145 221 * The hdhomerun_device_stream_stop function tells the device to stop streaming data. 146 222 */ 147 extern int hdhomerun_device_stream_start(struct hdhomerun_device_t *hd); 148 extern uint8_t *hdhomerun_device_stream_recv(struct hdhomerun_device_t *hd, size_t max_size, size_t *pactual_size); 149 extern void hdhomerun_device_stream_stop(struct hdhomerun_device_t *hd); 223 extern LIBTYPE int hdhomerun_device_stream_start(struct hdhomerun_device_t *hd); 224 extern LIBTYPE int hdhomerun_device_stream_refresh_target(struct hdhomerun_device_t *hd); 225 extern LIBTYPE uint8_t *hdhomerun_device_stream_recv(struct hdhomerun_device_t *hd, size_t max_size, size_t *pactual_size); 226 extern LIBTYPE void hdhomerun_device_stream_flush(struct hdhomerun_device_t *hd); 227 extern LIBTYPE void hdhomerun_device_stream_stop(struct hdhomerun_device_t *hd); 228 229 /* 230 * Channel scan API. 231 */ 232 extern LIBTYPE int hdhomerun_device_channelscan_init(struct hdhomerun_device_t *hd, const char *channelmap); 233 extern LIBTYPE int hdhomerun_device_channelscan_advance(struct hdhomerun_device_t *hd, struct hdhomerun_channelscan_result_t *result); 234 extern LIBTYPE int hdhomerun_device_channelscan_detect(struct hdhomerun_device_t *hd, struct hdhomerun_channelscan_result_t *result); 235 extern LIBTYPE uint8_t hdhomerun_device_channelscan_get_progress(struct hdhomerun_device_t *hd); 150 236 151 237 /* 152 238 * Check that the device is running the recommended firmware. … … 157 243 * Returns 0 if th firmware does not meet the minimum requriements for all operations. 158 244 * Returns -1 if an error occurs. 159 245 */ 160 extern int hdhomerun_device_firmware_version_check(struct hdhomerun_device_t *hd, uint32_t features);246 extern LIBTYPE int hdhomerun_device_firmware_version_check(struct hdhomerun_device_t *hd, uint32_t features); 161 247 162 248 /* 163 249 * Upload new firmware to the device. … … 168 254 * Returns 0 if the upload was rejected. 169 255 * Returns -1 if an error occurs. 170 256 */ 171 extern int hdhomerun_device_upgrade(struct hdhomerun_device_t *hd, FILE *upgrade_file);257 extern LIBTYPE int hdhomerun_device_upgrade(struct hdhomerun_device_t *hd, FILE *upgrade_file); 172 258 173 259 /* 174 260 * Low level accessor functions. 175 261 */ 176 extern struct hdhomerun_control_sock_t *hdhomerun_device_get_control_sock(struct hdhomerun_device_t *hd); 177 extern struct hdhomerun_video_sock_t *hdhomerun_device_get_video_sock(struct hdhomerun_device_t *hd); 262 extern LIBTYPE struct hdhomerun_control_sock_t *hdhomerun_device_get_control_sock(struct hdhomerun_device_t *hd); 263 extern LIBTYPE struct hdhomerun_video_sock_t *hdhomerun_device_get_video_sock(struct hdhomerun_device_t *hd); 264 265 /* 266 * Debug print internal stats. 267 */ 268 extern LIBTYPE void hdhomerun_device_set_debug(struct hdhomerun_device_t *hd, struct hdhomerun_debug_t *dbg); 269 extern LIBTYPE void hdhomerun_device_debug_print_video_stats(struct hdhomerun_device_t *hd); 270 271 extern LIBTYPE void hdhomerun_device_get_video_stats(struct hdhomerun_device_t *hd, struct hdhomerun_video_stats_t *stats); 178 272 179 273 #ifdef __cplusplus 180 274 } -
mythtv/libs/libmythtv/hdhomerun/hdhomerun_dhcp.c
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun_dhcp.c release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun_dhcp.c
1 /* 2 * hdhomerun_dhcp.c 3 * 4 * Copyright © 2006-2007 Silicondust Engineering Ltd. <www.silicondust.com>. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 3 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 31 */ 32 33 #include "hdhomerun.h" 34 #include "hdhomerun_dhcp.h" 35 36 struct dhcp_hdr_t { 37 uint8_t bootp_message_type; 38 uint8_t hardware_type; 39 uint8_t hardware_address_length; 40 uint8_t hops; 41 uint32_t transaction_id; 42 uint16_t seconds_elapsed; 43 uint16_t bootp_flags; 44 uint32_t client_ip; 45 uint32_t your_ip; 46 uint32_t next_server_ip; 47 uint32_t relay_agent_ip; 48 uint8_t client_mac[16]; 49 uint8_t server_host_name[64]; 50 uint8_t boot_file_name[128]; 51 uint32_t magic_cookie; 52 }; 53 54 struct hdhomerun_dhcp_t { 55 int sock; 56 uint32_t local_address; 57 pthread_t thread; 58 volatile bool_t terminate; 59 }; 60 61 static THREAD_FUNC_PREFIX hdhomerun_dhcp_thread_execute(void *arg); 62 63 struct hdhomerun_dhcp_t *hdhomerun_dhcp_create(uint32_t bind_address) 64 { 65 if (bind_address != 0) { 66 if ((bind_address & 0xFFFF0000) != 0xA9FE0000) { 67 return NULL; 68 } 69 } 70 71 /* Create socket. */ 72 int sock = (int)socket(AF_INET, SOCK_DGRAM, 0); 73 if (sock == -1) { 74 return NULL; 75 } 76 77 /* Set timeout. */ 78 setsocktimeout(sock, SOL_SOCKET, SO_RCVTIMEO, 1000); 79 80 /* Allow broadcast. */ 81 int sock_opt = 1; 82 setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&sock_opt, sizeof(sock_opt)); 83 84 /* Allow reuse. */ 85 sock_opt = 1; 86 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&sock_opt, sizeof(sock_opt)); 87 88 /* Bind socket. */ 89 struct sockaddr_in sock_addr; 90 memset(&sock_addr, 0, sizeof(sock_addr)); 91 sock_addr.sin_family = AF_INET; 92 sock_addr.sin_addr.s_addr = htonl(bind_address); 93 sock_addr.sin_port = htons(67); 94 if (bind(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) { 95 close(sock); 96 return NULL; 97 } 98 99 /* Allocate object. */ 100 struct hdhomerun_dhcp_t *dhcp = (struct hdhomerun_dhcp_t *)calloc(1, sizeof(struct hdhomerun_dhcp_t)); 101 if (!dhcp) { 102 close(sock); 103 return NULL; 104 } 105 106 dhcp->sock = sock; 107 108 if (bind_address != 0) { 109 dhcp->local_address = bind_address; 110 } else { 111 dhcp->local_address = 0xA9FEFFFF; 112 } 113 114 /* Spawn thread. */ 115 if (pthread_create(&dhcp->thread, NULL, &hdhomerun_dhcp_thread_execute, dhcp) != 0) { 116 close(sock); 117 free(dhcp); 118 return NULL; 119 } 120 121 /* Success. */ 122 return dhcp; 123 } 124 125 void hdhomerun_dhcp_destroy(struct hdhomerun_dhcp_t *dhcp) 126 { 127 dhcp->terminate = TRUE; 128 pthread_join(dhcp->thread, NULL); 129 130 close(dhcp->sock); 131 free(dhcp); 132 } 133 134 static void hdhomerun_dhcp_send(struct hdhomerun_dhcp_t *dhcp, uint8_t message_type, struct hdhomerun_pkt_t *pkt) 135 { 136 pkt->pos = pkt->start; 137 struct dhcp_hdr_t *hdr = (struct dhcp_hdr_t *)pkt->pos; 138 pkt->pos += sizeof(struct dhcp_hdr_t); 139 pkt->end = pkt->pos; 140 141 uint32_t remote_addr = 0xA9FE0000; 142 remote_addr |= (uint32_t)hdr->client_mac[4] << 8; 143 remote_addr |= (uint32_t)hdr->client_mac[5] << 0; 144 if ((remote_addr == 0xA9FE0000) || (remote_addr == 0xA9FEFFFF)) { 145 remote_addr = 0xA9FE8080; 146 } 147 148 hdr->bootp_message_type = 0x02; 149 hdr->your_ip = htonl(remote_addr); 150 hdr->next_server_ip = htonl(0x00000000); 151 152 hdhomerun_pkt_write_u8(pkt, 53); 153 hdhomerun_pkt_write_u8(pkt, 1); 154 hdhomerun_pkt_write_u8(pkt, message_type); 155 156 hdhomerun_pkt_write_u8(pkt, 54); 157 hdhomerun_pkt_write_u8(pkt, 4); 158 hdhomerun_pkt_write_u32(pkt, dhcp->local_address); 159 160 hdhomerun_pkt_write_u8(pkt, 51); 161 hdhomerun_pkt_write_u8(pkt, 4); 162 hdhomerun_pkt_write_u32(pkt, 7*24*60*60); 163 164 hdhomerun_pkt_write_u8(pkt, 1); 165 hdhomerun_pkt_write_u8(pkt, 4); 166 hdhomerun_pkt_write_u32(pkt, 0xFFFF0000); 167 168 hdhomerun_pkt_write_u8(pkt, 0xFF); 169 170 while (pkt->pos < pkt->start + 300) { 171 hdhomerun_pkt_write_u8(pkt, 0x00); 172 } 173 174 struct sockaddr_in sock_addr; 175 memset(&sock_addr, 0, sizeof(sock_addr)); 176 sock_addr.sin_family = AF_INET; 177 sock_addr.sin_addr.s_addr = htonl(0xFFFFFFFF); 178 sock_addr.sin_port = htons(68); 179 180 sendto(dhcp->sock, (char *)pkt->start, (int)(pkt->end - pkt->start), 0, (struct sockaddr *)&sock_addr, sizeof(sock_addr)); 181 } 182 183 static void hdhomerun_dhcp_recv(struct hdhomerun_dhcp_t *dhcp, struct hdhomerun_pkt_t *pkt) 184 { 185 pkt->pos = pkt->start; 186 struct dhcp_hdr_t *hdr = (struct dhcp_hdr_t *)pkt->pos; 187 pkt->pos += sizeof(struct dhcp_hdr_t); 188 if (pkt->pos > pkt->end) { 189 return; 190 } 191 192 if (ntohl(hdr->magic_cookie) != 0x63825363) { 193 return; 194 } 195 196 static uint8_t vendor[3] = {0x00, 0x18, 0xDD}; 197 if (memcmp(hdr->client_mac, vendor, 3) != 0) { 198 return; 199 } 200 201 if (pkt->pos + 3 > pkt->end) { 202 return; 203 } 204 if (hdhomerun_pkt_read_u8(pkt) != 53) { 205 return; 206 } 207 if (hdhomerun_pkt_read_u8(pkt) != 1) { 208 return; 209 } 210 uint8_t message_type_val = hdhomerun_pkt_read_u8(pkt); 211 212 switch (message_type_val) { 213 case 0x01: 214 hdhomerun_dhcp_send(dhcp, 0x02, pkt); 215 break; 216 case 0x03: 217 hdhomerun_dhcp_send(dhcp, 0x05, pkt); 218 break; 219 default: 220 return; 221 } 222 } 223 224 static THREAD_FUNC_PREFIX hdhomerun_dhcp_thread_execute(void *arg) 225 { 226 struct hdhomerun_dhcp_t *dhcp = (struct hdhomerun_dhcp_t *)arg; 227 struct hdhomerun_pkt_t pkt_inst; 228 229 while (1) { 230 if (dhcp->terminate) { 231 return NULL; 232 } 233 234 struct hdhomerun_pkt_t *pkt = &pkt_inst; 235 hdhomerun_pkt_reset(pkt); 236 237 int rx_length = recv(dhcp->sock, (char *)pkt->end, (int)(pkt->limit - pkt->end), 0); 238 if (rx_length <= 0) { 239 if (!sock_getlasterror_socktimeout) { 240 sleep(1); 241 } 242 continue; 243 } 244 pkt->end += rx_length; 245 246 hdhomerun_dhcp_recv(dhcp, pkt); 247 } 248 } -
mythtv/libs/libmythtv/hdhomerun/hdhomerun_dhcp.h
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun_dhcp.h release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun_dhcp.h
1 /* 2 * hdhomerun_dhcp.h 3 * 4 * Copyright © 2006 Silicondust Engineering Ltd. <www.silicondust.com>. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 3 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 31 */ 32 33 #ifdef __cplusplus 34 extern "C" { 35 #endif 36 37 struct hdhomerun_dhcp_t; 38 39 extern LIBTYPE struct hdhomerun_dhcp_t *hdhomerun_dhcp_create(uint32_t bind_address); 40 extern LIBTYPE void hdhomerun_dhcp_destroy(struct hdhomerun_dhcp_t *dhcp); 41 42 #ifdef __cplusplus 43 } 44 #endif -
mythtv/libs/libmythtv/hdhomerun/hdhomerun_discover.c
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun_discover.c release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun_discover.c
1 1 /* 2 2 * hdhomerun_discover.c 3 3 * 4 * Copyright © 2006Silicondust Engineering Ltd. <www.silicondust.com>.4 * Copyright © 2006-2007 Silicondust Engineering Ltd. <www.silicondust.com>. 5 5 * 6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU Lesser General Public 8 8 * License as published by the Free Software Foundation; either 9 * version 2.1of the License, or (at your option) any later version.9 * version 3 of the License, or (at your option) any later version. 10 10 * 11 11 * This library is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of … … 14 14 * Lesser General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 19 31 */ 20 32 21 #include "hdhomerun_os.h" 22 #include "hdhomerun_pkt.h" 23 #include "hdhomerun_discover.h" 33 #include "hdhomerun.h" 24 34 25 35 #if defined(__CYGWIN__) || defined(__WINDOWS__) 26 36 #include <windows.h> 27 #include <iptypes.h>28 37 #include <iphlpapi.h> 38 #define USE_IPHLPAPI 1 39 #else 40 #include <net/if.h> 41 #include <sys/ioctl.h> 42 #ifndef _SIZEOF_ADDR_IFREQ 43 #define _SIZEOF_ADDR_IFREQ(x) sizeof(x) 44 #endif 29 45 #endif 30 46 31 // for OSX 32 #include <unistd.h> // execl, pipe, sysconf 33 #include <sys/types.h> // waitpid 34 #include <sys/wait.h> // waitpid 47 #define HDHOMERUN_DISOCVER_MAX_SOCK_COUNT 16 35 48 36 49 struct hdhomerun_discover_sock_t { 37 50 int sock; 51 uint32_t local_ip; 52 uint32_t subnet_mask; 38 53 }; 39 54 40 static struct hdhomerun_discover_sock_t *hdhomerun_discover_create(void) 55 struct hdhomerun_discover_t { 56 struct hdhomerun_discover_sock_t socks[HDHOMERUN_DISOCVER_MAX_SOCK_COUNT]; 57 unsigned int sock_count; 58 struct hdhomerun_pkt_t tx_pkt; 59 struct hdhomerun_pkt_t rx_pkt; 60 }; 61 62 static bool_t hdhomerun_discover_sock_create(struct hdhomerun_discover_t *ds, uint32_t local_ip, uint32_t subnet_mask) 41 63 { 42 struct hdhomerun_discover_sock_t *ds = (struct hdhomerun_discover_sock_t *)malloc(sizeof(struct hdhomerun_discover_sock_t)); 43 if (!ds) { 44 return NULL; 64 if (ds->sock_count >= HDHOMERUN_DISOCVER_MAX_SOCK_COUNT) { 65 return FALSE; 45 66 } 46 67 47 68 /* Create socket. */ 48 ds->sock = (int)socket(AF_INET, SOCK_DGRAM, 0); 49 if (ds->sock == -1) { 50 free(ds); 51 return NULL; 69 int sock = (int)socket(AF_INET, SOCK_DGRAM, 0); 70 if (sock == -1) { 71 return FALSE; 52 72 } 53 73 54 74 /* Set timeouts. */ 55 setsocktimeout( ds->sock, SOL_SOCKET, SO_SNDTIMEO, 1000);56 setsocktimeout( ds->sock, SOL_SOCKET, SO_RCVTIMEO, 1000);75 setsocktimeout(sock, SOL_SOCKET, SO_SNDTIMEO, 1000); 76 setsocktimeout(sock, SOL_SOCKET, SO_RCVTIMEO, 1000); 57 77 58 78 /* Allow broadcast. */ 59 79 int sock_opt = 1; 60 setsockopt( ds->sock, SOL_SOCKET, SO_BROADCAST, (char *)&sock_opt, sizeof(sock_opt));80 setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&sock_opt, sizeof(sock_opt)); 61 81 62 82 /* Bind socket. */ 63 83 struct sockaddr_in sock_addr; 64 84 memset(&sock_addr, 0, sizeof(sock_addr)); 65 85 sock_addr.sin_family = AF_INET; 66 sock_addr.sin_addr.s_addr = htonl( INADDR_ANY);86 sock_addr.sin_addr.s_addr = htonl(local_ip); 67 87 sock_addr.sin_port = htons(0); 68 if (bind(ds->sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) { 69 close(ds->sock); 70 free(ds); 71 return NULL; 88 if (bind(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) { 89 close(sock); 90 return FALSE; 72 91 } 73 92 74 /* Success. */ 75 return ds; 76 } 93 /* Write sock entry. */ 94 struct hdhomerun_discover_sock_t *dss = &ds->socks[ds->sock_count++]; 95 dss->sock = sock; 96 dss->local_ip = local_ip; 97 dss->subnet_mask = subnet_mask; 77 98 78 static void hdhomerun_discover_destroy(struct hdhomerun_discover_sock_t *ds) 79 { 80 close(ds->sock); 81 free(ds); 99 return TRUE; 82 100 } 83 101 84 static int hdhomerun_discover_send_packet(struct hdhomerun_discover_sock_t *ds, uint32_t ip_addr, uint32_t device_type, uint32_t device_id) 85 { 86 uint8_t buffer[1024]; 87 uint8_t *ptr = buffer; 88 hdhomerun_write_discover_request(&ptr, device_type, device_id); 89 90 struct sockaddr_in sock_addr; 91 memset(&sock_addr, 0, sizeof(sock_addr)); 92 sock_addr.sin_family = AF_INET; 93 sock_addr.sin_addr.s_addr = htonl(ip_addr); 94 sock_addr.sin_port = htons(HDHOMERUN_DISCOVER_UDP_PORT); 95 96 int length = (int)(ptr - buffer); 97 if (sendto(ds->sock, (char *)buffer, (int)length, 0, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != length) { 98 return -1; 99 } 100 101 return 0; 102 } 103 104 #if defined(__APPLE__) 105 static int hdhomerun_discover_send_internal(struct hdhomerun_discover_sock_t *ds, unsigned long device_type, unsigned long device_id) 106 { 107 /* printf("Looking for 0x%lx with id 0x%lx\n", device_type, device_id); */ 108 int fds[2]; 109 if (pipe(fds) < 0) 110 { 111 printf("Pipe Failed\n"); 112 return -1; 113 } 114 115 pid_t child = fork(); 116 if (child < 0) 117 { 118 printf("Fork Failed\n"); 119 return -1; 120 } 121 else if (child == 0) 122 { 123 /* Child */ 124 int i = 0; 125 126 /* Attach stdout to pipe */ 127 close(1); 128 dup2(fds[1], 1); 129 130 /* Close all open file descriptors except stdout/stderr */ 131 for (i = sysconf(_SC_OPEN_MAX) - 1; i > 2; i--) 132 close(i); 133 134 /* Run command */ 135 execl("/bin/sh", "sh", "-c", "ifconfig", NULL); 136 137 /* Failed to exec */ 138 _exit(1); /* this exit is ok */ 139 } 140 else 141 { 142 /* Parent */ 143 int send_count = 0; 144 int status; 145 FILE *fp; 146 char line[1024]; 147 char adaptor[1024]; 148 149 close(fds[1]); 150 151 if (waitpid(child, &status, 0) < 0) 152 return -1; 153 154 if (WEXITSTATUS(status)) 155 return -1; 156 157 fp = fdopen(fds[0], "r"); 158 while (1) 159 { 160 char *ptr = NULL; 161 int netmask, broadcast; 162 int a,b,c,d; 163 164 if (!fgets(line, sizeof(line) - 1, fp)) 165 { 166 break; 167 } 168 169 line[1023] = 0; 170 171 /* find ": flags" */ 172 ptr = strnstr(line, ": flags", 1024 - 1); 173 if (ptr >= line) 174 { 175 /* grab adaptor before that */ 176 strncpy(adaptor, line, ptr-line); 177 adaptor[ptr-line] = 0; 178 } 179 180 /* find "netmask " */ 181 ptr = strnstr(line, "netmask ", 1024 - 1); 182 if (ptr <= line) 183 continue; 184 ptr += strlen("netmask "); 185 sscanf(ptr, "%x", &netmask); 186 187 /* find "broadcast " */ 188 ptr = strnstr(ptr, "broadcast ", 1024 - 1); 189 if (ptr <= line) 190 continue; 191 ptr += strlen("broadcast "); 192 sscanf(ptr, "%i.%i.%i.%i", &a, &b, &c, &d); 193 broadcast = a<<24 | b<<16 | c<<8 | d; 194 /* 195 printf("Adaptor: '%s' 0x%08x %i.%i.%i.%i\n", 196 adaptor, broadcast, a,b,c,d); 197 */ 198 199 /* send discover packet this adaptor */ 200 if (hdhomerun_discover_send_packet( 201 ds, broadcast, device_type, device_id) >= 0) 202 { 203 send_count++; 204 } 205 } 206 207 fclose(fp); /* this closes fds[0] as well */ 208 209 /* printf("send_count: %i\n\n", send_count); */ 210 return (send_count == 0) ? -1 : 0; 211 } 212 } 213 214 #elif defined(__CYGWIN__) || defined(__WINDOWS__) 215 216 static int hdhomerun_discover_send_internal(struct hdhomerun_discover_sock_t *ds, uint32_t device_type, uint32_t device_id) 102 #if defined(USE_IPHLPAPI) 103 static void hdhomerun_discover_sock_detect(struct hdhomerun_discover_t *ds) 217 104 { 218 105 PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO)); 219 106 ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO); … … 222 109 if (Ret != NO_ERROR) { 223 110 free(pAdapterInfo); 224 111 if (Ret != ERROR_BUFFER_OVERFLOW) { 225 return -1;112 return; 226 113 } 227 114 pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen); 228 115 Ret = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen); 229 116 if (Ret != NO_ERROR) { 230 117 free(pAdapterInfo); 231 return -1;118 return; 232 119 } 233 120 } 234 121 235 unsigned int send_count = 0;236 122 PIP_ADAPTER_INFO pAdapter = pAdapterInfo; 237 123 while (pAdapter) { 238 124 IP_ADDR_STRING *pIPAddr = &pAdapter->IpAddressList; 239 125 while (pIPAddr) { 240 uint32_t addr= ntohl(inet_addr(pIPAddr->IpAddress.String));126 uint32_t local_ip = ntohl(inet_addr(pIPAddr->IpAddress.String)); 241 127 uint32_t mask = ntohl(inet_addr(pIPAddr->IpMask.String)); 242 243 uint32_t broadcast = addr | ~mask;244 if ((broadcast == 0x00000000) || (broadcast == 0xFFFFFFFF)) {245 pIPAddr = pIPAddr->Next;246 continue;247 }248 128 249 if ( hdhomerun_discover_send_packet(ds, broadcast, device_type, device_id) <0) {129 if (local_ip == 0) { 250 130 pIPAddr = pIPAddr->Next; 251 131 continue; 252 132 } 253 133 254 send_count++; 255 134 hdhomerun_discover_sock_create(ds, local_ip, mask); 256 135 pIPAddr = pIPAddr->Next; 257 136 } 258 137 … … 260 139 } 261 140 262 141 free(pAdapterInfo); 263 264 if (send_count == 0) {265 return -1;266 }267 return 0;268 142 } 269 143 270 #el if defined(__linux__)144 #else 271 145 272 static int hdhomerun_discover_send_internal(struct hdhomerun_discover_sock_t *ds, uint32_t device_type, uint32_t device_id)146 static void hdhomerun_discover_sock_detect(struct hdhomerun_discover_t *ds) 273 147 { 274 FILE *fp = fopen("/proc/net/route", "r");275 if ( !fp) {276 return -1;148 int fd = socket(AF_INET, SOCK_DGRAM, 0); 149 if (fd == -1) { 150 return; 277 151 } 278 152 279 unsigned int send_count = 0; 280 while (1) { 281 char line[256]; 282 if (!fgets(line, sizeof(line), fp)) { 283 break; 284 } 285 line[255] = 0; 153 struct ifconf ifc; 154 uint8_t buf[8192]; 155 ifc.ifc_len = sizeof(buf); 156 ifc.ifc_buf = (char *)buf; 157 158 memset(buf, 0, sizeof(buf)); 286 159 287 uint32_t dest; 288 uint32_t mask; 289 if (sscanf(line, "%*s %x %*x %*x %*d %*d %*d %x", &dest, &mask) != 2) { 160 if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) { 161 close(fd); 162 return; 163 } 164 165 uint8_t *ptr = (uint8_t *)ifc.ifc_req; 166 uint8_t *end = (uint8_t *)&ifc.ifc_buf[ifc.ifc_len]; 167 168 while (ptr <= end) { 169 struct ifreq *ifr = (struct ifreq *)ptr; 170 ptr += _SIZEOF_ADDR_IFREQ(*ifr); 171 172 if (ioctl(fd, SIOCGIFADDR, ifr) != 0) { 290 173 continue; 291 174 } 292 dest = ntohl(dest); 293 mask = ntohl(mask); 294 295 uint32_t broadcast = dest | ~mask; 296 297 if ((broadcast == 0x00000000) || (broadcast == 0xFFFFFFFF)) { 175 struct sockaddr_in *addr_in = (struct sockaddr_in *)&(ifr->ifr_addr); 176 uint32_t local_ip = ntohl(addr_in->sin_addr.s_addr); 177 if (local_ip == 0) { 298 178 continue; 299 179 } 300 180 301 if ( hdhomerun_discover_send_packet(ds, broadcast, device_type, device_id) <0) {181 if (ioctl(fd, SIOCGIFNETMASK, ifr) != 0) { 302 182 continue; 303 183 } 184 struct sockaddr_in *mask_in = (struct sockaddr_in *)&(ifr->ifr_addr); 185 uint32_t mask = ntohl(mask_in->sin_addr.s_addr); 304 186 305 send_count++;187 hdhomerun_discover_sock_create(ds, local_ip, mask); 306 188 } 189 } 190 #endif 307 191 308 fclose(fp); 309 if (send_count == 0) { 310 return -1; 192 static struct hdhomerun_discover_t *hdhomerun_discover_create(void) 193 { 194 struct hdhomerun_discover_t *ds = (struct hdhomerun_discover_t *)calloc(1, sizeof(struct hdhomerun_discover_t)); 195 if (!ds) { 196 return NULL; 311 197 } 312 return 0; 198 199 /* Create a routable socket. */ 200 if (!hdhomerun_discover_sock_create(ds, 0, 0)) { 201 free(ds); 202 return NULL; 203 } 204 205 /* Detect & create local sockets. */ 206 hdhomerun_discover_sock_detect(ds); 207 208 /* Success. */ 209 return ds; 313 210 } 314 211 315 #else 212 static void hdhomerun_discover_destroy(struct hdhomerun_discover_t *ds) 213 { 214 unsigned int i; 215 for (i = 0; i < ds->sock_count; i++) { 216 struct hdhomerun_discover_sock_t *dss = &ds->socks[i]; 217 close(dss->sock); 218 } 316 219 317 static int hdhomerun_discover_send_internal(struct hdhomerun_discover_sock_t *ds, uint32_t device_type, uint32_t device_id) 220 free(ds); 221 } 222 223 static bool_t hdhomerun_discover_send_internal(struct hdhomerun_discover_t *ds, struct hdhomerun_discover_sock_t *dss, uint32_t target_ip, uint32_t device_type, uint32_t device_id) 318 224 { 319 return -1; 225 struct hdhomerun_pkt_t *tx_pkt = &ds->tx_pkt; 226 hdhomerun_pkt_reset(tx_pkt); 227 228 hdhomerun_pkt_write_u8(tx_pkt, HDHOMERUN_TAG_DEVICE_TYPE); 229 hdhomerun_pkt_write_var_length(tx_pkt, 4); 230 hdhomerun_pkt_write_u32(tx_pkt, device_type); 231 hdhomerun_pkt_write_u8(tx_pkt, HDHOMERUN_TAG_DEVICE_ID); 232 hdhomerun_pkt_write_var_length(tx_pkt, 4); 233 hdhomerun_pkt_write_u32(tx_pkt, device_id); 234 hdhomerun_pkt_seal_frame(tx_pkt, HDHOMERUN_TYPE_DISCOVER_REQ); 235 236 struct sockaddr_in sock_addr; 237 memset(&sock_addr, 0, sizeof(sock_addr)); 238 sock_addr.sin_family = AF_INET; 239 sock_addr.sin_addr.s_addr = htonl(target_ip); 240 sock_addr.sin_port = htons(HDHOMERUN_DISCOVER_UDP_PORT); 241 242 int length = (int)(tx_pkt->end - tx_pkt->start); 243 if (sendto(dss->sock, (char *)tx_pkt->start, length, 0, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != length) { 244 return FALSE; 245 } 246 247 return TRUE; 320 248 } 321 #endif322 249 323 static int hdhomerun_discover_send(struct hdhomerun_discover_sock_t *ds, uint32_t device_type, uint32_t device_id)250 static bool_t hdhomerun_discover_send_wildcard_ip(struct hdhomerun_discover_t *ds, uint32_t device_type, uint32_t device_id) 324 251 { 325 if (hdhomerun_discover_send_internal(ds, device_type, device_id) < 0) { 326 return hdhomerun_discover_send_packet(ds, 0xFFFFFFFF, device_type, device_id); 252 bool_t result = FALSE; 253 254 /* 255 * Send subnet broadcast using each local ip socket. 256 * This will work with multiple separate 169.254.x.x interfaces. 257 */ 258 unsigned int i; 259 for (i = 1; i < ds->sock_count; i++) { 260 struct hdhomerun_discover_sock_t *dss = &ds->socks[i]; 261 uint32_t target_ip = dss->local_ip | ~dss->subnet_mask; 262 result |= hdhomerun_discover_send_internal(ds, dss, target_ip, device_type, device_id); 327 263 } 328 return 0; 264 265 /* 266 * If no local ip sockets then fall back to sending a global broadcast letting the OS choose the interface. 267 */ 268 if (!result) { 269 struct hdhomerun_discover_sock_t *dss = &ds->socks[0]; 270 result = hdhomerun_discover_send_internal(ds, dss, 0xFFFFFFFF, device_type, device_id); 271 } 272 273 return result; 329 274 } 330 275 331 static int hdhomerun_discover_recv(struct hdhomerun_discover_sock_t *ds, struct hdhomerun_discover_device_t *result)276 static bool_t hdhomerun_discover_send_target_ip(struct hdhomerun_discover_t *ds, uint32_t target_ip, uint32_t device_type, uint32_t device_id) 332 277 { 333 struct timeval t; 334 t.tv_sec = 0; 335 t.tv_usec = 250000; 278 bool_t result = FALSE; 336 279 337 fd_set readfds; 338 FD_ZERO(&readfds); 339 FD_SET(ds->sock, &readfds); 280 /* 281 * Send targeted packet from any local ip that is in the same subnet. 282 * This will work with multiple separate 169.254.x.x interfaces. 283 */ 284 unsigned int i; 285 for (i = 1; i < ds->sock_count; i++) { 286 struct hdhomerun_discover_sock_t *dss = &ds->socks[i]; 287 if ((target_ip & dss->subnet_mask) != (dss->local_ip & dss->subnet_mask)) { 288 continue; 289 } 340 290 341 if (select(ds->sock+1, &readfds, NULL, NULL, &t) < 0) { 342 return -1; 291 result |= hdhomerun_discover_send_internal(ds, dss, target_ip, device_type, device_id); 343 292 } 344 if (!FD_ISSET(ds->sock, &readfds)) { 345 return 0; 293 294 /* 295 * If target IP does not match a local subnet then fall back to letting the OS choose the gateway interface. 296 */ 297 if (!result) { 298 struct hdhomerun_discover_sock_t *dss = &ds->socks[0]; 299 result = hdhomerun_discover_send_internal(ds, dss, target_ip, device_type, device_id); 300 } 301 302 return result; 303 } 304 305 static bool_t hdhomerun_discover_send(struct hdhomerun_discover_t *ds, uint32_t target_ip, uint32_t device_type, uint32_t device_id) 306 { 307 if (target_ip != 0) { 308 return hdhomerun_discover_send_target_ip(ds, target_ip, device_type, device_id); 346 309 } 347 310 348 uint8_t buffer[1024]; 311 return hdhomerun_discover_send_wildcard_ip(ds, device_type, device_id); 312 } 313 314 static int hdhomerun_discover_recv_internal(struct hdhomerun_discover_t *ds, struct hdhomerun_discover_sock_t *dss, struct hdhomerun_discover_device_t *result) 315 { 316 struct hdhomerun_pkt_t *rx_pkt = &ds->rx_pkt; 317 hdhomerun_pkt_reset(rx_pkt); 318 349 319 struct sockaddr_in sock_addr; 320 memset(&sock_addr, 0, sizeof(sock_addr)); 350 321 socklen_t sockaddr_size = sizeof(sock_addr); 351 int rx_length = recvfrom(ds->sock, (char *)buffer, sizeof(buffer), 0, (struct sockaddr *)&sock_addr, &sockaddr_size); 322 323 int rx_length = recvfrom(dss->sock, (char *)rx_pkt->end, (int)(rx_pkt->limit - rx_pkt->end), 0, (struct sockaddr *)&sock_addr, &sockaddr_size); 352 324 if (rx_length <= 0) { 353 325 /* Don't return error - windows machine on VPN can sometimes cause a sock error here but otherwise works. */ 354 326 return 0; 355 327 } 356 if (rx_length < HDHOMERUN_MIN_PEEK_LENGTH) { 357 return 0; 358 } 328 rx_pkt->end += rx_length; 359 329 360 size_t length = hdhomerun_peek_packet_length(buffer);361 if ( length > (size_t)rx_length) {330 uint16_t type; 331 if (hdhomerun_pkt_open_frame(rx_pkt, &type) <= 0) { 362 332 return 0; 363 333 } 364 365 uint8_t *ptr = buffer;366 uint8_t *end = buffer + length;367 int type = hdhomerun_process_packet(&ptr, &end);368 334 if (type != HDHOMERUN_TYPE_DISCOVER_RPY) { 369 335 return 0; 370 336 } … … 372 338 result->ip_addr = ntohl(sock_addr.sin_addr.s_addr); 373 339 result->device_type = 0; 374 340 result->device_id = 0; 341 375 342 while (1) { 376 343 uint8_t tag; 377 344 size_t len; 378 uint8_t * value;379 if ( hdhomerun_read_tlv(&ptr, end, &tag, &len, &value) < 0) {345 uint8_t *next = hdhomerun_pkt_read_tlv(rx_pkt, &tag, &len); 346 if (!next) { 380 347 break; 381 348 } 382 349 … … 385 352 if (len != 4) { 386 353 break; 387 354 } 388 result->device_type = hdhomerun_ read_u32(&value);355 result->device_type = hdhomerun_pkt_read_u32(rx_pkt); 389 356 break; 357 390 358 case HDHOMERUN_TAG_DEVICE_ID: 391 359 if (len != 4) { 392 360 break; 393 361 } 394 result->device_id = hdhomerun_ read_u32(&value);362 result->device_id = hdhomerun_pkt_read_u32(rx_pkt); 395 363 break; 364 396 365 default: 397 366 break; 398 367 } 368 369 rx_pkt->pos = next; 399 370 } 400 371 401 372 return 1; 402 373 } 403 374 404 static struct hdhomerun_discover_device_t *hdhomerun_discover_find_in_list(struct hdhomerun_discover_device_t result_list[], int count, uint32_t device_id) 375 static int hdhomerun_discover_recv(struct hdhomerun_discover_t *ds, struct hdhomerun_discover_device_t *result) 376 { 377 struct timeval t; 378 t.tv_sec = 0; 379 t.tv_usec = 250000; 380 381 fd_set readfds; 382 FD_ZERO(&readfds); 383 int max_sock = -1; 384 385 unsigned int i; 386 for (i = 0; i < ds->sock_count; i++) { 387 struct hdhomerun_discover_sock_t *dss = &ds->socks[i]; 388 FD_SET(dss->sock, &readfds); 389 if (dss->sock > max_sock) { 390 max_sock = dss->sock; 391 } 392 } 393 394 if (select(max_sock+1, &readfds, NULL, NULL, &t) < 0) { 395 return -1; 396 } 397 398 for (i = 0; i < ds->sock_count; i++) { 399 struct hdhomerun_discover_sock_t *dss = &ds->socks[i]; 400 if (!FD_ISSET(dss->sock, &readfds)) { 401 continue; 402 } 403 404 if (hdhomerun_discover_recv_internal(ds, dss, result) <= 0) { 405 continue; 406 } 407 408 return 1; 409 } 410 411 return 0; 412 } 413 414 static struct hdhomerun_discover_device_t *hdhomerun_discover_find_in_list(struct hdhomerun_discover_device_t result_list[], int count, uint32_t ip_addr) 405 415 { 406 416 int index; 407 417 for (index = 0; index < count; index++) { 408 418 struct hdhomerun_discover_device_t *result = &result_list[index]; 409 if (result-> device_id == device_id) {419 if (result->ip_addr == ip_addr) { 410 420 return result; 411 421 } 412 422 } … … 414 424 return NULL; 415 425 } 416 426 417 static int hdhomerun_discover_find_devices_internal(struct hdhomerun_discover_ sock_t *ds, uint32_t device_type, uint32_t device_id, struct hdhomerun_discover_device_t result_list[], int max_count)427 static int hdhomerun_discover_find_devices_internal(struct hdhomerun_discover_t *ds, uint32_t target_ip, uint32_t device_type, uint32_t device_id, struct hdhomerun_discover_device_t result_list[], int max_count) 418 428 { 419 429 int count = 0; 420 421 430 int attempt; 422 431 for (attempt = 0; attempt < 4; attempt++) { 423 if ( hdhomerun_discover_send(ds, device_type, device_id) < 0) {432 if (!hdhomerun_discover_send(ds, target_ip, device_type, device_id)) { 424 433 return -1; 425 434 } 426 435 … … 433 442 return -1; 434 443 } 435 444 if (ret == 0) { 436 break;445 continue; 437 446 } 438 447 439 448 /* Filter. */ … … 449 458 } 450 459 451 460 /* Ensure not already in list. */ 452 if (hdhomerun_discover_find_in_list(result_list, count, result-> device_id)) {461 if (hdhomerun_discover_find_in_list(result_list, count, result->ip_addr)) { 453 462 continue; 454 463 } 455 464 … … 464 473 return count; 465 474 } 466 475 467 int hdhomerun_discover_find_device(uint32_t device_id, struct hdhomerun_discover_device_t *result) 468 { 469 struct hdhomerun_discover_sock_t *ds = hdhomerun_discover_create(); 470 if (!ds) { 471 return -1; 472 } 473 474 int ret = hdhomerun_discover_find_devices_internal(ds, HDHOMERUN_DEVICE_TYPE_WILDCARD, device_id, result, 1); 475 476 hdhomerun_discover_destroy(ds); 477 return ret; 478 } 479 480 int hdhomerun_discover_find_devices(uint32_t device_type, struct hdhomerun_discover_device_t result_list[], int max_count) 476 int hdhomerun_discover_find_devices_custom(uint32_t target_ip, uint32_t device_type, uint32_t device_id, struct hdhomerun_discover_device_t result_list[], int max_count) 481 477 { 482 struct hdhomerun_discover_ sock_t *ds = hdhomerun_discover_create();478 struct hdhomerun_discover_t *ds = hdhomerun_discover_create(); 483 479 if (!ds) { 484 480 return -1; 485 481 } 486 482 487 int ret = hdhomerun_discover_find_devices_internal(ds, device_type, HDHOMERUN_DEVICE_ID_WILDCARD, result_list, max_count);483 int ret = hdhomerun_discover_find_devices_internal(ds, target_ip, device_type, device_id, result_list, max_count); 488 484 489 485 hdhomerun_discover_destroy(ds); 490 486 return ret; -
mythtv/libs/libmythtv/hdhomerun/hdhomerun_discover.h
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun_discover.h release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun_discover.h
1 1 /* 2 2 * hdhomerun_discover.h 3 3 * 4 * Copyright © 2006Silicondust Engineering Ltd. <www.silicondust.com>.4 * Copyright © 2006-2007 Silicondust Engineering Ltd. <www.silicondust.com>. 5 5 * 6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU Lesser General Public 8 8 * License as published by the Free Software Foundation; either 9 * version 2.1of the License, or (at your option) any later version.9 * version 3 of the License, or (at your option) any later version. 10 10 * 11 11 * This library is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of … … 14 14 * Lesser General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 19 31 */ 20 32 #ifdef __cplusplus 21 33 extern "C" { … … 28 40 }; 29 41 30 42 /* 31 * Find a device by device ID. 32 * 33 * The device information is stored in caller-supplied hdhomerun_discover_device_t var. 34 * Multiple attempts are made to find the device. 35 * Worst-case execution time is 1 second. 36 * 37 * Returns 1 on success. 38 * Returns 0 if not found. 39 * Retruns -1 on error. 40 */ 41 extern int hdhomerun_discover_find_device(uint32_t device_id, struct hdhomerun_discover_device_t *result); 42 43 /* 44 * Find all devices of a given type. 43 * Find devices. 45 44 * 46 45 * The device information is stored in caller-supplied array of hdhomerun_discover_device_t vars. 47 46 * Multiple attempts are made to find devices. 48 47 * Execution time is 1 second. 49 48 * 49 * Set target_ip to zero to auto-detect IP address. 50 * 50 51 * Returns the number of devices found. 51 52 * Retruns -1 on error. 52 53 */ 53 extern int hdhomerun_discover_find_devices(uint32_t device_type, struct hdhomerun_discover_device_t result_list[], int max_count);54 extern LIBTYPE int hdhomerun_discover_find_devices_custom(uint32_t target_ip, uint32_t device_type, uint32_t device_id, struct hdhomerun_discover_device_t result_list[], int max_count); 54 55 55 56 /* 56 57 * Verify that the device ID given is valid. … … 61 62 * Returns TRUE if valid. 62 63 * Returns FALSE if not valid. 63 64 */ 64 extern bool_t hdhomerun_discover_validate_device_id(uint32_t device_id);65 extern LIBTYPE bool_t hdhomerun_discover_validate_device_id(uint32_t device_id); 65 66 66 67 #ifdef __cplusplus 67 68 } -
mythtv/libs/libmythtv/hdhomerun/hdhomerun_os.h
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun_os.h release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun_os.h
1 1 /* 2 2 * hdhomerun_os.h 3 3 * 4 * Copyright © 2006Silicondust Engineering Ltd. <www.silicondust.com>.4 * Copyright © 2006-2008 Silicondust Engineering Ltd. <www.silicondust.com>. 5 5 * 6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU Lesser General Public 8 8 * License as published by the Free Software Foundation; either 9 * version 2.1of the License, or (at your option) any later version.9 * version 3 of the License, or (at your option) any later version. 10 10 * 11 11 * This library is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of … … 14 14 * Lesser General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 19 31 */ 20 32 21 #include <stdlib.h> 22 #include <stdio.h> 23 #include <string.h> 24 25 #if defined(WIN32) 33 #if defined(_WIN32) || defined(_WIN64) 26 34 #define __WINDOWS__ 27 35 #endif 28 36 29 37 #if defined(__WINDOWS__) 30 #include <windows.h> 31 #include <sys/types.h> 32 #include <sys/timeb.h> 38 #include "hdhomerun_os_windows.h" 33 39 #else 34 #include <unistd.h> 35 #include <errno.h> 36 #include <sys/types.h> 37 #include <sys/socket.h> 38 #include <netinet/in.h> 39 #include <arpa/inet.h> 40 #include <netdb.h> 41 #include <sys/time.h> 42 #include <sys/timeb.h> 43 #include <fcntl.h> 40 #include "hdhomerun_os_posix.h" 44 41 #endif 45 42 46 #include <pthread.h>47 48 43 #if !defined(TRUE) 49 44 #define TRUE 1 50 45 #endif 46 51 47 #if !defined(FALSE) 52 48 #define FALSE 0 53 49 #endif 54 55 #if defined(__WINDOWS__)56 57 typedef int bool_t;58 typedef unsigned __int8 uint8_t;59 typedef unsigned __int16 uint16_t;60 typedef unsigned __int32 uint32_t;61 typedef unsigned __int64 uint64_t;62 63 #define socklen_t int64 #define close closesocket65 #define sock_getlasterror WSAGetLastError()66 #define sock_getlasterror_socktimeout (WSAGetLastError() == WSAETIMEDOUT)67 #define atoll _atoi6468 #define strcasecmp _stricmp69 #define fseeko _fseeki6470 #define ftello _ftelli6471 #define usleep(us) Sleep((us)/1000)72 #define sleep(sec) Sleep((sec)*1000)73 74 static inline uint64_t getcurrenttime(void)75 {76 struct timeb tb;77 ftime(&tb);78 return ((uint64_t)tb.time * 1000) + tb.millitm;79 }80 81 static inline int setsocktimeout(int s, int level, int optname, uint64_t timeout)82 {83 int t = (int)timeout;84 return setsockopt(s, level, optname, (char *)&t, sizeof(t));85 }86 87 #else88 89 typedef int bool_t;90 91 #define sock_getlasterror errno92 #define sock_getlasterror_socktimeout (errno == EAGAIN)93 94 static inline uint64_t getcurrenttime(void)95 {96 struct timeval t;97 gettimeofday(&t, NULL);98 return ((uint64_t)t.tv_sec * 1000) + (t.tv_usec / 1000);99 }100 101 static inline int setsocktimeout(int s, int level, int optname, uint64_t timeout)102 {103 struct timeval t;104 t.tv_sec = timeout / 1000;105 t.tv_usec = (timeout % 1000) * 1000;106 return setsockopt(s, level, optname, (char *)&t, sizeof(t));107 }108 109 #endif110 -
mythtv/libs/libmythtv/hdhomerun/hdhomerun_os_posix.h
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun_os_posix.h release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun_os_posix.h
1 /* 2 * hdhomerun_os_posix.h 3 * 4 * Copyright © 2006-2008 Silicondust Engineering Ltd. <www.silicondust.com>. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 3 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 31 */ 32 33 #define _FILE_OFFSET_BITS 64 34 #include <stdlib.h> 35 #include <stdio.h> 36 #include <stdarg.h> 37 #include <string.h> 38 #include <unistd.h> 39 #include <errno.h> 40 #include <fcntl.h> 41 #include <sys/types.h> 42 #include <sys/socket.h> 43 #include <sys/time.h> 44 #include <sys/timeb.h> 45 #include <sys/wait.h> 46 #include <sys/signal.h> 47 #include <netinet/in.h> 48 #include <arpa/inet.h> 49 #include <netdb.h> 50 #include <pthread.h> 51 52 typedef int bool_t; 53 54 #define LIBTYPE 55 #define sock_getlasterror errno 56 #define sock_getlasterror_socktimeout (errno == EAGAIN) 57 #define console_vprintf vprintf 58 #define console_printf printf 59 #define THREAD_FUNC_PREFIX void * 60 61 static inline uint64_t getcurrenttime(void) 62 { 63 struct timeval t; 64 gettimeofday(&t, NULL); 65 return ((uint64_t)t.tv_sec * 1000) + (t.tv_usec / 1000); 66 } 67 68 static inline int setsocktimeout(int s, int level, int optname, uint64_t timeout) 69 { 70 struct timeval t; 71 t.tv_sec = timeout / 1000; 72 t.tv_usec = (timeout % 1000) * 1000; 73 return setsockopt(s, level, optname, (char *)&t, sizeof(t)); 74 } -
mythtv/libs/libmythtv/hdhomerun/hdhomerun_os_windows.h
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun_os_windows.h release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun_os_windows.h
1 /* 2 * hdhomerun_os_windows.h 3 * 4 * Copyright © 2006-2008 Silicondust Engineering Ltd. <www.silicondust.com>. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 3 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 31 */ 32 33 #define _WINSOCKAPI_ 34 #include <windows.h> 35 #include <winsock2.h> 36 #include <ws2tcpip.h> 37 #include <wspiapi.h> 38 #include <stdlib.h> 39 #include <stdio.h> 40 #include <stdarg.h> 41 #include <string.h> 42 #include <signal.h> 43 #include <time.h> 44 #include <sys/types.h> 45 #include <sys/timeb.h> 46 47 #if defined(DLL_IMPORT) 48 #define LIBTYPE __declspec( dllexport ) 49 #elif defined(DLL_EXPORT) 50 #define LIBTYPE __declspec( dllimport ) 51 #else 52 #define LIBTYPE 53 #endif 54 55 typedef int bool_t; 56 typedef signed __int8 int8_t; 57 typedef signed __int16 int16_t; 58 typedef signed __int32 int32_t; 59 typedef signed __int64 int64_t; 60 typedef unsigned __int8 uint8_t; 61 typedef unsigned __int16 uint16_t; 62 typedef unsigned __int32 uint32_t; 63 typedef unsigned __int64 uint64_t; 64 typedef HANDLE pthread_t; 65 typedef HANDLE pthread_mutex_t; 66 67 #define socklen_t int 68 #define close closesocket 69 #define sock_getlasterror WSAGetLastError() 70 #define sock_getlasterror_socktimeout (WSAGetLastError() == WSAETIMEDOUT) 71 #define va_copy(x, y) x = y 72 #define atoll _atoi64 73 #define strdup _strdup 74 #define strcasecmp _stricmp 75 #define snprintf _snprintf 76 #define fseeko _fseeki64 77 #define ftello _ftelli64 78 #define THREAD_FUNC_PREFIX DWORD WINAPI 79 #define SIGPIPE SIGABRT 80 81 static inline int usleep(unsigned int us) 82 { 83 Sleep((us)/1000); 84 return 0; 85 } 86 87 static inline int sleep(unsigned int sec) 88 { 89 Sleep((sec)*1000); 90 return 0; 91 } 92 93 static inline uint64_t getcurrenttime(void) 94 { 95 struct timeb tb; 96 ftime(&tb); 97 return ((uint64_t)tb.time * 1000) + tb.millitm; 98 } 99 100 static inline int setsocktimeout(int s, int level, int optname, uint64_t timeout) 101 { 102 int t = (int)timeout; 103 return setsockopt(s, level, optname, (char *)&t, sizeof(t)); 104 } 105 106 static inline int pthread_create(pthread_t *tid, void *attr, LPTHREAD_START_ROUTINE start, void *arg) 107 { 108 *tid = CreateThread(NULL, 0, start, arg, 0, NULL); 109 if (!*tid) { 110 return (int)GetLastError(); 111 } 112 return 0; 113 } 114 115 static inline int pthread_join(pthread_t tid, void **value_ptr) 116 { 117 while (1) { 118 DWORD ExitCode = 0; 119 if (!GetExitCodeThread(tid, &ExitCode)) { 120 return (int)GetLastError(); 121 } 122 if (ExitCode != STILL_ACTIVE) { 123 return 0; 124 } 125 } 126 } 127 128 static inline void pthread_mutex_init(pthread_mutex_t *mutex, void *attr) 129 { 130 *mutex = CreateMutex(NULL, FALSE, NULL); 131 } 132 133 static inline void pthread_mutex_lock(pthread_mutex_t *mutex) 134 { 135 WaitForSingleObject(*mutex, INFINITE); 136 } 137 138 static inline void pthread_mutex_unlock(pthread_mutex_t *mutex) 139 { 140 ReleaseMutex(*mutex); 141 } 142 143 /* 144 * The console output format should be set to UTF-8, however in XP and Vista this breaks batch file processing. 145 * Attempting to restore on exit fails to restore if the program is terminated by the user. 146 * Solution - set the output format each printf. 147 */ 148 static inline void console_vprintf(const char *fmt, va_list ap) 149 { 150 UINT cp = GetConsoleOutputCP(); 151 SetConsoleOutputCP(CP_UTF8); 152 vprintf(fmt, ap); 153 SetConsoleOutputCP(cp); 154 } 155 156 static inline void console_printf(const char *fmt, ...) 157 { 158 va_list ap; 159 va_start(ap, fmt); 160 console_vprintf(fmt, ap); 161 va_end(ap); 162 } -
mythtv/libs/libmythtv/hdhomerun/hdhomerun_pkt.c
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun_pkt.c release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun_pkt.c
1 1 /* 2 2 * hdhomerun_pkt.c 3 3 * 4 * Copyright © 2005-2006 Silicondust Engineering Ltd. <www.silicondust.com>.4 * Copyright © 2005-2006 Silicondust Engineering Ltd. <www.silicondust.com>. 5 5 * 6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU Lesser General Public 8 8 * License as published by the Free Software Foundation; either 9 * version 2.1of the License, or (at your option) any later version.9 * version 3 of the License, or (at your option) any later version. 10 10 * 11 11 * This library is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of … … 14 14 * Lesser General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 19 31 */ 20 32 21 #include "hdhomerun_os.h" 22 #include "hdhomerun_pkt.h" 33 #include "hdhomerun.h" 23 34 24 uint8_t hdhomerun_read_u8(uint8_t **pptr)35 struct hdhomerun_pkt_t *hdhomerun_pkt_create(void) 25 36 { 26 uint8_t *ptr = *pptr; 27 uint8_t v = *ptr++; 28 *pptr = ptr; 37 struct hdhomerun_pkt_t *pkt = (struct hdhomerun_pkt_t *)calloc(1, sizeof(struct hdhomerun_pkt_t)); 38 if (!pkt) { 39 return NULL; 40 } 41 42 hdhomerun_pkt_reset(pkt); 43 44 return pkt; 45 } 46 47 void hdhomerun_pkt_destroy(struct hdhomerun_pkt_t *pkt) 48 { 49 free(pkt); 50 } 51 52 void hdhomerun_pkt_reset(struct hdhomerun_pkt_t *pkt) 53 { 54 pkt->limit = pkt->buffer + sizeof(pkt->buffer) - 4; 55 pkt->start = pkt->buffer + 1024; 56 pkt->end = pkt->start; 57 pkt->pos = pkt->start; 58 } 59 60 static uint32_t hdhomerun_pkt_calc_crc(uint8_t *start, uint8_t *end) 61 { 62 uint8_t *pos = start; 63 uint32_t crc = 0xFFFFFFFF; 64 while (pos < end) { 65 uint8_t x = (uint8_t)(crc) ^ *pos++; 66 crc >>= 8; 67 if (x & 0x01) crc ^= 0x77073096; 68 if (x & 0x02) crc ^= 0xEE0E612C; 69 if (x & 0x04) crc ^= 0x076DC419; 70 if (x & 0x08) crc ^= 0x0EDB8832; 71 if (x & 0x10) crc ^= 0x1DB71064; 72 if (x & 0x20) crc ^= 0x3B6E20C8; 73 if (x & 0x40) crc ^= 0x76DC4190; 74 if (x & 0x80) crc ^= 0xEDB88320; 75 } 76 return crc ^ 0xFFFFFFFF; 77 } 78 79 uint8_t hdhomerun_pkt_read_u8(struct hdhomerun_pkt_t *pkt) 80 { 81 uint8_t v = *pkt->pos++; 29 82 return v; 30 83 } 31 84 32 uint16_t hdhomerun_ read_u16(uint8_t **pptr)85 uint16_t hdhomerun_pkt_read_u16(struct hdhomerun_pkt_t *pkt) 33 86 { 34 uint8_t *ptr = *pptr;35 87 uint16_t v; 36 v = (uint16_t)*ptr++ << 8; 37 v |= (uint16_t)*ptr++ << 0; 38 *pptr = ptr; 88 v = (uint16_t)*pkt->pos++ << 8; 89 v |= (uint16_t)*pkt->pos++ << 0; 39 90 return v; 40 91 } 41 92 42 uint32_t hdhomerun_ read_u32(uint8_t **pptr)93 uint32_t hdhomerun_pkt_read_u32(struct hdhomerun_pkt_t *pkt) 43 94 { 44 uint8_t *ptr = *pptr;45 95 uint32_t v; 46 v = (uint32_t)*ptr++ << 24; 47 v |= (uint32_t)*ptr++ << 16; 48 v |= (uint32_t)*ptr++ << 8; 49 v |= (uint32_t)*ptr++ << 0; 50 *pptr = ptr; 96 v = (uint32_t)*pkt->pos++ << 24; 97 v |= (uint32_t)*pkt->pos++ << 16; 98 v |= (uint32_t)*pkt->pos++ << 8; 99 v |= (uint32_t)*pkt->pos++ << 0; 51 100 return v; 52 101 } 53 102 54 size_t hdhomerun_ read_var_length(uint8_t **pptr, uint8_t *end)103 size_t hdhomerun_pkt_read_var_length(struct hdhomerun_pkt_t *pkt) 55 104 { 56 uint8_t *ptr = *pptr;57 105 size_t length; 58 106 59 if (p tr + 1 >end) {60 return -1;107 if (pkt->pos + 1 > pkt->end) { 108 return (size_t)-1; 61 109 } 62 110 63 length = (size_t)*p tr++;111 length = (size_t)*pkt->pos++; 64 112 if (length & 0x0080) { 65 if (p tr + 1 >end) {66 return -1;113 if (pkt->pos + 1 > pkt->end) { 114 return (size_t)-1; 67 115 } 68 116 69 117 length &= 0x007F; 70 length |= (size_t)*p tr++ << 7;118 length |= (size_t)*pkt->pos++ << 7; 71 119 } 72 120 73 *pptr = ptr;74 121 return length; 75 122 } 76 123 77 int hdhomerun_read_tlv(uint8_t **pptr, uint8_t *end, uint8_t *ptag, size_t *plength, uint8_t **pvalue)124 uint8_t *hdhomerun_pkt_read_tlv(struct hdhomerun_pkt_t *pkt, uint8_t *ptag, size_t *plength) 78 125 { 79 if ( end - *pptr < 2) {80 return -1;126 if (pkt->pos + 2 > pkt->end) { 127 return NULL; 81 128 } 82 129 83 *ptag = hdhomerun_read_u8(pptr); 84 *plength = hdhomerun_read_var_length(pptr, end); 85 *pvalue = *pptr; 86 87 if ((size_t)(end - *pptr) < *plength) { 88 return -1; 130 *ptag = hdhomerun_pkt_read_u8(pkt); 131 *plength = hdhomerun_pkt_read_var_length(pkt); 132 133 if (pkt->pos + *plength > pkt->end) { 134 return NULL; 89 135 } 90 136 91 *pptr += *plength; 92 return 0; 137 return pkt->pos + *plength; 93 138 } 94 139 95 void hdhomerun_ write_u8(uint8_t **pptr, uint8_t v)140 void hdhomerun_pkt_write_u8(struct hdhomerun_pkt_t *pkt, uint8_t v) 96 141 { 97 uint8_t *ptr = *pptr; 98 *ptr++ = v; 99 *pptr = ptr; 100 } 142 *pkt->pos++ = v; 101 143 102 void hdhomerun_write_u16(uint8_t **pptr, uint16_t v) 103 { 104 uint8_t *ptr = *pptr; 105 *ptr++ = (uint8_t)(v >> 8); 106 *ptr++ = (uint8_t)(v >> 0); 107 *pptr = ptr; 144 if (pkt->pos > pkt->end) { 145 pkt->end = pkt->pos; 146 } 108 147 } 109 148 110 void hdhomerun_ write_u32(uint8_t **pptr, uint32_t v)149 void hdhomerun_pkt_write_u16(struct hdhomerun_pkt_t *pkt, uint16_t v) 111 150 { 112 uint8_t *ptr = *pptr; 113 *ptr++ = (uint8_t)(v >> 24); 114 *ptr++ = (uint8_t)(v >> 16); 115 *ptr++ = (uint8_t)(v >> 8); 116 *ptr++ = (uint8_t)(v >> 0); 117 *pptr = ptr; 118 } 151 *pkt->pos++ = (uint8_t)(v >> 8); 152 *pkt->pos++ = (uint8_t)(v >> 0); 119 153 120 void hdhomerun_write_var_length(uint8_t **pptr, size_t v) 121 { 122 uint8_t *ptr = *pptr; 123 if (v <= 127) { 124 *ptr++ = (uint8_t)v; 125 } else { 126 *ptr++ = (uint8_t)(v | 0x80); 127 *ptr++ = (uint8_t)(v >> 7); 154 if (pkt->pos > pkt->end) { 155 pkt->end = pkt->pos; 128 156 } 129 *pptr = ptr;130 157 } 131 158 132 static void hdhomerun_write_mem(uint8_t **pptr, void *mem, size_t length)159 void hdhomerun_pkt_write_u32(struct hdhomerun_pkt_t *pkt, uint32_t v) 133 160 { 134 uint8_t *ptr = *pptr; 135 memcpy(ptr, mem, length); 136 ptr += length; 137 *pptr = ptr; 138 } 161 *pkt->pos++ = (uint8_t)(v >> 24); 162 *pkt->pos++ = (uint8_t)(v >> 16); 163 *pkt->pos++ = (uint8_t)(v >> 8); 164 *pkt->pos++ = (uint8_t)(v >> 0); 139 165 140 static uint32_t hdhomerun_calc_crc(uint8_t *start, uint8_t *end) 141 { 142 uint8_t *ptr = start; 143 uint32_t crc = 0xFFFFFFFF; 144 while (ptr < end) { 145 uint8_t x = (uint8_t)(crc) ^ *ptr++; 146 crc >>= 8; 147 if (x & 0x01) crc ^= 0x77073096; 148 if (x & 0x02) crc ^= 0xEE0E612C; 149 if (x & 0x04) crc ^= 0x076DC419; 150 if (x & 0x08) crc ^= 0x0EDB8832; 151 if (x & 0x10) crc ^= 0x1DB71064; 152 if (x & 0x20) crc ^= 0x3B6E20C8; 153 if (x & 0x40) crc ^= 0x76DC4190; 154 if (x & 0x80) crc ^= 0xEDB88320; 166 if (pkt->pos > pkt->end) { 167 pkt->end = pkt->pos; 155 168 } 156 return crc ^ 0xFFFFFFFF;157 169 } 158 170 159 static int hdhomerun_check_crc(uint8_t *start, uint8_t *end)171 void hdhomerun_pkt_write_var_length(struct hdhomerun_pkt_t *pkt, size_t v) 160 172 { 161 if (end - start < 8) { 162 return -1; 173 if (v <= 127) { 174 *pkt->pos++ = (uint8_t)v; 175 } else { 176 *pkt->pos++ = (uint8_t)(v | 0x80); 177 *pkt->pos++ = (uint8_t)(v >> 7); 163 178 } 164 uint8_t *ptr = end -= 4; 165 uint32_t actual_crc = hdhomerun_calc_crc(start, ptr); 166 uint32_t packet_crc; 167 packet_crc = (uint32_t)*ptr++ << 0; 168 packet_crc |= (uint32_t)*ptr++ << 8; 169 packet_crc |= (uint32_t)*ptr++ << 16; 170 packet_crc |= (uint32_t)*ptr++ << 24; 171 if (actual_crc != packet_crc) { 172 return -1; 179 180 if (pkt->pos > pkt->end) { 181 pkt->end = pkt->pos; 173 182 } 174 return 0;175 183 } 176 184 177 static void hdhomerun_write_header_length(uint8_t *ptr, size_t length)185 void hdhomerun_pkt_write_mem(struct hdhomerun_pkt_t *pkt, const void *mem, size_t length) 178 186 { 179 hdhomerun_write_u16(&ptr, (uint16_t)length);180 } 187 memcpy(pkt->pos, mem, length); 188 pkt->pos += length; 181 189 182 void hdhomerun_write_crc(uint8_t **pptr, uint8_t *start) 183 { 184 uint8_t *ptr = *pptr; 185 uint32_t crc = hdhomerun_calc_crc(start, ptr); 186 *ptr++ = (uint8_t)(crc >> 0); 187 *ptr++ = (uint8_t)(crc >> 8); 188 *ptr++ = (uint8_t)(crc >> 16); 189 *ptr++ = (uint8_t)(crc >> 24); 190 *pptr = ptr; 190 if (pkt->pos > pkt->end) { 191 pkt->end = pkt->pos; 192 } 191 193 } 192 194 193 void hdhomerun_write_discover_request(uint8_t **pptr, uint32_t device_type, uint32_t device_id)195 int hdhomerun_pkt_open_frame(struct hdhomerun_pkt_t *pkt, uint16_t *ptype) 194 196 { 195 uint8_t *start = *pptr; 196 hdhomerun_write_u16(pptr, HDHOMERUN_TYPE_DISCOVER_REQ); 197 hdhomerun_write_u16(pptr, 0); 197 pkt->pos = pkt->start; 198 198 199 hdhomerun_write_u8(pptr, HDHOMERUN_TAG_DEVICE_TYPE); 200 hdhomerun_write_var_length(pptr, 4); 201 hdhomerun_write_u32(pptr, device_type); 202 hdhomerun_write_u8(pptr, HDHOMERUN_TAG_DEVICE_ID); 203 hdhomerun_write_var_length(pptr, 4); 204 hdhomerun_write_u32(pptr, device_id); 199 if (pkt->pos + 4 > pkt->end) { 200 return 0; 201 } 205 202 206 hdhomerun_write_header_length(start + 2, (int)(*pptr - start - 4));207 hdhomerun_write_crc(pptr, start);208 } 203 *ptype = hdhomerun_pkt_read_u16(pkt); 204 size_t length = hdhomerun_pkt_read_u16(pkt); 205 pkt->pos += length; 209 206 210 void hdhomerun_write_get_set_request(uint8_t **pptr, const char *name, const char *value) 211 { 212 uint8_t *start = *pptr; 213 hdhomerun_write_u16(pptr, HDHOMERUN_TYPE_GETSET_REQ); 214 hdhomerun_write_u16(pptr, 0); 207 if (pkt->pos + 4 > pkt->end) { 208 pkt->pos = pkt->start; 209 return 0; 210 } 215 211 216 int name_len = (int)strlen(name) + 1; 217 hdhomerun_write_u8(pptr, HDHOMERUN_TAG_GETSET_NAME); 218 hdhomerun_write_var_length(pptr, name_len); 219 hdhomerun_write_mem(pptr, (void *)name, name_len); 212 uint32_t calc_crc = hdhomerun_pkt_calc_crc(pkt->start, pkt->pos); 220 213 221 if (value) { 222 int value_len = (int)strlen(value) + 1; 223 hdhomerun_write_u8(pptr, HDHOMERUN_TAG_GETSET_VALUE); 224 hdhomerun_write_var_length(pptr, value_len); 225 hdhomerun_write_mem(pptr, (void *)value, value_len); 214 uint32_t packet_crc; 215 packet_crc = (uint32_t)*pkt->pos++ << 0; 216 packet_crc |= (uint32_t)*pkt->pos++ << 8; 217 packet_crc |= (uint32_t)*pkt->pos++ << 16; 218 packet_crc |= (uint32_t)*pkt->pos++ << 24; 219 if (calc_crc != packet_crc) { 220 return -1; 226 221 } 227 222 228 hdhomerun_write_header_length(start + 2, (int)(*pptr - start - 4)); 229 hdhomerun_write_crc(pptr, start); 223 pkt->start += 4; 224 pkt->end = pkt->start + length; 225 pkt->pos = pkt->start; 226 return 1; 230 227 } 231 228 232 void hdhomerun_ write_upgrade_request(uint8_t **pptr, uint32_t sequence, void *data, size_t length)229 void hdhomerun_pkt_seal_frame(struct hdhomerun_pkt_t *pkt, uint16_t frame_type) 233 230 { 234 uint8_t *start = *pptr; 235 hdhomerun_write_u16(pptr, HDHOMERUN_TYPE_UPGRADE_REQ); 236 hdhomerun_write_u16(pptr, 0); 231 size_t length = pkt->end - pkt->start; 237 232 238 hdhomerun_write_u32(pptr, sequence);239 if (length > 0) {240 hdhomerun_write_mem(pptr, data, length);241 }233 pkt->start -= 4; 234 pkt->pos = pkt->start; 235 hdhomerun_pkt_write_u16(pkt, frame_type); 236 hdhomerun_pkt_write_u16(pkt, (uint16_t)length); 242 237 243 hdhomerun_write_header_length(start + 2, *pptr - start - 4); 244 hdhomerun_write_crc(pptr, start); 245 } 238 uint32_t crc = hdhomerun_pkt_calc_crc(pkt->start, pkt->end); 239 *pkt->end++ = (uint8_t)(crc >> 0); 240 *pkt->end++ = (uint8_t)(crc >> 8); 241 *pkt->end++ = (uint8_t)(crc >> 16); 242 *pkt->end++ = (uint8_t)(crc >> 24); 246 243 247 size_t hdhomerun_peek_packet_length(uint8_t *ptr) 248 { 249 ptr += 2; 250 return (size_t)hdhomerun_read_u16(&ptr) + 8; 244 pkt->pos = pkt->start; 251 245 } 252 253 int hdhomerun_process_packet(uint8_t **pptr, uint8_t **pend)254 {255 if (hdhomerun_check_crc(*pptr, *pend) < 0) {256 return -1;257 }258 *pend -= 4;259 260 uint16_t type = hdhomerun_read_u16(pptr);261 uint16_t length = hdhomerun_read_u16(pptr);262 if ((*pend - *pptr) < length) {263 return -1;264 }265 *pend = *pptr + length;266 return (int)type;267 }268 -
mythtv/libs/libmythtv/hdhomerun/hdhomerun_pkt.h
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun_pkt.h release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun_pkt.h
1 1 /* 2 2 * hdhomerun_pkt.h 3 3 * 4 * Copyright © 2005-2006 Silicondust Engineering Ltd. <www.silicondust.com>.4 * Copyright © 2005-2006 Silicondust Engineering Ltd. <www.silicondust.com>. 5 5 * 6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU Lesser General Public 8 8 * License as published by the Free Software Foundation; either 9 * version 2.1of the License, or (at your option) any later version.9 * version 3 of the License, or (at your option) any later version. 10 10 * 11 11 * This library is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of … … 14 14 * Lesser General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 19 31 */ 20 32 #ifdef __cplusplus 21 33 extern "C" { … … 110 122 #define HDHOMERUN_DISCOVER_UDP_PORT 65001 111 123 #define HDHOMERUN_CONTROL_TCP_PORT 65001 112 124 125 #define HDHOMERUN_MAX_PACKET_SIZE 1460 126 #define HDHOMERUN_MAX_PAYLOAD_SIZE 1452 127 113 128 #define HDHOMERUN_TYPE_DISCOVER_REQ 0x0002 114 129 #define HDHOMERUN_TYPE_DISCOVER_RPY 0x0003 115 130 #define HDHOMERUN_TYPE_GETSET_REQ 0x0004 … … 121 136 #define HDHOMERUN_TAG_DEVICE_ID 0x02 122 137 #define HDHOMERUN_TAG_GETSET_NAME 0x03 123 138 #define HDHOMERUN_TAG_GETSET_VALUE 0x04 139 #define HDHOMERUN_TAG_GETSET_LOCKKEY 0x15 124 140 #define HDHOMERUN_TAG_ERROR_MESSAGE 0x05 125 141 126 142 #define HDHOMERUN_DEVICE_TYPE_WILDCARD 0xFFFFFFFF … … 129 145 130 146 #define HDHOMERUN_MIN_PEEK_LENGTH 4 131 147 132 extern uint8_t hdhomerun_read_u8(uint8_t **pptr); 133 extern uint16_t hdhomerun_read_u16(uint8_t **pptr); 134 extern uint32_t hdhomerun_read_u32(uint8_t **pptr); 135 extern size_t hdhomerun_read_var_length(uint8_t **pptr, uint8_t *end); 136 extern void hdhomerun_write_u8(uint8_t **pptr, uint8_t v); 137 extern void hdhomerun_write_u16(uint8_t **pptr, uint16_t v); 138 extern void hdhomerun_write_u32(uint8_t **pptr, uint32_t v); 139 extern void hdhomerun_write_var_length(uint8_t **pptr, size_t v); 140 extern void hdhomerun_write_crc(uint8_t **pptr, uint8_t *start); 141 142 extern size_t hdhomerun_peek_packet_length(uint8_t *ptr); 143 extern int hdhomerun_process_packet(uint8_t **pptr, uint8_t **pend); 144 extern int hdhomerun_read_tlv(uint8_t **pptr, uint8_t *end, uint8_t *ptag, size_t *plength, uint8_t **pvalue); 145 146 extern void hdhomerun_write_discover_request(uint8_t **pptr, uint32_t device_type, uint32_t device_id); 147 extern void hdhomerun_write_get_set_request(uint8_t **pptr, const char *name, const char *value); 148 extern void hdhomerun_write_upgrade_request(uint8_t **pptr, uint32_t sequence, void *data, size_t length); 148 struct hdhomerun_pkt_t { 149 uint8_t *pos; 150 uint8_t *start; 151 uint8_t *end; 152 uint8_t *limit; 153 uint8_t buffer[3074]; 154 }; 155 156 extern LIBTYPE struct hdhomerun_pkt_t *hdhomerun_pkt_create(void); 157 extern LIBTYPE void hdhomerun_pkt_destroy(struct hdhomerun_pkt_t *pkt); 158 extern LIBTYPE void hdhomerun_pkt_reset(struct hdhomerun_pkt_t *pkt); 159 160 extern LIBTYPE uint8_t hdhomerun_pkt_read_u8(struct hdhomerun_pkt_t *pkt); 161 extern LIBTYPE uint16_t hdhomerun_pkt_read_u16(struct hdhomerun_pkt_t *pkt); 162 extern LIBTYPE uint32_t hdhomerun_pkt_read_u32(struct hdhomerun_pkt_t *pkt); 163 extern LIBTYPE size_t hdhomerun_pkt_read_var_length(struct hdhomerun_pkt_t *pkt); 164 extern LIBTYPE uint8_t *hdhomerun_pkt_read_tlv(struct hdhomerun_pkt_t *pkt, uint8_t *ptag, size_t *plength); 165 166 extern LIBTYPE void hdhomerun_pkt_write_u8(struct hdhomerun_pkt_t *pkt, uint8_t v); 167 extern LIBTYPE void hdhomerun_pkt_write_u16(struct hdhomerun_pkt_t *pkt, uint16_t v); 168 extern LIBTYPE void hdhomerun_pkt_write_u32(struct hdhomerun_pkt_t *pkt, uint32_t v); 169 extern LIBTYPE void hdhomerun_pkt_write_var_length(struct hdhomerun_pkt_t *pkt, size_t v); 170 extern LIBTYPE void hdhomerun_pkt_write_mem(struct hdhomerun_pkt_t *pkt, const void *mem, size_t length); 171 172 extern LIBTYPE bool_t hdhomerun_pkt_open_frame(struct hdhomerun_pkt_t *pkt, uint16_t *ptype); 173 extern LIBTYPE void hdhomerun_pkt_seal_frame(struct hdhomerun_pkt_t *pkt, uint16_t frame_type); 149 174 150 175 #ifdef __cplusplus 151 176 } 152 177 #endif 153 -
mythtv/libs/libmythtv/hdhomerun/hdhomerun_types.h
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun_types.h release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun_types.h
1 /* 2 * hdhomerun_types.h 3 * 4 * Copyright © 2008 Silicondust Engineering Ltd. <www.silicondust.com>. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 3 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 31 */ 32 33 struct hdhomerun_device_t; 34 35 struct hdhomerun_tuner_status_t { 36 char channel[32]; 37 char lock_str[32]; 38 bool_t signal_present; 39 bool_t lock_supported; 40 bool_t lock_unsupported; 41 unsigned int signal_strength; 42 unsigned int signal_to_noise_quality; 43 unsigned int symbol_error_quality; 44 uint32_t raw_bits_per_second; 45 uint32_t packets_per_second; 46 }; 47 48 struct hdhomerun_channelscan_program_t { 49 char program_str[64]; 50 uint16_t program_number; 51 uint16_t virtual_major; 52 uint16_t virtual_minor; 53 uint16_t type; 54 char name[32]; 55 }; 56 57 #define HDHOMERUN_CHANNELSCAN_MAX_PROGRAM_COUNT 64 58 59 struct hdhomerun_channelscan_result_t { 60 char channel_str[64]; 61 uint32_t channelmap; 62 uint32_t frequency; 63 struct hdhomerun_tuner_status_t status; 64 int program_count; 65 struct hdhomerun_channelscan_program_t programs[HDHOMERUN_CHANNELSCAN_MAX_PROGRAM_COUNT]; 66 }; 67 68 struct hdhomerun_plotsample_t { 69 int16_t real; 70 int16_t imag; 71 }; -
mythtv/libs/libmythtv/hdhomerun/hdhomerun_video.c
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun_video.c release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun_video.c
1 1 /* 2 2 * hdhomerun_video.c 3 3 * 4 * Copyright © 2006 Silicondust Engineering Ltd. <www.silicondust.com>.4 * Copyright © 2006 Silicondust Engineering Ltd. <www.silicondust.com>. 5 5 * 6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU Lesser General Public 8 8 * License as published by the Free Software Foundation; either 9 * version 2.1of the License, or (at your option) any later version.9 * version 3 of the License, or (at your option) any later version. 10 10 * 11 11 * This library is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of … … 14 14 * Lesser General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 19 31 */ 20 32 21 #include "hdhomerun_os.h" 22 #include "hdhomerun_pkt.h" 23 #include "hdhomerun_video.h" 33 #include "hdhomerun.h" 24 34 25 35 struct hdhomerun_video_sock_t { 36 pthread_mutex_t lock; 26 37 uint8_t *buffer; 27 38 size_t buffer_size; 28 39 volatile size_t head; 29 40 volatile size_t tail; 30 41 size_t advance; 31 volatile bool_t running;32 42 volatile bool_t terminate; 33 43 pthread_t thread; 34 44 int sock; 45 uint32_t rtp_sequence; 46 struct hdhomerun_debug_t *dbg; 47 volatile uint32_t packet_count; 48 volatile uint32_t transport_error_count; 49 volatile uint32_t network_error_count; 50 volatile uint32_t sequence_error_count; 51 volatile uint32_t overflow_error_count; 52 volatile uint8_t sequence[0x2000]; 35 53 }; 36 54 37 static void *hdhomerun_video_thread(void *arg);55 static THREAD_FUNC_PREFIX hdhomerun_video_thread_execute(void *arg); 38 56 39 57 static bool_t hdhomerun_video_bind_sock_internal(struct hdhomerun_video_sock_t *vs, uint16_t listen_port) 40 58 { … … 80 98 return NULL; 81 99 } 82 100 101 pthread_mutex_init(&vs->lock, NULL); 102 103 /* Reset sequence tracking. */ 104 hdhomerun_video_flush(vs); 105 83 106 /* Buffer size. */ 84 107 vs->buffer_size = (buffer_size / VIDEO_DATA_PACKET_SIZE) * VIDEO_DATA_PACKET_SIZE; 85 108 if (vs->buffer_size == 0) { … … 113 136 114 137 /* Bind socket. */ 115 138 if (!hdhomerun_video_bind_sock(vs, listen_port)) { 116 hdhomerun_video_destroy(vs); 139 close(vs->sock); 140 free(vs->buffer); 141 free(vs); 117 142 return NULL; 118 143 } 119 144 120 145 /* Start thread. */ 121 if (pthread_create(&vs->thread, NULL, &hdhomerun_video_thread, vs) != 0) { 122 hdhomerun_video_destroy(vs); 146 if (pthread_create(&vs->thread, NULL, &hdhomerun_video_thread_execute, vs) != 0) { 147 close(vs->sock); 148 free(vs->buffer); 149 free(vs); 123 150 return NULL; 124 151 } 125 vs->running = 1;126 152 127 153 /* Success. */ 128 154 return vs; … … 130 156 131 157 void hdhomerun_video_destroy(struct hdhomerun_video_sock_t *vs) 132 158 { 133 if (vs->running) { 134 vs->terminate = 1; 135 pthread_join(vs->thread, NULL); 136 } 159 vs->terminate = TRUE; 160 pthread_join(vs->thread, NULL); 161 137 162 close(vs->sock); 138 163 free(vs->buffer); 164 139 165 free(vs); 140 166 } 141 167 168 void hdhomerun_video_set_debug(struct hdhomerun_video_sock_t *vs, struct hdhomerun_debug_t *dbg) 169 { 170 vs->dbg = dbg; 171 } 172 142 173 uint16_t hdhomerun_video_get_local_port(struct hdhomerun_video_sock_t *vs) 143 174 { 144 175 struct sockaddr_in sock_addr; 145 176 socklen_t sockaddr_size = sizeof(sock_addr); 146 177 if (getsockname(vs->sock, (struct sockaddr*)&sock_addr, &sockaddr_size) != 0) { 178 hdhomerun_debug_printf(vs->dbg, "hdhomerun_video_get_local_port: getsockname failed (%d)\n", sock_getlasterror); 147 179 return 0; 148 180 } 149 181 return ntohs(sock_addr.sin_port); 150 182 } 151 183 152 int hdhomerun_video_get_sock(struct hdhomerun_video_sock_t *vs)184 static void hdhomerun_video_stats_ts_pkt(struct hdhomerun_video_sock_t *vs, uint8_t *ptr) 153 185 { 154 return vs->sock; 186 uint16_t packet_identifier = ((uint16_t)(ptr[1] & 0x1F) << 8) | (uint16_t)ptr[2]; 187 if (packet_identifier == 0x1FFF) { 188 return; 189 } 190 191 bool_t transport_error = ptr[1] >> 7; 192 if (transport_error) { 193 vs->transport_error_count++; 194 vs->sequence[packet_identifier] = 0xFF; 195 return; 196 } 197 198 uint8_t continuity_counter = ptr[3] & 0x0F; 199 uint8_t previous_sequence = vs->sequence[packet_identifier]; 200 201 if (continuity_counter == ((previous_sequence + 1) & 0x0F)) { 202 vs->sequence[packet_identifier] = continuity_counter; 203 return; 204 } 205 if (previous_sequence == 0xFF) { 206 vs->sequence[packet_identifier] = continuity_counter; 207 return; 208 } 209 if (continuity_counter == previous_sequence) { 210 return; 211 } 212 213 vs->sequence_error_count++; 214 vs->sequence[packet_identifier] = continuity_counter; 155 215 } 156 216 157 static void *hdhomerun_video_thread(void *arg) 217 static void hdhomerun_video_parse_rtp(struct hdhomerun_video_sock_t *vs, struct hdhomerun_pkt_t *pkt) 218 { 219 pkt->pos += 2; 220 uint32_t rtp_sequence = hdhomerun_pkt_read_u16(pkt); 221 pkt->pos += 8; 222 223 if (rtp_sequence != ((vs->rtp_sequence + 1) & 0xFFFF)) { 224 if (vs->rtp_sequence != 0xFFFFFFFF) { 225 vs->network_error_count++; 226 227 /* restart pid sequence check */ 228 memset((void *)vs->sequence, 0xFF, sizeof(vs->sequence)); 229 } 230 } 231 232 vs->rtp_sequence = rtp_sequence; 233 } 234 235 static THREAD_FUNC_PREFIX hdhomerun_video_thread_execute(void *arg) 158 236 { 159 237 struct hdhomerun_video_sock_t *vs = (struct hdhomerun_video_sock_t *)arg; 238 struct hdhomerun_pkt_t pkt_inst; 160 239 161 240 while (!vs->terminate) { 162 size_t head = vs->head; 241 struct hdhomerun_pkt_t *pkt = &pkt_inst; 242 hdhomerun_pkt_reset(pkt); 163 243 164 244 /* Receive. */ 165 int length = recv(vs->sock, (char *)vs->buffer + head, VIDEO_DATA_PACKET_SIZE, 0); 245 int length = recv(vs->sock, (char *)pkt->end, VIDEO_RTP_DATA_PACKET_SIZE, 0); 246 pkt->end += length; 247 248 if (length == VIDEO_RTP_DATA_PACKET_SIZE) { 249 hdhomerun_video_parse_rtp(vs, pkt); 250 length = (int)(pkt->end - pkt->pos); 251 } 252 166 253 if (length != VIDEO_DATA_PACKET_SIZE) { 167 254 if (length > 0) { 168 255 /* Data received but not valid - ignore. */ … … 172 259 /* Wait for more data. */ 173 260 continue; 174 261 } 175 vs->terminate = 1;262 vs->terminate = TRUE; 176 263 return NULL; 177 264 } 178 265 266 pthread_mutex_lock(&vs->lock); 267 268 /* Store in ring buffer. */ 269 size_t head = vs->head; 270 uint8_t *ptr = vs->buffer + head; 271 memcpy(ptr, pkt->pos, length); 272 273 /* Stats. */ 274 vs->packet_count++; 275 hdhomerun_video_stats_ts_pkt(vs, ptr + TS_PACKET_SIZE * 0); 276 hdhomerun_video_stats_ts_pkt(vs, ptr + TS_PACKET_SIZE * 1); 277 hdhomerun_video_stats_ts_pkt(vs, ptr + TS_PACKET_SIZE * 2); 278 hdhomerun_video_stats_ts_pkt(vs, ptr + TS_PACKET_SIZE * 3); 279 hdhomerun_video_stats_ts_pkt(vs, ptr + TS_PACKET_SIZE * 4); 280 hdhomerun_video_stats_ts_pkt(vs, ptr + TS_PACKET_SIZE * 5); 281 hdhomerun_video_stats_ts_pkt(vs, ptr + TS_PACKET_SIZE * 6); 282 179 283 /* Calculate new head. */ 180 284 head += length; 181 285 if (head >= vs->buffer_size) { … … 184 288 185 289 /* Check for buffer overflow. */ 186 290 if (head == vs->tail) { 291 vs->overflow_error_count++; 292 pthread_mutex_unlock(&vs->lock); 187 293 continue; 188 294 } 189 295 190 296 /* Atomic update. */ 191 297 vs->head = head; 298 299 pthread_mutex_unlock(&vs->lock); 192 300 } 193 301 194 302 return NULL; … … 196 304 197 305 uint8_t *hdhomerun_video_recv(struct hdhomerun_video_sock_t *vs, size_t max_size, size_t *pactual_size) 198 306 { 307 pthread_mutex_lock(&vs->lock); 308 199 309 size_t head = vs->head; 200 310 size_t tail = vs->tail; 201 311 … … 212 322 if (head == tail) { 213 323 vs->advance = 0; 214 324 *pactual_size = 0; 325 pthread_mutex_unlock(&vs->lock); 215 326 return NULL; 216 327 } 217 328 … … 219 330 if (size == 0) { 220 331 vs->advance = 0; 221 332 *pactual_size = 0; 333 pthread_mutex_unlock(&vs->lock); 222 334 return NULL; 223 335 } 224 336 … … 233 345 } 234 346 vs->advance = size; 235 347 *pactual_size = size; 236 return vs->buffer + tail; 348 uint8_t *result = vs->buffer + tail; 349 350 pthread_mutex_unlock(&vs->lock); 351 return result; 237 352 } 238 353 239 354 void hdhomerun_video_flush(struct hdhomerun_video_sock_t *vs) 240 355 { 241 /* Atomic update of tail. */ 356 pthread_mutex_lock(&vs->lock); 357 242 358 vs->tail = vs->head; 243 359 vs->advance = 0; 360 361 memset((void *)vs->sequence, 0xFF, sizeof(vs->sequence)); 362 363 vs->rtp_sequence = 0xFFFFFFFF; 364 365 vs->packet_count = 0; 366 vs->transport_error_count = 0; 367 vs->network_error_count = 0; 368 vs->sequence_error_count = 0; 369 vs->overflow_error_count = 0; 370 371 pthread_mutex_unlock(&vs->lock); 244 372 } 245 373 374 void hdhomerun_video_debug_print_stats(struct hdhomerun_video_sock_t *vs) 375 { 376 struct hdhomerun_video_stats_t stats; 377 hdhomerun_video_get_stats(vs, &stats); 378 379 hdhomerun_debug_printf(vs->dbg, "video sock: pkt=%ld net=%ld te=%ld miss=%ld drop=%ld\n", 380 stats.packet_count, stats.network_error_count, 381 stats.transport_error_count, stats.sequence_error_count, 382 stats.overflow_error_count 383 ); 384 } 385 386 void hdhomerun_video_get_stats(struct hdhomerun_video_sock_t *vs, struct hdhomerun_video_stats_t *stats) 387 { 388 memset(stats, 0, sizeof(struct hdhomerun_video_stats_t)); 389 390 pthread_mutex_lock(&vs->lock); 391 392 stats->packet_count = vs->packet_count; 393 stats->network_error_count = vs->network_error_count; 394 stats->transport_error_count = vs->transport_error_count; 395 stats->sequence_error_count = vs->sequence_error_count; 396 stats->overflow_error_count = vs->overflow_error_count; 397 398 pthread_mutex_unlock(&vs->lock); 399 } -
mythtv/libs/libmythtv/hdhomerun/hdhomerun_video.h
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/hdhomerun_video.h release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/hdhomerun_video.h
1 1 /* 2 2 * hdhomerun_video.h 3 3 * 4 * Copyright © 2006 Silicondust Engineering Ltd. <www.silicondust.com>.4 * Copyright © 2006 Silicondust Engineering Ltd. <www.silicondust.com>. 5 5 * 6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU Lesser General Public 8 8 * License as published by the Free Software Foundation; either 9 * version 2.1of the License, or (at your option) any later version.9 * version 3 of the License, or (at your option) any later version. 10 10 * 11 11 * This library is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of … … 14 14 * Lesser General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * As a special exception to the GNU Lesser General Public License, 20 * you may link, statically or dynamically, an application with a 21 * publicly distributed version of the Library to produce an 22 * executable file containing portions of the Library, and 23 * distribute that executable file under terms of your choice, 24 * without any of the additional requirements listed in clause 4 of 25 * the GNU Lesser General Public License. 26 * 27 * By "a publicly distributed version of the Library", we mean 28 * either the unmodified Library as distributed by Silicondust, or a 29 * modified version of the Library that is distributed under the 30 * conditions defined in the GNU Lesser General Public License. 19 31 */ 20 32 #ifdef __cplusplus 21 33 extern "C" { … … 23 35 24 36 struct hdhomerun_video_sock_t; 25 37 38 struct hdhomerun_video_stats_t { 39 uint32_t packet_count; 40 uint32_t network_error_count; 41 uint32_t transport_error_count; 42 uint32_t sequence_error_count; 43 uint32_t overflow_error_count; 44 }; 45 26 46 #define TS_PACKET_SIZE 188 27 47 #define VIDEO_DATA_PACKET_SIZE (188 * 7) 28 48 #define VIDEO_DATA_BUFFER_SIZE_1S (20000000 / 8) 29 49 50 #define VIDEO_RTP_DATA_PACKET_SIZE ((188 * 7) + 12) 51 30 52 /* 31 53 * Create a video/data socket. 32 54 * … … 37 59 * 38 60 * When no longer needed, the socket should be destroyed by calling hdhomerun_control_destroy. 39 61 */ 40 extern struct hdhomerun_video_sock_t *hdhomerun_video_create(uint16_t listen_port, size_t buffer_size);41 extern void hdhomerun_video_destroy(struct hdhomerun_video_sock_t *vs);62 extern LIBTYPE struct hdhomerun_video_sock_t *hdhomerun_video_create(uint16_t listen_port, size_t buffer_size); 63 extern LIBTYPE void hdhomerun_video_destroy(struct hdhomerun_video_sock_t *vs); 42 64 43 65 /* 44 66 * Get the port the socket is listening on. 45 67 * 46 68 * Returns 16-bit port with native endianness, or 0 on error. 47 69 */ 48 extern uint16_t hdhomerun_video_get_local_port(struct hdhomerun_video_sock_t *vs); 49 50 /* 51 * Get the low-level socket handle. 52 */ 53 extern int hdhomerun_video_get_sock(struct hdhomerun_video_sock_t *vs); 70 extern LIBTYPE uint16_t hdhomerun_video_get_local_port(struct hdhomerun_video_sock_t *vs); 54 71 55 72 /* 56 73 * Read data from buffer. … … 69 86 * The buffer is implemented as a ring buffer. It is possible for this function to return a small 70 87 * amount of data when more is available due to the wrap-around case. 71 88 */ 72 extern uint8_t *hdhomerun_video_recv(struct hdhomerun_video_sock_t *vs, size_t max_size, size_t *pactual_size);89 extern LIBTYPE uint8_t *hdhomerun_video_recv(struct hdhomerun_video_sock_t *vs, size_t max_size, size_t *pactual_size); 73 90 74 91 /* 75 92 * Flush the buffer. 76 93 */ 77 extern void hdhomerun_video_flush(struct hdhomerun_video_sock_t *vs); 94 extern LIBTYPE void hdhomerun_video_flush(struct hdhomerun_video_sock_t *vs); 95 96 /* 97 * Debug print internal stats. 98 */ 99 extern LIBTYPE void hdhomerun_video_set_debug(struct hdhomerun_video_sock_t *vs, struct hdhomerun_debug_t *dbg); 100 extern LIBTYPE void hdhomerun_video_debug_print_stats(struct hdhomerun_video_sock_t *vs); 101 102 extern LIBTYPE void hdhomerun_video_get_stats(struct hdhomerun_video_sock_t *vs, struct hdhomerun_video_stats_t *stats); 78 103 79 104 #ifdef __cplusplus 80 105 } -
mythtv/libs/libmythtv/hdhomerun/lgpl.txt
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhomerun/lgpl.txt release.19703.0116b/mythtv/libs/libmythtv/hdhomerun/lgpl.txt
1 GNU LESSER GENERAL PUBLIC LICENSE2 Version 2.1, February 1999 1 GNU LESSER GENERAL PUBLIC LICENSE 2 Version 3, 29 June 2007 3 3 4 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 5 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 4 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> 6 5 Everyone is permitted to copy and distribute verbatim copies 7 6 of this license document, but changing it is not allowed. 8 7 9 [This is the first released version of the Lesser GPL. It also counts10 as the successor of the GNU Library Public License, version 2, hence11 the version number 2.1.]12 13 Preamble14 15 The licenses for most software are designed to take away your16 freedom to share and change it. By contrast, the GNU General Public17 Licenses are intended to guarantee your freedom to share and change18 free software--to make sure the software is free for all its users.19 20 This license, the Lesser General Public License, applies to some21 specially designated software packages--typically libraries--of the22 Free Software Foundation and other authors who decide to use it. You23 can use it too, but we suggest you first think carefully about whether24 this license or the ordinary General Public License is the better25 strategy to use in any particular case, based on the explanations below.26 27 When we speak of free software, we are referring to freedom of use,28 not price. Our General Public Licenses are designed to make sure that29 you have the freedom to distribute copies of free software (and charge30 for this service if you wish); that you receive source code or can get31 it if you want it; that you can change the software and use pieces of32 it in new free programs; and that you are informed that you can do33 these things.34 35 To protect your rights, we need to make restrictions that forbid36 distributors to deny you these rights or to ask you to surrender these37 rights. These restrictions translate to certain responsibilities for38 you if you distribute copies of the library or if you modify it.39 40 For example, if you distribute copies of the library, whether gratis41 or for a fee, you must give the recipients all the rights that we gave42 you. You must make sure that they, too, receive or can get the source43 code. If you link other code with the library, you must provide44 complete object files to the recipients, so that they can relink them45 with the library after making changes to the library and recompiling46 it. And you must show them these terms so they know their rights.47 48 We protect your rights with a two-step method: (1) we copyright the49 library, and (2) we offer you this license, which gives you legal50 permission to copy, distribute and/or modify the library.51 52 To protect each distributor, we want to make it very clear that53 there is no warranty for the free library. Also, if the library is54 modified by someone else and passed on, the recipients should know55 that what they have is not the original version, so that the original56 author's reputation will not be affected by problems that might be57 introduced by others.58 59 8 60 Finally, software patents pose a constant threat to the existence of61 any free program. We wish to make sure that a company cannot62 effectively restrict the users of a free program by obtaining a63 restrictive license from a patent holder. Therefore, we insist that64 any patent license obtained for a version of the library must be65 consistent with the full freedom of use specified in this license.66 67 Most GNU software, including some libraries, is covered by the68 ordinary GNU General Public License. This license, the GNU Lesser69 General Public License, applies to certain designated libraries, and70 is quite different from the ordinary General Public License. We use71 this license for certain libraries in order to permit linking those72 libraries into non-free programs.73 74 When a program is linked with a library, whether statically or using75 a shared library, the combination of the two is legally speaking a76 combined work, a derivative of the original library. The ordinary77 General Public License therefore permits such linking only if the78 entire combination fits its criteria of freedom. The Lesser General79 Public License permits more lax criteria for linking other code with80 the library.81 82 We call this license the "Lesser" General Public License because it83 does Less to protect the user's freedom than the ordinary General84 Public License. It also provides other free software developers Less85 of an advantage over competing non-free programs. These disadvantages86 are the reason we use the ordinary General Public License for many87 libraries. However, the Lesser license provides advantages in certain88 special circumstances.89 90 For example, on rare occasions, there may be a special need to91 encourage the widest possible use of a certain library, so that it becomes92 a de-facto standard. To achieve this, non-free programs must be93 allowed to use the library. A more frequent case is that a free94 library does the same job as widely used non-free libraries. In this95 case, there is little to gain by limiting the free library to free96 software only, so we use the Lesser General Public License.97 98 In other cases, permission to use a particular library in non-free99 programs enables a greater number of people to use a large body of100 free software. For example, permission to use the GNU C Library in101 non-free programs enables many more people to use the whole GNU102 operating system, as well as its variant, the GNU/Linux operating103 system.104 105 Although the Lesser General Public License is Less protective of the106 users' freedom, it does ensure that the user of a program that is107 linked with the Library has the freedom and the wherewithal to run108 that program using a modified version of the Library.109 110 The precise terms and conditions for copying, distribution and111 modification follow. Pay close attention to the difference between a112 "work based on the library" and a "work that uses the library". The113 former contains code derived from the library, whereas the latter must114 be combined with the library in order to run.115 116 9 117 GNU LESSER GENERAL PUBLIC LICENSE118 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION119 120 0. This License Agreement applies to any software library or other121 program which contains a notice placed by the copyright holder or122 other authorized party saying it may be distributed under the terms of123 this Lesser General Public License (also called "this License").124 Each licensee is addressed as "you".125 126 A "library" means a collection of software functions and/or data127 prepared so as to be conveniently linked with application programs128 (which use some of those functions and data) to form executables.129 130 The "Library", below, refers to any such software library or work131 which has been distributed under these terms. A "work based on the132 Library" means either the Library or any derivative work under133 copyright law: that is to say, a work containing the Library or a134 portion of it, either verbatim or with modifications and/or translated135 straightforwardly into another language. (Hereinafter, translation is136 included without limitation in the term "modification".)137 138 "Source code" for a work means the preferred form of the work for139 making modifications to it. For a library, complete source code means140 all the source code for all modules it contains, plus any associated141 interface definition files, plus the scripts used to control compilation142 and installation of the library.143 144 Activities other than copying, distribution and modification are not145 covered by this License; they are outside its scope. The act of146 running a program using the Library is not restricted, and output from147 such a program is covered only if its contents constitute a work based148 on the Library (independent of the use of the Library in a tool for149 writing it). Whether that is true depends on what the Library does150 and what the program that uses the Library does.151 152 1. You may copy and distribute verbatim copies of the Library's153 complete source code as you receive it, in any medium, provided that154 you conspicuously and appropriately publish on each copy an155 appropriate copyright notice and disclaimer of warranty; keep intact156 all the notices that refer to this License and to the absence of any157 warranty; and distribute a copy of this License along with the158 Library.159 160 You may charge a fee for the physical act of transferring a copy,161 and you may at your option offer warranty protection in exchange for a162 fee.163 164 10 165 2. You may modify your copy or copies of the Library or any portion166 of it, thus forming a work based on the Library, and copy and167 distribute such modifications or work under the terms of Section 1168 above, provided that you also meet all of these conditions:169 170 a) The modified work must itself be a software library.171 172 b) You must cause the files modified to carry prominent notices173 stating that you changed the files and the date of any change.174 175 c) You must cause the whole of the work to be licensed at no176 charge to all third parties under the terms of this License.177 178 d) If a facility in the modified Library refers to a function or a179 table of data to be supplied by an application program that uses180 the facility, other than as an argument passed when the facility181 is invoked, then you must make a good faith effort to ensure that,182 in the event an application does not supply such function or183 table, the facility still operates, and performs whatever part of184 its purpose remains meaningful.185 186 (For example, a function in a library to compute square roots has187 a purpose that is entirely well-defined independent of the188 application. Therefore, Subsection 2d requires that any189 application-supplied function or table used by this function must190 be optional: if the application does not supply it, the square191 root function must still compute square roots.)192 193 These requirements apply to the modified work as a whole. If194 identifiable sections of that work are not derived from the Library,195 and can be reasonably considered independent and separate works in196 themselves, then this License, and its terms, do not apply to those197 sections when you distribute them as separate works. But when you198 distribute the same sections as part of a whole which is a work based199 on the Library, the distribution of the whole must be on the terms of200 this License, whose permissions for other licensees extend to the201 entire whole, and thus to each and every part regardless of who wrote202 it.203 204 Thus, it is not the intent of this section to claim rights or contest205 your rights to work written entirely by you; rather, the intent is to206 exercise the right to control the distribution of derivative or207 collective works based on the Library.208 209 In addition, mere aggregation of another work not based on the Library210 with the Library (or with a work based on the Library) on a volume of211 a storage or distribution medium does not bring the other work under212 the scope of this License.213 214 3. You may opt to apply the terms of the ordinary GNU General Public215 License instead of this License to a given copy of the Library. To do216 this, you must alter all the notices that refer to this License, so217 that they refer to the ordinary GNU General Public License, version 2,218 instead of to this License. (If a newer version than version 2 of the219 ordinary GNU General Public License has appeared, then you can specify220 that version instead if you wish.) Do not make any other change in221 these notices.222 223 11 224 Once this change is made in a given copy, it is irreversible for225 that copy, so the ordinary GNU General Public License applies to all226 subsequent copies and derivative works made from that copy.227 228 This option is useful when you wish to copy part of the code of229 the Library into a program that is not a library.230 231 4. You may copy and distribute the Library (or a portion or232 derivative of it, under Section 2) in object code or executable form233 under the terms of Sections 1 and 2 above provided that you accompany234 it with the complete corresponding machine-readable source code, which235 must be distributed under the terms of Sections 1 and 2 above on a236 medium customarily used for software interchange.237 238 If distribution of object code is made by offering access to copy239 from a designated place, then offering equivalent access to copy the240 source code from the same place satisfies the requirement to241 distribute the source code, even though third parties are not242 compelled to copy the source along with the object code.243 244 5. A program that contains no derivative of any portion of the245 Library, but is designed to work with the Library by being compiled or246 linked with it, is called a "work that uses the Library". Such a247 work, in isolation, is not a derivative work of the Library, and248 therefore falls outside the scope of this License.249 250 However, linking a "work that uses the Library" with the Library251 creates an executable that is a derivative of the Library (because it252 contains portions of the Library), rather than a "work that uses the253 library". The executable is therefore covered by this License.254 Section 6 states terms for distribution of such executables.255 256 When a "work that uses the Library" uses material from a header file257 that is part of the Library, the object code for the work may be a258 derivative work of the Library even though the source code is not.259 Whether this is true is especially significant if the work can be260 linked without the Library, or if the work is itself a library. The261 threshold for this to be true is not precisely defined by law.262 263 If such an object file uses only numerical parameters, data264 structure layouts and accessors, and small macros and small inline265 functions (ten lines or less in length), then the use of the object266 file is unrestricted, regardless of whether it is legally a derivative267 work. (Executables containing this object code plus portions of the268 Library will still fall under Section 6.)269 270 Otherwise, if the work is a derivative of the Library, you may271 distribute the object code for the work under the terms of Section 6.272 Any executables containing that work also fall under Section 6,273 whether or not they are linked directly with the Library itself.274 275 12 276 6. As an exception to the Sections above, you may also combine or277 link a "work that uses the Library" with the Library to produce a278 work containing portions of the Library, and distribute that work279 under terms of your choice, provided that the terms permit280 modification of the work for the customer's own use and reverse281 engineering for debugging such modifications.282 283 You must give prominent notice with each copy of the work that the284 Library is used in it and that the Library and its use are covered by285 this License. You must supply a copy of this License. If the work286 during execution displays copyright notices, you must include the287 copyright notice for the Library among them, as well as a reference288 directing the user to the copy of this License. Also, you must do one289 of these things:290 291 a) Accompany the work with the complete corresponding292 machine-readable source code for the Library including whatever293 changes were used in the work (which must be distributed under294 Sections 1 and 2 above); and, if the work is an executable linked295 with the Library, with the complete machine-readable "work that296 uses the Library", as object code and/or source code, so that the297 user can modify the Library and then relink to produce a modified298 executable containing the modified Library. (It is understood299 that the user who changes the contents of definitions files in the300 Library will not necessarily be able to recompile the application301 to use the modified definitions.)302 303 b) Use a suitable shared library mechanism for linking with the304 Library. A suitable mechanism is one that (1) uses at run time a305 copy of the library already present on the user's computer system,306 rather than copying library functions into the executable, and (2)307 will operate properly with a modified version of the library, if308 the user installs one, as long as the modified version is309 interface-compatible with the version that the work was made with.310 311 c) Accompany the work with a written offer, valid for at312 least three years, to give the same user the materials313 specified in Subsection 6a, above, for a charge no more314 than the cost of performing this distribution.315 316 d) If distribution of the work is made by offering access to copy317 from a designated place, offer equivalent access to copy the above318 specified materials from the same place.319 320 e) Verify that the user has already received a copy of these321 materials or that you have already sent this user a copy.322 323 For an executable, the required form of the "work that uses the324 Library" must include any data and utility programs needed for325 reproducing the executable from it. However, as a special exception,326 the materials to be distributed need not include anything that is327 normally distributed (in either source or binary form) with the major328 components (compiler, kernel, and so on) of the operating system on329 which the executable runs, unless that component itself accompanies330 the executable.331 332 It may happen that this requirement contradicts the license333 restrictions of other proprietary libraries that do not normally334 accompany the operating system. Such a contradiction means you cannot335 use both them and the Library together in an executable that you336 distribute.337 338 13 339 7. You may place library facilities that are a work based on the340 Library side-by-side in a single library together with other library341 facilities not covered by this License, and distribute such a combined342 library, provided that the separate distribution of the work based on343 the Library and of the other library facilities is otherwise344 permitted, and provided that you do these two things:345 346 a) Accompany the combined library with a copy of the same work347 based on the Library, uncombined with any other library348 facilities. This must be distributed under the terms of the349 Sections above.350 351 b) Give prominent notice with the combined library of the fact352 that part of it is a work based on the Library, and explaining353 where to find the accompanying uncombined form of the same work.354 355 8. You may not copy, modify, sublicense, link with, or distribute356 the Library except as expressly provided under this License. Any357 attempt otherwise to copy, modify, sublicense, link with, or358 distribute the Library is void, and will automatically terminate your359 rights under this License. However, parties who have received copies,360 or rights, from you under this License will not have their licenses361 terminated so long as such parties remain in full compliance.362 363 9. You are not required to accept this License, since you have not364 signed it. However, nothing else grants you permission to modify or365 distribute the Library or its derivative works. These actions are366 prohibited by law if you do not accept this License. Therefore, by367 modifying or distributing the Library (or any work based on the368 Library), you indicate your acceptance of this License to do so, and369 all its terms and conditions for copying, distributing or modifying370 the Library or works based on it.371 372 10. Each time you redistribute the Library (or any work based on the373 Library), the recipient automatically receives a license from the374 original licensor to copy, distribute, link with or modify the Library375 subject to these terms and conditions. You may not impose any further376 restrictions on the recipients' exercise of the rights granted herein.377 You are not responsible for enforcing compliance by third parties with378 this License.379 380 14 381 11. If, as a consequence of a court judgment or allegation of patent382 infringement or for any other reason (not limited to patent issues),383 conditions are imposed on you (whether by court order, agreement or384 otherwise) that contradict the conditions of this License, they do not385 excuse you from the conditions of this License. If you cannot386 distribute so as to satisfy simultaneously your obligations under this387 License and any other pertinent obligations, then as a consequence you388 may not distribute the Library at all. For example, if a patent389 license would not permit royalty-free redistribution of the Library by390 all those who receive copies directly or indirectly through you, then391 the only way you could satisfy both it and this License would be to392 refrain entirely from distribution of the Library.393 394 If any portion of this section is held invalid or unenforceable under any395 particular circumstance, the balance of the section is intended to apply,396 and the section as a whole is intended to apply in other circumstances.397 398 It is not the purpose of this section to induce you to infringe any399 patents or other property right claims or to contest validity of any400 such claims; this section has the sole purpose of protecting the401 integrity of the free software distribution system which is402 implemented by public license practices. Many people have made403 generous contributions to the wide range of software distributed404 through that system in reliance on consistent application of that405 system; it is up to the author/donor to decide if he or she is willing406 to distribute software through any other system and a licensee cannot407 impose that choice.408 409 This section is intended to make thoroughly clear what is believed to410 be a consequence of the rest of this License.411 412 12. If the distribution and/or use of the Library is restricted in413 certain countries either by patents or by copyrighted interfaces, the414 original copyright holder who places the Library under this License may add415 an explicit geographical distribution limitation excluding those countries,416 so that distribution is permitted only in or among countries not thus417 excluded. In such case, this License incorporates the limitation as if418 written in the body of this License.419 420 13. The Free Software Foundation may publish revised and/or new421 versions of the Lesser General Public License from time to time.422 Such new versions will be similar in spirit to the present version,423 but may differ in detail to address new problems or concerns.424 425 Each version is given a distinguishing version number. If the Library426 specifies a version number of this License which applies to it and427 "any later version", you have the option of following the terms and428 conditions either of that version or of any later version published by429 the Free Software Foundation. If the Library does not specify a430 license version number, you may choose any version ever published by431 the Free Software Foundation.432 433 15 434 14. If you wish to incorporate parts of the Library into other free435 programs whose distribution conditions are incompatible with these,436 write to the author to ask for permission. For software which is437 copyrighted by the Free Software Foundation, write to the Free438 Software Foundation; we sometimes make exceptions for this. Our439 decision will be guided by the two goals of preserving the free status440 of all derivatives of our free software and of promoting the sharing441 and reuse of software generally.442 443 NO WARRANTY444 445 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO446 WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.447 EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR448 OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY449 KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE450 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR451 PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE452 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME453 THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.454 455 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN456 WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY457 AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU458 FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR459 CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE460 LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING461 RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A462 FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF463 SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH464 DAMAGES.465 466 END OF TERMS AND CONDITIONS467 468 16 469 How to Apply These Terms to Your New Libraries470 471 If you develop a new library, and you want it to be of the greatest472 possible use to the public, we recommend making it free software that473 everyone can redistribute and change. You can do so by permitting474 redistribution under these terms (or, alternatively, under the terms of the475 ordinary General Public License).476 477 To apply these terms, attach the following notices to the library. It is478 safest to attach them to the start of each source file to most effectively479 convey the exclusion of warranty; and each file should have at least the480 "copyright" line and a pointer to where the full notice is found.481 482 <one line to give the library's name and a brief idea of what it does.>483 Copyright (C) <year> <name of author>484 485 This library is free software; you can redistribute it and/or486 modify it under the terms of the GNU Lesser General Public487 License as published by the Free Software Foundation; either488 version 2.1 of the License, or (at your option) any later version.489 490 This library is distributed in the hope that it will be useful,491 but WITHOUT ANY WARRANTY; without even the implied warranty of492 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU493 Lesser General Public License for more details.494 495 You should have received a copy of the GNU Lesser General Public496 License along with this library; if not, write to the Free Software497 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA498 499 Also add information on how to contact you by electronic and paper mail.500 501 You should also get your employer (if you work as a programmer) or your502 school, if any, to sign a "copyright disclaimer" for the library, if503 necessary. Here is a sample; alter the names:504 505 Yoyodyne, Inc., hereby disclaims all copyright interest in the506 library `Frob' (a library for tweaking knobs) written by James Random Hacker.507 508 <signature of Ty Coon>, 1 April 1990509 Ty Coon, President of Vice510 511 That's all there is to it!512 513 17 18 This version of the GNU Lesser General Public License incorporates 19 the terms and conditions of version 3 of the GNU General Public 20 License, supplemented by the additional permissions listed below. 21 22 0. Additional Definitions. 23 24 As used herein, "this License" refers to version 3 of the GNU Lesser 25 General Public License, and the "GNU GPL" refers to version 3 of the GNU 26 General Public License. 27 28 "The Library" refers to a covered work governed by this License, 29 other than an Application or a Combined Work as defined below. 30 31 An "Application" is any work that makes use of an interface provided 32 by the Library, but which is not otherwise based on the Library. 33 Defining a subclass of a class defined by the Library is deemed a mode 34 of using an interface provided by the Library. 35 36 A "Combined Work" is a work produced by combining or linking an 37 Application with the Library. The particular version of the Library 38 with which the Combined Work was made is also called the "Linked 39 Version". 40 41 The "Minimal Corresponding Source" for a Combined Work means the 42 Corresponding Source for the Combined Work, excluding any source code 43 for portions of the Combined Work that, considered in isolation, are 44 based on the Application, and not on the Linked Version. 45 46 The "Corresponding Application Code" for a Combined Work means the 47 object code and/or source code for the Application, including any data 48 and utility programs needed for reproducing the Combined Work from the 49 Application, but excluding the System Libraries of the Combined Work. 50 51 1. Exception to Section 3 of the GNU GPL. 52 53 You may convey a covered work under sections 3 and 4 of this License 54 without being bound by section 3 of the GNU GPL. 55 56 2. Conveying Modified Versions. 57 58 If you modify a copy of the Library, and, in your modifications, a 59 facility refers to a function or data to be supplied by an Application 60 that uses the facility (other than as an argument passed when the 61 facility is invoked), then you may convey a copy of the modified 62 version: 63 64 a) under this License, provided that you make a good faith effort to 65 ensure that, in the event an Application does not supply the 66 function or data, the facility still operates, and performs 67 whatever part of its purpose remains meaningful, or 68 69 b) under the GNU GPL, with none of the additional permissions of 70 this License applicable to that copy. 71 72 3. Object Code Incorporating Material from Library Header Files. 73 74 The object code form of an Application may incorporate material from 75 a header file that is part of the Library. You may convey such object 76 code under terms of your choice, provided that, if the incorporated 77 material is not limited to numerical parameters, data structure 78 layouts and accessors, or small macros, inline functions and templates 79 (ten or fewer lines in length), you do both of the following: 80 81 a) Give prominent notice with each copy of the object code that the 82 Library is used in it and that the Library and its use are 83 covered by this License. 84 85 b) Accompany the object code with a copy of the GNU GPL and this license 86 document. 87 88 4. Combined Works. 89 90 You may convey a Combined Work under terms of your choice that, 91 taken together, effectively do not restrict modification of the 92 portions of the Library contained in the Combined Work and reverse 93 engineering for debugging such modifications, if you also do each of 94 the following: 95 96 a) Give prominent notice with each copy of the Combined Work that 97 the Library is used in it and that the Library and its use are 98 covered by this License. 99 100 b) Accompany the Combined Work with a copy of the GNU GPL and this license 101 document. 102 103 c) For a Combined Work that displays copyright notices during 104 execution, include the copyright notice for the Library among 105 these notices, as well as a reference directing the user to the 106 copies of the GNU GPL and this license document. 107 108 d) Do one of the following: 109 110 0) Convey the Minimal Corresponding Source under the terms of this 111 License, and the Corresponding Application Code in a form 112 suitable for, and under terms that permit, the user to 113 recombine or relink the Application with a modified version of 114 the Linked Version to produce a modified Combined Work, in the 115 manner specified by section 6 of the GNU GPL for conveying 116 Corresponding Source. 117 118 1) Use a suitable shared library mechanism for linking with the 119 Library. A suitable mechanism is one that (a) uses at run time 120 a copy of the Library already present on the user's computer 121 system, and (b) will operate properly with a modified version 122 of the Library that is interface-compatible with the Linked 123 Version. 124 125 e) Provide Installation Information, but only if you would otherwise 126 be required to provide such information under section 6 of the 127 GNU GPL, and only to the extent that such information is 128 necessary to install and execute a modified version of the 129 Combined Work produced by recombining or relinking the 130 Application with a modified version of the Linked Version. (If 131 you use option 4d0, the Installation Information must accompany 132 the Minimal Corresponding Source and Corresponding Application 133 Code. If you use option 4d1, you must provide the Installation 134 Information in the manner specified by section 6 of the GNU GPL 135 for conveying Corresponding Source.) 136 137 5. Combined Libraries. 138 139 You may place library facilities that are a work based on the 140 Library side by side in a single library together with other library 141 facilities that are not Applications and are not covered by this 142 License, and convey such a combined library under terms of your 143 choice, if you do both of the following: 144 145 a) Accompany the combined library with a copy of the same work based 146 on the Library, uncombined with any other library facilities, 147 conveyed under the terms of this License. 148 149 b) Give prominent notice with the combined library that part of it 150 is a work based on the Library, and explaining where to find the 151 accompanying uncombined form of the same work. 152 153 6. Revised Versions of the GNU Lesser General Public License. 154 155 The Free Software Foundation may publish revised and/or new versions 156 of the GNU Lesser General Public License from time to time. Such new 157 versions will be similar in spirit to the present version, but may 158 differ in detail to address new problems or concerns. 159 160 Each version is given a distinguishing version number. If the 161 Library as you received it specifies that a certain numbered version 162 of the GNU Lesser General Public License "or any later version" 163 applies to it, you have the option of following the terms and 164 conditions either of that published version or of any later version 165 published by the Free Software Foundation. If the Library as you -
mythtv/libs/libmythtv/hdhrchannel.cpp
+received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/hdhrchannel.cpp release.19703.0116b/mythtv/libs/libmythtv/hdhrchannel.cpp
42 42 if (valid && hdhomerun_discover_validate_device_id(_device_id)) 43 43 return; 44 44 45 _device_id = HDHOMERUN_DEVICE_ID_WILDCARD; 45 46 /* Otherwise, is it a valid IP address? */ 46 47 struct in_addr address; 47 48 if (inet_aton(device, &address)) … … 99 100 100 101 /* Discover. */ 101 102 struct hdhomerun_discover_device_t result; 102 int ret = hdhomerun_discover_find_device (_device_id, &result);103 int ret = hdhomerun_discover_find_devices_custom(0, HDHOMERUN_DEVICE_TYPE_WILDCARD, _device_id, &result, 1); 103 104 if (ret < 0) 104 105 { 105 106 VERBOSE(VB_IMPORTANT, LOC_ERR + "Unable to send discovery request" + ENO); -
mythtv/libs/libmythtv/libmythtv.pro
diff -r -u -N -X diff.exclude -x release.19703.0116a -x release.19703.0116b release.19703.0116a/mythtv/libs/libmythtv/libmythtv.pro release.19703.0116b/mythtv/libs/libmythtv/libmythtv.pro
461 461 # HDHomeRun library 462 462 HEADERS += hdhomerun/hdhomerun_pkt.h hdhomerun/hdhomerun_discover.h 463 463 HEADERS += hdhomerun/hdhomerun_video.h hdhomerun/hdhomerun_control.h 464 HEADERS += hdhomerun/hdhomerun_os.h 464 HEADERS += hdhomerun/hdhomerun_os.h hdhomerun/hdhomerun.h 465 HEADERS += hdhomerun/hdhomerun_dhcp.h hdhomerun/hdhomerun_types.h 466 HEADERS += hdhomerun/hdhomerun_channels.h 467 HEADERS += hdhomerun/hdhomerun_channelscan.h 468 HEADERS += hdhomerun/hdhomerun_debug.h 465 469 466 470 SOURCES += hdhomerun/hdhomerun_pkt.c hdhomerun/hdhomerun_discover.c 467 471 SOURCES += hdhomerun/hdhomerun_video.c hdhomerun/hdhomerun_control.c 472 SOURCES += hdhomerun/hdhomerun_debug.c hdhomerun/hdhomerun_channels.c 473 SOURCES += hdhomerun/hdhomerun_dhcp.c hdhomerun/hdhomerun_channelscan.c 474 SOURCES += hdhomerun/hdhomerun_device.c 475 468 476 } 469 477 470 478 # Support for PVR-150/250/350/500, etc. on Linux