179 lines
4.3 KiB
C
179 lines
4.3 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <linux/fb.h>
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
|
|
|
|
#define SCREEN_FILE "/dev/fb0"
|
|
|
|
#define SERVER_IP "192.168.1.50"
|
|
#define SERVER_PORT 8080
|
|
#define TCP_PACKET_SIZE 1024 // 1KB chunks for sending
|
|
|
|
|
|
|
|
|
|
typedef struct DisplayInfo {
|
|
int framebuffer;
|
|
int width;
|
|
int height;
|
|
int bpp;
|
|
size_t screensize;
|
|
} DisplayInfo;
|
|
|
|
|
|
int get_display_info(DisplayInfo *info) {
|
|
// Open fb0 file descriptor and get display information. Saves them in the struct
|
|
char *fb_path = SCREEN_FILE;
|
|
|
|
int fb = open(fb_path, O_RDONLY);
|
|
if (fb < 0) {
|
|
perror("Can't open framebuffer");
|
|
return -1;
|
|
}
|
|
|
|
|
|
struct fb_var_screeninfo vinfo;
|
|
if (ioctl(fb, FBIOGET_VSCREENINFO, &vinfo)) {
|
|
perror("ioctl failed");
|
|
close(fb);
|
|
return -1;
|
|
}
|
|
|
|
|
|
info->framebuffer = fb;
|
|
info->width = vinfo.xres;
|
|
info->height = vinfo.yres;
|
|
info->bpp = vinfo.bits_per_pixel;
|
|
info->screensize = info->width * info->height * (info->bpp / 8);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int TakeScreenshot(DisplayInfo *info, unsigned char *buffer){
|
|
// Set the cursor at the start of framebuffer (fb0), then copy it on buffer
|
|
if (lseek(info->framebuffer, 0, SEEK_SET) < 0) {
|
|
perror("lseek failed");
|
|
close(info->framebuffer);
|
|
return -1;
|
|
}
|
|
|
|
if (read(info->framebuffer, buffer, info->screensize) != info->screensize) {
|
|
perror("read failed");
|
|
close(info->framebuffer);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int TCP_connect() {
|
|
int socketfd;
|
|
struct sockaddr_in server_addr;
|
|
|
|
// Create TCP socket
|
|
socketfd = socket(AF_INET, SOCK_STREAM, 0);
|
|
if (socketfd < 0) {
|
|
perror("Can't create socket");
|
|
return -1;
|
|
}
|
|
|
|
// Configure server address
|
|
memset(&server_addr, 0, sizeof(server_addr));
|
|
server_addr.sin_family = AF_INET;
|
|
server_addr.sin_port = htons(SERVER_PORT);
|
|
server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
|
|
|
|
// Connect to server
|
|
if (connect(socketfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
|
|
perror("Can't connect");
|
|
close(socketfd);
|
|
return -1;
|
|
}
|
|
|
|
printf("Connected to %s:%d\n", SERVER_IP, SERVER_PORT);
|
|
return socketfd;
|
|
}
|
|
|
|
int TCP_disconnect(int socketfd) {
|
|
close(socketfd);
|
|
}
|
|
|
|
int TCP_send_data(int socketfd, DisplayInfo *info, unsigned char *buffer) {
|
|
int buffer_size = info->screensize;
|
|
|
|
int total_sent = 0;
|
|
while (total_sent < buffer_size) {
|
|
// Calculate how many byte i still have to send (could be TCP_PACKET_SIZE or less)
|
|
int to_send = 0;
|
|
if (buffer_size - total_sent > TCP_PACKET_SIZE) {
|
|
to_send = TCP_PACKET_SIZE;
|
|
} else {
|
|
to_send = (buffer_size - total_sent);
|
|
}
|
|
|
|
// Send the package and update the total_sent value
|
|
int sent = send(socketfd, buffer + total_sent, to_send, 0);
|
|
total_sent += sent;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int main (){
|
|
// Use display information to allocate the correct size of memory
|
|
DisplayInfo info;
|
|
get_display_info(&info);
|
|
|
|
unsigned char *buffer = malloc(info.screensize);
|
|
if (!buffer) {
|
|
perror("malloc failed");
|
|
close(info.framebuffer);
|
|
}
|
|
|
|
|
|
// Create TCP connection and returns socket file descriptor
|
|
int socketfd = TCP_connect();
|
|
// Send the display information to the server
|
|
send(socketfd, &(info.width), sizeof(int), 0);
|
|
send(socketfd, &(info.height), sizeof(int), 0);
|
|
send(socketfd, &(info.bpp), sizeof(int), 0);
|
|
|
|
printf("width = %d\n", info.width);
|
|
printf("height = %d\n", info.height);
|
|
printf("bpp = %d\n", info.bpp);
|
|
printf("buffer_size = %zu\n", info.screensize);
|
|
|
|
|
|
int i=0;
|
|
while (1) {
|
|
// Copy the framebuffer fb0 into buffer
|
|
TakeScreenshot(&info, buffer);
|
|
|
|
// Send the data in chunks of TCP_BUFFER_SIZE
|
|
printf("Start transmission[%d]\n", i);
|
|
TCP_send_data(socketfd, &info, buffer);
|
|
printf("Buffer sent[%d]\n", i);
|
|
|
|
// Wait a second
|
|
sleep(0.5);
|
|
i++;
|
|
}
|
|
|
|
|
|
// Clean
|
|
TCP_disconnect(socketfd);
|
|
close(info.framebuffer);
|
|
free(buffer);
|
|
return 0;
|
|
|
|
} |