/** * Avalia se o pacote deve ser redirecionado ou salvo. * @param packet Ponteiro para o pacote. * @param usage_type Tipo do cliente que está chamando a função. * @return 0 em falha e !0 em sucesso. */ int where_to_send(char *packet, usage_type_t usage_type) { struct iphdr *ip; struct udphdr *udp; struct data_info *data; struct in_addr tmp; int ret; ip = (struct iphdr *)packet; udp = get_udp_packet(packet); /* Verifica a sanidade do pacote, se estiver com erro, dropa */ if (!sanity_check(ip)) { printf("Packet received with error, dropping.\n"); cstats.lost_pkts++; return 0; } switch (usage_type) { case ROUTER_USAGE: /* Router esta fazendo forward do pacote, subtrai ttl */ ip->ttl -= IPTTLDEC; ip->check = 0; ip->check = in_cksum((unsigned short *)ip, ip->tot_len); cstats.fw_pkts += ip->tot_len; printf("Forwarding packet:\n"); printf("\tPacket ttl %d\n", ip->ttl); printf("\tPacket size: %d bytes\n", ip->tot_len); tmp.s_addr = ip->saddr; printf("\tFrom: %s\n", inet_ntoa(tmp)); tmp.s_addr = ip->daddr; printf("\tTo: %s\n", inet_ntoa(tmp)); if ((ret = send_data(packet)) < 0) { printf("* Error forwarding packet. *\n"); cstats.lost_pkts++; } break; default: data = get_packet_data(packet); if (data->fragmented) { save_packet_fragment(data); if (is_packet_complete(data)) { /* Se o pacote for um fragmento e completar o dado, salva e * remove do buffer */ printf("Fragmented Data complete.\n"); struct data_info *dinfo = get_defragmented_data(data->id); ret = save_data(dinfo); cstats.recv_pkts += ip->tot_len; printf("Data received:\n"); printf("\tPacket: %lld bytes\n", dinfo->tot_len); tmp.s_addr = ip->saddr; printf("\tFrom: %s\n", inet_ntoa(tmp)); printf("\tFile Name: %s\n", ((char *)dinfo + sizeof(struct data_info))); printf("\tFile size: %ld bytes\n", dinfo->data_size); } else { /* Se o pacote for um fragmento, apenas adiciona ao buffer e * adiciona seus dados à estatística. */ cstats.recv_pkts += ip->tot_len; printf("."); ret = 0; } break; } /* Se o pacote não for um fragmento, salva e adiciona seus dados à * estatística. */ ret = save_data(data); cstats.recv_pkts += ip->tot_len; printf("Data received:\n"); printf("\tPacket: %d bytes\n", ip->tot_len); tmp.s_addr = ip->saddr; printf("\tFrom: %s\n", inet_ntoa(tmp)); printf("\tFile Name: %s\n", ((char *)data + sizeof(struct data_info))); printf("\tFile size: %ld bytes\n", data->data_size); break; } return ret; }
// application entry point int main(int argc, char* argv[]) { int fbfd = 0; struct fb_var_screeninfo orig_vinfo; struct fb_var_screeninfo vinfo; struct fb_fix_screeninfo finfo; long int screensize = 0; char *fbp = 0; char packet[1120]; ssize_t packet_size; int sock_fd = get_udp_socket(UDP_PORT); // Open the file for reading and writing fbfd = open("/dev/fb0", O_RDWR); if (!fbfd) { die("Error: cannot open framebuffer device.\n"); } printf("The framebuffer device was opened successfully.\n"); // Get variable screen information if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) { printf("Error reading variable information.\n"); } printf("Original %dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel ); // Store for reset (copy vinfo to vinfo_orig) memcpy(&orig_vinfo, &vinfo, sizeof(struct fb_var_screeninfo)); // Change variable info vinfo.bits_per_pixel = 24; if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &vinfo)) { printf("Error setting variable information.\n"); } // Get fixed screen information if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) { printf("Error reading fixed information.\n"); } // map fb to user mem screensize = finfo.smem_len; fbp = (char*)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0); if ((long)fbp == -1) { die("Failed to mmap.\n"); } else { // draw... int x, y, pixelcount; unsigned int color = 0; int pixeloffset = 2; int pixellength = 0; unsigned int pix_offset; unsigned bpp = vinfo.bits_per_pixel / 8; while( (packet_size = get_udp_packet(sock_fd, packet, sizeof(packet))) >= 0 ) { if((uint8_t)packet[0] == 1){ pixellength = 8; } else { pixellength = 7; } // how many pixels pixelcount = (packet_size-1)/pixellength; //printf("%d pixels in packet of size: %d using a pixel size of: %d \n", pixelcount, packet_size, pixellength); // fetch a pixel from the udp socket int i = 0; for(i=pixeloffset; // skip pixeloffset i<packet_size-(pixellength-1); // walk trough all bytes untill we get to the end minus one package length i+=pixellength){ x = (uint8_t)packet[i ] + (((uint8_t)packet[i+1])<<8); y = (uint8_t)packet[i+2] + (((uint8_t)packet[i+3])<<8); //printf("%d %d %d %d %d %d\n", x, y, packet[i ], packet[i+1], packet[i+2], packet[i+3]); if(x < vinfo.xres && y < vinfo.yres){ pix_offset = bpp * x + y * finfo.line_length; fbp[pix_offset++] = packet[i+6]; fbp[pix_offset++] = packet[i+5]; fbp[pix_offset] = packet[i+4]; } } } } // cleanup munmap((void *)fbp, screensize); if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &orig_vinfo)) { printf("Error re-setting variable information.\n"); } close(fbfd); return 0; }
// application entry point int main(int argc, char* argv[]) { uint8_t packet[ (8 * MAX_PIXELS) + 32]; // 8 bytes per pixel is the maximum size ssize_t packet_size; uint16_t x, y; uint8_t r, g, b, a; uint8_t pixellength = 0, protocol, version; uint16_t i; uint8_t offset = 2; int sock_fd = get_udp_socket(UDP_PORT); // Init screen buffer if (!init_frame_buffer()) { die("Failed to init screen buffer.\n"); } // draw each udp packet while( (packet_size = get_udp_packet(sock_fd, (char*)&packet, sizeof(packet))) >= 0 ) { // Get protocol from the packet version = packet[1]; // the version protocol = packet[0]; // protocol switch //printf("V:%d, P:%d\n", version, protocol); switch (protocol) { // Protocol 0: xyrgb 16:16:8:8:8 specified for each pixel case 0: pixellength = 7; packet_size = MIN(offset + (pixellength * MAX_PIXELS), packet_size); for (i=offset; i<packet_size; i+=pixellength) { x = packet[i ] | packet[i+1]<<8; y = packet[i+2] | packet[i+3]<<8; r = packet[i+4]; g = packet[i+5]; b = packet[i+6]; a = 0xFF; write_pixel_to_screen(x, y, r, g, b, a); } break; // Protocol 1: xyrgba 16:16:8:8:8:8 specified for each pixel case 1: pixellength = 8; packet_size = MIN(offset + (pixellength * MAX_PIXELS), packet_size); for (i=offset; i<packet_size; i+=pixellength) { x = packet[i ] | packet[i+1]<<8; y = packet[i+2] | packet[i+3]<<8; r = packet[i+4]; g = packet[i+5]; b = packet[i+6]; a = packet[i+7]; write_pixel_to_screen(x, y, r, g, b, a); } break; // Protocol 2: xyrgb 12:12:8:8:8 specified for each pixel case 2: pixellength = 6; packet_size = MIN(offset + (pixellength * MAX_PIXELS), packet_size); for (i=offset; i<packet_size; i+=pixellength) { x = packet[i ] | (packet[i+1]&0xF0)<<4; y = (packet[i+1]&0x0F) | packet[i+2]<<4; r = packet[i+3]; g = packet[i+4]; b = packet[i+5]; a = 0xFF; write_pixel_to_screen(x, y, r, g, b, a); } break; // Protocol 3: xyrgba 12:12:8:8:8:8 specified for each pixel case 3: pixellength = 7; packet_size = MIN(offset + (pixellength * MAX_PIXELS), packet_size); for (i=offset; i<packet_size; i+=pixellength) { x = packet[i ] | (packet[i+1]&0xF0)<<4; y = (packet[i+1]&0x0F) | packet[i+2]<<4; r = packet[i+3]; g = packet[i+4]; b = packet[i+5]; a = packet[i+6]; write_pixel_to_screen(x, y, r, g, b, a); } break; // Protocol 4: xyrgb 12:12:3:3:2 specified for each pixel case 4: pixellength = 4; packet_size = MIN(offset + (pixellength * MAX_PIXELS), packet_size); for (i=offset; i<packet_size; i+=pixellength) { x = packet[i ] | (packet[i+1]&0xF0)<<4; y = (packet[i+1]&0x0F) | packet[i+2]<<4; r = packet[i+3] & 0xE0; g = packet[i+3]<<3 & 0xE0; b = packet[i+3]<<6 & 0xC0; a = 0xFF; write_pixel_to_screen(x, y, r, g, b, a); } break; // Protocol 5: xyrgba 12:12:2:2:2:2 specified for each pixel case 5: pixellength = 4; packet_size = MIN(offset + (pixellength * MAX_PIXELS), packet_size); for (i=offset; i<packet_size; i+=pixellength) { x = packet[i ] | (packet[i+1]&0xF0)<<4; y = (packet[i+1]&0x0F) | packet[i+2]<<4; r = packet[i+3] & 0xC0; g = packet[i+3]<<2 & 0xC0; b = packet[i+3]<<4 & 0xC0; a = packet[i+3]<<6 & 0xC0; write_pixel_to_screen(x, y, r, g, b, a); } break; // Error no recognied protocol defined default: break; } } // Deinitialize screen buffer deinit_frame_buffer(); return 0; }