- * @return number of bytes used (on the physical network, with overheads);
- * -1 on hard errors (i.e. address invalid); 0 is a legal value
- * and does NOT mean that the message was not transmitted (DV)
- */
-static ssize_t
-wlan_plugin_send(void *cls, const struct GNUNET_PeerIdentity * target,
- const char *msgbuf, size_t msgbuf_size, unsigned int priority,
- struct GNUNET_TIME_Relative timeout, struct Session *session,
- const void *addr, size_t addrlen, int force_address,
- GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
-{
- struct Plugin * plugin = cls;
- struct PendingMessage * newmsg;
- struct WlanHeader * wlanheader;
-
- //check if msglen > 0
- GNUNET_assert(msgbuf_size > 0);
-
- //get session if needed
- if (session == NULL)
- {
- if (wlan_plugin_address_suggested(plugin, addr, addrlen) == GNUNET_OK)
- {
- session = get_session(plugin, addr);
- }
- else
- {
- GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
- _("Wlan Address len %d is wrong\n"), addrlen);
- return -1;
- }
- }
-
- //TODO target "problem" not solved
- //if (session->target != NULL){
- // GNUNET_assert(session->target == *target);
- //} else {
- session->target = *target;
- //}
-
-
- //queue message:
-
- //queue message in session
- //test if there is no other message in the "queue"
- //FIXME: to many send requests
- //GNUNET_assert (session->pending_message == NULL);
- if (session->pending_message != NULL)
- {
- newmsg = session->pending_message;
- GNUNET_log(
- GNUNET_ERROR_TYPE_ERROR,
- "wlan_plugin_send: a pending message is already in the queue for this client\n remaining time to send this message is %u, queued fragment messages %u\n",
- GNUNET_TIME_absolute_get_remaining(newmsg->timeout).rel_value,
- session->fragment_messages_out_count);
- if (session->pending_message2 != NULL)
- {
- GNUNET_log(
- GNUNET_ERROR_TYPE_ERROR,
- "wlan_plugin_send: two pending messages are already in the queue for this client\n");
- return -1;
- }
- }
-
- newmsg = GNUNET_malloc(sizeof(struct PendingMessage));
- (newmsg->msg) = GNUNET_malloc(msgbuf_size + sizeof(struct WlanHeader));
- wlanheader = (struct WlanHeader *) newmsg->msg;
- //copy msg to buffer, not fragmented / segmented yet, but with message header
- wlanheader->header.size = htons(msgbuf_size + sizeof(struct WlanHeader));
- wlanheader->header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_DATA);
- memcpy(&(wlanheader->target), target, sizeof(struct GNUNET_PeerIdentity));
- wlanheader->crc = htonl(getcrc32(msgbuf, msgbuf_size));
- memcpy(&wlanheader[1], msgbuf, msgbuf_size);
- newmsg->transmit_cont = cont;
- newmsg->transmit_cont_cls = cont_cls;
- newmsg->timeout = GNUNET_TIME_relative_to_absolute(timeout);
-
- newmsg->timeout.abs_value = newmsg->timeout.abs_value - 500;
-
- newmsg->message_size = msgbuf_size + sizeof(struct WlanHeader);
-
- if (session->pending_message == NULL)
- {
- session->pending_message = newmsg;
- }
- else
- {
- session->pending_message2 = newmsg;
- }
-
-#if DEBUG_wlan
- GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
- "New message for %p with size (incl wlan header) %u added\n", session,
- newmsg->message_size);
-#endif
-
- //queue session
- queue_session(plugin, session);
-
- check_fragment_queue(plugin);
- //FIXME not the correct size
- return msgbuf_size;
-
-}
-
-/**
- * Iterate over the fragment messages of the given session.
- *
- * @param cls argument to give to iterator
- * @param node node to iterate over
- * @param element value stored at the node
- * @param cost cost associated with the node
- * @return GNUNET_YES if we should continue to iterate,
- * GNUNET_NO if not.
- */
-static int
-free_fragment_message_from_session(void *cls,
- struct GNUNET_CONTAINER_HeapNode *node, void *element,
- GNUNET_CONTAINER_HeapCostType cost)
-{
- struct Plugin_Session_pair * pair = (struct Plugin_Session_pair *) cls;
- struct FragmentMessage * fm = (struct FragmentMessage*) element;
-
- if (fm->session == pair->session)
- {
-
- free_fragment_message(pair->plugin, fm);
- }
- return GNUNET_YES;
-
-}
-
-/**
- * Search for fragment message with given id and session
- *
- * @param cls argument to give to iterator
- * @param node node to iterate over
- * @param element value stored at the node
- * @param cost cost associated with the node
- * @return GNUNET_YES if we should continue to iterate,
- * GNUNET_NO if not.
- */
-static int
-search_fragment_message_from_session_and_id(void *cls,
- struct GNUNET_CONTAINER_HeapNode *node, void *element,
- GNUNET_CONTAINER_HeapCostType cost)
-{
- struct Session_id_fragment_triple * triple =
- (struct Session_id_fragment_triple *) cls;
- struct FragmentMessage * fm = (struct FragmentMessage*) element;
-
- if ((fm->session == triple->session) && (fm->message_id_out
- == triple->message_id))
- {
- triple->fm = fm;
- return GNUNET_NO;
- }
- return GNUNET_YES;
-
-}
-
-/**
- * function to get the message in the fragement queue (out) of a session with a specific id
- * @param session pointer to the session
- * @param message_id id of the message
- * @return pointer to the struct FragmentMessage
- */
-static struct FragmentMessage *
-get_fragment_message_from_session_and_id(struct Plugin * plugin,
- struct Session * session, uint32_t message_id)
-{
- struct Session_id_fragment_triple triple;
- triple.session = session;
- triple.message_id = message_id;
- GNUNET_CONTAINER_heap_iterate(plugin->pending_Fragment_Messages,
- &search_fragment_message_from_session_and_id, &triple);
- return triple.fm;
-}
-
-/**
- * function to get the receive message of a session
- * @param plugin pointer to the plugin struct
- * @param session session this fragment belongs to
- */
-static struct Receive_Message_Queue *
-get_receive_message_from_session(struct Plugin * plugin,
- struct Session * session)
-{
- struct Receive_Message_Queue * rec_message = plugin->receive_messages_head;
- while (rec_message != NULL)
- {
- if (rec_message->session == session)
- {
- return rec_message;
- }
- rec_message = rec_message->next;
- }
- return NULL;
-}
-
-/**
- * Function to dispose the fragments received for a message and the message
- * @param plugin pointer to the plugin struct
- * @param rec_message pointer to the struct holding the message which should be freed
- */
-static void
-free_receive_message(struct Plugin* plugin,
- struct Receive_Message_Queue * rx_message)
-{
- GNUNET_assert(rx_message !=NULL);
- struct Receive_Fragment_Queue * rec_queue = rx_message->frag_head;
- struct Receive_Fragment_Queue * rec_queue2;
-
- while (rec_queue != NULL)
- {
- rec_queue2 = rec_queue;
- rec_queue = rec_queue->next;
- GNUNET_free(rec_queue2);
- }
-
- GNUNET_CONTAINER_DLL_remove(plugin->receive_messages_head,plugin->receive_messages_teil, rx_message);
-
- GNUNET_assert(plugin->pending_receive_messages > 0);
- GNUNET_assert(rx_message->session->fragment_messages_in_count > 0);
-
- plugin->pending_receive_messages--;
- rx_message->session->fragment_messages_in_count--;
- GNUNET_free(rx_message);
-}
-
-/**
- * function to get the receive message of a session
- * @param plugin pointer to the plugin struct
- * @param session session this fragment belongs to
- */
-static void
-check_receive_message_timeouts(struct Plugin * plugin, struct Session * session)
-{
- struct Receive_Message_Queue * rec_message = plugin->receive_messages_head;
- while (rec_message != NULL)
- {
- if (GNUNET_TIME_absolute_get_remaining(rec_message->timeout).rel_value
- == 0)
- {
- free_receive_message(plugin, rec_message);
- }
- rec_message = rec_message->next;
- }
-
-}
-
-//TODO DOXIGEN
-static void
-free_session(struct Plugin * plugin, struct Sessionqueue * queue)
-{
- struct Sessionqueue * pendingsession;
- struct Sessionqueue * pendingsession_tmp;
- struct PendingMessage * pm;
- struct Receive_Message_Queue * receive_queue;
- struct Plugin_Session_pair pair;
- int check = 0;
-
- GNUNET_assert(queue != NULL);
- GNUNET_assert(queue->content != NULL);
-
- //session found
- //is this session pending for send
- pendingsession = plugin->pending_Sessions_head;
- while (pendingsession != NULL)
- {
- pendingsession_tmp = pendingsession->next;
- if (pendingsession->content == queue->content)
- {
- plugin->pendingsessions--;
- GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head,
- plugin->pending_Sessions_tail,
- pendingsession);
- GNUNET_free(pendingsession);
-
- GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
- "Remove session %p from pending session queue\n",
- queue->content);
- GNUNET_assert (check == 0);
- check = 1;
- }
- pendingsession = pendingsession_tmp;
- }
-
- //is something of this session in the fragment queue?
- pair.plugin = plugin;
- pair.session = queue->content;
- GNUNET_CONTAINER_heap_iterate(plugin->pending_Fragment_Messages,
- &free_fragment_message_from_session, &pair);
-
- //dispose all received fragments
- receive_queue = get_receive_message_from_session(plugin, queue->content);
- while (receive_queue != NULL)
- {
- free_receive_message(plugin, receive_queue);
- receive_queue = get_receive_message_from_session(plugin, queue->content);
- }
-
- // remove PendingMessage
- pm = queue->content->pending_message;
- if (pm != NULL)
- {
- GNUNET_free_non_null(pm->msg);
- GNUNET_free(pm);
- }
-
- // remove PendingMessage
- pm = queue->content->pending_message2;
- if (pm != NULL)
- {
- GNUNET_free_non_null(pm->msg);
- GNUNET_free(pm);
- }
-
- GNUNET_CONTAINER_DLL_remove(plugin->sessions,
- plugin->sessions_tail,
- queue);
- GNUNET_free(queue->content);
- GNUNET_free(queue);
- plugin->session_count--;
- check_fragment_queue(plugin);
-}
-
-/**
- * Function that can be used to force the plugin to disconnect
- * from the given peer and cancel all previous transmissions
- * (and their continuation).
- *
- * @param cls closure
- * @param target peer from which to disconnect
- */
-static void
-wlan_plugin_disconnect(void *cls, const struct GNUNET_PeerIdentity *target)
-{
- struct Plugin *plugin = cls;
- struct Sessionqueue * queue = plugin->sessions;
-
- // just look at all the session for the needed one
- while (queue != NULL)
- {
- // content is never NULL
- GNUNET_assert (queue->content != NULL);
- if (memcmp(target, &(queue->content->target),
- sizeof(struct GNUNET_PeerIdentity)) == 0)
- {
- free_session(plugin, queue);
- return;
- }
- // try next
- queue = queue->next;
- }
-}
-
-/**
- * Convert the transports address to a nice, human-readable
- * format.
- *
- * @param cls closure
- * @param type name of the transport that generated the address
- * @param addr one of the addresses of the host, NULL for the last address
- * the specific address format depends on the transport
- * @param addrlen length of the address
- * @param numeric should (IP) addresses be displayed in numeric form?
- * @param timeout after how long should we give up?
- * @param asc function to call on each string
- * @param asc_cls closure for asc
- */
-static void
-wlan_plugin_address_pretty_printer(void *cls, const char *type,
- const void *addr, size_t addrlen, int numeric,
- struct GNUNET_TIME_Relative timeout,
- GNUNET_TRANSPORT_AddressStringCallback asc, void *asc_cls)
-{
- char ret[92];
- const unsigned char * input;
-
- //GNUNET_assert(cls !=NULL);
- if (addrlen != 6)
- {
- /* invalid address (MAC addresses have 6 bytes) */
- GNUNET_break (0);
- asc(asc_cls, NULL);
- return;
- }
- input = (const unsigned char*) addr;
- GNUNET_snprintf(ret, sizeof(ret),
- "%s Mac-Address %.2X:%.2X:%.2X:%.2X:%.2X:%.2X", PROTOCOL_PREFIX,
- input[0], input[1], input[2], input[3], input[4], input[5]);
- asc(asc_cls, ret);
-}
-
-
-/**
- * Function to test if fragment number already exists in the fragments received
- *
- * @param rec_message message this fragment belongs to
- * @param fh Fragmentheader of the fragment
- * @return GNUNET_YES if fragment exists already, GNUNET_NO if it does not exists in the queue of the session
- */
-static int
-is_double_msg(struct Receive_Message_Queue * rx_msg,
- struct FragmentationHeader * fh)
-{
- //test if bitfield is okay
-#if DEBUG_wlan
- check_message_fragment_bitfield(rx_msg);
-#endif
-
- return testBit((char *) &rx_msg->received_fragments, ntohs(
- fh->fragment_off_or_num));
-
-}
-
-/**
- * Function to insert a fragment in a queue of a message
- * @param session session the fragment belongs to
- * @param rec_queue fragment to add