dvbcfg_zapchannel.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. /*
  2. * dvbcfg - support for linuxtv configuration files
  3. * zap channel file support
  4. *
  5. * Copyright (C) 2006 Christoph Pfister <christophpfister@gmail.com>
  6. * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2.1 of the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  21. */
  22. #define _GNU_SOURCE
  23. #include <malloc.h>
  24. #include <string.h>
  25. #include <ctype.h>
  26. #include "dvbcfg_zapchannel.h"
  27. #include "dvbcfg_common.h"
  28. static const struct dvbcfg_setting dvbcfg_inversion_list[] = {
  29. { "INVERSION_ON", DVBFE_INVERSION_ON },
  30. { "INVERSION_OFF", DVBFE_INVERSION_OFF },
  31. { "INVERSION_AUTO", DVBFE_INVERSION_AUTO },
  32. { NULL, 0 }
  33. };
  34. static const struct dvbcfg_setting dvbcfg_fec_list[] = {
  35. { "FEC_1_2", DVBFE_FEC_1_2 },
  36. { "FEC_2_3", DVBFE_FEC_2_3 },
  37. { "FEC_3_4", DVBFE_FEC_3_4 },
  38. { "FEC_4_5", DVBFE_FEC_4_5 },
  39. { "FEC_5_6", DVBFE_FEC_5_6 },
  40. { "FEC_6_7", DVBFE_FEC_6_7 },
  41. { "FEC_7_8", DVBFE_FEC_7_8 },
  42. { "FEC_8_9", DVBFE_FEC_8_9 },
  43. { "FEC_AUTO", DVBFE_FEC_AUTO },
  44. { "FEC_NONE", DVBFE_FEC_NONE },
  45. { NULL, 0 }
  46. };
  47. static const struct dvbcfg_setting dvbcfg_dvbc_modulation_list[] = {
  48. { "QAM_16", DVBFE_DVBC_MOD_QAM_16 },
  49. { "QAM_32", DVBFE_DVBC_MOD_QAM_32 },
  50. { "QAM_64", DVBFE_DVBC_MOD_QAM_64 },
  51. { "QAM_128", DVBFE_DVBC_MOD_QAM_128 },
  52. { "QAM_256", DVBFE_DVBC_MOD_QAM_256 },
  53. { "QAM_AUTO", DVBFE_DVBC_MOD_AUTO },
  54. { NULL, 0 }
  55. };
  56. static const struct dvbcfg_setting dvbcfg_bandwidth_list[] = {
  57. { "BANDWIDTH_6_MHZ", DVBFE_DVBT_BANDWIDTH_6_MHZ },
  58. { "BANDWIDTH_7_MHZ", DVBFE_DVBT_BANDWIDTH_7_MHZ },
  59. { "BANDWIDTH_8_MHZ", DVBFE_DVBT_BANDWIDTH_8_MHZ },
  60. { "BANDWIDTH_AUTO", DVBFE_DVBT_BANDWIDTH_AUTO },
  61. { NULL, 0 }
  62. };
  63. static const struct dvbcfg_setting dvbcfg_constellation_list[] = {
  64. { "QAM_16", DVBFE_DVBT_CONST_QAM_16 },
  65. { "QAM_32", DVBFE_DVBT_CONST_QAM_32 },
  66. { "QAM_64", DVBFE_DVBT_CONST_QAM_64 },
  67. { "QAM_128", DVBFE_DVBT_CONST_QAM_128 },
  68. { "QAM_256", DVBFE_DVBT_CONST_QAM_256 },
  69. { "QPSK", DVBFE_DVBT_CONST_QPSK },
  70. { "QAM_AUTO", DVBFE_DVBT_CONST_AUTO },
  71. { NULL, 0 }
  72. };
  73. static const struct dvbcfg_setting dvbcfg_transmission_mode_list[] = {
  74. { "TRANSMISSION_MODE_2K", DVBFE_DVBT_TRANSMISSION_MODE_2K },
  75. { "TRANSMISSION_MODE_8K", DVBFE_DVBT_TRANSMISSION_MODE_8K },
  76. { "TRANSMISSION_MODE_AUTO", DVBFE_DVBT_TRANSMISSION_MODE_AUTO },
  77. { NULL, 0 }
  78. };
  79. static const struct dvbcfg_setting dvbcfg_guard_interval_list[] = {
  80. { "GUARD_INTERVAL_1_32", DVBFE_DVBT_GUARD_INTERVAL_1_32 },
  81. { "GUARD_INTERVAL_1_16", DVBFE_DVBT_GUARD_INTERVAL_1_16 },
  82. { "GUARD_INTERVAL_1_8", DVBFE_DVBT_GUARD_INTERVAL_1_8 },
  83. { "GUARD_INTERVAL_1_4", DVBFE_DVBT_GUARD_INTERVAL_1_4 },
  84. { "GUARD_INTERVAL_AUTO", DVBFE_DVBT_GUARD_INTERVAL_AUTO },
  85. { NULL, 0 }
  86. };
  87. static const struct dvbcfg_setting dvbcfg_hierarchy_list[] = {
  88. { "HIERARCHY_1", DVBFE_DVBT_HIERARCHY_1 },
  89. { "HIERARCHY_2", DVBFE_DVBT_HIERARCHY_2 },
  90. { "HIERARCHY_4", DVBFE_DVBT_HIERARCHY_4 },
  91. { "HIERARCHY_AUTO", DVBFE_DVBT_HIERARCHY_AUTO },
  92. { "HIERARCHY_NONE", DVBFE_DVBT_HIERARCHY_NONE },
  93. { NULL, 0 }
  94. };
  95. static const struct dvbcfg_setting dvbcfg_atsc_modulation_list[] = {
  96. { "8VSB", DVBFE_ATSC_MOD_VSB_8 },
  97. { "16VSB", DVBFE_ATSC_MOD_VSB_16 },
  98. { "QAM_64", DVBFE_ATSC_MOD_QAM_64 },
  99. { "QAM_256", DVBFE_ATSC_MOD_QAM_256 },
  100. { NULL, 0 }
  101. };
  102. int dvbcfg_zapchannel_parse(FILE *file, dvbcfg_zapcallback callback, void *private_data)
  103. {
  104. char *line_buf = NULL;
  105. size_t line_size = 0;
  106. int line_len = 0;
  107. int ret_val = 0;
  108. while ((line_len = getline(&line_buf, &line_size, file)) > 0) {
  109. char *line_tmp = line_buf;
  110. char *line_pos = line_buf;
  111. struct dvbcfg_zapchannel tmp;
  112. /* remove newline and comments (started with hashes) */
  113. while ((*line_tmp != '\0') && (*line_tmp != '\n') && (*line_tmp != '#'))
  114. line_tmp++;
  115. *line_tmp = '\0';
  116. /* parse name */
  117. dvbcfg_parse_string(&line_pos, ":", tmp.name, sizeof(tmp.name));
  118. if (!line_pos)
  119. continue;
  120. /* parse frequency */
  121. tmp.fe_params.frequency = dvbcfg_parse_int(&line_pos, ":");
  122. if (!line_pos)
  123. continue;
  124. /* try to determine frontend type */
  125. if (strstr(line_pos, ":FEC_")) {
  126. if (strstr(line_pos, ":HIERARCHY_"))
  127. tmp.fe_type = DVBFE_TYPE_DVBT;
  128. else
  129. tmp.fe_type = DVBFE_TYPE_DVBC;
  130. } else {
  131. if (strstr(line_pos, "VSB:") || strstr(line_pos, "QAM_"))
  132. tmp.fe_type = DVBFE_TYPE_ATSC;
  133. else
  134. tmp.fe_type = DVBFE_TYPE_DVBS;
  135. }
  136. /* parse frontend specific settings */
  137. switch (tmp.fe_type) {
  138. case DVBFE_TYPE_ATSC:
  139. /* inversion */
  140. tmp.fe_params.inversion = DVBFE_INVERSION_AUTO;
  141. /* modulation */
  142. tmp.fe_params.u.atsc.modulation =
  143. dvbcfg_parse_setting(&line_pos, ":", dvbcfg_atsc_modulation_list);
  144. if (!line_pos)
  145. continue;
  146. break;
  147. case DVBFE_TYPE_DVBC:
  148. /* inversion */
  149. tmp.fe_params.inversion =
  150. dvbcfg_parse_setting(&line_pos, ":", dvbcfg_inversion_list);
  151. if (!line_pos)
  152. continue;
  153. /* symbol rate */
  154. tmp.fe_params.u.dvbc.symbol_rate = dvbcfg_parse_int(&line_pos, ":");
  155. if (!line_pos)
  156. continue;
  157. /* fec */
  158. tmp.fe_params.u.dvbc.fec_inner =
  159. dvbcfg_parse_setting(&line_pos, ":", dvbcfg_fec_list);
  160. if (!line_pos)
  161. continue;
  162. /* modulation */
  163. tmp.fe_params.u.dvbc.modulation =
  164. dvbcfg_parse_setting(&line_pos, ":", dvbcfg_dvbc_modulation_list);
  165. if (!line_pos)
  166. continue;
  167. break;
  168. case DVBFE_TYPE_DVBS:
  169. /* adjust frequency */
  170. tmp.fe_params.frequency *= 1000;
  171. /* inversion */
  172. tmp.fe_params.inversion = DVBFE_INVERSION_AUTO;
  173. /* fec */
  174. tmp.fe_params.u.dvbs.fec_inner = DVBFE_FEC_AUTO;
  175. /* polarization */
  176. tmp.polarization = tolower(dvbcfg_parse_char(&line_pos, ":"));
  177. if (!line_pos)
  178. continue;
  179. if ((tmp.polarization != 'h') &&
  180. (tmp.polarization != 'v') &&
  181. (tmp.polarization != 'l') &&
  182. (tmp.polarization != 'r'))
  183. continue;
  184. /* satellite switch position */
  185. tmp.diseqc_switch = dvbcfg_parse_int(&line_pos, ":");
  186. if (!line_pos)
  187. continue;
  188. /* symbol rate */
  189. tmp.fe_params.u.dvbs.symbol_rate =
  190. dvbcfg_parse_int(&line_pos, ":") * 1000;
  191. if (!line_pos)
  192. continue;
  193. break;
  194. case DVBFE_TYPE_DVBT:
  195. /* inversion */
  196. tmp.fe_params.inversion =
  197. dvbcfg_parse_setting(&line_pos, ":", dvbcfg_inversion_list);
  198. if (!line_pos)
  199. continue;
  200. /* bandwidth */
  201. tmp.fe_params.u.dvbt.bandwidth =
  202. dvbcfg_parse_setting(&line_pos, ":", dvbcfg_bandwidth_list);
  203. if (!line_pos)
  204. continue;
  205. /* fec hp */
  206. tmp.fe_params.u.dvbt.code_rate_HP =
  207. dvbcfg_parse_setting(&line_pos, ":", dvbcfg_fec_list);
  208. if (!line_pos)
  209. continue;
  210. /* fec lp */
  211. tmp.fe_params.u.dvbt.code_rate_LP =
  212. dvbcfg_parse_setting(&line_pos, ":", dvbcfg_fec_list);
  213. if (!line_pos)
  214. continue;
  215. /* constellation */
  216. tmp.fe_params.u.dvbt.constellation =
  217. dvbcfg_parse_setting(&line_pos, ":", dvbcfg_constellation_list);
  218. if (!line_pos)
  219. continue;
  220. /* transmission mode */
  221. tmp.fe_params.u.dvbt.transmission_mode =
  222. dvbcfg_parse_setting(&line_pos, ":", dvbcfg_transmission_mode_list);
  223. if (!line_pos)
  224. continue;
  225. /* guard interval */
  226. tmp.fe_params.u.dvbt.guard_interval =
  227. dvbcfg_parse_setting(&line_pos, ":", dvbcfg_guard_interval_list);
  228. if (!line_pos)
  229. continue;
  230. /* hierarchy */
  231. tmp.fe_params.u.dvbt.hierarchy_information =
  232. dvbcfg_parse_setting(&line_pos, ":", dvbcfg_hierarchy_list);
  233. if (!line_pos)
  234. continue;
  235. break;
  236. }
  237. /* parse video and audio pids and service id */
  238. tmp.video_pid = dvbcfg_parse_int(&line_pos, ":");
  239. if (!line_pos)
  240. continue;
  241. tmp.audio_pid = dvbcfg_parse_int(&line_pos, ":");
  242. if (!line_pos)
  243. continue;
  244. tmp.service_id = dvbcfg_parse_int(&line_pos, ":");
  245. if (!line_pos) /* old files don't have a service id */
  246. tmp.service_id = 0;
  247. /* invoke callback */
  248. if ((ret_val = callback(&tmp, private_data)) != 0) {
  249. if (ret_val < 0)
  250. ret_val = 0;
  251. break;
  252. }
  253. }
  254. if (line_buf)
  255. free(line_buf);
  256. return ret_val;
  257. }
  258. int dvbcfg_zapchannel_save(FILE *file, dvbcfg_zapcallback callback, void *private_data)
  259. {
  260. int ret_val = 0;
  261. struct dvbcfg_zapchannel tmp;
  262. while ((ret_val = callback(&tmp, private_data)) == 0) {
  263. /* name */
  264. if ((ret_val = fprintf(file, "%s:", tmp.name)) < 0)
  265. return ret_val;
  266. /* frontend specific settings */
  267. switch (tmp.fe_type) {
  268. case DVBFE_TYPE_ATSC:
  269. if ((ret_val = fprintf(file, "%i:%s:",
  270. tmp.fe_params.frequency,
  271. dvbcfg_lookup_setting(tmp.fe_params.u.atsc.modulation,
  272. dvbcfg_atsc_modulation_list))) < 0)
  273. return ret_val;
  274. break;
  275. case DVBFE_TYPE_DVBC:
  276. if ((ret_val = fprintf(file, "%i:%s:%i:%s:%s:",
  277. tmp.fe_params.frequency,
  278. dvbcfg_lookup_setting(tmp.fe_params.inversion,
  279. dvbcfg_inversion_list),
  280. tmp.fe_params.u.dvbc.symbol_rate,
  281. dvbcfg_lookup_setting(tmp.fe_params.u.dvbc.fec_inner,
  282. dvbcfg_fec_list),
  283. dvbcfg_lookup_setting(tmp.fe_params.u.dvbc.modulation,
  284. dvbcfg_dvbc_modulation_list))) < 0)
  285. return ret_val;
  286. break;
  287. case DVBFE_TYPE_DVBS:
  288. if ((ret_val = fprintf(file, "%i:%c:%i:%i:",
  289. tmp.fe_params.frequency / 1000,
  290. tolower(tmp.polarization),
  291. tmp.diseqc_switch,
  292. tmp.fe_params.u.dvbs.symbol_rate / 1000)) < 0)
  293. return ret_val;
  294. break;
  295. case DVBFE_TYPE_DVBT:
  296. if ((ret_val = fprintf(file, "%i:%s:%s:%s:%s:%s:%s:%s:%s:",
  297. tmp.fe_params.frequency,
  298. dvbcfg_lookup_setting(tmp.fe_params.inversion,
  299. dvbcfg_inversion_list),
  300. dvbcfg_lookup_setting(tmp.fe_params.u.dvbt.bandwidth,
  301. dvbcfg_bandwidth_list),
  302. dvbcfg_lookup_setting(tmp.fe_params.u.dvbt.code_rate_HP,
  303. dvbcfg_fec_list),
  304. dvbcfg_lookup_setting(tmp.fe_params.u.dvbt.code_rate_LP,
  305. dvbcfg_fec_list),
  306. dvbcfg_lookup_setting(tmp.fe_params.u.dvbt.constellation,
  307. dvbcfg_constellation_list),
  308. dvbcfg_lookup_setting(tmp.fe_params.u.dvbt.transmission_mode,
  309. dvbcfg_transmission_mode_list),
  310. dvbcfg_lookup_setting(tmp.fe_params.u.dvbt.guard_interval,
  311. dvbcfg_guard_interval_list),
  312. dvbcfg_lookup_setting(tmp.fe_params.u.dvbt.hierarchy_information,
  313. dvbcfg_hierarchy_list))) < 0)
  314. return ret_val;
  315. break;
  316. }
  317. /* video and audio pids and service id */
  318. if ((ret_val = fprintf(file, "%i:%i:%i\n",
  319. tmp.video_pid, tmp.audio_pid, tmp.service_id)) < 0)
  320. return ret_val;
  321. }
  322. if (ret_val < 0)
  323. ret_val = 0;
  324. return ret_val;
  325. }