aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
authorDavid Brodski <david@brodski.eu>2011-10-26 00:02:43 +0000
committerDavid Brodski <david@brodski.eu>2011-10-26 00:02:43 +0000
commit9095e6a2fc69654f993c37c0e5e4159dbd88028d (patch)
tree2d1cfed79d7f758c6de4cea0bab66ff2b815306c /src/transport
parentf8473f9b393e7c8ebebbbcd11ffd89de5f4cf1cb (diff)
downloadgnunet-9095e6a2fc69654f993c37c0e5e4159dbd88028d.tar.gz
gnunet-9095e6a2fc69654f993c37c0e5e4159dbd88028d.zip
Bugfix where no data was send. Added restart of helper process when not working anymore.
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/plugin_transport_wlan.c695
1 files changed, 414 insertions, 281 deletions
diff --git a/src/transport/plugin_transport_wlan.c b/src/transport/plugin_transport_wlan.c
index b3faf4480..b4d219f28 100644
--- a/src/transport/plugin_transport_wlan.c
+++ b/src/transport/plugin_transport_wlan.c
@@ -68,6 +68,11 @@
68#define HELLO_BEACON_SCALING_FACTOR 30 68#define HELLO_BEACON_SCALING_FACTOR 30
69 69
70/** 70/**
71 * scaling factor for restarting the helper
72 */
73#define HELPER_RESTART_SCALING_FACTOR 2
74
75/**
71 * max size of fragment queue 76 * max size of fragment queue
72 */ 77 */
73#define FRAGMENT_QUEUE_SIZE 10 78#define FRAGMENT_QUEUE_SIZE 10
@@ -93,8 +98,8 @@
93/** 98/**
94 * LLC fields for better compatibility 99 * LLC fields for better compatibility
95 */ 100 */
96#define WLAN_LLC_DSAP_FIELD 0xf 101#define WLAN_LLC_DSAP_FIELD 0x1f
97#define WLAN_LLC_SSAP_FIELD 0xf 102#define WLAN_LLC_SSAP_FIELD 0x1f
98 103
99 104
100/** 105/**
@@ -251,6 +256,11 @@ struct Plugin
251 char *interface; 256 char *interface;
252 257
253 /** 258 /**
259 * Mode of operation for the helper, 0 = normal, 1 = first loopback, 2 = second loopback
260 */
261 long long unsigned int testmode;
262
263 /**
254 * The mac_address of the wlan card given to us by the helper. 264 * The mac_address of the wlan card given to us by the helper.
255 */ 265 */
256 struct MacAddress mac_address; 266 struct MacAddress mac_address;
@@ -311,9 +321,24 @@ struct Plugin
311 */ 321 */
312struct Finish_send 322struct Finish_send
313{ 323{
324 /**
325 * pointer to the global plugin struct
326 */
314 struct Plugin *plugin; 327 struct Plugin *plugin;
315 char *msgheader; 328
329 /**
330 * head of the next part to send to the helper
331 */
332 char *head_of_next_write;
333
334 /**
335 * Start of the message to send, needed for free
336 */
316 struct GNUNET_MessageHeader *msgstart; 337 struct GNUNET_MessageHeader *msgstart;
338
339 /**
340 * rest size to send
341 */
317 ssize_t size; 342 ssize_t size;
318}; 343};
319 344
@@ -680,6 +705,9 @@ free_session (struct Plugin *plugin, struct Sessionqueue *queue,
680static struct MacEndpoint * 705static struct MacEndpoint *
681create_macendpoint (struct Plugin *plugin, const struct MacAddress *addr); 706create_macendpoint (struct Plugin *plugin, const struct MacAddress *addr);
682 707
708static void
709finish_sending (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
710
683/** 711/**
684 * Generates a nice hexdump of a memory area. 712 * Generates a nice hexdump of a memory area.
685 * 713 *
@@ -1393,6 +1421,328 @@ add_message_for_send (void *cls, const struct GNUNET_MessageHeader *hdr)
1393 set_next_send (plugin); 1421 set_next_send (plugin);
1394} 1422}
1395 1423
1424
1425/**
1426 * We have been notified that wlan-helper has written something to stdout.
1427 * Handle the output, then reschedule this function to be called again once
1428 * more is available.
1429 *
1430 * @param cls the plugin handle
1431 * @param tc the scheduling context
1432 */
1433static void
1434wlan_plugin_helper_read (void *cls,
1435 const struct GNUNET_SCHEDULER_TaskContext *tc)
1436{
1437 struct Plugin *plugin = cls;
1438
1439 plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK;
1440
1441 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
1442 return;
1443
1444 char mybuf[WLAN_MTU + sizeof (struct GNUNET_MessageHeader)];
1445 ssize_t bytes;
1446
1447 bytes =
1448 GNUNET_DISK_file_read (plugin->server_stdout_handle, mybuf,
1449 sizeof (mybuf));
1450 if (bytes <= 0)
1451 {
1452#if DEBUG_wlan
1453 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
1454 _
1455 ("Finished reading from wlan-helper stdout with code: %d\n"),
1456 bytes);
1457#endif
1458 return;
1459 }
1460 GNUNET_SERVER_mst_receive (plugin->suid_tokenizer, NULL, mybuf, bytes,
1461 GNUNET_NO, GNUNET_NO);
1462
1463 GNUNET_assert (plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK);
1464 plugin->server_read_task =
1465 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
1466 plugin->server_stdout_handle,
1467 &wlan_plugin_helper_read, plugin);
1468}
1469
1470/**
1471 * Start the gnunet-wlan-helper process.
1472 *
1473 * @param plugin the transport plugin
1474 * @return GNUNET_YES if process was started, GNUNET_SYSERR on error
1475 */
1476static int
1477wlan_transport_start_wlan_helper (struct Plugin *plugin)
1478{
1479 const char *filenamehw = "gnunet-transport-wlan-helper";
1480 const char *filenameloopback = "gnunet-transport-wlan-helper-dummy";
1481
1482 plugin->server_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_NO, GNUNET_YES);
1483 if (plugin->server_stdout == NULL)
1484 return GNUNET_SYSERR;
1485
1486 plugin->server_stdin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO);
1487 if (plugin->server_stdin == NULL)
1488 return GNUNET_SYSERR;
1489
1490 /* Start the server process */
1491
1492 if (plugin->testmode == 0)
1493 {
1494
1495#if DEBUG_wlan
1496 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
1497 "Starting gnunet-wlan-helper process cmd: %s %s %i\n",
1498 filenamehw, plugin->interface, plugin->testmode);
1499#endif
1500
1501 if (GNUNET_OS_check_helper_binary (filenamehw) == GNUNET_YES)
1502 {
1503 plugin->server_proc =
1504 GNUNET_OS_start_process (plugin->server_stdin, plugin->server_stdout,
1505 filenamehw, filenamehw, plugin->interface,
1506 NULL);
1507 }
1508 else if (GNUNET_OS_check_helper_binary (filenamehw) == GNUNET_NO)
1509 {
1510 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
1511 "gnunet-transport-wlan-helper is not suid, please change it or look at the doku\n");
1512 GNUNET_break (0);
1513 }
1514 else
1515 {
1516 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
1517 "gnunet-transport-wlan-helper not found, please look if it exists and is the $PATH variable!\n");
1518 GNUNET_break (0);
1519 }
1520
1521 }
1522 else if (plugin->testmode == 1)
1523 {
1524
1525#if DEBUG_wlan
1526 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
1527 "Starting gnunet-wlan-helper loopback 1 process cmd: %s %s %i\n",
1528 filenameloopback, plugin->interface, plugin->testmode);
1529#endif
1530
1531 if (GNUNET_OS_check_helper_binary (filenameloopback) != GNUNET_SYSERR)
1532 {
1533 plugin->server_proc =
1534 GNUNET_OS_start_process (plugin->server_stdin, plugin->server_stdout,
1535 filenameloopback, filenameloopback, "1",
1536 NULL);
1537 }
1538 else
1539 {
1540 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
1541 "gnunet-transport-wlan-helper-dummy not found, please look if it exists and is the $PATH variable!\n");
1542 GNUNET_break (0);
1543 }
1544 }
1545 else if (plugin->testmode == 2)
1546 {
1547#if DEBUG_wlan
1548 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
1549 "Starting gnunet-wlan-helper loopback 2 process cmd: %s %s %i\n",
1550 filenameloopback, plugin->interface, plugin->testmode);
1551#endif
1552 if (GNUNET_OS_check_helper_binary (filenameloopback) != GNUNET_SYSERR)
1553 {
1554 plugin->server_proc =
1555 GNUNET_OS_start_process (plugin->server_stdin, plugin->server_stdout,
1556 filenameloopback, filenameloopback, "2",
1557 NULL);
1558 }
1559 else
1560 {
1561 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
1562 "gnunet-transport-wlan-helper-dummy not found, please look if it exists and is in the $PATH variable!\n");
1563 GNUNET_break (0);
1564 }
1565 }
1566 if (plugin->server_proc == NULL)
1567 {
1568#if DEBUG_wlan
1569 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
1570 "Failed to start gnunet-wlan-helper process\n");
1571#endif
1572 return GNUNET_SYSERR;
1573 }
1574
1575 /* Close the write end of the read pipe */
1576 GNUNET_DISK_pipe_close_end (plugin->server_stdout,
1577 GNUNET_DISK_PIPE_END_WRITE);
1578
1579 /* Close the read end of the write pipe */
1580 GNUNET_DISK_pipe_close_end (plugin->server_stdin, GNUNET_DISK_PIPE_END_READ);
1581
1582 plugin->server_stdout_handle =
1583 GNUNET_DISK_pipe_handle (plugin->server_stdout,
1584 GNUNET_DISK_PIPE_END_READ);
1585 plugin->server_stdin_handle =
1586 GNUNET_DISK_pipe_handle (plugin->server_stdin,
1587 GNUNET_DISK_PIPE_END_WRITE);
1588
1589 GNUNET_assert (plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK);
1590
1591#if DEBUG_wlan
1592 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
1593 "Adding server_read_task for the wlan-helper\n");
1594#endif
1595
1596 plugin->server_read_task =
1597 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
1598 plugin->server_stdout_handle,
1599 &wlan_plugin_helper_read, plugin);
1600
1601 return GNUNET_YES;
1602}
1603
1604/**
1605 * Stops the gnunet-wlan-helper process.
1606 *
1607 * @param plugin the transport plugin
1608 * @return GNUNET_YES if process was started, GNUNET_SYSERR on error
1609 */
1610static int
1611wlan_transport_stop_wlan_helper (struct Plugin *plugin)
1612{
1613#if DEBUG_wlan
1614 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
1615 "Stoping WLAN helper process\n");
1616#endif
1617
1618 if (plugin->server_write_delay_task != GNUNET_SCHEDULER_NO_TASK)
1619 {
1620 GNUNET_SCHEDULER_cancel (plugin->server_write_delay_task);
1621 plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK;
1622 }
1623 if (plugin->server_write_task != GNUNET_SCHEDULER_NO_TASK)
1624 {
1625 GNUNET_SCHEDULER_cancel (plugin->server_write_task);
1626 plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
1627 }
1628 if (plugin->server_read_task != GNUNET_SCHEDULER_NO_TASK)
1629 {
1630 GNUNET_SCHEDULER_cancel (plugin->server_read_task);
1631 plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK;
1632 }
1633
1634 GNUNET_DISK_pipe_close (plugin->server_stdout);
1635 GNUNET_DISK_pipe_close (plugin->server_stdin);
1636 GNUNET_OS_process_kill (plugin->server_proc, 9);
1637 GNUNET_OS_process_close (plugin->server_proc);
1638
1639 return GNUNET_YES;
1640}
1641
1642/**
1643 * function for delayed restart of the helper process
1644 * @param cls Finish_send struct if message should be finished
1645 * @param tc TaskContext
1646 */
1647static void
1648delay_restart_helper (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1649{
1650 struct Finish_send *finish = cls;
1651 struct Plugin *plugin;
1652 plugin = finish->plugin;
1653
1654 plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
1655 if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
1656 {
1657 GNUNET_free_non_null(finish->msgstart);
1658 GNUNET_free (finish);
1659 return;
1660 }
1661
1662 wlan_transport_start_wlan_helper(plugin);
1663
1664 if (finish->size != 0)
1665 {
1666 plugin->server_write_task =
1667 GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
1668 plugin->server_stdin_handle,
1669 &finish_sending, finish);
1670 }
1671 else
1672 {
1673 set_next_send (plugin);
1674 GNUNET_free_non_null(finish->msgstart);
1675 GNUNET_free (finish);
1676 }
1677
1678}
1679
1680/**
1681 * Function to restart the helper
1682 * @param plugin pointer to the global plugin struct
1683 * @param finish pointer to the Finish_send struct to finish
1684 */
1685static void
1686restart_helper(struct Plugin *plugin, struct Finish_send *finish)
1687{
1688 static struct GNUNET_TIME_Relative next_try = {1000};
1689 GNUNET_assert(finish != NULL);
1690
1691 wlan_transport_stop_wlan_helper(plugin);
1692 plugin->server_write_task = GNUNET_SCHEDULER_add_delayed (next_try, &delay_restart_helper, finish);
1693 GNUNET_TIME_relative_multiply(next_try, HELPER_RESTART_SCALING_FACTOR);
1694
1695}
1696
1697/**
1698 * function to finish a sending if not all could have been writen befor
1699 * @param cls pointer to the Finish_send struct
1700 * @param tc TaskContext
1701 */
1702static void
1703finish_sending (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1704{
1705 struct Finish_send *finish = cls;
1706 struct Plugin *plugin;
1707 ssize_t bytes;
1708
1709 plugin = finish->plugin;
1710 plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
1711
1712 if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
1713 {
1714 GNUNET_free (finish->msgstart);
1715 GNUNET_free (finish);
1716 return;
1717 }
1718 bytes =
1719 GNUNET_DISK_file_write (plugin->server_stdin_handle, finish->head_of_next_write,
1720 finish->size);
1721
1722 if (bytes != finish->size)
1723 {
1724 if (bytes != GNUNET_SYSERR)
1725 {
1726 finish->head_of_next_write += bytes;
1727 finish->size -= bytes;
1728 plugin->server_write_task =
1729 GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
1730 plugin->server_stdin_handle,
1731 &finish_sending, finish);
1732 }
1733 else
1734 {
1735 restart_helper(plugin, finish);
1736 }
1737 }
1738 else
1739 {
1740 GNUNET_free (finish->msgstart);
1741 GNUNET_free (finish);
1742 set_next_send (plugin);
1743 }
1744}
1745
1396/** 1746/**
1397 * function to send a hello beacon 1747 * function to send a hello beacon
1398 * @param plugin pointer to the plugin struct 1748 * @param plugin pointer to the plugin struct
@@ -1414,6 +1764,7 @@ send_hello_beacon (struct Plugin *plugin)
1414 struct Radiotap_Send *radioHeader; 1764 struct Radiotap_Send *radioHeader;
1415 struct GNUNET_MessageHeader *msgheader2; 1765 struct GNUNET_MessageHeader *msgheader2;
1416 const struct GNUNET_MessageHeader *hello; 1766 const struct GNUNET_MessageHeader *hello;
1767 struct Finish_send * finish;
1417 1768
1418 GNUNET_assert (plugin != NULL); 1769 GNUNET_assert (plugin != NULL);
1419 1770
@@ -1451,14 +1802,22 @@ send_hello_beacon (struct Plugin *plugin)
1451 _ 1802 _
1452 ("Error writing to wlan healper. errno == %d, ERROR: %s\n"), 1803 ("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
1453 errno, strerror (errno)); 1804 errno, strerror (errno));
1805 finish = GNUNET_malloc (sizeof (struct Finish_send));
1806 finish->plugin = plugin;
1807 finish->head_of_next_write = NULL;
1808 finish->size = 0;
1809 finish->msgstart = NULL;
1810 restart_helper(plugin, finish);
1454 1811
1455 } 1812 }
1456 GNUNET_assert (bytes != GNUNET_SYSERR); 1813 else
1457 GNUNET_assert (bytes == size); 1814 {
1815 GNUNET_assert (bytes == size);
1816 set_next_send (plugin);
1817 }
1458 GNUNET_free (msgheader); 1818 GNUNET_free (msgheader);
1459 1819
1460 set_next_beacon_time (plugin); 1820 set_next_beacon_time (plugin);
1461 set_next_send (plugin);
1462} 1821}
1463 1822
1464/** 1823/**
@@ -1618,13 +1977,17 @@ check_fragment_queue (struct Plugin *plugin)
1618/** 1977/**
1619 * Function to send an ack, does not free the ack 1978 * Function to send an ack, does not free the ack
1620 * @param plugin pointer to the plugin 1979 * @param plugin pointer to the plugin
1621 * @param ack pointer to the ack to send
1622 */ 1980 */
1623static void 1981static void
1624send_ack (struct Plugin *plugin, struct AckSendQueue *ack) 1982send_ack (struct Plugin *plugin)
1625{ 1983{
1626 1984
1627 ssize_t bytes; 1985 ssize_t bytes;
1986 struct AckSendQueue *ack;
1987 struct Finish_send * finish;
1988
1989 ack = plugin->ack_send_queue_head;
1990
1628 1991
1629#if DEBUG_wlan 1992#if DEBUG_wlan
1630 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, 1993 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
@@ -1649,52 +2012,19 @@ send_ack (struct Plugin *plugin, struct AckSendQueue *ack)
1649 _ 2012 _
1650 ("Error writing to wlan healper. errno == %d, ERROR: %s\n"), 2013 ("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
1651 errno, strerror (errno)); 2014 errno, strerror (errno));
1652 2015 finish = GNUNET_malloc (sizeof (struct Finish_send));
1653 } 2016 finish->plugin = plugin;
1654 GNUNET_assert (bytes != GNUNET_SYSERR); 2017 finish->head_of_next_write = NULL;
1655 GNUNET_assert (bytes == ntohs (ack->hdr->size)); 2018 finish->size = 0;
1656 set_next_send (plugin); 2019 finish->msgstart = NULL;
1657} 2020 restart_helper(plugin, finish);
1658
1659/**
1660 * function to finish a sending if not all could have been writen befor
1661 * @param cls pointer to the Finish_send struct
1662 * @param tc TaskContext
1663 */
1664static void
1665finish_sending (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1666{
1667 struct Finish_send *finish = cls;
1668 struct Plugin *plugin;
1669 ssize_t bytes;
1670
1671 plugin = finish->plugin;
1672 plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
1673
1674 if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
1675 {
1676 GNUNET_free (finish->msgstart);
1677 GNUNET_free (finish);
1678 return;
1679 }
1680 bytes =
1681 GNUNET_DISK_file_write (plugin->server_stdin_handle, finish->msgheader,
1682 finish->size);
1683 GNUNET_assert (bytes != GNUNET_SYSERR);
1684
1685 if (bytes != finish->size)
1686 {
1687 finish->msgheader = finish->msgheader + bytes;
1688 finish->size = finish->size - bytes;
1689 plugin->server_write_task =
1690 GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
1691 plugin->server_stdin_handle,
1692 &finish_sending, finish);
1693 } 2021 }
1694 else 2022 else
1695 { 2023 {
1696 GNUNET_free (finish->msgstart); 2024 GNUNET_assert (bytes == ntohs (ack->hdr->size));
1697 GNUNET_free (finish); 2025 GNUNET_CONTAINER_DLL_remove (plugin->ack_send_queue_head,
2026 plugin->ack_send_queue_tail, ack);
2027 GNUNET_free (ack);
1698 set_next_send (plugin); 2028 set_next_send (plugin);
1699 } 2029 }
1700} 2030}
@@ -1719,16 +2049,11 @@ do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1719 struct FragmentMessage *fm; 2049 struct FragmentMessage *fm;
1720 struct Finish_send *finish; 2050 struct Finish_send *finish;
1721 struct FragmentMessage_queue *fmq; 2051 struct FragmentMessage_queue *fmq;
1722 struct AckSendQueue *ack;
1723 ssize_t bytes; 2052 ssize_t bytes;
1724 2053
1725 if (plugin->ack_send_queue_head != NULL) 2054 if (plugin->ack_send_queue_head != NULL)
1726 { 2055 {
1727 ack = plugin->ack_send_queue_head; 2056 send_ack (plugin);
1728 GNUNET_CONTAINER_DLL_remove (plugin->ack_send_queue_head,
1729 plugin->ack_send_queue_tail, ack);
1730 send_ack (plugin, ack);
1731 GNUNET_free (ack);
1732 return; 2057 return;
1733 } 2058 }
1734 2059
@@ -1736,6 +2061,7 @@ do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1736 if (GNUNET_TIME_absolute_get_remaining (plugin->beacon_time).rel_value == 0) 2061 if (GNUNET_TIME_absolute_get_remaining (plugin->beacon_time).rel_value == 0)
1737 { 2062 {
1738 send_hello_beacon (plugin); 2063 send_hello_beacon (plugin);
2064 set_next_send(plugin);
1739 return; 2065 return;
1740 } 2066 }
1741 2067
@@ -1765,35 +2091,36 @@ do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1765 bytes = 2091 bytes =
1766 GNUNET_DISK_file_write (plugin->server_stdin_handle, fm->frag, 2092 GNUNET_DISK_file_write (plugin->server_stdin_handle, fm->frag,
1767 fm->size); 2093 fm->size);
1768 if (bytes == GNUNET_SYSERR) 2094
1769 {
1770 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
1771 _
1772 ("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
1773 errno, strerror (errno));
1774 //TODO START NEW WLAN HELPER
1775 /*
1776 * alle sessions beenden
1777 * neu starten (alle 5 sec)
1778 * alles bis dahin ablehnen
1779 */
1780 }
1781 //GNUNET_assert (bytes != GNUNET_SYSERR);
1782 2095
1783 if (bytes != fm->size) 2096 if (bytes != fm->size)
1784 { 2097 {
1785 finish = GNUNET_malloc (sizeof (struct Finish_send)); 2098 finish = GNUNET_malloc (sizeof (struct Finish_send));
1786 finish->plugin = plugin; 2099 finish->plugin = plugin;
1787 finish->msgheader = fm->frag + bytes;
1788 finish->size = fm->size - bytes;
1789 finish->msgstart = (struct GNUNET_MessageHeader *) fm->frag; 2100 finish->msgstart = (struct GNUNET_MessageHeader *) fm->frag;
1790
1791 GNUNET_assert (plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK); 2101 GNUNET_assert (plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK);
1792 2102
1793 plugin->server_write_task = 2103 if (bytes == GNUNET_SYSERR)
1794 GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, 2104 {
1795 plugin->server_stdin_handle, 2105 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
1796 &finish_sending, finish); 2106 _
2107 ("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
2108 errno, strerror (errno));
2109
2110 finish->head_of_next_write = fm->frag;
2111 finish->size = fm->size;
2112 restart_helper(plugin, finish);
2113 }
2114 else
2115 {
2116 finish->head_of_next_write = fm->frag + bytes;
2117 finish->size = fm->size - bytes;
2118 plugin->server_write_task =
2119 GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
2120 plugin->server_stdin_handle,
2121 &finish_sending, finish);
2122 }
2123
1797 fm->frag = NULL; 2124 fm->frag = NULL;
1798 } 2125 }
1799 else 2126 else
@@ -1990,6 +2317,8 @@ free_macendpoint (struct Plugin *plugin, struct MacEndpoint *endpoint)
1990 GNUNET_CONTAINER_DLL_remove (plugin->mac_head, plugin->mac_tail, endpoint); 2317 GNUNET_CONTAINER_DLL_remove (plugin->mac_head, plugin->mac_tail, endpoint);
1991 if (endpoint->timeout_task != GNUNET_SCHEDULER_NO_TASK) 2318 if (endpoint->timeout_task != GNUNET_SCHEDULER_NO_TASK)
1992 GNUNET_SCHEDULER_cancel (endpoint->timeout_task); 2319 GNUNET_SCHEDULER_cancel (endpoint->timeout_task);
2320 plugin->mac_count--;
2321 GNUNET_STATISTICS_set(plugin->env->stats, _("# wlan mac endpoints"), plugin->mac_count, GNUNET_NO);
1993 GNUNET_free (endpoint); 2322 GNUNET_free (endpoint);
1994 2323
1995} 2324}
@@ -2625,6 +2954,7 @@ create_macendpoint (struct Plugin *plugin, const struct MacAddress *addr)
2625 newend); 2954 newend);
2626 2955
2627 plugin->mac_count++; 2956 plugin->mac_count++;
2957 GNUNET_STATISTICS_set(plugin->env->stats, _("# wlan mac endpoints"), plugin->mac_count, GNUNET_NO);
2628 GNUNET_CONTAINER_DLL_insert_tail (plugin->mac_head, plugin->mac_tail, newend); 2958 GNUNET_CONTAINER_DLL_insert_tail (plugin->mac_head, plugin->mac_tail, newend);
2629#if DEBUG_wlan 2959#if DEBUG_wlan
2630 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, 2960 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
@@ -2795,186 +3125,6 @@ wlan_process_helper (void *cls, void *client,
2795} 3125}
2796 3126
2797/** 3127/**
2798 * We have been notified that wlan-helper has written something to stdout.
2799 * Handle the output, then reschedule this function to be called again once
2800 * more is available.
2801 *
2802 * @param cls the plugin handle
2803 * @param tc the scheduling context
2804 */
2805static void
2806wlan_plugin_helper_read (void *cls,
2807 const struct GNUNET_SCHEDULER_TaskContext *tc)
2808{
2809 struct Plugin *plugin = cls;
2810
2811 plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK;
2812
2813 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
2814 return;
2815
2816 char mybuf[WLAN_MTU + sizeof (struct GNUNET_MessageHeader)];
2817 ssize_t bytes;
2818
2819 bytes =
2820 GNUNET_DISK_file_read (plugin->server_stdout_handle, mybuf,
2821 sizeof (mybuf));
2822 if (bytes <= 0)
2823 {
2824#if DEBUG_wlan
2825 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2826 _
2827 ("Finished reading from wlan-helper stdout with code: %d\n"),
2828 bytes);
2829#endif
2830 return;
2831 }
2832 GNUNET_SERVER_mst_receive (plugin->suid_tokenizer, NULL, mybuf, bytes,
2833 GNUNET_NO, GNUNET_NO);
2834
2835 GNUNET_assert (plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK);
2836 plugin->server_read_task =
2837 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
2838 plugin->server_stdout_handle,
2839 &wlan_plugin_helper_read, plugin);
2840}
2841
2842/**
2843 * Start the gnunet-wlan-helper process.
2844 *
2845 * @param plugin the transport plugin
2846 * @param testmode should we use the dummy driver for testing?
2847 * @return GNUNET_YES if process was started, GNUNET_SYSERR on error
2848 */
2849static int
2850wlan_transport_start_wlan_helper (struct Plugin *plugin, int testmode)
2851{
2852 const char *filenamehw = "gnunet-transport-wlan-helper";
2853 const char *filenameloopback = "gnunet-transport-wlan-helper-dummy";
2854
2855 plugin->server_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_NO, GNUNET_YES);
2856 if (plugin->server_stdout == NULL)
2857 return GNUNET_SYSERR;
2858
2859 plugin->server_stdin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO);
2860 if (plugin->server_stdin == NULL)
2861 return GNUNET_SYSERR;
2862
2863 /* Start the server process */
2864
2865 if (testmode == 0)
2866 {
2867
2868#if DEBUG_wlan
2869 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2870 "Starting gnunet-wlan-helper process cmd: %s %s %i\n",
2871 filenamehw, plugin->interface, testmode);
2872#endif
2873
2874 if (GNUNET_OS_check_helper_binary (filenamehw) == GNUNET_YES)
2875 {
2876 plugin->server_proc =
2877 GNUNET_OS_start_process (plugin->server_stdin, plugin->server_stdout,
2878 filenamehw, filenamehw, plugin->interface,
2879 NULL);
2880 }
2881 else if (GNUNET_OS_check_helper_binary (filenamehw) == GNUNET_NO)
2882 {
2883 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
2884 "gnunet-transport-wlan-helper is not suid, please change it or look at the doku\n");
2885 GNUNET_break (0);
2886 }
2887 else
2888 {
2889 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
2890 "gnunet-transport-wlan-helper not found, please look if it exists and is the $PATH variable!\n");
2891 GNUNET_break (0);
2892 }
2893
2894 }
2895 else if (testmode == 1)
2896 {
2897
2898#if DEBUG_wlan
2899 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2900 "Starting gnunet-wlan-helper loopback 1 process cmd: %s %s %i\n",
2901 filenameloopback, plugin->interface, testmode);
2902#endif
2903
2904 if (GNUNET_OS_check_helper_binary (filenameloopback) != GNUNET_SYSERR)
2905 {
2906 plugin->server_proc =
2907 GNUNET_OS_start_process (plugin->server_stdin, plugin->server_stdout,
2908 filenameloopback, filenameloopback, "1",
2909 NULL);
2910 }
2911 else
2912 {
2913 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
2914 "gnunet-transport-wlan-helper-dummy not found, please look if it exists and is the $PATH variable!\n");
2915 GNUNET_break (0);
2916 }
2917 }
2918 else if (testmode == 2)
2919 {
2920#if DEBUG_wlan
2921 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2922 "Starting gnunet-wlan-helper loopback 2 process cmd: %s %s %i\n",
2923 filenameloopback, plugin->interface, testmode);
2924#endif
2925 if (GNUNET_OS_check_helper_binary (filenameloopback) != GNUNET_SYSERR)
2926 {
2927 plugin->server_proc =
2928 GNUNET_OS_start_process (plugin->server_stdin, plugin->server_stdout,
2929 filenameloopback, filenameloopback, "2",
2930 NULL);
2931 }
2932 else
2933 {
2934 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
2935 "gnunet-transport-wlan-helper-dummy not found, please look if it exists and is in the $PATH variable!\n");
2936 GNUNET_break (0);
2937 }
2938 }
2939 if (plugin->server_proc == NULL)
2940 {
2941#if DEBUG_wlan
2942 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2943 "Failed to start gnunet-wlan-helper process\n");
2944#endif
2945 return GNUNET_SYSERR;
2946 }
2947
2948 /* Close the write end of the read pipe */
2949 GNUNET_DISK_pipe_close_end (plugin->server_stdout,
2950 GNUNET_DISK_PIPE_END_WRITE);
2951
2952 /* Close the read end of the write pipe */
2953 GNUNET_DISK_pipe_close_end (plugin->server_stdin, GNUNET_DISK_PIPE_END_READ);
2954
2955 plugin->server_stdout_handle =
2956 GNUNET_DISK_pipe_handle (plugin->server_stdout,
2957 GNUNET_DISK_PIPE_END_READ);
2958 plugin->server_stdin_handle =
2959 GNUNET_DISK_pipe_handle (plugin->server_stdin,
2960 GNUNET_DISK_PIPE_END_WRITE);
2961
2962 GNUNET_assert (plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK);
2963
2964#if DEBUG_wlan
2965 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2966 "Adding server_read_task for the wlan-helper\n");
2967#endif
2968
2969 plugin->server_read_task =
2970 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
2971 plugin->server_stdout_handle,
2972 &wlan_plugin_helper_read, plugin);
2973
2974 return GNUNET_YES;
2975}
2976
2977/**
2978 * Exit point from the plugin. 3128 * Exit point from the plugin.
2979 * @param cls pointer to the api struct 3129 * @param cls pointer to the api struct
2980 */ 3130 */
@@ -2993,10 +3143,7 @@ libgnunet_plugin_transport_wlan_done (void *cls)
2993 "libgnunet_plugin_transport_wlan_done started\n"); 3143 "libgnunet_plugin_transport_wlan_done started\n");
2994#endif 3144#endif
2995 3145
2996 GNUNET_DISK_pipe_close (plugin->server_stdout); 3146 wlan_transport_stop_wlan_helper(plugin);
2997 GNUNET_DISK_pipe_close (plugin->server_stdin);
2998 GNUNET_OS_process_kill (plugin->server_proc, 9);
2999 GNUNET_OS_process_close (plugin->server_proc);
3000 3147
3001 GNUNET_assert (cls != NULL); 3148 GNUNET_assert (cls != NULL);
3002 //free sessions 3149 //free sessions
@@ -3007,21 +3154,7 @@ libgnunet_plugin_transport_wlan_done (void *cls)
3007 endpoint = endpoint_next; 3154 endpoint = endpoint_next;
3008 3155
3009 } 3156 }
3010 if (plugin->server_write_delay_task != GNUNET_SCHEDULER_NO_TASK) 3157
3011 {
3012 GNUNET_SCHEDULER_cancel (plugin->server_write_delay_task);
3013 plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK;
3014 }
3015 if (plugin->server_write_task != GNUNET_SCHEDULER_NO_TASK)
3016 {
3017 GNUNET_SCHEDULER_cancel (plugin->server_write_task);
3018 plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
3019 }
3020 if (plugin->server_read_task != GNUNET_SCHEDULER_NO_TASK)
3021 {
3022 GNUNET_SCHEDULER_cancel (plugin->server_read_task);
3023 plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK;
3024 }
3025 3158
3026 if (plugin->suid_tokenizer != NULL) 3159 if (plugin->suid_tokenizer != NULL)
3027 GNUNET_SERVER_mst_destroy (plugin->suid_tokenizer); 3160 GNUNET_SERVER_mst_destroy (plugin->suid_tokenizer);
@@ -3048,7 +3181,6 @@ libgnunet_plugin_transport_wlan_init (void *cls)
3048 struct GNUNET_TRANSPORT_PluginEnvironment *env = cls; 3181 struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
3049 struct GNUNET_TRANSPORT_PluginFunctions *api; 3182 struct GNUNET_TRANSPORT_PluginFunctions *api;
3050 struct Plugin *plugin; 3183 struct Plugin *plugin;
3051 static unsigned long long testmode = 0;
3052 3184
3053 GNUNET_assert (cls != NULL); 3185 GNUNET_assert (cls != NULL);
3054 3186
@@ -3057,6 +3189,7 @@ libgnunet_plugin_transport_wlan_init (void *cls)
3057 plugin->pendingsessions = 0; 3189 plugin->pendingsessions = 0;
3058 GNUNET_STATISTICS_set(plugin->env->stats, _("# wlan pending sessions"), plugin->pendingsessions, GNUNET_NO); 3190 GNUNET_STATISTICS_set(plugin->env->stats, _("# wlan pending sessions"), plugin->pendingsessions, GNUNET_NO);
3059 plugin->mac_count = 0; 3191 plugin->mac_count = 0;
3192 GNUNET_STATISTICS_set(plugin->env->stats, _("# wlan mac endpoints"), plugin->mac_count, GNUNET_NO);
3060 plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK; 3193 plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
3061 plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK; 3194 plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK;
3062 plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK; 3195 plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK;
@@ -3086,8 +3219,8 @@ libgnunet_plugin_transport_wlan_init (void *cls)
3086 { 3219 {
3087 if (GNUNET_SYSERR == 3220 if (GNUNET_SYSERR ==
3088 GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-wlan", 3221 GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-wlan",
3089 "TESTMODE", &testmode)) 3222 "TESTMODE", &(plugin->testmode)))
3090 testmode = 0; //default value 3223 plugin->testmode = 0; //default value
3091 } 3224 }
3092 3225
3093 if (GNUNET_CONFIGURATION_have_value (env->cfg, "transport-wlan", "INTERFACE")) 3226 if (GNUNET_CONFIGURATION_have_value (env->cfg, "transport-wlan", "INTERFACE"))
@@ -3102,7 +3235,7 @@ libgnunet_plugin_transport_wlan_init (void *cls)
3102 } 3235 }
3103 3236
3104 //start the plugin 3237 //start the plugin
3105 wlan_transport_start_wlan_helper (plugin, testmode); 3238 wlan_transport_start_wlan_helper (plugin);
3106 set_next_beacon_time (plugin); 3239 set_next_beacon_time (plugin);
3107 set_next_send(plugin); 3240 set_next_send(plugin);
3108#if DEBUG_wlan 3241#if DEBUG_wlan