Exemple #1
0
/*---------------------------------------------------------------------------*/
static void
handle_data(struct rudolph1_conn *c, struct rudolph1_datapacket *p)
{
  if(LT(c->version, p->h.version)) {
    PRINTF("%d.%d: rudolph1 new version %d, chunk %d\n",
	   rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
	   p->h.version, p->h.chunk);
    c->version = p->h.version;
    c->highest_chunk_heard = c->chunk = 0;
      if(p->h.chunk != 0) {
	send_nack(c);
      } else {
	write_data(c, 0, p->data, p->datalen);
	c->chunk = 1; /* Next chunk is 1. */
      }
      /*    }*/
  } else if(p->h.version == c->version) {
    PRINTF("%d.%d: got chunk %d (%d) highest heard %d\n",
	   rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
	   p->h.chunk, c->chunk, c->highest_chunk_heard);

    if(p->h.chunk == c->chunk) {
      PRINTF("%d.%d: received chunk %d\n",
	     rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
	     p->h.chunk);
      write_data(c, p->h.chunk, p->data, p->datalen);
      if(c->highest_chunk_heard < c->chunk) {
	c->highest_chunk_heard = c->chunk;
      }
      c->chunk++;
    } else if(p->h.chunk > c->chunk) {
      PRINTF("%d.%d: received chunk %d > %d, sending NACK\n",
	     rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
	     p->h.chunk, c->chunk);
      send_nack(c);
      c->highest_chunk_heard = p->h.chunk;
    } else if(p->h.chunk < c->chunk) {
      /* Ignore packets with a lower chunk number */
    }

    /* If we have heard a higher chunk number, we send a NACK so that
       we get a repair for the next packet. */
    
    if(c->highest_chunk_heard > p->h.chunk) {
      send_nack(c);
    }
  } else { /* p->h.version < c->current.h.version */
    /* Ignore packets with old version */
  }

}
static bool ast_write_data(struct drm_device *dev, u8 data)
{
	struct ast_private *ast = dev->dev_private;

	if (wait_nack(ast)) {
		send_nack(ast);
		ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, data);
		send_ack(ast);
		if (wait_ack(ast)) {
			send_nack(ast);
			return true;
		}
	}
	send_nack(ast);
	return false;
}
Exemple #3
0
/* called from layer 3, when a packet arrives for layer 4 */
void A_input(struct pkt packet)
{
    printf("CCH> A_input> Got packet\n");

    // isChecksumValid
    if(pkt_checksum_valid(&packet)) {
        printf("CCH> A_input> Valid checksum\n");

        // isACK
        if(strncmp(packet.payload, ACK, strlen(ACK)) == 0) {
            if(packet.acknum == last_pkt->seqnum) {
                printf("CCH> A_input> Received valid ACK\n");
                last_ack = &packet;
                stoptimer(A);
            } else {
                // We received an ACK we don't care about
                printf("CCH> A_input> Received invalid ACK (ignoring)\n");
            }
        // isNACK
        } else if (strncmp(packet.payload, NACK, strlen(ACK)) == 0) {
            printf("CCH> A_input> Received NACK\n");
            send_pkt(A, last_pkt);
        } else {
            // Message
            stoptimer(A);
            tolayer5(A, packet.payload);
        }
    } else {
        printf("CCH> A_input> Invalid checksum\n");
        send_nack(A, &packet);
        stoptimer(A);
        starttimer(A, TIMEOUT);
        return;
    }
}
static bool ast_read_data(struct drm_device *dev, u8 *data)
{
	struct ast_private *ast = dev->dev_private;
	u8 tmp;

	*data = 0;

	if (wait_ack(ast) == false)
		return false;
	tmp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd3, 0xff);
	*data = tmp;
	if (wait_nack(ast) == false) {
		send_nack(ast);
		return false;
	}
	send_nack(ast);
	return true;
}
static bool ast_write_cmd(struct drm_device *dev, u8 data)
{
	struct ast_private *ast = dev->dev_private;
	int retry = 0;
	if (wait_nack(ast)) {
		send_nack(ast);
		ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, data);
		send_ack(ast);
		set_cmd_trigger(ast);
		do {
			if (wait_ack(ast)) {
				clear_cmd_trigger(ast);
				send_nack(ast);
				return true;
			}
		} while (retry++ < 100);
	}
	clear_cmd_trigger(ast);
	send_nack(ast);
	return false;
}
Exemple #6
0
/*---------------------------------------------------------------------------*/
static void
recv(struct stbroadcast_conn *stbroadcast)
{
  struct rudolph0_conn *c = (struct rudolph0_conn *)stbroadcast;
  struct rudolph0_datapacket *p = packetbuf_dataptr();

  if(p->h.type == TYPE_DATA) {
    if(c->current.h.version != p->h.version) {
      PRINTF("rudolph0 new version %d\n", p->h.version);
      c->current.h.version = p->h.version;
      c->current.h.chunk = 0;
      c->cb->write_chunk(c, 0, RUDOLPH0_FLAG_NEWFILE, p->data, 0);
      if(p->h.chunk != 0) {
	send_nack(c);
      } else {
	c->cb->write_chunk(c, 0, RUDOLPH0_FLAG_NONE, p->data, p->datalen);
	c->current.h.chunk++;
      }
    } else if(p->h.version == c->current.h.version) {
      if(p->h.chunk == c->current.h.chunk) {
	PRINTF("received chunk %d\n", p->h.chunk);
	if(p->datalen < RUDOLPH0_DATASIZE) {
	  c->cb->write_chunk(c, c->current.h.chunk * RUDOLPH0_DATASIZE,
			     RUDOLPH0_FLAG_LASTCHUNK, p->data, p->datalen);
	} else {
	  c->cb->write_chunk(c, c->current.h.chunk * RUDOLPH0_DATASIZE,
			     RUDOLPH0_FLAG_NONE, p->data, p->datalen);
	}
	c->current.h.chunk++;
	
      } else if(p->h.chunk > c->current.h.chunk) {
	PRINTF("received chunk %d > %d, sending NACK\n", p->h.chunk, c->current.h.chunk);
	send_nack(c);
      }
    } else { /* p->h.version < c->current.h.version */
      /* Ignore packets with old version */
    }
  }
}
void UdpMulticastChannel::notify_received(char* data, size_t sz,boost::asio::ip::udp::endpoint sender_endpoint)
{
    std::vector<unsigned>* lost;
    NetworkPacket* packet = new NetworkPacket;
    if (packet->ParseFromArray(data,sz))
    {
        lost = incoming->add_packet(packet);
        if (lost->size() > 0 )
        {
            send_nack(packet,sender_endpoint,lost);
        }
    }
    //std::cout << "Received: " << sz << " bytes " << std::endl;
    receive_from_network();
}
Exemple #8
0
void* rms_manager(void* arg) {
	//init
	int 	nfound;
	int 	ret;
	int		err;
	int		itr;
	int		ipc_read;
	int		count;
	int 	gottime;
	char 	*data;
	float   t1;
	float   t2;
	fd_set	readset;
	struct 	timeval timeout;
	struct 	timeval ratechk;
	unsigned long 	*keys;
	unsigned long 	*seq;

	rms_meta_msg *msg;
	rms_meta_peer *peer;
	int		addr_len;
	rms_msg_hbeat *hbeat;

	rmscb *rmsb = (rmscb*)arg;

	gottime = 0;

	while(rmsb->active) {
		FD_ZERO(&readset);
		FD_SET(rmsb->ipc_sock, &readset);
		FD_SET(rmsb->mcast_sock, &readset);

		timeout.tv_sec	= 1;
		timeout.tv_usec = 0;

		nfound= select(rmsb->maxsock, &readset, (fd_set*)0, (fd_set*)0, &timeout);

		if(nfound > 0) {
			//available to read on mcast port
			if((nfound = FD_ISSET(rmsb->mcast_sock, &readset)) > 0) {
				msg = alloc_meta_msg();
				ret = recvfrom(rmsb->mcast_sock,
						&msg->buf,
						msg->size,
						0,
						(struct sockaddr*)&rmsb->recv_addr,
						&addr_len);
				printf("\n\tRMC: recvd %d bytes from %ld",
					ret,
					rmsb->recv_addr.sin_addr.s_addr);
				if(ret < sizeof(rms_msg_hdr)) {
					//not enough data
					continue;
				}
				msg->hdr->length = ntohs(msg->hdr->length);
				msg->hdr->sequence = ntohl(msg->hdr->sequence);
				msg->hdr->id  = ntohl(msg->hdr->id);
				if(ret < msg->hdr->length + sizeof(rms_msg_hdr)) {
					//not enough data
					continue;
				}
				switch(msg->hdr->type) {
				case RMS_DATA:
					if(!htbl_get(rmsb->ht_peers, msg->hdr->id, (void*)&peer)) {
						//peer not registered, drop packet
						release_meta_msg(msg);
					}
					else {
					peer->sequence_sent = msg->hdr->sequence;
					if(peer->sequence_rcvd + 1 != msg->hdr->sequence) {
						//gap in sequence num
						if(peer->sequence_rcvd < msg->hdr->sequence) {
							//cache msg
							htbl_put(peer->ht_unseq_msgs, msg->hdr->sequence, msg);

							//send NACK
							msg = alloc_meta_msg();
							send_nack(rmsb, peer, msg);
						}
						//else retransmitted data, drop packet
						release_meta_msg(msg);
					}
					else {
						//in sequence
						//syncqueue_signal_data(rmsb->inmsgq, msg);
						nfound = msg->hdr->length;
						ret = send(rmsb->ipc_sock, &nfound, sizeof(int),0);
						ret = 0;
						while(ret < nfound) {
							ret+=send(rmsb->ipc_sock, msg->data+ret, nfound-ret, 0);
						}
						peer->sequence_rcvd++;

						//release out of sequence data if any
						while(htbl_remove(peer->ht_unseq_msgs, peer->sequence_sent, (void*)&msg)) {
							//syncqueue_signal_data(rmsb->inmsgq, msg);
							nfound = msg->hdr->length;
							ret = send(rmsb->ipc_sock, &nfound, sizeof(int),0);
							ret = 0;
							while(ret < nfound) {
								ret+=send(rmsb->ipc_sock, msg->data+ret, nfound-ret, 0);
							}
							peer->sequence_rcvd++;
						}
					}}
					break;

				case RMS_HEARTBEAT:
					hbeat = (rms_msg_hbeat*) msg->data;
					data = msg->data + sizeof(rms_msg_hbeat);
					if(!htbl_get(rmsb->ht_peers, msg->hdr->id, (void*)&peer)) {
						//peer not registered, register it
						if(hbeat->namelen) {
							rms_meta_peer_init(&peer, msg->data, msg->hdr->id);
						}
						else {
							rms_meta_peer_init(&peer, "noname", msg->hdr->id);
						}

						htbl_put(rmsb->ht_peers, peer->id, peer);
						mqueue_add(rmsb->mq_peers, peer);
					}

					peer->lost = ntohs(hbeat->lost);
					//check for namelen
					if(hbeat->namelen) {
						hbeat->namelen = htonl(hbeat->namelen);
						data+=hbeat->namelen;
					}

					//check for acks
					if(hbeat->acks) {
						seq = (unsigned long*)data;
						hbeat->acks = ntohs(hbeat->acks);
						for(itr=0;itr < hbeat->acks; itr++) {
							if(ntohl(seq[itr*2])== rmsb->self->id) {
								peer->sequence_sync = ntohl(seq[itr*2 + 1]);
								break;
							}
						}
						data+=hbeat->acks*2*sizeof(long);
					}

					//check for piggybacked data
					if(hbeat->pgback) {
						hbeat->pgback = ntohs(hbeat->pgback);
					}

					gettimeofday(&timeout, NULL);
					gottime=1;
					peer->last_hbeat.tv_sec = timeout.tv_sec;
					peer->last_hbeat.tv_usec = timeout.tv_usec;
					if(peer->sequence_sent + 1 != msg->hdr->sequence) {
						//gap in sequence num
						if(peer->sequence_sent < msg->hdr->sequence) {
							//send NACK
							send_nack(rmsb, peer, msg);
						}
					}
					release_meta_msg(msg);
					break;

				case RMS_NACK:
					seq = (unsigned long*)msg->data;
					count = seq[0];
					rmsb->ucast_addr.sin_addr.s_addr = htonl(msg->hdr->id);
					for(itr=1; itr <= count; itr++) {
						seq[itr]=ntohl(seq[itr]);
						if(htbl_get(rmsb->outmsgbuf, seq[itr], (void*)&msg)) {
							ret = sendto(rmsb->mcast_sock,
									msg->buf,
									msg->length + sizeof(rms_msg_hdr),
									0,
									(struct sockaddr*) &rmsb->ucast_addr,
									sizeof(rmsb->ucast_addr));
						}
					}
					break;

				case RMS_LEAVE:
					if(htbl_remove(rmsb->ht_peers, msg->hdr->id, (void*)&peer)) {
						//clean up unseq msgs buffer
						count = htbl_count(peer->ht_unseq_msgs);
						keys = (unsigned long*)malloc(count*sizeof(unsigned long));
						memset(keys,0,count*sizeof(unsigned long));
						count = htbl_enum_keys(peer->ht_unseq_msgs, (void*)keys, count);
						for(itr = 0; itr < count; itr++) {
							if(htbl_remove(peer->ht_unseq_msgs, keys[itr], (void*)&msg)) {
								release_meta_msg(msg);
							}
						}
						free(keys);
						mqueue_remove_item(rmsb->mq_peers, peer);
						rms_meta_peer_free(peer);
					}
					break;

				case RMS_ACK:
				case RMS_JOIN:
				case RMS_CERT:
				default:
					//unimplemented options, drop packet
					release_meta_msg(msg);
					break;
				}
			}

			//available to read on ipc port
			if((nfound = FD_ISSET(rmsb->ipc_sock, &readset)) > 0) {
				err = 1;
				ret = recv(rmsb->ipc_sock,
						&ipc_read,
						sizeof(int),
						0);
				if(ret > 0) {
					//alloc buffer
					msg = alloc_meta_msg();
					if(ipc_read > rmsb->bufsize) {
						rmsb->bufsize =  ipc_read * 1.5;
						msg->size = rmsb->bufsize;
						msg->buf = realloc(msg->buf,msg->size);
						msg->hdr = (rms_msg_hdr*)msg->buf;
						msg->data = msg->buf + sizeof(rms_msg_hdr);
					}
					ret = recv(rmsb->ipc_sock,
							&msg->data,
							ipc_read,
							0);
					if(ret == ipc_read) {
						msg->length =  ipc_read;
						msg->hdr->type = RMS_DATA;
						msg->hdr->length = htons(msg->length);
						msg->hdr->sequence = htonl(rmsb->self->sequence_sent);
						msg->hdr->id  = htonl(rmsb->self->id);
						ret = sendto(rmsb->mcast_sock,
								msg->buf,
								ret + sizeof(rms_msg_hdr),
								0,
								(struct sockaddr*) &rmsb->mcast_addr,
								sizeof(rmsb->mcast_addr));
						if (ret > 0) {
							htbl_put(rmsb->outmsgbuf, rmsb->self->sequence_sent, msg);
							rmsb->self->sequence_sent++;
							rmsb->msg_this_sec++;
							err = 0;
						}
					}
				}
				if(err) {
					release_meta_msg(msg);
				}
			}
		}

		//do periodic things
		if(!gottime)
			gettimeofday(&timeout, NULL);
		gottime=0;

		//heartbeat
		if(timeout.tv_sec - rmsb->self->last_hbeat.tv_sec >= rmsb->hbeat_rate) {
			//time for hbeat
			send_hbeat(rmsb, NULL,0);

			//check msg send rate
			t1 = (float)timeout.tv_sec + ((float)timeout.tv_usec)/1000000;
			t2 = (float)rmsb->self->last_hbeat.tv_sec
				+ ((float)rmsb->self->last_hbeat.tv_usec)/1000000;

			rmsb->msg_per_sec = rmsb->msg_this_sec/(t1-t2);

			//calculate heartbeat rate
			rmsb->hbeat_rate  = RMS_RATE_FACTOR / rmsb->msg_per_sec;

			//clamp
			if(rmsb->hbeat_rate > 5)
				rmsb->hbeat_rate = 5;
			else if(rmsb->hbeat_rate < 1)
				rmsb->hbeat_rate = 1;

			rmsb->msg_this_sec = 0;

			rmsb->self->last_hbeat.tv_sec = timeout.tv_sec;
			rmsb->self->last_hbeat.tv_usec = timeout.tv_usec;
		}

		//if acks are used
		if(rmsb->hb_ack) {
			//clear buffers
			count = mqueue_size(rmsb->mq_peers);
			for(itr=0; itr < count; itr++) {
				peer = (rms_meta_peer*) mqueue_peek_at_index(rmsb->mq_peers, itr);
				if(peer->sequence_sync < rmsb->self->sequence_sync);
					rmsb->self->sequence_sync = peer->sequence_sync;
			}
			while(rmsb->oldest_seq < rmsb->self->sequence_sync){
				if(htbl_remove(rmsb->outmsgbuf, rmsb->oldest_seq, (void*)&msg)) {
					release_meta_msg(msg);
				}
				rmsb->oldest_seq++;
			}
		}
	}
	//send leave message
	msg = alloc_meta_msg();
	msg->hdr->type = RMS_LEAVE;
	msg->hdr->length = 0;
	msg->hdr->sequence = htonl(rmsb->self->sequence_sent);
	msg->hdr->id  = htonl(rmsb->self->id);
	ret = sendto(rmsb->mcast_sock,
			msg->buf,
			sizeof(rms_msg_hdr),
			0,
			(struct sockaddr*) &rmsb->mcast_addr,
			sizeof(rmsb->mcast_addr));
	release_meta_msg(msg);
	return 0;
}
Exemple #9
0
/*---------------------------------------------------------------------------*/
void
rudolph0_force_restart(struct rudolph0_conn *c)
{
  c->current.h.chunk = 0;
  send_nack(c);
}
Exemple #10
0
/*---------------------------------------------------------------------*/
static
PT_THREAD(recv_udpthread(struct pt *pt))
{
  int len;
  struct codeprop_udphdr *uh = (struct codeprop_udphdr *)uip_appdata;

  /*  if(uip_newdata()) {
    PRINTF(("recv_udpthread: id %d uh->id %d\n", s.id, htons(uh->id)));
    }*/

  PT_BEGIN(pt);

  while(1) {

    do {
      PT_WAIT_UNTIL(pt, uip_newdata() &&
		    uh->type == HTONS(TYPE_DATA) &&
		    htons(uh->id) > s.id);

      if(htons(uh->addr) != 0) {
	s.addr = 0;
	send_nack(uh, 0);
      }

    } while(htons(uh->addr) != 0);

    /*    leds_on(LEDS_YELLOW);
	  beep_down(10000);*/

    s.addr = 0;
    s.id = htons(uh->id);
    s.len = htons(uh->len);

    timer_set(&s.timer, CONNECTION_TIMEOUT);
/*     process_post(PROCESS_BROADCAST, codeprop_event_quit, (process_data_t)NULL); */

    while(s.addr < s.len) {

      if(htons(uh->addr) == s.addr) {
	/*	leds_blink();*/
	len = uip_datalen() - UDPHEADERSIZE;
	if(len > 0) {
	  /*	  eeprom_write(EEPROMFS_ADDR_CODEPROP + s.addr,
		  &uh->data[0], len);*/
	  cfs_seek(fd, s.addr, CFS_SEEK_SET);
	  cfs_write(fd, &uh->data[0], len);

	  /*	  beep();*/
	  PRINTF(("Saved %d bytes at address %d, %d bytes left\n",
		  uip_datalen() - UDPHEADERSIZE, s.addr,
		  s.len - s.addr));

	  s.addr += len;
	}

      } else if(htons(uh->addr) > s.addr) {
	PRINTF(("sending nack since 0x%x != 0x%x\n", htons(uh->addr), s.addr));
	send_nack(uh, s.addr);
      }

      if(s.addr < s.len) {

	/*	timer_set(&s.nacktimer, NACK_TIMEOUT);*/

	do {
	  timer_set(&s.nacktimer, HIT_NACK_TIMEOUT);
	  PT_YIELD_UNTIL(pt, timer_expired(&s.nacktimer) ||
			 (uip_newdata() &&
			  uh->type == HTONS(TYPE_DATA) &&
			  htons(uh->id) == s.id));
	  if(timer_expired(&s.nacktimer)) {
	    send_nack(uh, s.addr);
	  }
	} while(timer_expired(&s.nacktimer));
      }

    }

    /*    leds_off(LEDS_YELLOW);
	  beep_quick(2);*/
    /*    printf("Received entire bunary over udr\n");*/
    codeprop_start_program();
    PT_EXIT(pt);
  }

  PT_END(pt);
}
static void clear_cmd(struct ast_private *ast)
{
	send_nack(ast);
	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, 0x00);
}
error_code_t ls_remote(receiver_param *rp, const char *command)
{
    struct frame_t frame_info;
    struct frame_t recv_frame_info;
    char *recv_frame;
    char *frame;
    char buffer[32];
    int done;
    error_code_t e = OK;
    int timeout_count = 0;
    
    int sequence = 0;
    
    if (command[2] != ' ' && command[2] != '\0')
        return INV_CMD;
    
    frame_info.size = strlen(&command[3]);
    frame_info.sequence = 0;
    frame_info.type = 'L';
    frame_info.data = malloc(frame_info.size);
    strcpy(frame_info.data, &command[3]); 
    frame = create_frame(&frame_info);
    
    done = 0;
    while (!done)
    {
        if (timeout_count == 0)
        {
            if (send(rp->source_sd, frame, FRAME_MAX_SIZE, 0) <= 0)
                perror("WARNING");
        }
        pthread_mutex_lock(&receive_queue_mutex);
        recv_frame = list_dequeue(rp->queue);
        pthread_mutex_unlock(&receive_queue_mutex);
        
        if (recv_frame)
        {
            if (decode_frame(recv_frame, &recv_frame_info))
            {
                if (sequence == recv_frame_info.sequence)
                {
                    if (recv_frame_info.type == 'X' || recv_frame_info.type == 'Z')
                    {
                        send_ack(rp->source_sd, sequence);
                        sequence = (sequence+1) % (FRAME_SEQ_MAX+1);
                        memcpy(buffer, recv_frame_info.data, recv_frame_info.size);
                        buffer[recv_frame_info.size] = '\0';
                        printf("%s", buffer);
                        if (recv_frame_info.type == 'Z') done = 1;
                    }
                    else if (recv_frame_info.type == 'N')
                        timeout_count = 0;
                }
                else if (abs((frame_info.sequence-sequence) % (FRAME_SEQ_MAX+1)) < WINDOW_SIZE)
                {
                    send_nack(rp->source_sd, frame_info.sequence);
                }
                else
                {
                    send_ack(rp->source_sd, frame_info.sequence);
                }
                free(recv_frame_info.data);
            }
            else
            {
                send_nack(rp->source_sd, sequence);
            }
            free(recv_frame);
        }
        else
        {
            usleep(2);
            timeout_count = (timeout_count + 1) % (TIMEOUT_LIMIT + 1);
        }
    }
    free(frame);
    free(frame_info.data);
    
    return e;
}
Exemple #13
0
/*---------------------------------------------------------------------------*/
static void
recv(struct polite_conn *polite)
{
  struct rudolph2_conn *c = (struct rudolph2_conn *)polite;
  struct rudolph2_hdr *hdr = packetbuf_dataptr();

  /* Only accept NACKs from nodes that are farther away from the base
     than us. */

  if(hdr->type == TYPE_NACK && hdr->hops_from_base > c->hops_from_base) {
    c->nacks++;
    PRINTF("%d.%d: Got NACK for %d:%d (%d:%d)\n",
	   rimeaddr_node_addr.u8[RIMEADDR_SIZE-2], rimeaddr_node_addr.u8[RIMEADDR_SIZE-1],
	   hdr->version, hdr->chunk,
	   c->version, c->rcv_nxt);
    if(hdr->version == c->version) {
      if(hdr->chunk < c->rcv_nxt) {
	c->snd_nxt = hdr->chunk;
	send_data(c, SEND_INTERVAL);
      }
    } else if(LT(hdr->version, c->version)) {
      c->snd_nxt = 0;
      send_data(c, SEND_INTERVAL);
    }
  } else if(hdr->type == TYPE_DATA) {
    if(hdr->hops_from_base < c->hops_from_base) {
      /* Only accept data from nodes that are closer to the base than
	 us. */
      c->hops_from_base = hdr->hops_from_base + 1;
      if(LT(c->version, hdr->version)) {
	PRINTF("%d.%d: rudolph2 new version %d, chunk %d\n",
	       rimeaddr_node_addr.u8[RIMEADDR_SIZE-2], rimeaddr_node_addr.u8[RIMEADDR_SIZE-1],
	       hdr->version, hdr->chunk);
	c->version = hdr->version;
	c->snd_nxt = c->rcv_nxt = 0;
	c->flags &= ~FLAG_LAST_RECEIVED;
	c->flags &= ~FLAG_LAST_SENT;
	if(hdr->chunk != 0) {
	  send_nack(c);
	} else {
	  packetbuf_hdrreduce(sizeof(struct rudolph2_hdr));
	  write_data(c, 0, packetbuf_dataptr(), packetbuf_totlen());
	}
      } else if(hdr->version == c->version) {
	PRINTF("%d.%d: got chunk %d snd_nxt %d rcv_nxt %d\n",
	       rimeaddr_node_addr.u8[RIMEADDR_SIZE-2], rimeaddr_node_addr.u8[RIMEADDR_SIZE-1],
	       hdr->chunk, c->snd_nxt, c->rcv_nxt);
	
	if(hdr->chunk == c->rcv_nxt) {
	  int len;
	  packetbuf_hdrreduce(sizeof(struct rudolph2_hdr));
	  PRINTF("%d.%d: received chunk %d len %d\n",
		 rimeaddr_node_addr.u8[RIMEADDR_SIZE-2], rimeaddr_node_addr.u8[RIMEADDR_SIZE-1],
		 hdr->chunk, packetbuf_totlen());
	  len = packetbuf_totlen();
	  write_data(c, hdr->chunk, packetbuf_dataptr(), packetbuf_totlen());
	  c->rcv_nxt++;
	  if(len < RUDOLPH2_DATASIZE) {
	    c->flags |= FLAG_LAST_RECEIVED;
	    send_data(c, RESEND_INTERVAL);
	    ctimer_set(&c->t, RESEND_INTERVAL, timed_send, c);
	  }
	} else if(hdr->chunk > c->rcv_nxt) {
	  PRINTF("%d.%d: received chunk %d > %d, sending NACK\n",
		 rimeaddr_node_addr.u8[RIMEADDR_SIZE-2], rimeaddr_node_addr.u8[RIMEADDR_SIZE-1],
		 hdr->chunk, c->rcv_nxt);
	  send_nack(c);
	} else if(hdr->chunk < c->rcv_nxt) {
	  /* Ignore packets with a lower chunk number */
	}
      }
    }
  }
}
Exemple #14
0
void process_cmd(struct cmd_frame_t *cmd)
{
        int res;
        
        reply.status = ACK; // change to NACK as necessary
        reply.cmd = cmd->cmd;

        switch (cmd->cmd) {
        case CMD_ECHO:
                reply.data[0] = cmd->echo.length;
                memcpy(&reply.data[1], cmd->echo.data, cmd->echo.length);
                send_reply(&reply, cmd->echo.length+3);
                break;

        case CMD_RESET:
                if (cmd->reset_magic == RESET_MAGIC) {
                        usb_peripheral_reset();
                        CREG_M4MEMMAP = 0x10400000;
                        scb_reset_system();
                } else {
                        send_nack();
                }
                break;

        case CMD_GET_EVENT_COUNTERS:
        {
                struct event_counters counters = get_last_event_counters();
                memcpy(reply.data, &counters, sizeof(struct event_counters));
                send_reply(&reply, 2+sizeof(struct event_counters));
                break;
        }

        case CMD_GET_STAGE_GAINS:
                memcpy(reply.data, stage_fb_gains, sizeof(stage_fb_gains));
                send_reply(&reply, 2+sizeof(stage_fb_gains));
                break;

        case CMD_SET_STAGE_GAINS:
                memcpy(stage_fb_gains, cmd->set_stage_gains, sizeof(stage_fb_gains));
                send_ack();
                break;
                
        case CMD_GET_STAGE_SETPOINT:
                memcpy(reply.data, stage_fb_setpoint, sizeof(stage_fb_setpoint));
                send_reply(&reply, 2+sizeof(stage_fb_setpoint));
                break;

        case CMD_SET_STAGE_SETPOINT:
                memcpy(stage_fb_setpoint, cmd->set_stage_setpoint, sizeof(stage_fb_setpoint));
                send_ack();
                break;

        case CMD_GET_PSD_GAINS:
                memcpy(reply.data, psd_fb_gains, sizeof(psd_fb_gains));
                send_reply(&reply, 2+sizeof(psd_fb_gains));
                break;

        case CMD_SET_PSD_GAINS:
                memcpy(psd_fb_gains, cmd->set_psd_gains, sizeof(psd_fb_gains));
                send_ack();
                break;

        case CMD_GET_PSD_SETPOINT:
                memcpy(reply.data, psd_fb_setpoint, sizeof(psd_fb_setpoint));
                send_reply(&reply, 2+sizeof(psd_fb_setpoint));
                break;

        case CMD_SET_PSD_SETPOINT:
                memcpy(psd_fb_setpoint, cmd->set_psd_setpoint, sizeof(psd_fb_setpoint));
                send_ack();
                break;
        
        case CMD_GET_MAX_ERROR:
                memcpy(reply.data, &max_error, sizeof(max_error));
                send_reply(&reply, 2+sizeof(max_error));
                break;

        case CMD_SET_MAX_ERROR:
                max_error = cmd->set_max_error;
                send_ack();
                break;

        case CMD_GET_OUTPUT_GAINS:
        {
                fixed16_t* tmp = (fixed16_t*) reply.data;
                for (unsigned int i=0; i<STAGE_OUTPUTS; i++) {
                        *tmp = stage_outputs[i].p_gain; tmp++;
                        *tmp = stage_outputs[i].i_gain; tmp++;
                }
                send_reply(&reply, 2+2*STAGE_OUTPUTS*sizeof(fixed16_t));
                break;
        }

        case CMD_SET_OUTPUT_GAINS:
        {
                for (unsigned int i=0; i<STAGE_OUTPUTS; i++) {
                        stage_outputs[i].p_gain = cmd->set_output_gains[i][0];
                        stage_outputs[i].i_gain = cmd->set_output_gains[i][1];
                }
                send_ack();
                break;
        }

        case CMD_GET_OUTPUT_TAUS:
        {
                for (unsigned int i=0; i<STAGE_OUTPUTS; i++) {
                        reply.data[i] = pi_get_tau(&stage_outputs[i]);
                }
                send_reply(&reply, 2+3);
                break;
        }

        case CMD_SET_OUTPUT_TAUS:
        {
                for (unsigned int i=0; i<STAGE_OUTPUTS; i++) {
                        pi_set_tau(&stage_outputs[i], cmd->set_output_taus[i]);
                }
                send_ack();
                break;
        }

        case CMD_GET_ADC_FREQ:
                reply.data32[0] = 0; //TODO adc_get_trigger_freq();
                send_reply(&reply, 2+4);
                break;

        case CMD_SET_ADC_FREQ:
                adc_set_trigger_freq(cmd->set_adc_freq);
                send_ack();
                break;
                
        case CMD_GET_ADC_TRIGGER_MODE:
                reply.data[0] = adc_get_trigger_mode();
                send_reply(&reply, 2+1);
                break;

        case CMD_SET_ADC_TRIGGER_MODE:
                adc_set_trigger_mode(cmd->set_adc_trigger_mode);
                send_ack();
                break;

        case CMD_START_ADC_STREAM:
                adc_streaming = true;
                send_ack();
                break;

        case CMD_STOP_ADC_STREAM:
                adc_streaming = false;
                adc_flush();
                send_ack();
                break;

        case CMD_FLUSH_ADC_STREAM:
                if (adc_flush() == 0) {
                        send_ack();
                } else {
                        send_nack();
                }
                break;

        case CMD_GET_ADC_DECIMATION:
        {
                reply.data32[0] = adc_get_decimation();
                send_reply(&reply, 2+4);
                break;
        }
                
        case CMD_SET_ADC_DECIMATION:
                if (adc_set_decimation(cmd->set_adc_decimation) == 0) {
                        send_ack();
                } else {
                        send_nack();
                }
                break;

        case CMD_GET_FEEDBACK_FREQ:
        {
                unsigned int freq = feedback_get_loop_freq();
                reply.data32[0] = freq;
                send_reply(&reply, 2+4);
                break;
        }

        case CMD_SET_FEEDBACK_FREQ:
                feedback_set_loop_freq(cmd->set_feedback_freq);
                send_ack();
                break;

        case CMD_GET_FEEDBACK_MODE:
                reply.data[0] = feedback_get_mode();
                send_reply(&reply, 3);
                break;

        case CMD_SET_FEEDBACK_MODE:
                feedback_set_mode(cmd->set_feedback_mode);
                send_ack();
                break;

        case CMD_SET_RAW_POS:
                if (feedback_set_position(cmd->set_raw_pos) == 0) {
                        send_ack();
                } else {
                        send_nack();
                }
                break;

        case CMD_CLEAR_PATH:
                clear_path();
                send_ack();
                break;
                
        case CMD_ENQUEUE_POINTS:
                res = 0;
                if (cmd->enqueue_points.npts > 0)
                        res = enqueue_points((uint16_t*) &cmd->enqueue_points.points, cmd->enqueue_points.npts);
                if (res == -1 || res == 0) {
                        reply.data[0] = res != -1; // were the points added?
                        reply.data[1] = is_path_running();
                        send_reply(&reply, 4);
                } else {
                        send_nack();
                }
                break;

        case CMD_START_PATH:
                if (start_path(cmd->start_path.freq, cmd->start_path.synchronous_adc) == 0) {
                        send_ack();
                } else {
                        send_nack();
                }
                break;

        case CMD_SET_EXCITATION:
        {
                struct set_excitation* const se = &cmd->set_excitation;
                struct excitation_buffer* const exc = &excitations[se->channel];

                if ((se->length + se->offset > MAX_EXCITATION_LENGTH)
                    || (se->channel >= 3))
                {
                        send_nack();
                        break;
                }

                exc->length = 0;
                exc->offset = 0;
                if (se->length != 0) {
                        memcpy(&exc->samples[se->offset],
                               &se->samples,
                               sizeof(uint16_t) * se->length);
                }
                exc->length = se->total_length;
                send_ack();
                break;
        }

        case CMD_GET_SEARCH_STEP:
                memcpy(reply.data, search_fb_step,
                       sizeof(search_fb_step));
                send_reply(&reply, 2+sizeof(search_fb_step));
                break;

        case CMD_SET_SEARCH_STEP:
                memcpy(search_fb_step, cmd->set_search_step,
                       sizeof(search_fb_step));
                send_ack();
                break;

        case CMD_GET_SEARCH_OBJ_GAINS:
                memcpy(reply.data, search_obj_gains,
                       sizeof(search_obj_gains));
                send_reply(&reply, 2+sizeof(search_obj_gains));
                break;

        case CMD_SET_SEARCH_OBJ_GAINS:
                memcpy(search_obj_gains, cmd->set_search_obj_gains,
                       sizeof(search_obj_gains));
                send_ack();
                break;

        case CMD_GET_SEARCH_OBJ_THRESH:
                memcpy(reply.data, &search_obj_thresh,
                       sizeof(search_obj_thresh));
                send_reply(&reply, 2+sizeof(search_obj_thresh));
                break;

        case CMD_SET_SEARCH_OBJ_THRESH:
                search_obj_thresh = cmd->set_search_obj_thresh,
                send_ack();
                break;

        case CMD_GET_COARSE_FB_PARAMS:
                memcpy(reply.data, &coarse_fb_channels,
                       sizeof(coarse_fb_channels));
                send_reply(&reply, 2+sizeof(coarse_fb_channels));
                break;

        case CMD_SET_COARSE_FB_PARAMS:
                memcpy(coarse_fb_channels, cmd->set_coarse_fb_params,
                       sizeof(coarse_fb_channels));
                send_ack();
                break;

        default:
                send_nack();
                return;
        }
}
Exemple #15
0
/*---------------------------------------------------------------------------*/
static void
handle_data(struct rudolph1mh_conn *c, struct rudolph1mh_datapacket *p)
{
  //Only called if partner is correct of NULL
  PRINTF("Handle P: %d:%d - %d\n",
         c->partner.u8[0], c->partner.u8[1], p->h.chunk);
  if(p->h.chunk == 0) { //New stream
    PRINTF("%d.%d: rudolph1mh new v_id %d, chunk %d\n",
        rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
        p->h.s_id, p->h.chunk);
    c->s_id = p->h.s_id;
    c->highest_chunk = c->chunk = 0;
    if(p->h.chunk != 0) {
      send_nack(c);
    }
    else {
       if(!c->cb->write_chunk){
         printf("No write-callback\n");
         return;
       }
      c->cb->write_chunk(c, 0, RUDOLPH1MH_FLAG_NEWFILE, p->data, 0);
      write_data(c, 0, p->data, p->datalen);
      c->chunk = 1; /* Next chunk is 1. */
      //ctimer_set(&c->t, send_interval * 30, send_next_packet, c);
    }
    /*    }*/
  }
  else if(p->h.s_id == c->s_id) {

    PRINTF("%d.%d: got chunk %d (%d) highest heard %d\n",
        rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
        p->h.chunk, c->chunk, c->highest_chunk);

    if(p->h.chunk == c->chunk) {
      PRINTF("%d.%d: received chunk %d\n",
          rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
          p->h.chunk);
      write_data(c, p->h.chunk, p->data, p->datalen);
      if(c->highest_chunk < c->chunk) {
        c->highest_chunk = c->chunk;
      }
      c->chunk++;
    }
    else if(p->h.chunk > c->chunk) {
      PRINTF("%d.%d: received chunk %d > %d, sending NACK\n",
          rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
          p->h.chunk, c->chunk);
      send_nack(c);
      c->highest_chunk = p->h.chunk;
    }
    else if(p->h.chunk < c->chunk) {
      /* Ignore packets with a lower chunk number */
    }

    /* If we have heard a higher chunk number, we send a NACK so that
     we get a repair for the next packet. */

    if(c->highest_chunk > p->h.chunk) {
      send_nack(c);
    }
  }
  else { /* p->h.s_id < c->current.h.s_id */
    PRINTF("%d.%d: Recieved s_id %i expected %i\n",
              rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
              p->h.s_id, c->s_id);
    /* Ignore packets with old s_id */
  }

}