- struct MacEndpoint *next;
- /**
- * dll prev
- */
- struct MacEndpoint *prev;
-
- /**
- * peer mac address
- */
- struct MacAddress addr;
-
- /**
- * Defrag context for this mac endpoint
- */
- struct GNUNET_DEFRAGMENT_Context *defrag;
-
- /**
- * count of messages in the fragment out queue for this mac endpoint
- */
-
- int fragment_messages_out_count;
-
- //TODO DOXIGEN
- uint8_t rate;
- uint16_t tx_power;
- uint8_t antenna;
-
- /**
- * Duplicates received
- */
- int dups;
-
- /**
- * Fragments received
- */
- int fragc;
-
- /**
- * Acks received
- */
- int acks;
-
- /**
- * Last activity on this endpoint. Used to select preferred
- * connection.
- */
- struct GNUNET_TIME_Absolute last_activity;
-
- /**
- * Timeout task.
- */
- GNUNET_SCHEDULER_TaskIdentifier timeout_task;
-};
-
-/**
- * Struct for Messages in the fragment queue
- */
-struct FragmentMessage
-{
-
- /**
- * Session this message belongs to
- */
- struct Session *session;
-
- /**
- * This is a doubly-linked list.
- */
- struct FragmentMessage *next;
-
- /**
- * This is a doubly-linked list.
- */
- struct FragmentMessage *prev;
-
- /**
- * Fragmentation context
- */
- struct GNUNET_FRAGMENT_Context *fragcontext;
-
- /**
- * Timeout value for the message.
- */
- struct GNUNET_TIME_Absolute timeout;
-
- /**
- * Timeout task.
- */
- GNUNET_SCHEDULER_TaskIdentifier timeout_task;
-
- /**
- * Fragment to send
- */
- char *frag;
-
- /**
- * size of message
- */
- size_t size;
-
- /**
- * pointer to the ieee wlan header
- */
- struct ieee80211_frame *ieeewlanheader;
- /**
- * pointer to the radiotap header
- */
- struct Radiotap_Send *radioHeader;
-};
-
-static void
-do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
-
-static void
-free_session (struct Plugin *plugin, struct Sessionqueue *queue,
- int do_free_macendpoint);
-
-static struct MacEndpoint *
-create_macendpoint (struct Plugin *plugin, const struct MacAddress *addr);
-
-static void
-finish_sending (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
-
-/**
- * Generates a nice hexdump of a memory area.
- *
- * \param mem pointer to memory to dump
- * \param length how many bytes to dump
- */
-static void
-hexdump (const void *mem, unsigned length)
-{
- char line[80];
- char *src = (char *) mem;
-
- printf ("dumping %u bytes from %p\r\n"
- " 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF\r\n",
- length, src);
- unsigned i;
- int j;
-
- for (i = 0; i < length; i += 16, src += 16)
- {
- char *t = line;
-
- t += sprintf (t, "%04x: ", i);
- for (j = 0; j < 16; j++)
- {
- if (i + j < length)
- t += sprintf (t, "%02X", src[j] & 0xff);
- else
- t += sprintf (t, " ");
-
- t += sprintf (t, j % 2 ? " " : "-");
- }
-
- t += sprintf (t, " ");
- for (j = 0; j < 16; j++)
- {
- if (i + j < length)
- {
- if (isprint ((unsigned char) src[j]))
- t += sprintf (t, "%c", src[j]);
- else
- t += sprintf (t, ".");
- }
- else
- {
- t += sprintf (t, " ");
- }
- }
-
- t += sprintf (t, "\r\n");
- printf ("%s", line);
- }
-}
-
-/**
- * Function to find a MacEndpoint with a specific mac addr
- * @param plugin pointer to the plugin struct
- * @param addr pointer to the mac address
- * @param create_new GNUNET_YES if a new end point should be created
- * @return
- */
-static struct MacEndpoint *
-get_macendpoint (struct Plugin *plugin, const struct MacAddress *addr,
- int create_new)
-{
- struct MacEndpoint *queue = plugin->mac_head;
-
- while (queue != NULL)
- {
- //GNUNET_assert (queue->sessions_head != NULL);
- if (memcmp (addr, &queue->addr, sizeof (struct MacAddress)) == 0)
- return queue; /* session found */
- queue = queue->next;
- }
-
- if (create_new == GNUNET_YES)
- {
- return create_macendpoint (plugin, addr);
- }
- else
- {
- return NULL;
- }
-
-}
-
-/**
- * search for a session with the macendpoint and peer id
- *
- * @param plugin pointer to the plugin struct
- * @param endpoint pointer to the mac endpoint of the peer
- * @param peer pointer to the peerid
- * @return returns the session
- */
-static struct Session *
-search_session (struct Plugin *plugin, const struct MacEndpoint *endpoint,
- const struct GNUNET_PeerIdentity *peer)
-{
- GNUNET_assert (endpoint != NULL);
- struct Sessionqueue *queue = endpoint->sessions_head;
-
- while (queue != NULL)
- {
- GNUNET_assert (queue->content != NULL);
- if (memcmp
- (peer, &queue->content->target,
- sizeof (struct GNUNET_PeerIdentity)) == 0)
- return queue->content; /* session found */
- queue = queue->next;
- }
- return NULL;
-}
-
-/**
- * Function called for a quick conversion of the binary address to
- * a numeric address. Note that the caller must not free the
- * address and that the next call to this function is allowed
- * to override the address again.
- *
- * @param cls closure
- * @param addr binary address
- * @param addrlen length of the address
- * @return string representing the same address
- */
-static const char *
-wlan_plugin_address_to_string (void *cls, const void *addr, size_t addrlen)
-{
- static char ret[40];
- const struct MacAddress *mac;
-
- if (addrlen != sizeof (struct MacAddress))
- {
- GNUNET_break (0);
- return NULL;
- }
- mac = addr;
- GNUNET_snprintf (ret, sizeof (ret), "%s Mac-Address %X:%X:%X:%X:%X:%X",
- PROTOCOL_PREFIX, mac->mac[0], mac->mac[1], mac->mac[2],
- mac->mac[3], mac->mac[4], mac->mac[5]);
-
- return ret;
-}
-
-/**
- * Function for the scheduler if a session times out
- * @param cls pointer to the Sessionqueue
- * @param tc pointer to the GNUNET_SCHEDULER_TaskContext
- */
-static void
-session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct Sessionqueue *queue = cls;
-
- GNUNET_assert (queue != NULL);
- GNUNET_assert (queue->content != NULL);
- queue->content->timeout_task = GNUNET_SCHEDULER_NO_TASK;
- if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
- {
- return;
- }
- if (GNUNET_TIME_absolute_get_remaining
- (GNUNET_TIME_absolute_add
- (queue->content->last_activity, SESSION_TIMEOUT)).rel_value == 0)
- {
-
- GNUNET_assert (queue->content->mac != NULL);
- GNUNET_assert (queue->content->mac->plugin != NULL);
- GNUNET_STATISTICS_update (queue->content->mac->plugin->env->stats,
- _("# wlan session timeouts"), 1, GNUNET_NO);
- free_session (queue->content->mac->plugin, queue, GNUNET_YES);
- }
- else
- {
- queue->content->timeout_task =
- GNUNET_SCHEDULER_add_delayed (SESSION_TIMEOUT, &session_timeout, queue);
- }
-}
-
-/**
- * create a new session
- *
- * @param plugin pointer to the plugin struct
- * @param endpoint pointer to the mac endpoint of the peer
- * @param peer peer identity to use for this session
- * @return returns the session
- */
-static struct Session *
-create_session (struct Plugin *plugin, struct MacEndpoint *endpoint,
- const struct GNUNET_PeerIdentity *peer)
-{
- GNUNET_assert (endpoint != NULL);
- GNUNET_assert (plugin != NULL);
- GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan session created"), 1,
- GNUNET_NO);
- struct Sessionqueue *queue =
- GNUNET_malloc (sizeof (struct Sessionqueue) + sizeof (struct Session));
-
- GNUNET_CONTAINER_DLL_insert_tail (endpoint->sessions_head,
- endpoint->sessions_tail, queue);
-
- queue->content = (struct Session *) &queue[1];
- queue->content->mac = endpoint;
- queue->content->target = *peer;
- queue->content->last_activity = GNUNET_TIME_absolute_get ();
- queue->content->timeout_task =
- GNUNET_SCHEDULER_add_delayed (SESSION_TIMEOUT, &session_timeout, queue);
-
-#if DEBUG_wlan
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
- "New session %p with endpoint %p: %s\n", queue->content,
- endpoint, wlan_plugin_address_to_string (NULL,
- endpoint->addr.mac,
- 6));
-#endif
-
- return queue->content;
-}
-
-/**
- * Get session from address, create if no session exists
- *
- * @param plugin pointer to the plugin struct
- * @param addr pointer to the mac address of the peer
- * @param peer pointer to the peerid
- * @return returns the session
- */
-static struct Session *
-get_session (struct Plugin *plugin, const struct MacAddress *addr,
- const struct GNUNET_PeerIdentity *peer)
-{
- struct MacEndpoint *mac;
-
- mac = get_macendpoint (plugin, addr, GNUNET_YES);
- struct Session *session = search_session (plugin, mac, peer);
-
- if (session != NULL)
- return session;
- return create_session (plugin, mac, peer);
-}
-
-/**
- * Queue the session to send data
- * checks if there is a message pending
- * checks if this session is not allready in the queue
- * @param plugin pointer to the plugin
- * @param session pointer to the session to add
- */
-static void
-queue_session (struct Plugin *plugin, struct Session *session)
-{
- struct Sessionqueue *queue = plugin->pending_Sessions_head;
-
- if (session->pending_message_head != NULL)
- {
- while (queue != NULL)
- {
- // content is never NULL
- GNUNET_assert (queue->content != NULL);
- // is session already in queue?
- if (session == queue->content)
- {
- return;
- }
- // try next
- queue = queue->next;
- }
-
- // Session is not in the queue
-
- queue = GNUNET_malloc (sizeof (struct Sessionqueue));
- queue->content = session;
-
- //insert at the tail
- GNUNET_CONTAINER_DLL_insert_tail (plugin->pending_Sessions_head,
- plugin->pending_Sessions_tail, queue);
- plugin->pendingsessions++;
- GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"),
- plugin->pendingsessions, GNUNET_NO);
- }
-
-}
-
-/**
- * Function to schedule the write task, executed after a delay
- * @param cls pointer to the plugin struct
- * @param tc GNUNET_SCHEDULER_TaskContext pointer
- */
-static void
-delay_fragment_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct Plugin *plugin = cls;
-
- plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK;
-
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
- return;
-
- // GNUNET_TIME_UNIT_FOREVER_REL is needed to clean up old msg
- if (plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK)
- {
- plugin->server_write_task =
- GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
- plugin->server_stdin_handle,
- &do_transmit, plugin);
- }
-}
-
-/**
- * Function to calculate the time of the next periodic "hello-beacon"
- * @param plugin pointer to the plugin struct
- */
-static void
-set_next_beacon_time (struct Plugin *const plugin)
-{
- //under 10 known peers: once a second
- if (plugin->mac_count < 10)
- {
- plugin->beacon_time =
- GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
- GNUNET_TIME_relative_multiply
- (GNUNET_TIME_UNIT_SECONDS,
- HELLO_BEACON_SCALING_FACTOR));
- }
- //under 30 known peers: every 10 seconds
- else if (plugin->mac_count < 30)
- {
- plugin->beacon_time =
- GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
- GNUNET_TIME_relative_multiply
- (GNUNET_TIME_UNIT_SECONDS,
- 10 * HELLO_BEACON_SCALING_FACTOR));
- }
- //over 30 known peers: once a minute
- else
- {
- plugin->beacon_time =
- GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
- GNUNET_TIME_relative_multiply
- (GNUNET_TIME_UNIT_MINUTES,
- HELLO_BEACON_SCALING_FACTOR));
- }
-}
-
-/**
- * Function to set the timer for the next timeout of the fragment queue
- * @param plugin the handle to the plugin struct
- */
-static void
-set_next_send (struct Plugin *const plugin)
-{
- struct GNUNET_TIME_Relative next_send;
-
- //abort if helper is not running
- if (plugin->helper_is_running == GNUNET_NO)
- {
- return;
- }
-
- //cancel old task
- if (plugin->server_write_delay_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_SCHEDULER_cancel (plugin->server_write_delay_task);
- plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK;
- }
-
- //check if some acks are in the queue
- if (plugin->ack_send_queue_head != NULL)
- {
- next_send = GNUNET_TIME_UNIT_ZERO;
- }
-
- //check if there are some fragments in the queue
- else if (plugin->sending_messages_head != NULL)
- {
- next_send = GNUNET_TIME_UNIT_ZERO;
- }
- else
- {
- next_send = GNUNET_TIME_absolute_get_remaining (plugin->beacon_time);
- }
-
-#if DEBUG_wlan
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
- "Next packet is send in: %u\n", next_send.rel_value);
-#endif
-
- if (next_send.rel_value == GNUNET_TIME_UNIT_ZERO.rel_value)
- {
- if (plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK)
- {
- plugin->server_write_task =
- GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
- plugin->server_stdin_handle,
- &do_transmit, plugin);
- }
- }
- else
- {
- if (plugin->server_write_delay_task == GNUNET_SCHEDULER_NO_TASK)
- {
- plugin->server_write_delay_task =
- GNUNET_SCHEDULER_add_delayed (next_send, &delay_fragment_task,
- plugin);
- }
- }
-}
-
-/**
- * Function to get the next queued Session, removes the session from the queue
- * @param plugin pointer to the plugin struct
- * @return pointer to the session found, returns NULL if there is now session in the queue
- */
-static struct Session *
-get_next_queue_session (struct Plugin *plugin)
-{
- struct Session *session;
- struct Sessionqueue *sessionqueue;
- struct Sessionqueue *sessionqueue_alt;
- struct PendingMessage *pm;
-
- sessionqueue = plugin->pending_Sessions_head;
-
- while (sessionqueue != NULL)
- {
- session = sessionqueue->content;
-
- GNUNET_assert (session != NULL);
- pm = session->pending_message_head;
-
- if (pm == NULL)
- {
-#if DEBUG_wlan
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
- "pending message is empty, should not happen. session %p\n",
- session);
-#endif
- sessionqueue_alt = sessionqueue;
- sessionqueue = sessionqueue->next;
- plugin->pendingsessions--;
- GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"),
- plugin->pendingsessions, GNUNET_NO);
- GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head,
- plugin->pending_Sessions_tail,
- sessionqueue_alt);
-
- GNUNET_free (sessionqueue_alt);
- continue;
-
- }
-
- //check for message timeout
- if (GNUNET_TIME_absolute_get_remaining (pm->timeout).rel_value > 0)
- {
- //check if session has no message in the fragment queue
- if ((session->mac->fragment_messages_out_count <
- FRAGMENT_QUEUE_MESSAGES_OUT_PER_MACENDPOINT) &&
- (session->fragment_messages_out_count <
- FRAGMENT_QUEUE_MESSAGES_OUT_PER_SESSION))
- {
- plugin->pendingsessions--;
- GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"),
- plugin->pendingsessions, GNUNET_NO);
- GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head,
- plugin->pending_Sessions_tail,
- sessionqueue);
- GNUNET_free (sessionqueue);
-
- return session;
- }
- else
- {
- sessionqueue = sessionqueue->next;
- }
- }
- else
- {
- GNUNET_CONTAINER_DLL_remove (session->pending_message_head,
- session->pending_message_tail, pm);
-
- //call the cont func that it did not work
- if (pm->transmit_cont != NULL)
- pm->transmit_cont (pm->transmit_cont_cls, &(session->target),
- GNUNET_SYSERR);
- GNUNET_free (pm->msg);
- GNUNET_free (pm);
-
- if (session->pending_message_head == NULL)
- {
- sessionqueue_alt = sessionqueue;
- sessionqueue = sessionqueue->next;
- plugin->pendingsessions--;
- GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"),
- plugin->pendingsessions, GNUNET_NO);
- GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head,
- plugin->pending_Sessions_tail,
- sessionqueue_alt);
-
- GNUNET_free (sessionqueue_alt);
- }
- }
-
- }
- return NULL;
-}
-
-/**
- * frees the space of a message in the fragment queue (send queue)
- * @param plugin the plugin struct
- * @param fm message to free
- */
-static void
-free_fragment_message (struct Plugin *plugin, struct FragmentMessage *fm)
-{
- struct Session *session = fm->session;
- struct MacEndpoint *endpoint = session->mac;
- struct FragmentMessage_queue *fmq;
- struct FragmentMessage_queue *fmq_next;
-
- fmq = plugin->sending_messages_head;
- while (fmq != NULL)
- {
- fmq_next = fmq->next;
- if (fmq->content == fm)
- {
- GNUNET_CONTAINER_DLL_remove (plugin->sending_messages_head,
- plugin->sending_messages_tail, fmq);
- GNUNET_free (fmq);
- }
- fmq = fmq_next;
- }
-
- (session->mac->fragment_messages_out_count)--;
- session->fragment_messages_out_count--;
- plugin->pending_Fragment_Messages--;
- GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending fragments"),
- plugin->pending_Fragment_Messages, GNUNET_NO);
- GNUNET_CONTAINER_DLL_remove (endpoint->sending_messages_head,
- endpoint->sending_messages_tail, fm);
- GNUNET_FRAGMENT_context_destroy (fm->fragcontext);
- if (fm->timeout_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_SCHEDULER_cancel (fm->timeout_task);
- fm->timeout_task = GNUNET_SCHEDULER_NO_TASK;
- }
-
- GNUNET_free (fm);
-
- queue_session (plugin, session);
-#if DEBUG_wlan
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
- "Free pending fragment messages %p, session %p\n", fm,
- session);
-#endif
-}
-
-/**
- * function to fill the radiotap header
- * @param plugin pointer to the plugin struct
- * @param endpoint pointer to the endpoint
- * @param header pointer to the radiotap header
- * @return GNUNET_YES at success
- */
-static int
-getRadiotapHeader (struct Plugin *plugin, struct MacEndpoint *endpoint,
- struct Radiotap_Send *header)
-{
-
- if (endpoint != NULL)
- {
- header->rate = endpoint->rate;
- header->tx_power = endpoint->tx_power;
- header->antenna = endpoint->antenna;
- }
- else
- {
- header->rate = 255;
- header->tx_power = 0;
- header->antenna = 0;
- }
-
- return GNUNET_YES;
-}
-
-/**
- * function to generate the wlan hardware header for one packet
- * @param Header address to write the header to
- * @param to_mac_addr address of the recipient
- * @param plugin pointer to the plugin struct
- * @param size size of the whole packet, needed to calculate the time to send the packet
- * @return GNUNET_YES if there was no error
- */
-static int
-getWlanHeader (struct ieee80211_frame *Header,
- const struct MacAddress *to_mac_addr, struct Plugin *plugin,
- unsigned int size)
-{
- uint16_t *tmp16;
- const int rate = 11000000;
-
- Header->i_fc[0] = IEEE80211_FC0_TYPE_DATA;
- Header->i_fc[1] = 0x00;
- memcpy (&Header->i_addr3, &mac_bssid_gnunet, sizeof (mac_bssid_gnunet));
- memcpy (&Header->i_addr2, plugin->mac_address.mac,
- sizeof (plugin->mac_address));
- memcpy (&Header->i_addr1, to_mac_addr, sizeof (struct MacAddress));
-
- tmp16 = (uint16_t *) Header->i_dur;
- *tmp16 = (uint16_t) GNUNET_htole16 ((size * 1000000) / rate + 290);
- Header->llc[0] = WLAN_LLC_DSAP_FIELD;
- Header->llc[1] = WLAN_LLC_SSAP_FIELD;
-
- return GNUNET_YES;
-}
-
-
-/**
- * function to add a fragment of a message to send
- * @param cls FragmentMessage this message belongs to
- * @param hdr pointer to the start of the message
- */
-static void
-add_message_for_send (void *cls, const struct GNUNET_MessageHeader *hdr)
-{
-
- struct FragmentMessage *fm = cls;
- struct FragmentMessage_queue *fmqueue;
-
- GNUNET_assert (cls != NULL);
- GNUNET_assert (fm->frag == NULL);
- struct MacEndpoint *endpoint = fm->session->mac;
- struct Plugin *plugin = endpoint->plugin;
- struct GNUNET_MessageHeader *msgheader;
- struct GNUNET_MessageHeader *msgheader2;
- uint16_t size;
-
-#if DEBUG_wlan_retransmission > 1
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
- "Adding fragment of message %p to send, session %p, endpoint %p, type %u\n",
- fm, fm->session, endpoint, hdr->type);
-#endif
-
- size =
- sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_Send) +
- sizeof (struct ieee80211_frame) + ntohs (hdr->size);
- fm->frag = GNUNET_malloc (size);
- fm->size = size;
-
- msgheader = (struct GNUNET_MessageHeader *) fm->frag;
- msgheader->size = htons (size);
- msgheader->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
-
- fm->radioHeader = (struct Radiotap_Send *) &msgheader[1];
- fm->ieeewlanheader = (struct ieee80211_frame *) &fm->radioHeader[1];
- msgheader2 = (struct GNUNET_MessageHeader *) &fm->ieeewlanheader[1];
- memcpy (msgheader2, hdr, ntohs (hdr->size));
-
- fmqueue = GNUNET_malloc (sizeof (struct FragmentMessage_queue));
- fmqueue->content = fm;
-
- GNUNET_CONTAINER_DLL_insert_tail (plugin->sending_messages_head,
- plugin->sending_messages_tail, fmqueue);
- set_next_send (plugin);
-}
-
-
-/**
- * We have been notified that gnunet-helper-transport-wlan has written something to stdout.
- * Handle the output, then reschedule this function to be called again once
- * more is available.
- *
- * @param cls the plugin handle
- * @param tc the scheduling context
- */
-static void
-wlan_plugin_helper_read (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct Plugin *plugin = cls;
-
- plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK;
-
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
- return;
-
- char mybuf[WLAN_MTU + sizeof (struct GNUNET_MessageHeader)];
- ssize_t bytes;
-
- bytes =
- GNUNET_DISK_file_read (plugin->server_stdout_handle, mybuf,
- sizeof (mybuf));
- if (bytes <= 0)
- {
-#if DEBUG_wlan
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
- _
- ("Finished reading from gnunet-helper-transport-wlan stdout with code: %d\n"),
- bytes);
-#endif
- return;
- }
- GNUNET_SERVER_mst_receive (plugin->suid_tokenizer, NULL, mybuf, bytes,
- GNUNET_NO, GNUNET_NO);
-
- GNUNET_assert (plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK);
- plugin->server_read_task =
- GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
- plugin->server_stdout_handle,
- &wlan_plugin_helper_read, plugin);
-}
-
-/**
- * Start the gnunet-helper-transport-wlan process.
- *
- * @param plugin the transport plugin
- * @return GNUNET_YES if process was started, GNUNET_SYSERR on error
- */
-static int
-wlan_transport_start_wlan_helper (struct Plugin *plugin)
-{
- const char *filenamehw = "gnunet-helper-transport-wlan";
- const char *filenameloopback = "gnunet-helper-transport-wlan-dummy";
- char *absolute_filename = NULL;
-
- if (plugin->helper_is_running == GNUNET_YES)
- {
-#if DEBUG_wlan
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
- "wlan_transport_start_wlan_helper not needed, helper already running!");
-#endif
- return GNUNET_YES;
- }
-
- plugin->server_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_NO, GNUNET_YES);
- if (plugin->server_stdout == NULL)
- return GNUNET_SYSERR;
-
- plugin->server_stdin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO);
- if (plugin->server_stdin == NULL)
- return GNUNET_SYSERR;
-
- if ((plugin->testmode == 1) || (plugin->testmode == 2))
- {
- if (GNUNET_OS_check_helper_binary (filenameloopback) == GNUNET_YES)
- {
- absolute_filename = GNUNET_strdup (filenameloopback);
- }
- else
- {
- char cwd[FILENAME_MAX];
-
- GNUNET_assert (getcwd (cwd, sizeof (cwd)) != NULL);
-
- GNUNET_asprintf (&absolute_filename, "%s%s%s", cwd, DIR_SEPARATOR_STR,
- filenameloopback);
-
- if (GNUNET_DISK_file_test (filenameloopback) != GNUNET_YES)
- {
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
- "Helper `%s' not found! %i\n", absolute_filename);
- GNUNET_break (0);
- }
- }
- }
-
- /* Start the server process */
-
- if (plugin->testmode == 0)
- {
-
-#if DEBUG_wlan
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
- "Starting gnunet-helper-transport-wlan process cmd: %s %s %i\n",
- filenamehw, plugin->interface, plugin->testmode);
-#endif
-
- if (GNUNET_OS_check_helper_binary (filenamehw) == GNUNET_YES)
- {
- plugin->server_proc =
- GNUNET_OS_start_process (plugin->server_stdin, plugin->server_stdout,
- filenamehw, filenamehw, plugin->interface,
- NULL);
- }
- else if (GNUNET_OS_check_helper_binary (filenamehw) == GNUNET_NO)
- {
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
- "gnunet-helper-transport-wlan is not suid, please change it or look at the doku\n");
- GNUNET_break (0);
- }
- else
- {
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
- "gnunet-helper-transport-wlan not found, please look if it exists and is the $PATH variable!\n");
- GNUNET_break (0);
- }
-
- }
- else if (plugin->testmode == 1)
- {
-
-#if DEBUG_wlan
- GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, PLUGIN_LOG_NAME,
- "Starting gnunet-helper-transport-wlan-dummy loopback 1 process cmd: %s %s %i\n",
- absolute_filename, plugin->interface, plugin->testmode);
-#endif
- plugin->server_proc =
- GNUNET_OS_start_process (plugin->server_stdin, plugin->server_stdout,
- absolute_filename, absolute_filename, "1",
- NULL);
- if (plugin->server_proc == NULL)
- {
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
- "`%s' not found, please look if it exists and is in the $PATH variable!\n",
- absolute_filename);
- GNUNET_break (0);
- }
- }
- else if (plugin->testmode == 2)
- {
-#if DEBUG_wlan
- GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, PLUGIN_LOG_NAME,
- "Starting gnunet-helper-transport-wlan-dummy loopback 2 process cmd: %s %s %i\n",
- absolute_filename, plugin->interface, plugin->testmode);
-#endif
-
- plugin->server_proc =
- GNUNET_OS_start_process (plugin->server_stdin, plugin->server_stdout,
- absolute_filename, absolute_filename, "2",
- NULL);
- if (plugin->server_proc == NULL)
- {
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
- "`%s' not found, please look if it exists and is in the $PATH variable!\n",
- absolute_filename);
- GNUNET_break (0);
- }
- }
- if (absolute_filename != NULL)
- GNUNET_free (absolute_filename);
- if (plugin->server_proc == NULL)
- {
-#if DEBUG_wlan
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
- "Failed to start gnunet-helper-transport-wlan process\n");
-#endif
- return GNUNET_SYSERR;
- }
-
-
-
- /* Close the write end of the read pipe */
- GNUNET_DISK_pipe_close_end (plugin->server_stdout,
- GNUNET_DISK_PIPE_END_WRITE);
-
- /* Close the read end of the write pipe */
- GNUNET_DISK_pipe_close_end (plugin->server_stdin, GNUNET_DISK_PIPE_END_READ);
-
- plugin->server_stdout_handle =
- GNUNET_DISK_pipe_handle (plugin->server_stdout,
- GNUNET_DISK_PIPE_END_READ);
- plugin->server_stdin_handle =
- GNUNET_DISK_pipe_handle (plugin->server_stdin,
- GNUNET_DISK_PIPE_END_WRITE);
-
- GNUNET_assert (plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK);
-
-#if DEBUG_wlan
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
- "Adding server_read_task for the gnunet-helper-transport-wlan\n");
-#endif
-
- plugin->server_read_task =
- GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
- plugin->server_stdout_handle,
- &wlan_plugin_helper_read, plugin);