+ if (bytes == GNUNET_SYSERR)
+ {
+ GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
+ _
+ ("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
+ errno, strerror (errno));
+ finish = GNUNET_malloc (sizeof (struct Finish_send));
+ finish->plugin = plugin;
+ finish->head_of_next_write = NULL;
+ finish->size = 0;
+ finish->msgstart = NULL;
+ restart_helper (plugin, finish);
+
+ set_next_beacon_time (plugin);
+
+ }
+ else
+ {
+ GNUNET_assert (bytes == size);
+ set_next_beacon_time (plugin);
+ set_next_send (plugin);
+ }
+ GNUNET_free (msgheader);
+
+
+}
+
+/**
+ * function to add an ack to send it for a received fragment
+ * @param cls MacEndpoint this ack belongs to
+ * @param msg_id id of the message
+ * @param hdr pointer to the hdr where the ack is stored
+ *
+ */
+
+static void
+add_ack_for_send (void *cls, uint32_t msg_id,
+ const struct GNUNET_MessageHeader *hdr)
+{
+
+ struct AckSendQueue *ack;
+
+ GNUNET_assert (cls != NULL);
+ struct MacEndpoint *endpoint = cls;
+ struct Plugin *plugin = endpoint->plugin;
+ struct GNUNET_MessageHeader *msgheader;
+ struct GNUNET_MessageHeader *msgheader2;
+ uint16_t size;
+
+ size =
+ sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_Send) +
+ sizeof (struct ieee80211_frame) + ntohs (hdr->size) +
+ sizeof (struct AckSendQueue);
+
+ ack = GNUNET_malloc (size);
+ ack->message_id = msg_id;
+ ack->endpoint = endpoint;
+
+ size =
+ sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_Send) +
+ sizeof (struct ieee80211_frame) + ntohs (hdr->size);
+
+ msgheader = (struct GNUNET_MessageHeader *) &ack[1];
+ ack->hdr = (struct GNUNET_MessageHeader *) &ack[1];
+ msgheader->size = htons (size);
+ msgheader->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
+
+ ack->radioHeader = (struct Radiotap_Send *) &msgheader[1];
+ ack->ieeewlanheader = (struct ieee80211_frame *) &(ack->radioHeader)[1];
+ msgheader2 = (struct GNUNET_MessageHeader *) &(ack->ieeewlanheader)[1];
+ memcpy (msgheader2, hdr, ntohs (hdr->size));
+
+ GNUNET_CONTAINER_DLL_insert_tail (plugin->ack_send_queue_head,
+ plugin->ack_send_queue_tail, ack);
+
+#if DEBUG_wlan_retransmission > 1
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
+ "Adding ack with message id %u to send, AckSendQueue %p, endpoint %p\n",
+ msg_id, ack, endpoint);
+#endif
+
+ set_next_send (plugin);
+}
+
+/**
+ * Function for the scheduler if a FragmentMessage times out
+ * @param cls pointer to the FragmentMessage
+ * @param tc pointer to the GNUNET_SCHEDULER_TaskContext
+ */
+static void
+fragmentmessage_timeout (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct FragmentMessage *fm = cls;
+
+ GNUNET_assert (fm != NULL);
+ fm->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+ if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
+ {
+ return;
+ }
+ free_fragment_message (fm->session->mac->plugin, fm);
+}
+
+/**
+ * Function to check if there is some space in the fragment queue
+ * inserts a message if space is available
+ * @param plugin the plugin struct
+ */
+
+static void
+check_fragment_queue (struct Plugin *plugin)
+{
+ struct Session *session;
+ struct FragmentMessage *fm;
+ struct GNUNET_PeerIdentity pid;
+
+ struct PendingMessage *pm;
+
+ if (plugin->pending_Fragment_Messages < FRAGMENT_QUEUE_SIZE)
+ {
+ session = get_next_queue_session (plugin);
+ if (session != NULL)
+ {
+ pm = session->pending_message_head;
+ GNUNET_assert (pm != NULL);
+ GNUNET_CONTAINER_DLL_remove (session->pending_message_head,
+ session->pending_message_tail, pm);
+ 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);
+
+ fm = GNUNET_malloc (sizeof (struct FragmentMessage));
+ fm->session = session;
+ fm->timeout.abs_value = pm->timeout.abs_value;
+ fm->frag = NULL;
+ fm->fragcontext =
+ GNUNET_FRAGMENT_context_create (plugin->env->stats, WLAN_MTU,
+ &plugin->tracker,
+ GNUNET_TIME_UNIT_SECONDS,
+ &(pm->msg->header),
+ &add_message_for_send, fm);
+ fm->timeout_task =
+ GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining
+ (fm->timeout), fragmentmessage_timeout,
+ fm);
+ GNUNET_CONTAINER_DLL_insert_tail (session->mac->sending_messages_head,
+ session->mac->sending_messages_tail,
+ fm);
+
+ if (pm->transmit_cont != NULL)
+ {
+ pid = session->target;
+ pm->transmit_cont (pm->transmit_cont_cls, &pid, GNUNET_OK);
+#if DEBUG_wlan
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
+ "called pm->transmit_cont for %p\n", session);
+#endif
+ }