Exemplo n.º 1
0
void handle_incoming_acks(Sender * sender,
                          LLnode ** outgoing_frames_head_ptr)
{
    //TODO: Suggested steps for handling incoming ACKs
    //    1) Dequeue the ACK from the sender->input_framelist_head
    //    2) Convert the char * buffer to a Frame data type
    //    3) Check whether the frame is corrupted
    //    4) Check whether the frame is for this sender
    //    5) Do sliding window protocol for sender/receiver pair 
    int incoming_ack_length = ll_get_length(sender->input_framelist_head);
    while (incoming_ack_length > 0) {
        LLnode * ll_ack_node = ll_pop_node(&sender->input_framelist_head);
        incoming_ack_length = ll_get_length(sender->input_framelist_head);
        char * raw_char_buf = (char *) ll_ack_node->value;
        int flag = is_corrupted(raw_char_buf, MAX_FRAME_SIZE);
        //fprintf(stderr, "SFLAG = %d\n", flag);
        if (flag == 0) {
           // fprintf(stderr, "CORRUPTED\n");
            break;
        }
        Frame * ackFrame = convert_char_to_frame(raw_char_buf);
        free (raw_char_buf);

        if (sender->send_id == ackFrame->src_id) {
            if (!((sender->LAR <= sender->seqNum &&
                   ackFrame->seqNum > sender->LAR &&
                   ackFrame->seqNum <= sender->seqNum) ||
                  (sender->LAR > sender->seqNum &&
                  (ackFrame->seqNum > sender->LAR ||
                   ackFrame->seqNum <= sender->seqNum))))
                break;
      //      fprintf(stderr, "Receiver[%d] Ack #%d\n",ackFrame->dst_id, 
        //                                           ackFrame->seqNum);
           // fprintf(stderr, "OLD LAR %d and OLD sendQSize %d\n", sender->LAR, sender->sendQSize);
            do {
                int i = 0;
                for (;i < SWS; i++) {
                    if (sender->sendQ[i].inuse == 1) {
                        Frame * qFrame = (Frame *)sender->sendQ[i].msg;
                        if (qFrame->seqNum == sender->LAR){
                            sender->sendQ[i].inuse = 0;
                            sender->sendQSize--;
                   //         fprintf(stderr, "REMOVING FRAME %d\n", qFrame->seqNum);
                        }
                    }
                }
                sender->LAR++;
            } while (sender->LAR != ackFrame->seqNum);
            //fprintf(stderr, "LAR = %d and SENDQSIZE %d\n", sender->LAR, sender->sendQSize);
        } 
        free (ackFrame);
        free (ll_ack_node);
    }
}
Exemplo n.º 2
0
void handle_incoming_msgs(Receiver * receiver,
                          LLnode ** outgoing_frames_head_ptr)
{
    //TODO: Suggested steps for handling incoming frames
    //    1) Dequeue the Frame from the sender->input_framelist_head
    //    2) Convert the char * buffer to a Frame data type
    //    3) Check whether the frame is corrupted
    //    4) Check whether the frame is for this receiver
    //    5) Do sliding window protocol for sender/receiver pair

    int incoming_msgs_length = ll_get_length(receiver->input_framelist_head);
    while (incoming_msgs_length > 0)
    {
        //Pop a node off the front of the link list and update the count
        LLnode * ll_inmsg_node = ll_pop_node(&receiver->input_framelist_head);
        incoming_msgs_length = ll_get_length(receiver->input_framelist_head);

        //DUMMY CODE: Print the raw_char_buf
        //NOTE: You should not blindly print messages!
        //      Ask yourself: Is this message really for me?
        //                    Is this message corrupted?
        //                    Is this an old, retransmitted message?           
        char * raw_char_buf = (char *) ll_inmsg_node->value;
        
	if (chksum_all(raw_char_buf))
	{
	    fprintf(stderr, "chksum error\n");
	    free(raw_char_buf);
            free(ll_inmsg_node);
	    continue;
	}
        Frame * inframe = convert_char_to_frame(raw_char_buf);
	if (inframe->src == receiver->send_id)
	{
	    if (inframe->dst == receiver->recv_id)
	    {
		Frame * outframe;
		char* buf;

		outframe = build_ack(receiver, inframe);

		buf = add_chksum(outframe);
		print_receiver(receiver);
		ll_append_node(outgoing_frames_head_ptr, buf);
		free(outframe);
	    }
	}

	//free(inframe);
	free(raw_char_buf);
        free(ll_inmsg_node);
    }
}
Exemplo n.º 3
0
Arquivo: sender.c Projeto: s4byun/SWP
void handle_incoming_acks(Sender * sender,
        LLnode ** outgoing_frames_head_ptr)
{
    int incoming_msgs_length = ll_get_length(sender->input_framelist_head);
    while(incoming_msgs_length > 0)
    {
        //Receive the ACK and update the list length
        LLnode * ll_inmsg_node = ll_pop_node(&sender->input_framelist_head);
        incoming_msgs_length = ll_get_length(sender->input_framelist_head);

        //Convert the ACK node to an actual frame
        char * raw_char_buf = (char *) ll_inmsg_node->value;
        Frame * inframe = convert_char_to_frame(raw_char_buf);

        //Don't need the node anymore
        ll_destroy_node(ll_inmsg_node);

        //Checks if the frame is corrupted
        if(crc8(raw_char_buf, MAX_FRAME_SIZE))
        {
            //Checks if this ACK is for this sender
            if(atoi(inframe->sender_addr) == sender->send_id)
            {
                int id = atoi(inframe->receiver_addr);
                int seqnum = (int) inframe->seqnum;

                if(is_valid_sender(sender, seqnum, id))
                {
                    fprintf(stderr, "ACK %d RECEIVED\n", seqnum);
                    send_Q** buf = sender->send_q_head[id];
                    int lar = sender->LAR[id];
                    while(lar != seqnum)
                    {
                        lar = (lar == MAX_SEQ_NUM) ? 0 : lar + 1;
                        free(buf[lar % WS]->frame);
                        free(buf[lar % WS]->frame_timeout);
                        buf[lar % WS]->frame = NULL;
                        buf[lar % WS]->frame_timeout = NULL;
                    }
                    sender->LAR[id] = lar;
                }
            }
        }

        free(inframe);
    }
}
Exemplo n.º 4
0
Arquivo: sender.c Projeto: popacai/SWP
void handle_incoming_acks(Sender * sender,
                          LLnode ** outgoing_frames_head_ptr)
{
    //TODO: Suggested steps for handling incoming ACKs
    //    1) Dequeue the ACK from the sender->input_framelist_head
    //    2) Convert the char * buffer to a Frame data type
    //    3) Check whether the frame is corrupted
    //    4) Check whether the frame is for this sender
    //    5) Do sliding window protocol for sender/receiver pair   
    int incoming_msgs_length = ll_get_length(sender->input_framelist_head);
    while (incoming_msgs_length > 0)
    {
        LLnode * ll_inmsg_node = ll_pop_node(&sender->input_framelist_head);
        incoming_msgs_length = ll_get_length(sender->input_framelist_head);
        char * raw_char_buf = (char *) ll_inmsg_node->value;
        Frame * inframe = convert_char_to_frame(raw_char_buf);
	short checksum;

	checksum = chksum((unsigned short*) raw_char_buf, 
			    MAX_FRAME_SIZE / 2);
	if (checksum)
	{
	    fprintf(stderr, "send checksum error\n");
	    continue;
	}
        free(raw_char_buf);

	if (sender->send_id == inframe->dst)
	{
	    if (inframe->flag == ACK)
	    {
		recv_ack(sender, inframe);
	    }
	}

	free(inframe);
    }
}
Exemplo n.º 5
0
void handle_incoming_msgs(Receiver *r, LLnode **output_framelist_head) {
  while( ll_get_length(r->input_framelist_head) > 0 ) {
    LLnode *msgNode = ll_pop_node(&r->input_framelist_head);
    char *raw_buf = (char *)msgNode->value;
    Frame *inframe = convert_char_to_frame(raw_buf);

    // If corrupted, drop this frame 
    if( !(crc32(inframe, 4+FRAME_PAYLOAD_SIZE) ^ inframe->crc) ) {
      // if not the right recipient, drop this frame
      if( r->recv_id == inframe->dst ) {
        printf("<RECV_%d>:[%s]\n", r->recv_id, inframe->data);
        char *ack_buf = (char *)malloc(MAX_FRAME_SIZE);
        memcpy(ack_buf, raw_buf, MAX_FRAME_SIZE);
        ack_buf[3] = ACK_FLAG;
        ll_append_node(output_framelist_head, ack_buf);
      }
    }

    free(msgNode);
    free(raw_buf);
    free(inframe);
  }
}
Exemplo n.º 6
0
void * run_receiver(void * input_receiver)
{    
    struct timespec   time_spec;
    struct timeval    curr_timeval;
    const int WAIT_SEC_TIME = 0;
    const long WAIT_USEC_TIME = 100000;
    Receiver * receiver = (Receiver *) input_receiver;
    LLnode * outgoing_frames_head;


    //This incomplete receiver thread, at a high level, loops as follows:
    //1. Determine the next time the thread should wake up if there is nothing in the incoming queue(s)
    //2. Grab the mutex protecting the input_msg queue
    //3. Dequeues messages from the input_msg queue and prints them
    //4. Releases the lock
    //5. Sends out any outgoing messages

    pthread_cond_init(&receiver->buffer_cv, NULL);
    pthread_mutex_init(&receiver->buffer_mutex, NULL);

    while(1)
    {    
        //NOTE: Add outgoing messages to the outgoing_frames_head pointer
        outgoing_frames_head = NULL;
        gettimeofday(&curr_timeval, 
                     NULL);

        //Either timeout or get woken up because you've received a datagram
        //NOTE: You don't really need to do anything here, but it might be useful for debugging purposes to have the receivers periodically wakeup and print info
        time_spec.tv_sec  = curr_timeval.tv_sec;
        time_spec.tv_nsec = curr_timeval.tv_usec * 1000;
        time_spec.tv_sec += WAIT_SEC_TIME;
        time_spec.tv_nsec += WAIT_USEC_TIME * 1000;
        if (time_spec.tv_nsec >= 1000000000)
        {
            time_spec.tv_sec++;
            time_spec.tv_nsec -= 1000000000;
        }

        //*****************************************************************************************
        //NOTE: Anything that involves dequeing from the input frames should go 
        //      between the mutex lock and unlock, because other threads CAN/WILL access these structures
        //*****************************************************************************************
        pthread_mutex_lock(&receiver->buffer_mutex);

        //Check whether anything arrived
        int incoming_msgs_length = ll_get_length(receiver->input_framelist_head);
        if (incoming_msgs_length == 0)
        {
            //Nothing has arrived, do a timed wait on the condition variable (which releases the mutex). Again, you don't really need to do the timed wait.
            //A signal on the condition variable will wake up the thread and reacquire the lock
            pthread_cond_timedwait(&receiver->buffer_cv, 
                                   &receiver->buffer_mutex,
                                   &time_spec);
        }

        handle_incoming_msgs(receiver,
                             &outgoing_frames_head);

        pthread_mutex_unlock(&receiver->buffer_mutex);
        
        //CHANGE THIS AT YOUR OWN RISK!
        //Send out all the frames user has appended to the outgoing_frames list
        int ll_outgoing_frame_length = ll_get_length(outgoing_frames_head);
        while(ll_outgoing_frame_length > 0)
        {
            LLnode * ll_outframe_node = ll_pop_node(&outgoing_frames_head);
            char * char_buf = (char *) ll_outframe_node->value;
            
            //The following function frees the memory for the char_buf object
            send_msg_to_senders(char_buf);

            //Free up the ll_outframe_node
            free(ll_outframe_node);

            ll_outgoing_frame_length = ll_get_length(outgoing_frames_head);
        }
    }
    pthread_exit(NULL);

}
Exemplo n.º 7
0
Arquivo: sender.c Projeto: s4byun/SWP
void * run_sender(void * input_sender)
{    
    struct timespec   time_spec;
    struct timeval    curr_timeval;
    const int WAIT_SEC_TIME = 0;
    const long WAIT_USEC_TIME = 100000;
    Sender * sender = (Sender *) input_sender;    
    LLnode * outgoing_frames_head;
    struct timeval * expiring_timeval;
    long sleep_usec_time, sleep_sec_time;

    //This incomplete sender thread, at a high level, loops as follows:
    //1. Determine the next time the thread should wake up
    //2. Grab the mutex protecting the input_cmd/inframe queues
    //3. Dequeues messages from the input queue and adds them to the outgoing_frames list
    //4. Releases the lock
    //5. Sends out the messages

    while(1)
    {    
        outgoing_frames_head = NULL;

        //Get the current time
        gettimeofday(&curr_timeval, 
                NULL);

        //time_spec is a data structure used to specify when the thread should wake up
        //The time is specified as an ABSOLUTE (meaning, conceptually, you specify 9/23/2010 @ 1pm, wakeup)
        time_spec.tv_sec  = curr_timeval.tv_sec;
        time_spec.tv_nsec = curr_timeval.tv_usec * 1000;

        //Check for the next event we should handle
        expiring_timeval = sender_get_next_expiring_timeval(sender);

        //Perform full on timeout
        if (expiring_timeval == NULL)
        {
            time_spec.tv_sec += WAIT_SEC_TIME;
            time_spec.tv_nsec += WAIT_USEC_TIME * 1000;
        }
        else
        {
            //Take the difference between the next event and the current time
            sleep_usec_time = timeval_usecdiff(&curr_timeval,
                    expiring_timeval);

            //Sleep if the difference is positive
            if (sleep_usec_time > 0)
            {
                sleep_sec_time = sleep_usec_time/1000000;
                sleep_usec_time = sleep_usec_time % 1000000;   
                time_spec.tv_sec += sleep_sec_time;
                time_spec.tv_nsec += sleep_usec_time*1000;
            }   
        }

        //Check to make sure we didn't "overflow" the nanosecond field
        if (time_spec.tv_nsec >= 1000000000)
        {
            time_spec.tv_sec++;
            time_spec.tv_nsec -= 1000000000;
        }


        //*****************************************************************************************
        //NOTE: Anything that involves dequeing from the input frames or input commands should go 
        //      between the mutex lock and unlock, because other threads CAN/WILL access these structures
        //*****************************************************************************************
        pthread_mutex_lock(&sender->buffer_mutex);

        //Check whether anything has arrived
        int input_cmd_length = ll_get_length(sender->input_cmdlist_head);
        int inframe_queue_length = ll_get_length(sender->input_framelist_head);

        //Nothing (cmd nor incoming frame) has arrived, so do a timed wait on the sender's condition variable (releases lock)
        //A signal on the condition variable will wakeup the thread and reaquire the lock
        if (input_cmd_length == 0 &&
                inframe_queue_length == 0)
        {

            pthread_cond_timedwait(&sender->buffer_cv, 
                    &sender->buffer_mutex,
                    &time_spec);
        }
        //Implement this
        handle_incoming_acks(sender,
                &outgoing_frames_head);

        //Implement this
        handle_input_cmds(sender,
                &outgoing_frames_head);

        pthread_mutex_unlock(&sender->buffer_mutex);


        //Implement this
        handle_timedout_frames(sender,
                &outgoing_frames_head);

        //CHANGE THIS AT YOUR OWN RISK!
        //Send out all the frames
        int ll_outgoing_frame_length = ll_get_length(outgoing_frames_head);

        while(ll_outgoing_frame_length > 0)
        {
            LLnode * ll_outframe_node = ll_pop_node(&outgoing_frames_head);
            char * char_buf = (char *)  ll_outframe_node->value;

            //Don't worry about freeing the char_buf, the following function does that
            send_msg_to_receivers(char_buf);

            //Free up the ll_outframe_node
            free(ll_outframe_node);

            ll_outgoing_frame_length = ll_get_length(outgoing_frames_head);
        }
    }
    pthread_exit(NULL);
    return 0;
}
Exemplo n.º 8
0
Arquivo: sender.c Projeto: s4byun/SWP
void handle_input_cmds(Sender * sender,
        LLnode ** outgoing_frames_head_ptr)
{
    int input_cmd_length = ll_get_length(sender->input_cmdlist_head);

    //Split the message if it's too long
    ll_split_head(&sender->input_cmdlist_head, FRAME_PAYLOAD_SIZE - 1);

    //Recheck the command queue length to see if stdin_thread dumped a command on us
    input_cmd_length = ll_get_length(sender->input_cmdlist_head);

    while (input_cmd_length > 0) 
    {
        //Pop a node off and update the input_cmd_length
        LLnode * ll_input_cmd_node = ll_pop_node(&sender->input_cmdlist_head);
        input_cmd_length = ll_get_length(sender->input_cmdlist_head);

        //Cast to Cmd type and free up the memory for the node
        Cmd * outgoing_cmd = (Cmd *) ll_input_cmd_node->value;
        free(ll_input_cmd_node);

        //Convert uint16_t to string
        char* src = malloc(MAC_ADDR_SIZE);
        char* dst = malloc(MAC_ADDR_SIZE);
        sprintf(src, "%u", outgoing_cmd->src_id);
        sprintf(dst, "%u", outgoing_cmd->dst_id);

        int id = atoi(dst);

        if(send_q_size(sender, id) < WS)
        {
            Frame * outgoing_frame = (Frame *) malloc (sizeof(Frame));

            //Populate the outgoing frame's fields
            strncpy(outgoing_frame->receiver_addr, dst, MAC_ADDR_SIZE);
            strncpy(outgoing_frame->sender_addr, src, MAC_ADDR_SIZE);
            strncpy(outgoing_frame->data, outgoing_cmd->message, FRAME_PAYLOAD_SIZE);

            //Assign seqnum to the outgoing frame
            outgoing_frame->seqnum = sender->seqnum[id];

            char* raw_char_buf = convert_frame_to_char(outgoing_frame); 

            //Assign crc to the outgoing frame
            outgoing_frame->crc = crc8(raw_char_buf, MAX_FRAME_SIZE);

            free(raw_char_buf);

            //At this point, we don't need the outgoing_cmd
            free(outgoing_cmd->message);
            free(outgoing_cmd);

            //Update LFS
            sender->LFS[id] = sender->seqnum[id];

            //Convert the message to the outgoing_charbuf and send it
            char * outgoing_charbuf = convert_frame_to_char(outgoing_frame);
            //fprintf(stderr, "MESSAGE %s SENT\n", outgoing_frame->data);
            ll_append_node(outgoing_frames_head_ptr, outgoing_charbuf);

            sender->send_q_head[id][sender->seqnum[id] % WS]->frame = malloc(sizeof(Frame));

            //Store the sent frame in the sent queue
            memcpy(sender->send_q_head[id][sender->seqnum[id] % WS]->frame, outgoing_frame, sizeof(Frame)); 
            sender->send_q_head[id][sender->seqnum[id] % WS]->frame_timeout = NULL;

            free(outgoing_frame);
            sender->seqnum[id] = (sender->seqnum[id] == 255) ? 0 : sender->seqnum[id] + 1;
        }
        else
        {
            ll_append_node_at_front(&sender->input_cmdlist_head, outgoing_cmd);
            input_cmd_length = ll_get_length(sender->input_cmdlist_head);
            break;
        }
    }
}
Exemplo n.º 9
0
void handle_input_cmds(Sender * sender,
                       LLnode ** outgoing_frames_head_ptr)
{
    //TODO: Suggested steps for handling input cmd
    //    1) Dequeue the Cmd from sender->input_cmdlist_head
    //    2) Convert to Frame
    //    3) Set up the frame according to the sliding window protocol
    //    4) Compute CRC and add CRC to Frame

    int input_cmd_length = ll_get_length(sender->input_cmdlist_head);
    
        
    //Recheck the command queue length to see if stdin_thread dumped a command on us
    input_cmd_length = ll_get_length(sender->input_cmdlist_head);
    ll_split_head(&sender->input_cmdlist_head, FRAME_PAYLOAD_SIZE - 1);
    while (input_cmd_length > 0 && sender->sendQSize <= SWS)
    {
    //    fprintf(stderr, "%d %d\n", input_cmd_length, ll_get_length(sender->input_cmdlist_head));
    
        unsigned char upper = sender->LAR + SWS - 1;
        //printf("%d %d %d ", sender->LAR, upper, sender->seqNum);
        if (!((sender->LAR <= upper && 
               sender->seqNum >= sender->LAR &&
               sender->seqNum <= upper) ||
              (sender->LAR > upper &&
              (sender->seqNum >= sender->LAR ||
               sender->seqNum <= upper))))
            break;
        //Pop a node off and update the input_cmd_length
        LLnode * ll_input_cmd_node = ll_pop_node(&sender->input_cmdlist_head);
        input_cmd_length = ll_get_length(sender->input_cmdlist_head);

        //Cast to Cmd type and free up the memory for the node
        Cmd * outgoing_cmd = (Cmd *) ll_input_cmd_node->value;
        free(ll_input_cmd_node);
            

        //DUMMY CODE: Add the raw char buf to the outgoing_frames list
        //NOTE: You should not blindly send this message out!
        //      Ask yourself: Is this message actually going to the right receiver (recall that default behavior of send is to broadcast to all receivers)?
        //                    Does the receiver have enough space in in it's input queue to handle this message?
        //                    Were the previous messages sent to this receiver ACTUALLY delivered to the receiver?
        int msg_length = strlen(outgoing_cmd->message);
        if (msg_length > MAX_FRAME_SIZE)
        {
            //Do something about messages that exceed the frame size
            printf("<SEND_%d>: sending messages of length greater than %d is not implemented\n", sender->send_id, MAX_FRAME_SIZE);
        }
        else
        {
            //This is probably ONLY one step you want
            Frame * outgoing_frame = (Frame *) malloc (sizeof(Frame));
            strcpy(outgoing_frame->data, outgoing_cmd->message);
            outgoing_frame->src_id = outgoing_cmd->src_id;
            outgoing_frame->dst_id = outgoing_cmd->dst_id;
            outgoing_frame->seqNum = sender->seqNum;
            sender->seqNum++;
            //if (sender->seqNum >= SWS)
            //    sender->seqNum = 0;
            //if (sender->seqNum == 5)
            //    sender->seqNum++;

            //At this point, we don't need the outgoing_cmd
            free(outgoing_cmd->message);
            free(outgoing_cmd);

            //Convert the message to the outgoing_charbuf
            char * outgoing_charbuf = convert_frame_to_char(outgoing_frame);
            append_crc(outgoing_charbuf, MAX_FRAME_SIZE);
            //fprintf(stderr, "Sending %d with data %s\n", outgoing_frame->seqNum,outgoing_frame->data);
            ll_append_node(outgoing_frames_head_ptr,
                           outgoing_charbuf);
            int i = 0;
            for (; i < SWS; i++) {
                if (sender->sendQ[i].inuse == 0) {
                    sender->sendQSize++;
                    struct timeval * timeout = malloc(sizeof(struct timeval));
                    setTimeOutTime(timeout);
                    sender->sendQ[i].inuse = 1;
                    sender->sendQ[i].timeout = timeout;
                    sender->sendQ[i].msg =(Frame *)malloc(MAX_FRAME_SIZE);
                    memcpy(sender->sendQ[i].msg,outgoing_frame,MAX_FRAME_SIZE);
                    break;
                }
            }
            free(outgoing_frame);
        }
    }   
}
Exemplo n.º 10
0
Arquivo: sender.c Projeto: popacai/SWP
void handle_input_cmds(Sender * sender,
                       LLnode ** outgoing_frames_head_ptr)
{
    //TODO: Suggested steps for handling input cmd
    //    1) Dequeue the Cmd from sender->input_cmdlist_head
    //    2) Convert to Frame
    //    3) Set up the frame according to the sliding window protocol
    //    4) Compute CRC and add CRC to Frame

    int input_cmd_length = ll_get_length(sender->input_cmdlist_head);
    
        
    //Recheck the command queue length to see if stdin_thread dumped a command on us
    input_cmd_length = ll_get_length(sender->input_cmdlist_head);
    while (input_cmd_length > 0)
    {
        //Pop a node off and update the input_cmd_length
        LLnode * ll_input_cmd_node = ll_pop_node(&sender->input_cmdlist_head);
        input_cmd_length = ll_get_length(sender->input_cmdlist_head);

        //Cast to Cmd type and free up the memory for the node
        Cmd * outgoing_cmd = (Cmd *) ll_input_cmd_node->value;
        free(ll_input_cmd_node);
            

        //DUMMY CODE: Add the raw char buf to the outgoing_frames list
        //NOTE: You should not blindly send this message out!
        //      Ask yourself: Is this message actually going to the right receiver (recall that default behavior of send is to broadcast to all receivers)?
        //                    Does the receiver have enough space in in it's input queue to handle this message?
        //                    Were the previous messages sent to this receiver ACTUALLY delivered to the receiver?
        int msg_length = strlen(outgoing_cmd->message);
        if (msg_length > 0)
        {
	    //init id
	    sender->recv_id = outgoing_cmd->dst_id;
	    
	    //init sender
	    sender->LFS = -1;
	    sender->LAR = -1;
	    sender->SWS = 8;
	    sender->FSS = (msg_length + TEMP_SIZE - 1) / TEMP_SIZE;
	    //sender->FSS = (msg_length + TEMP_SIZE) / TEMP_SIZE;
	    sender->fin = 0;// not fin

	    free(sender->message);
	    sender->message = malloc(msg_length + 1);

	    strcpy(sender->message, outgoing_cmd->message);
	    sender->message_length = msg_length;

	    //init buffer;
	    sender->buffer = (struct Frame**) malloc(8 * sizeof(Frame*));
	    sender->timestamp = malloc(8 * sizeof(struct timeval));

	    int i;
	    struct timeval init_time;
	    gettimeofday(&init_time, NULL);
	    init_time.tv_sec += 999999;

	    for (i = 0; i < 8; i++)
	    {
		sender->buffer[i] = malloc(1);
		sender->timestamp[i] = init_time;
	    }


	    //print_sender(sender);

        }
        else
        {
            //This is probably ONLY one step you want
            Frame * outgoing_frame = (Frame *) malloc (sizeof(Frame));
            strcpy(outgoing_frame->data, outgoing_cmd->message);

            //At this point, we don't need the outgoing_cmd
            free(outgoing_cmd->message);
            free(outgoing_cmd);

            //Convert the message to the outgoing_charbuf
            char * outgoing_charbuf = convert_frame_to_char(outgoing_frame);
	    //char * outgoing_charbuf = add_chksum(outgoing_frame);
            ll_append_node(outgoing_frames_head_ptr,
                           outgoing_charbuf);
            free(outgoing_frame);
        }
    }   
}