Files
KoboShare/KoboShare_client.c
2026-06-12 20:44:16 +02:00

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;
}