config.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. /*
  2. * Copyright (C) 2003-2006 by egnite Software GmbH
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the copyright holders nor the names of
  16. * contributors may be used to endorse or promote products derived
  17. * from this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  22. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  23. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  24. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  25. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  26. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  27. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  28. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  29. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. * SUCH DAMAGE.
  31. *
  32. * For additional information see http://www.ethernut.de/
  33. */
  34. /*!
  35. * $Id: config.c 4473 2012-08-20 15:12:45Z haraldkipp $
  36. */
  37. #include <sys/types.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <arpa/inet.h>
  41. #include <net/if_var.h>
  42. #include "config.h"
  43. #include <stdio.h>
  44. /*!
  45. * \brief List of radio stations.
  46. */
  47. RADIOSTATION *station;
  48. /*!
  49. * \brief Radio status and control.
  50. */
  51. RADIOCONTROL radio;
  52. /*
  53. * Save a binary into the EEPROM.
  54. */
  55. static int ConfigSaveBinary(int addr, void *val, size_t len)
  56. {
  57. #if defined(__AVR__)
  58. size_t i;
  59. uint8_t *cp = val;
  60. for (i = 0; i < len; cp++, i++)
  61. if (eeprom_read_byte((void *) (addr + i)) != *cp)
  62. eeprom_write_byte((void *) (addr + i), *cp);
  63. #endif /* __AVR__ */
  64. return len;
  65. }
  66. /*
  67. * Save a string into the EEPROM.
  68. */
  69. static int ConfigSaveString(int addr, char * str)
  70. {
  71. int rc = 0;
  72. #if defined(__AVR__)
  73. do {
  74. if (eeprom_read_byte((void *) (addr + rc)) != *str)
  75. eeprom_write_byte((void *) (addr + rc), *str);
  76. rc++;
  77. } while (*str++);
  78. #endif /* __AVR__ */
  79. return rc;
  80. }
  81. /*
  82. * Read a string from EEPROM.
  83. */
  84. static size_t ConfigLoadString(int addr, char * str, size_t size)
  85. {
  86. size_t rc = 0;
  87. #if defined(__AVR__)
  88. while (rc < size) {
  89. *str = eeprom_read_byte((void *) (addr + rc));
  90. rc++;
  91. if (*str++ == 0)
  92. break;
  93. }
  94. #endif /* __AVR__ */
  95. return rc;
  96. }
  97. /*
  98. * Read a binary value from EEPROM.
  99. */
  100. static int ConfigLoadBinary(int addr, void *val, size_t len)
  101. {
  102. #if defined(__AVR__)
  103. size_t i;
  104. uint8_t *cp = val;
  105. for (i = 0; i < len; cp++, i++)
  106. *cp = eeprom_read_byte((void *) (addr + i));
  107. #endif /* __AVR__ */
  108. return len;
  109. }
  110. /*!
  111. * \brief Calculate total size of configuration data.
  112. *
  113. * \return Number of bytes used by configuration data.
  114. */
  115. size_t ConfigSize(void)
  116. {
  117. size_t rc = 0;
  118. uint8_t idx;
  119. RADIOSTATION *rsp;
  120. for (idx = 0; idx < MAXNUM_STATIONS; idx++) {
  121. rsp = &station[idx];
  122. if (station[idx].rs_port == 0)
  123. break;
  124. rc += sizeof(rsp->rs_port);
  125. rc += sizeof(rsp->rs_ip);
  126. if (rsp->rs_url)
  127. rc += strlen(rsp->rs_url);
  128. rc++;
  129. }
  130. rc += sizeof(station[0].rs_port);
  131. return rc;
  132. }
  133. /*!
  134. * \brief Configure a station list entry.
  135. *
  136. * \param idx Index of the entry.
  137. * \param url URL of the station.
  138. *
  139. * \return 0 on success, -1 otherwise.
  140. */
  141. int ConfigStation(uint8_t idx, const char * url)
  142. {
  143. uint32_t ip;
  144. uint16_t port = 80;
  145. char *buf;
  146. char *cp;
  147. if (idx >= MAXNUM_STATIONS) {
  148. idx = 0;
  149. while (idx < MAXNUM_STATIONS && station[idx].rs_port)
  150. idx++;
  151. }
  152. if (idx >= MAXNUM_STATIONS)
  153. return -1;
  154. else {
  155. buf = malloc(strlen(url) + 1);
  156. /* Extract IP address. */
  157. cp = buf;
  158. while (*url && *url != '/' && *url != ':')
  159. *cp++ = *url++;
  160. *cp = 0;
  161. if ((int) (ip = inet_addr(buf)) == -1)
  162. idx = -1;
  163. else {
  164. /* Extract URL path. */
  165. cp = buf;
  166. if (*url == '/') {
  167. url++;
  168. while (*url && *url != ':')
  169. *cp++ = *url++;
  170. }
  171. *cp = 0;
  172. /* Extract port. */
  173. if (*url == ':')
  174. port = atoi(url + 1);
  175. if (port) {
  176. station[idx].rs_ip = ip;
  177. station[idx].rs_port = port;
  178. if (*buf) {
  179. station[idx].rs_url = malloc(strlen(buf) + 1);
  180. strcpy(station[idx].rs_url, buf);
  181. }
  182. }
  183. }
  184. free(buf);
  185. }
  186. return idx;
  187. }
  188. /*
  189. * Allocate heap memory for configuration structure.
  190. */
  191. static void ConfigCreate(void)
  192. {
  193. uint8_t idx;
  194. if (station == 0)
  195. station = malloc(MAXNUM_STATIONS * sizeof(RADIOSTATION));
  196. else {
  197. /* Release all memory occupied by the current configuration. */
  198. for (idx = 0; idx < MAXNUM_STATIONS; idx++) {
  199. if (station[idx].rs_port == 0)
  200. break;
  201. if (station[idx].rs_url)
  202. free(station[idx].rs_url);
  203. }
  204. }
  205. memset(station, 0, MAXNUM_STATIONS * sizeof(RADIOSTATION));
  206. }
  207. /*!
  208. * \brief Reset configuration.
  209. */
  210. void ConfigResetFactory(void)
  211. {
  212. ConfigCreate();
  213. /* Initial radio control settings. */
  214. radio.rc_rstation = 2;
  215. radio.rc_rvolume = 223;
  216. /*
  217. * Add pre-configured radio stations.
  218. */
  219. /* Local server. */
  220. ConfigStation(MAXNUM_STATIONS, "192.168.192.11:8000");
  221. /* elDOradio 56 kbit */
  222. ConfigStation(MAXNUM_STATIONS, "129.217.234.42/128:8000");
  223. /* Virgin 32 kbit. */
  224. ConfigStation(MAXNUM_STATIONS, "212.187.204.62:80");
  225. /* qpop.nl 48 kbit */
  226. ConfigStation(MAXNUM_STATIONS, "194.109.192.226:8010");
  227. /* idobi 24 kbit */
  228. ConfigStation(MAXNUM_STATIONS, "66.28.100.131:8004");
  229. /* Radiosound-7-24 24 kbit. */
  230. ConfigStation(MAXNUM_STATIONS, "64.202.98.51:7650");
  231. /* DH Netradio 56 kbit */
  232. ConfigStation(MAXNUM_STATIONS, "205.188.234.38:8030");
  233. /* Cable radio 56 kbit. */
  234. ConfigStation(MAXNUM_STATIONS, "62.25.96.7:8080");
  235. /* MIBN1 40 kbit. */
  236. ConfigStation(MAXNUM_STATIONS, "216.234.109.21:8000");
  237. /* RFK 56 kbit */
  238. ConfigStation(MAXNUM_STATIONS, "64.202.98.33:2530");
  239. /* Braingell 24 kbit. */
  240. ConfigStation(MAXNUM_STATIONS, "216.237.145.20:8000");
  241. /* HipHop 48 kbit. */
  242. ConfigStation(MAXNUM_STATIONS, "64.202.98.33:6150");
  243. /* Flensburg 56 kbit */
  244. ConfigStation(MAXNUM_STATIONS, "217.160.210.37:8000");
  245. /* Boombastic 24 kbit. */
  246. ConfigStation(MAXNUM_STATIONS, "212.43.230.20:8000");
  247. /* Russia 24 kbit */
  248. ConfigStation(MAXNUM_STATIONS, "62.118.255.5:9000");
  249. /* Frequence3 16 kbit. */
  250. ConfigStation(MAXNUM_STATIONS, "212.180.2.19:8010");
  251. /* KCTI Country 16 kbit. */
  252. ConfigStation(MAXNUM_STATIONS, "63.125.62.117:8000");
  253. /* Klassik 40 kbit. */
  254. ConfigStation(MAXNUM_STATIONS, "62.157.113.86:8000");
  255. /* m2ktalk 8kbit */
  256. ConfigStation(MAXNUM_STATIONS, "209.17.76.226:8010");
  257. /* Christian Media 16 kbit. */
  258. ConfigStation(MAXNUM_STATIONS, "64.202.98.32:6610");
  259. /* Newsradio 24 kbit. */
  260. ConfigStation(MAXNUM_STATIONS, "65.172.162.93:9191");
  261. #ifdef ETHERNUT2
  262. /*
  263. * These stations require Ethernut 2.
  264. */
  265. /* Grapeshot 128 kbit. */
  266. ConfigStation(MAXNUM_STATIONS, "66.28.45.159:8075");
  267. /* Radiostorm 128 kbit. */
  268. ConfigStation(MAXNUM_STATIONS, "64.236.34.141/stream/1014:80");
  269. /* Digitally imported 128 kbit. */
  270. ConfigStation(MAXNUM_STATIONS, "205.188.209.193/stream/1003:80");
  271. /* SmoothJazz 128 kbit */
  272. ConfigStation(MAXNUM_STATIONS, "64.236.34.141/stream/1005:80");
  273. /* Tosh Jamaica 128 kbit. */
  274. ConfigStation(MAXNUM_STATIONS, "38.144.33.148:8022");
  275. /* weird 160 kbit */
  276. ConfigStation(MAXNUM_STATIONS, "209.98.88.40:8007");
  277. /* Stratovarius 192 kbit */
  278. ConfigStation(MAXNUM_STATIONS, "210.120.247.22:1290");
  279. /* Virgin 128 kbit. */
  280. ConfigStation(MAXNUM_STATIONS, "64.236.34.72/stream/1031:80");
  281. /* Virgin 128 kbit. */
  282. ConfigStation(MAXNUM_STATIONS, "64.236.34.141/stream/1031:80");
  283. #endif
  284. }
  285. /*!
  286. * \brief Load configuration from EEPROM.
  287. *
  288. * If no configuration is available, some preconfigured stations
  289. * are loaded.
  290. *
  291. * \return 0 on success, -1 if no configuration data had been found.
  292. */
  293. int ConfigLoad(void)
  294. {
  295. int rc = -1;
  296. int addr = CONFAPP_EE_OFFSET;
  297. char *buf;
  298. uint8_t idx;
  299. RADIOSTATION *rsp;
  300. buf = malloc(MAXLEN_URL + 1);
  301. addr += ConfigLoadString(addr, buf, sizeof(CONFAPP_EE_NAME));
  302. if (strcmp(buf, CONFAPP_EE_NAME) == 0) {
  303. ConfigCreate();
  304. rc = 0;
  305. /*
  306. * Read radio settings from EEPROM.
  307. */
  308. addr += ConfigLoadBinary(addr, &radio.rc_rstation, sizeof(radio.rc_rstation));
  309. addr += ConfigLoadBinary(addr, &radio.rc_rvolume, sizeof(radio.rc_rvolume));
  310. /*
  311. * Read station configuration from EEPROM.
  312. */
  313. for (idx = 0; idx < MAXNUM_STATIONS; idx++) {
  314. rsp = &station[idx];
  315. addr += ConfigLoadBinary(addr, &rsp->rs_port, sizeof(rsp->rs_port));
  316. addr += ConfigLoadBinary(addr, &rsp->rs_ip, sizeof(rsp->rs_ip));
  317. addr += ConfigLoadString(addr, buf, MAXLEN_URL);
  318. if (*buf) {
  319. rsp->rs_url = malloc(strlen(buf) + 1);
  320. strcpy(rsp->rs_url, buf);
  321. }
  322. }
  323. }
  324. free(buf);
  325. return rc;
  326. }
  327. /*!
  328. * \brief Save radio control settings.
  329. *
  330. * Saves currently selected station and volume.
  331. */
  332. void ConfigSaveControl(void)
  333. {
  334. int addr = CONFAPP_EE_OFFSET + sizeof(CONFAPP_EE_NAME);
  335. /* Save radio control. */
  336. addr += ConfigSaveBinary(addr, &radio.rc_cstation, sizeof(radio.rc_cstation));
  337. addr += ConfigSaveBinary(addr, &radio.rc_cvolume, sizeof(radio.rc_cvolume));
  338. }
  339. /*!
  340. * \brief Save configuration in EEPROM.
  341. */
  342. void ConfigSave(void)
  343. {
  344. uint8_t idx;
  345. RADIOSTATION *rsp;
  346. int addr = CONFAPP_EE_OFFSET;
  347. NutNetSaveConfig();
  348. /* Save our name. */
  349. addr += ConfigSaveString(addr, CONFAPP_EE_NAME);
  350. /* Save radio control. */
  351. addr += ConfigSaveBinary(addr, &radio.rc_cstation, sizeof(radio.rc_cstation));
  352. addr += ConfigSaveBinary(addr, &radio.rc_cvolume, sizeof(radio.rc_cvolume));
  353. /* Save stations. */
  354. for (idx = 0; idx < MAXNUM_STATIONS; idx++) {
  355. rsp = &station[idx];
  356. addr += ConfigSaveBinary(addr, &rsp->rs_port, sizeof(rsp->rs_port));
  357. addr += ConfigSaveBinary(addr, &rsp->rs_ip, sizeof(rsp->rs_ip));
  358. if (rsp->rs_url)
  359. addr += ConfigSaveString(addr, rsp->rs_url);
  360. else
  361. addr += ConfigSaveString(addr, "");
  362. }
  363. }