static int can_echo_gen(void) { struct can_frame tx_frames[CAN_MSG_COUNT]; struct can_frame rx_frame; unsigned char counter = 0; int send_pos = 0, recv_pos = 0, unprocessed = 0, loops = 0; int i; while (running) { if (unprocessed < CAN_MSG_COUNT) { /* still send messages */ tx_frames[send_pos].can_dlc = CAN_MSG_LEN; tx_frames[send_pos].can_id = CAN_MSG_ID; for (i = 0; i < CAN_MSG_LEN; i++) tx_frames[send_pos].data[i] = counter + i; if (send_frame(&tx_frames[send_pos])) return -1; /* increment to be equal to expected */ tx_frames[send_pos].can_id++; for (i = 0; i < CAN_MSG_LEN; i++) tx_frames[send_pos].data[i]++; send_pos++; if (send_pos == CAN_MSG_COUNT) send_pos = 0; unprocessed++; if (verbose == 1) echo_progress(counter); counter++; if ((counter % 33) == 0) millisleep(3); else millisleep(1); } else { if (recv_frame(&rx_frame)) return -1; if (verbose > 1) print_frame(&rx_frame); /* compare with expected */ compare_frame(&tx_frames[recv_pos], &rx_frame); loops++; if (test_loops && loops >= test_loops) break; recv_pos++; if (recv_pos == CAN_MSG_COUNT) recv_pos = 0; unprocessed--; } } printf("\nTest messages sent and received: %d\n", loops); return 0; }
static int can_echo_dut(void) { unsigned int frame_count = 0; struct timeval tvn, tv_stop; struct can_frame frame; int i; while (running) { if (recv_frame(&frame)) return -1; frame_count++; if (verbose == 1) { echo_progress(frame.data[0]); } else if (verbose > 1) { printf("%04x: ", frame.can_id); if (frame.can_id & CAN_RTR_FLAG) { printf("remote request"); } else { printf("[%d]", frame.can_dlc); for (i = 0; i < frame.can_dlc; i++) printf(" %02x", frame.data[i]); } printf("\n"); } frame.can_id++; for (i = 0; i < frame.can_dlc; i++) frame.data[i]++; if (send_frame(&frame)) return -1; /* * to force a interlacing of the frames send by DUT and PC * test tool a waiting time is injected */ if (frame_count == CAN_MSG_WAIT) { frame_count = 0; if (gettimeofday(&tv_stop, NULL)) { perror("gettimeofday failed\n"); return -1; } else { tv_stop.tv_usec += 3000; if (tv_stop.tv_usec > 999999) { tv_stop.tv_sec++; tv_stop.tv_usec = tv_stop.tv_usec % 1000000; } gettimeofday(&tvn, NULL); while ((tv_stop.tv_sec > tvn.tv_sec) || ((tv_stop.tv_sec = tvn.tv_sec) && (tv_stop.tv_usec >= tvn.tv_usec))) gettimeofday(&tvn, NULL); } } } return 0; }
void* recv_loop(void* args) { uint8_t control, info[MAX_BUFFER/2]; bool disc = false; while (!disc) { recv_frame(&control, info); if (len_recv >= 0) { report_frame("rx", buf_recv, "OK"); pthread_cond_signal(&received); } pthread_mutex_lock(&disc_lock); disc = disconnect; pthread_mutex_unlock(&disc_lock); } return NULL; }
/** * Repondre a une requete d'un joueur * NOTA: cette fonction est bloquante et attend une requete d'un joueur * * @param sock Socket du joueur ayant envoye une requete * @param the_players Liste des joueurs * @return Resultat de l'echange compose de 2 champs: * - type: correspond le plus souvent au type de trame * ou a une fin de connexion * - content: correspond au contenu brut de l'echange, a savoir * une structure Player, un identifiant ou un ordre. */ Result* respond(int sock, Players the_players) { Result* result = NULL; Frame frame = recv_frame(sock); /*debug*/ print_frame(frame); if(check_frame(frame) == SUCCESS) { /* Deconnexion du joueur */ if(frame->pennant == SPECIAL_FRAME) { result = malloc(sizeof(Result)); remove_player_by_sock(sock, the_players, 1); result->type = NOT_CONNECTED; result->content = NULL; /* Traitement du serveur a la requete du client */ } else { switch(frame->id) { case Connect: result = respond_connect(sock, the_players, frame); break; case Initiate: result = respond_initiate(sock, the_players, frame); break; case Order: result = respond_order(sock, the_players, frame); break; /* Type de trame inconnu ou non autorisee du protocole * @todo si type de trame existant, renvoyer une erreur specifique */ default: PRINT_UNKNOWN_FRAME_TYPE(frame->id); break; } } } if(frame != NULL) { free_frame(frame); } return result; }
/** @fn fcserver_ret_t fcserver_process (fcserver_t* server, int clientSocket) * @brief Speak with the client * * @param[in] server structure, where the client should be put in * @param[in] client the connected client to talk to. * @return status */ static fcserver_ret_t process_client(fcserver_t* server, fcclient_t* client) { int n, offset = 0; int type=-1; int length = 0; int write_offset = 0; /* FIXME the server->tmpMem should probalby exists for each client * (even if only one client, connected to the wall can generate the huge packets) */ n = hwal_socket_tcp_read(client->clientsocket, (server->tmpMem + server->reading_offset), (server->tmpMemSize - server->reading_offset)); /*FIXME try to check if client is still connected FCSERVER_RET_CLOSED */ /* First check, if the Client has something to say */ if (n == -1) { /* no new packet found on the network */ return FCSERVER_RET_NOTHINGNEW; } else if (n == 0) { return FCSERVER_RET_CLOSED; } else if (n < HEADER_LENGTH) { DEBUG_PLINE("Error : Network read error"); return FCSERVER_RET_IOERR; } offset = get_header(server->tmpMem, 0, &type, &length); if (offset == -1) { DEBUG_PLINE("Error : Could not analyze header"); return FCSERVER_RET_IOERR; } /* Add the already extracted bytes to the new ones */ n += server->reading_offset; DEBUG_PLINE("New Header typ: %d length of information: %d [fetched is %d byte from the network]",type,length, n); if (length > n) { server->reading_offset = n; DEBUG_PLINE("Update offset to %d", server->reading_offset); } else { /* reset the fragment detection for packets */ server->reading_offset = 0; /* Decode the information */ switch (type) { case SNIPTYPE_REQUEST: { char *color; int seqId; int meta_offset; int meta_length; int frames_per_second, width, heigth; char *generator_name; char *generator_version; offset = recv_request(server->tmpMem, offset, &color, &seqId, &meta_offset, &meta_length); if (offset == -1) { DEBUG_PLINE("recv_request Faild!"); } else { DEBUG_PLINE("Parse Request, Color: %s, seqId: %d",color,seqId); } offset = parse_metadata(server->tmpMem,meta_offset,&frames_per_second, &width, &heigth, &generator_name, &generator_version); if (offset == -1) { DEBUG_PLINE("parse Metadata Faild!"); return -1; } else { DEBUG_PLINE("Metadata, fps: %d, width: %d, height: %d, gen._name: %s, gen._version: %s", frames_per_second,width,heigth,generator_name,generator_version); } /* allocate some memory for answering */ uint8_t *output = hwal_malloc(BUFFERSIZE_OUTPUT); hwal_memset(output, 0, BUFFERSIZE_OUTPUT); uint8_t *buffer = hwal_malloc(BUFFERSIZE_SENDINGBUFFER); hwal_memset(output, 0, BUFFERSIZE_SENDINGBUFFER); /* Verify , if the client has the correct resolution */ if (server->width == width && server->height == heigth) { client->clientstatus = FCCLIENT_STATUS_WAITING; /* Send the client an acknowledgement (ACK) */ write_offset = send_ack(buffer, write_offset); DEBUG_PLINE("ACK Request send"); } else { uint8_t buffer[BUFFERSIZE_SENDINGBUFFER]; /* Inform the client with an error message */ char descr[] = "Wrong Screen resolution"; DEBUG_PLINE("Error while requesting: '%s'", descr); write_offset = send_error(buffer, write_offset, FCSERVER_ERR_RESOLUTION, descr); } /* send the corresponding message: Success or error */ add_header(buffer, output, write_offset); hwal_socket_tcp_write(client->clientsocket, output, write_offset+HEADER_LENGTH); hwal_free(buffer); hwal_free(output); /* Free all resources needed for sending */ hwal_free(color); hwal_free(generator_name); hwal_free(generator_version); break; } case SNIPTYPE_FRAME: { int x, y, red, green, blue; int frame_length; int frame_offset, frame_offset_start; int index; offset = recv_frame(server->tmpMem, offset, &frame_offset, &frame_length); if (offset == -1) { DEBUG_PLINE("recv_frame Faild!"); } else { DEBUG_PLINE("Parse Frame, frame_length: %d",frame_length); } frame_offset_start = frame_offset; do { frame_offset = frame_parse_pixel(server->tmpMem,frame_offset, &red, &green, &blue, &x, &y); index = (((x * server->width) + y) * 3); server->imageBuffer[index + 0] = red; server->imageBuffer[index + 1] = green; server->imageBuffer[index + 2] = blue; } while (frame_offset < (frame_offset_start+frame_length)); if (server->onNewImage > 0) { server->onNewImage(server->imageBuffer, server->width, server->height); } break; } case SNIPTYPE_INFOREQUEST: { uint8_t *output = hwal_malloc(BUFFERSIZE_OUTPUT); hwal_memset(output, 0, BUFFERSIZE_OUTPUT); uint8_t *buffer = hwal_malloc(BUFFERSIZE_SENDINGBUFFER); hwal_memset(output, 0, BUFFERSIZE_SENDINGBUFFER); uint8_t *meta = hwal_malloc(BUFFERSIZE_SENDINGBUFFER); hwal_memset(output, 0, BUFFERSIZE_SENDINGBUFFER); int offset_meta = create_metadata(meta, 0, FCSERVER_DEFAULT_FPS, server->width, server->height, FCSERVER_DEFAULT_NAME, FCSERVER_DEFAULT_VERSION); write_offset = send_infoanswer(buffer, write_offset, meta, offset_meta); add_header(buffer, output, write_offset); hwal_socket_tcp_write(client->clientsocket, output, write_offset+HEADER_LENGTH); DEBUG_PLINE("Answered %dx%d pixel (%d fps) for '%s' on version '%s'",server->width, server->height, FCSERVER_DEFAULT_FPS, FCSERVER_DEFAULT_NAME, FCSERVER_DEFAULT_VERSION); hwal_free(meta); hwal_free(buffer); hwal_free(output); } break; case SNIPTYPE_PING: case SNIPTYPE_PONG: case SNIPTYPE_ERROR: case SNIPTYPE_START: case SNIPTYPE_ACK: case SNIPTYPE_NACK: case SNIPTYPE_TIMEOUT: case SNIPTYPE_ABORT: case SNIPTYPE_EOS: case SNIPTYPE_INFOANSWER: default: DEBUG_PLINE("%d is not implemented",type); break; } } return FCSERVER_RET_OK; }
void main1(int argc, char** argv) { srand(time(0)); //init protocol_init(argc, argv); //arguments windowSize = 22; retimer = 3300;//retransmit timer acktimer = 600; bufferSize = windowSize / 2;//buffer size //init datalink layer senderLeft = 0;//left edge of sender senderRight = 0;//right edge of sender, which has data unfilled receiverLeft = 0;//left edge of receiver //receiverRight = bufferSize - 1;//right edge of receiver isPhysicalLayerReady = -1; lastAck = windowSize - 1; //init buffer sender = (buffer*)malloc(sizeof(buffer)* bufferSize); receiver = (buffer*)malloc(sizeof(buffer)* bufferSize); for (int i = 0; i < bufferSize; i++) { sender[i].frameArrived = false; receiver[i].frameArrived = false; sender[i].hasSent = false; receiver[i].hasSent = false; } //init interfcace enable_network_layer(); bool isNetworkEnabled = true; //init event args int eventArgs = -1; int eventKind = -1; //allocate temp space unsigned char temp[MAX_PACKET_SIZE + 11]; //main loop while (true) { static int frameLength; eventKind = wait_for_event(&eventArgs);//get event switch (eventKind) { case PHYSICAL_LAYER_READY: isPhysicalLayerReady = 1; break; case NETWORK_LAYER_READY: //if buffer nearly full if (((senderRight > senderLeft) && (senderRight - senderLeft == bufferSize - 1)) || (senderRight < senderLeft) && (windowSize - senderLeft + senderRight == bufferSize - 1)) { disable_network_layer(); isNetworkEnabled = false; } //store frame in buffer sender[senderRight % bufferSize].length = get_packet(sender[senderRight % bufferSize].data); //slide window senderRight = (senderRight + 1) % windowSize; break; case FRAME_RECEIVED: //init temperory variables frameLength = recv_frame(temp, MAX_PACKET_SIZE + 7); if (frameLength > MAX_PACKET_SIZE + 7) ;//frame is too large, discard it else { //check crc if (crc32(temp, frameLength) != 0) {//crc faild if (isInBuffer(senderLeft, senderRight, temp[0] == FRAME_DATA ? temp[2] : temp[1], false)) { //send nak temp[0] = FRAME_NAK;//if the 2nd byte is error, it may sends false nak, but it doesn't matter mySendFrame(temp, 2); } } else { if (temp[0] == FRAME_ACK) {//if it's an ack frame if (isInBuffer(senderLeft, senderRight, temp[1], false)) { if (isInBuffer(lastAck, senderRight, temp[1], false)) lastAck = temp[1]; //else do noting break; } } else if (temp[0] == FRAME_NAK) {//if it's a nak frame if (isInBuffer(senderLeft, senderRight, temp[1], false)) { //retranmit temp[0] = 1; memcpy(temp + 3, sender[temp[1] % bufferSize].data, sender[temp[1] % bufferSize].length * sizeof(unsigned char)); mySendFrame(temp, sender[temp[1] % bufferSize].length + 3); break; } } else if (temp[0] == FRAME_DATA) {//if it's a data frame if (isInBuffer(lastAck, senderRight, temp[2], false)) lastAck = temp[2]; if (isInBuffer(receiverLeft, (receiverLeft + bufferSize) % windowSize, temp[1], true)){ if (!receiver[temp[1] % bufferSize].frameArrived) { receiver[temp[1] % bufferSize].frameArrived = true; receiver[temp[1] % bufferSize].length = frameLength - 7; for (int i = 0; i < frameLength - 7; i++) { receiver[temp[1] % bufferSize].data[i] = temp[3 + i]; } } } } } } break; case DATA_TIMEOUT: //just retransmit the frame if (isInBuffer(lastAck, senderRight, eventArgs, false) && isInBuffer(senderLeft, senderRight, eventArgs, false)) { if (sender[eventArgs % bufferSize].hasSent) {//if it has been sent if (eventArgs == senderLeft || rand() % 10 > 10) { //build the frame temp[0] = FRAME_DATA; temp[1] = eventArgs; memcpy((void*)(temp + 3), sender[eventArgs % bufferSize].data, sender[eventArgs % bufferSize].length * sizeof(unsigned char)); //transmit mySendFrame(temp, sender[eventArgs % bufferSize].length + 3); } else start_timer(eventArgs, retimer * (rand() % 10 / 10.0 + 1)); } } break; case ACK_TIMEOUT: //just send an ack temp[0] = FRAME_ACK; mySendFrame(temp, 2); break; } //sliding the sender window //send { int i = senderLeft; while (isInBuffer(senderLeft, senderRight, i, false)) { if (sender[i % bufferSize].hasSent == false){ if (isPhysicalLayerReady == 1 || isPhysicalLayerReady == -1 || phl_sq_len() < 1000) { //build the frame temp[0] = FRAME_DATA; temp[1] = i % windowSize; memcpy((void*)(temp + 3), sender[i % bufferSize].data, sender[i % bufferSize].length * sizeof(unsigned char)); //transmit mySendFrame(temp, sender[i % bufferSize].length + 3); sender[i % bufferSize].hasSent = true; isPhysicalLayerReady = 0; } break; } i = (i + 1) % windowSize; } } //slide while (isInBuffer(senderLeft, senderRight, lastAck, false)) {//·â×°º¯Êý sender[senderLeft % bufferSize].hasSent = false; stop_timer(senderLeft); senderLeft = (senderLeft + 1) % windowSize; } //enable network layer if (!(((senderRight > senderLeft) && (senderRight - senderLeft == bufferSize)) || (senderRight < senderLeft) && (windowSize - senderLeft + senderRight == bufferSize)) && !isNetworkEnabled) { enable_network_layer(); isNetworkEnabled = true; } //sliding the receiver window { int i = 0; for (i = 0; i < bufferSize; i++) { if (receiver[(receiverLeft + i) % bufferSize].frameArrived) { put_packet(receiver[(receiverLeft + i) % bufferSize].data, receiver[(receiverLeft + i) % bufferSize].length); receiver[(receiverLeft + i) % bufferSize].frameArrived = false; } else break; } receiverLeft = (receiverLeft + i) % windowSize; } } }
int main(int argc, char ** argv) { int event, arg; struct FRAME r; int len = 0; int i; protocol_init(argc, argv); lprintf("Designed by JackalDire\n"); disable_network_layer(); for (;;) { event = wait_for_event(&arg); switch (event) { case NETWORK_LAYER_READY: get_packet(buffer[next_frame_to_send]); // fetch new packet from physical layer nbuffered++; send_data_frame(); inc(&next_frame_to_send); break; case PHYSICAL_LAYER_READY: phl_ready = 1; break; case FRAME_RECEIVED: len = recv_frame((unsigned char *)&r, sizeof r); if (len < 5 || crc32((unsigned char *)&r, len) != 0) { /* discard the error packet with wrong crc checksum */ /* TODO : add NAK to accelerate resending */ dbg_event("**** receiver error, bad CRC checksum, packet discarded.\n"); break; } if (r.kind == FRAME_DATA) { dbg_frame("Recv DATA %d %d, ID %d\n", r.seq, r.ack, *(short *)r.data); if (r.seq == frame_expected) { /* transmit the receive packet to network layer */ put_packet(r.data, PKT_LEN); // 7 = 3B other fields + 4B crc code inc(&frame_expected); start_ack_timer(ACK_TIMER); } } /* ACK n means packets earlier than n were received correctly, * so make packet ack_expeced ~ r.ack acknowledged */ while (between(ack_expected, r.ack, next_frame_to_send)) { --nbuffered; stop_timer(ack_expected); inc(&ack_expected); } break; case DATA_TIMEOUT: dbg_event("---- DATA %d timeout\n", arg); next_frame_to_send = ack_expected; /* retransmit all packets in the buffer when timeout */ for (i = 1; i <= nbuffered; ++i) { send_data_frame(); inc(&next_frame_to_send); } break; case ACK_TIMEOUT: /* send a separate ACK frame if there is no outstream for a specific time */ dbg_event("---- ACK %d timeout\n", arg); send_ack_frame(); } /* disable networklayer when outstrem buffer if full */ if (nbuffered < MAX_SEQ && phl_ready) enable_network_layer(); else disable_network_layer(); } }