session.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. /*
  2. * Copyright STREAMIT BV, 2010.
  3. *
  4. * Project : SIR
  5. * Module : Session
  6. * File name $Workfile: Session.c $
  7. * Last Save $Date: 2003/08/16 $
  8. * $Revision: 0.1 $
  9. * Creation Date : 2003/08/16
  10. *
  11. * Description : Handles the connection to the Internet via
  12. * ethernet or modem/ppp
  13. *
  14. */
  15. #define LOG_MODULE LOG_SESSION_MODULE
  16. /*--------------------------------------------------------------------------*/
  17. /* Include files */
  18. /*--------------------------------------------------------------------------*/
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <io.h>
  22. #include <fcntl.h>
  23. #include <dev/nicrtl.h>
  24. #include <dev/uartavr.h>
  25. #include <dev/ppp.h>
  26. #include <sys/heap.h>
  27. #include <sys/thread.h>
  28. #include <sys/timer.h>
  29. #include <sys/confnet.h>
  30. #include <netdb.h>
  31. #include <net/route.h>
  32. #include <arpa/inet.h>
  33. #include <pro/httpd.h>
  34. #include <pro/dhcp.h>
  35. #ifdef NUTDEBUG
  36. #include <sys/osdebug.h>
  37. #include <net/netdebug.h>
  38. #endif
  39. #include <sys/confos.h>
  40. //#pragma text:appcode
  41. #include "system.h"
  42. #include "session.h"
  43. #include "log.h"
  44. //#include "settings.h"
  45. #include "display.h"
  46. #include "version.h"
  47. /*!
  48. * \addtogroup Session
  49. */
  50. /*@{*/
  51. /*--------------------------------------------------------------------------*/
  52. /* Constant definitions */
  53. /*--------------------------------------------------------------------------*/
  54. /*!\brief Ethernet chip definitions */
  55. #define ETH0_BASE 0xC300
  56. #define ETH0_IRQ 5
  57. /*--------------------------------------------------------------------------*/
  58. /* Type declarations */
  59. /*--------------------------------------------------------------------------*/
  60. /*!\brief State of this module */
  61. typedef enum T_SESSION_STATE
  62. {
  63. STATE_IDLE = 0, /* We are idle */
  64. STATE_STARTING, /* We're setting up the session */
  65. STATE_OPEN, /* We have a session */
  66. STATE_STOPPING /* We're stopping */
  67. } TStreamerState;
  68. /*--------------------------------------------------------------------------*/
  69. /* Local variables */
  70. /*--------------------------------------------------------------------------*/
  71. /*!\brief Uart device */
  72. static FILE *g_pUart;
  73. /*!\brief Name of the ethernet device */
  74. static char szEthernetIfName[sizeof(devEth0.dev_name)];
  75. /*!\brief Global error code. */
  76. static TError g_tError;
  77. /*--------------------------------------------------------------------------*/
  78. /* Global variables */
  79. /*--------------------------------------------------------------------------*/
  80. /*--------------------------------------------------------------------------*/
  81. /* Local functions */
  82. /*--------------------------------------------------------------------------*/
  83. static void SetDhcpDnsServers(u_long dwDns1, u_long dwDns2);
  84. static void SetFixedDnsServers(void);
  85. static INLINE TError NetConfig(CONST char *szIfName);
  86. /*!
  87. * \brief Set and save DNS server settings
  88. *
  89. * If no servers are specified, NutOS is asked
  90. * for the DNS servers. If NutOS doesn't have any,
  91. * we retrieve the previously saved servers
  92. * Finally, the servers that are current, are stored
  93. * in the settings and NutOS itself
  94. *
  95. * \param dwDns1 IP address of first DNS server
  96. * \param dwDns2 IP address of second DNS server
  97. *
  98. * \return -
  99. */
  100. static void SetDhcpDnsServers(u_long dwDns1, u_long dwDns2)
  101. {
  102. // //char szDns[sizeof(SETTINGS_POINTER->Isp.szDns1)];
  103. // /*
  104. // * If not specified get current DNS' from NutOs
  105. // */
  106. // if ((dwDns1 == 0) && (dwDns2 == 0))
  107. // {
  108. // NutGetDnsServers(&dwDns1, &dwDns2);
  109. // }
  110. // /*
  111. // * If still no DNS servers, get previously saved config
  112. // */
  113. // if ((dwDns1 == 0) && (dwDns2 == 0))
  114. // {
  115. // //SettingsGet(szDns, &SETTINGS_POINTER->Isp.szDns1, sizeof(szDns));
  116. // if ((dwDns1 = inet_addr(szDns)) == (u_long)-1)
  117. // {
  118. // dwDns1 = 0;
  119. // }
  120. // //SettingsGet(szDns, &SETTINGS_POINTER->Isp.szDns2, sizeof(szDns));
  121. // if ((dwDns2 = inet_addr(szDns)) == (u_long)-1)
  122. // {
  123. // dwDns2 = 0;
  124. // }
  125. // }
  126. // /*
  127. // * Save DNS servers and let NutOs use them
  128. // */
  129. // if ((dwDns1 != 0) || (dwDns2 != 0))
  130. // {
  131. // strcpy(szDns, inet_ntoa(dwDns1));
  132. // //SettingsSet(szDns, &SETTINGS_POINTER->Isp.szDns1, sizeof(szDns));
  133. // strcpy(szDns, inet_ntoa(dwDns2));
  134. // //SettingsSet(szDns, &SETTINGS_POINTER->Isp.szDns2, sizeof(szDns));
  135. // NutDnsConfig2(0, 0, dwDns1, dwDns2);
  136. // }
  137. }
  138. static void SetFixedDnsServers(void)
  139. {
  140. // u_long dwDns1, dwDns2;
  141. // char szDns[sizeof(SETTINGS_POINTER->Isp.szDns1)];
  142. // //SettingsGet(szDns, &SETTINGS_POINTER->Isp.szDns1, sizeof(szDns));
  143. // if ((dwDns1 = inet_addr(szDns)) == (u_long)-1)
  144. // {
  145. // dwDns1 = 0;
  146. // }
  147. // //SettingsGet(szDns, &SETTINGS_POINTER->Isp.szDns2, sizeof(szDns));
  148. // if ((dwDns2 = inet_addr(szDns)) == (u_long)-1)
  149. // {
  150. // dwDns2 = 0;
  151. // }
  152. // NutDnsConfig2(0, 0, dwDns1, dwDns2);
  153. }
  154. static void TryGetDhcp(u_long timeout)
  155. {
  156. /*
  157. * Make sure DHCP is started by setting the
  158. * *CONFIGURED* IP address to zero.
  159. * AND erase the previous IP address, just in case
  160. * our MAC address changed.
  161. */
  162. confnet.cdn_cip_addr = 0;
  163. confnet.cdn_ip_addr = 0;
  164. confnet.cdn_ip_mask = 0;
  165. #ifdef NUTDEBUG
  166. NutTraceTcp(stdout, 1);
  167. NutTraceHeap(stdout, 0); // doesn't function !!
  168. NutTraceOs(stdout, 0); // doesn't function !!
  169. #endif
  170. /*
  171. * Start DHCP, and wait for the answer (or timeout)
  172. */
  173. LogMsg_P(LOG_DEBUG, PSTR("DHCP client started"));
  174. if (NutDhcpIfConfig(szEthernetIfName, confnet.cdn_mac, timeout))
  175. {
  176. LogMsg_P(LOG_DEBUG, PSTR("No DHCP address retrieved"));
  177. }
  178. else
  179. {
  180. LogMsg_P(LOG_INFO, PSTR("Ethernet interface %s ready"), inet_ntoa(confnet.cdn_ip_addr));
  181. #ifdef NUTDEBUG
  182. NutTraceTcp(stdout, 0);
  183. NutTraceHeap(stdout, 0);
  184. NutTraceOs(stdout, 0);
  185. #endif
  186. }
  187. }
  188. /*!
  189. * \brief Configures the ethernet interface
  190. *
  191. * Send out a DHCP request.
  192. * An error is returned if no response from a DHCP server
  193. * was received
  194. *
  195. * \param szIfName Name of the device.
  196. *
  197. * \return OK if success, TError otherwise
  198. */
  199. static INLINE TError NetConfig(CONST char *szIfName)
  200. {
  201. // u_long ulMac;
  202. // u_long ulSerialNumber;
  203. // u_long ulIpAddress;
  204. // u_char byTempValue;
  205. // char szIp[sizeof(SETTINGS_POINTER->Isp.szIp)];
  206. // LogMsg_P(LOG_DEBUG, PSTR("Configuring ethernet %s"), szIfName);
  207. // /*
  208. // * LAN configuration using EEPROM values or DHCP/ARP method.
  209. // * If it fails, use fixed values.
  210. // */
  211. // if (NutNetLoadConfig(szIfName) != 0)
  212. // {
  213. // /*
  214. // * No previous config, ignore
  215. // */
  216. // }
  217. // /*
  218. // * Override any previously used MAC address by
  219. // * the one from our own setup
  220. // *
  221. // * The MAC address is 00:xx:xx:0y:yy:yy
  222. // * where x = 4 digits from the IEEE assigned adres
  223. // * y = 5 digits from our serial number
  224. // */
  225. // ulMac = SettingsGetMacIeee();
  226. // ulMac = __byte_swap4(ulMac) >> 8;
  227. // memcpy(confnet.cdn_mac, &ulMac, sizeof(confnet.cdn_mac)/2);
  228. // //ulSerialNumber = SettingsGetSerialnumber();
  229. // ulSerialNumber = __byte_swap4(ulSerialNumber) >> 8;
  230. // memcpy(&confnet.cdn_mac[sizeof(confnet.cdn_mac)/2], &ulSerialNumber, sizeof(confnet.cdn_mac)/2);
  231. // LogMsg_P(LOG_INFO, PSTR("MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x"),
  232. // confnet.cdn_mac[0],
  233. // confnet.cdn_mac[1],
  234. // confnet.cdn_mac[2],
  235. // confnet.cdn_mac[3],
  236. // confnet.cdn_mac[4],
  237. // confnet.cdn_mac[5]);
  238. // /*
  239. // * Save the new MAC address
  240. // */
  241. // NutNetSaveConfig();
  242. // /*
  243. // * Bring up the network.
  244. // * Use fixed settings if DHCP is disabled.
  245. // * If the fixed IP address is invalid use DHCP anyway.
  246. // */
  247. // //SettingsGet(szIp, &SETTINGS_POINTER->Isp.szIp, sizeof(szIp));
  248. // ulIpAddress = inet_addr(szIp);
  249. // if (ulIpAddress == -1)
  250. // {
  251. // ulIpAddress = 0;
  252. // }
  253. // //SettingsGet(&byTempValue, &SETTINGS_POINTER->Isp.bDhcp, sizeof(byTempValue));
  254. // if ((byTempValue == 0) &&
  255. // (ulIpAddress != 0))
  256. // {
  257. // /*
  258. // * Use fixed settings.
  259. // */
  260. // LogMsg_P(LOG_INFO, PSTR("Fixed IP address used"));
  261. // confnet.cdn_cip_addr = inet_addr(szIp);
  262. // //SettingsGet(szIp, &SETTINGS_POINTER->Isp.szGateway, sizeof(szIp));
  263. // confnet.cdn_gateway = inet_addr(szIp);
  264. // if (confnet.cdn_gateway == -1)
  265. // {
  266. // confnet.cdn_gateway = 0;
  267. // }
  268. // //SettingsGet(szIp, &SETTINGS_POINTER->Isp.szNetmask, sizeof(szIp));
  269. // confnet.cdn_ip_mask = inet_addr(szIp);
  270. // if (confnet.cdn_ip_mask == -1)
  271. // {
  272. // confnet.cdn_ip_mask = 0;
  273. // }
  274. // if (NutNetIfConfig(szIfName, confnet.cdn_mac, confnet.cdn_cip_addr, confnet.cdn_ip_mask) == 0)
  275. // {
  276. // NUTDEVICE *dev;
  277. // /*
  278. // * Add the default route
  279. // */
  280. // if ((dev = NutDeviceLookup(szIfName)) != 0 && dev->dev_type == IFTYP_NET)
  281. // {
  282. // NutIpRouteAdd(0, 0, confnet.cdn_gateway, dev);
  283. // }
  284. // LogMsg_P(LOG_INFO, PSTR("Ethernet interface %s ready"), inet_ntoa(confnet.cdn_ip_addr));
  285. // }
  286. // else
  287. // {
  288. // LogMsg_P(LOG_ERR, PSTR("Incorrect static Ip settings"));
  289. // }
  290. // SetFixedDnsServers();
  291. // }
  292. // else
  293. // {
  294. // /*
  295. // * Use DHCP.
  296. // */
  297. // TryGetDhcp(20000L);
  298. // SetDhcpDnsServers(0,0);
  299. // }
  300. return(OK);
  301. }
  302. /*!
  303. * \brief Starts the ethernet interface
  304. *
  305. * Waits for DHCP to finish configuring the interface
  306. * If that doesn't happen the interface is configured
  307. * using the previous settings.
  308. *
  309. * \return OK if success, TError otherwise
  310. */
  311. static INLINE TError StartNet(void)
  312. {
  313. TError tError = OK;
  314. u_char byTempValue = 0;
  315. /*
  316. * Check if we use DHCP
  317. */
  318. //SettingsGet(&byTempValue, &SETTINGS_POINTER->Isp.bDhcp, sizeof(byTempValue));
  319. if (byTempValue != 0)
  320. {
  321. if (NutDhcpIsConfigured() == 0)
  322. {
  323. if (NutNetLoadConfig(szEthernetIfName) ||
  324. NutNetIfConfig(szEthernetIfName, confnet.cdn_mac, confnet.cdn_ip_addr, confnet.cdn_ip_mask))
  325. {
  326. LogMsg_P(LOG_ERR, PSTR("No usable network"));
  327. tError = SESSION_NODHCP_NOEEPROM;
  328. }
  329. else
  330. {
  331. NUTDEVICE *dev;
  332. /*
  333. * Add the default route
  334. */
  335. if ((dev = NutDeviceLookup(szEthernetIfName)) != 0 && dev->dev_type == IFTYP_NET)
  336. {
  337. NutIpRouteAdd(0, 0, confnet.cdn_gateway, dev);
  338. }
  339. LogMsg_P(LOG_WARNING, PSTR("No DHCP response, trying previous network settings..."));
  340. }
  341. /*
  342. * Set current DNS servers
  343. */
  344. SetDhcpDnsServers(0, 0);
  345. }
  346. }
  347. /*
  348. * Stop all debugging
  349. */
  350. #ifdef NUTDEBUG
  351. NutTraceTcp(stdout, 0);
  352. NutTraceHeap(stdout, 0);
  353. NutTraceOs(stdout, 0);
  354. #endif
  355. return(tError);
  356. }
  357. /*--------------------------------------------------------------------------*/
  358. /* Global functions */
  359. /*--------------------------------------------------------------------------*/
  360. /*!
  361. * \brief Initialises this module
  362. *
  363. * \note With NutOS 3.2.1 it is not possible
  364. * to have both a ppp and eth0 device
  365. * registered at the same time and still
  366. * have DHCP working.
  367. * So switching interface is currently
  368. * a reason for reboot!
  369. *
  370. * \return OK if success, TError otherwise
  371. */
  372. TError SessionInit(void)
  373. {
  374. TError tError = OK;
  375. /*
  376. * Initialise globals
  377. */
  378. g_pUart = 0;
  379. g_tError = OK;
  380. strncpy_P(szEthernetIfName, PSTR("eth0"), sizeof(szEthernetIfName));
  381. /*
  382. * Create a unique hostname from our serial number
  383. * Save the hostname in NutOS
  384. */
  385. //sprintf_P(confos.hostname, PSTR("%.10s%5.5lX"), VersionGetAppProductName(), SettingsGetSerialnumber());
  386. NutSaveConfig();
  387. /*
  388. * Try to bring up the selected
  389. * interface. Error if none configured
  390. */
  391. /*
  392. * Register Realtek controller
  393. */
  394. if (NutRegisterDevice(&devEth0, ETH0_BASE, ETH0_IRQ))
  395. {
  396. LogMsg_P(LOG_EMERG, PSTR("Registering ethernet failed"));
  397. tError = SESSION_NODEVICE;
  398. }
  399. else
  400. {
  401. /* Let the chip settle down from init */
  402. NutSleep(1000);
  403. }
  404. /*
  405. * If we have an ethernet interface start it on init
  406. */
  407. if (tError == OK)
  408. {
  409. tError = NetConfig(szEthernetIfName);
  410. }
  411. g_tError = tError;
  412. return(tError);
  413. }
  414. /*!
  415. * \brief Opens a session
  416. *
  417. * If this succeeds you can start communicating
  418. * to the Internet
  419. *
  420. * \return OK if success, TError otherwise
  421. */
  422. TError SessionOpen(void)
  423. {
  424. TError tError = OK;
  425. g_tError = OK;
  426. /*
  427. * Try to bring up the selected
  428. * interface. Error if none configured
  429. */
  430. tError = StartNet();
  431. /*
  432. * Display our network settings
  433. */
  434. if (tError == OK)
  435. {
  436. u_long ulPrimaryDNS;
  437. u_long ulSecondaryDNS;
  438. /*
  439. * Display our IP settings.
  440. */
  441. LogMsg_P(LOG_INFO, PSTR(" Local IP: %s"), inet_ntoa(confnet.cdn_ip_addr));
  442. LogMsg_P(LOG_INFO, PSTR("Gateway IP: %s"), inet_ntoa(confnet.cdn_gateway));
  443. NutGetDnsServers(&ulPrimaryDNS, &ulSecondaryDNS);
  444. LogMsg_P(LOG_INFO, PSTR(" Pri. DNS: %s"), inet_ntoa(ulPrimaryDNS));
  445. LogMsg_P(LOG_INFO, PSTR(" Sec. DNS: %s"), inet_ntoa(ulSecondaryDNS));
  446. }
  447. g_tError = tError;
  448. return(tError);
  449. }
  450. /*!
  451. * \brief Return the session status
  452. *
  453. * Call to check the status of a session.
  454. *
  455. * \return see above
  456. */
  457. TError SessionStatus(void)
  458. {
  459. return(g_tError);
  460. }
  461. /*!
  462. * \brief Stop the session
  463. *
  464. * \return OK if success, TError otherwise
  465. */
  466. TError SessionClose(void)
  467. {
  468. g_tError = USER_ABORT;
  469. return(OK);
  470. }
  471. /*@}*/