From f100110465931e4617a955abea28c1567f97f375 Mon Sep 17 00:00:00 2001 From: aprochazka Date: Fri, 31 Mar 2023 00:16:29 +0200 Subject: [PATCH] add receiver application for CDC video transfer --- Receiver/Displayer.cpp | 156 ++++++++++++++++++++++++++++++ Receiver/Displayer.hpp | 104 ++++++++++++++++++++ Receiver/ImageView.cpp | 138 ++++++++++++++++++++++++++ Receiver/ImageView.hpp | 23 +++++ Receiver/Makefile | 17 ++++ Receiver/Receiver.cpp | 214 +++++++++++++++++++++++++++++++++++++++++ Receiver/Receiver.hpp | 37 +++++++ Receiver/Transfer.cpp | 70 ++++++++++++++ Receiver/Transfer.hpp | 6 ++ Receiver/main.cpp | 59 ++++++++++++ Receiver/main.hpp | 15 +++ 11 files changed, 839 insertions(+) create mode 100644 Receiver/Displayer.cpp create mode 100644 Receiver/Displayer.hpp create mode 100644 Receiver/ImageView.cpp create mode 100644 Receiver/ImageView.hpp create mode 100644 Receiver/Makefile create mode 100644 Receiver/Receiver.cpp create mode 100644 Receiver/Receiver.hpp create mode 100644 Receiver/Transfer.cpp create mode 100644 Receiver/Transfer.hpp create mode 100644 Receiver/main.cpp create mode 100644 Receiver/main.hpp diff --git a/Receiver/Displayer.cpp b/Receiver/Displayer.cpp new file mode 100644 index 0000000..c4bdf24 --- /dev/null +++ b/Receiver/Displayer.cpp @@ -0,0 +1,156 @@ +#include "main.hpp" +#include "Displayer.hpp" + + +int Displayer::createWindow() { + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to initialize SDL: %s", SDL_GetError()); + return 1; + } + + window = SDL_CreateWindow("Image Viewer", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1920, 1080, SDL_WINDOW_SHOWN); + if (!window) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create window: %s", SDL_GetError()); + SDL_Quit(); + return 1; + } + + return 0; +} + +int Displayer::renderWindow(){ + renderer = SDL_CreateRenderer(window, -1, 0); + + if (!renderer) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create renderer: %s", SDL_GetError()); + SDL_DestroyWindow(window); + SDL_Quit(); + return 1; + } + + return 0; +} + +int Displayer::imageFromVector(std::vector* img){ + imageRwops = SDL_RWFromMem(img->data(), img->size()); + + return 0; +} + +int Displayer::createImageSurface(){ + imageSurface = IMG_Load_RW(imageRwops, 0); + if (!imageSurface) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to load image: %s", IMG_GetError()); + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + SDL_Quit(); + return 1; + } + + return 0; +} + +int Displayer::textureFromSurface(){ + + currentTextureIndexMutex.lock(); + + switch(currentTextureIndex){ + case 0: + texture2 = SDL_CreateTextureFromSurface(renderer, imageSurface); + break; + case 1: + texture3 = SDL_CreateTextureFromSurface(renderer, imageSurface); + break; + case 2: + texture1 = SDL_CreateTextureFromSurface(renderer, imageSurface); + break; + default: + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to asess currentTextureIndex: %s", SDL_GetError()); + return 1; + } + + currentTextureIndex++; + currentTextureIndex %= 3; + + currentTextureIndexMutex.unlock(); + SDL_FreeSurface(imageSurface); + + if (!texture1 || !texture2 || !texture3) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create texture: %s", SDL_GetError()); + return 1; + } + + return 0; +} + +int Displayer::windowDestroy(){ + SDL_DestroyTexture(texture1); + SDL_DestroyTexture(texture2); + SDL_DestroyTexture(texture3); + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + SDL_Quit(); + return 0; +} + +int Displayer::windowLoop(){ + bool quit = false; + while (!quit) { + SDL_Event event; + while (SDL_PollEvent(&event)) { + if (event.type == SDL_QUIT) { + quit = true; + } + } + + SDL_RenderClear(renderer); + + currentTextureIndexMutex.lock(); + + switch(currentTextureIndex) { + case 0: + SDL_RenderCopy(renderer, texture1, NULL, NULL); + break; + case 1: + SDL_RenderCopy(renderer, texture2, NULL, NULL); + break; + case 2: + SDL_RenderCopy(renderer, texture3, NULL, NULL); + break; + default: + std::cout << "error 18" << std::endl; + break; + } + SDL_RenderPresent(renderer); + + currentTextureIndexMutex.unlock(); + + + } + + return 0; +} + +int Displayer::vectorToTexture(std::vector* img){ + + imageFromVector(img); + createImageSurface(); + textureFromSurface(); + + return 0; +} + +int Displayer::flipThroughTextures(){ + int flipIdx = 0; + while(1){ + if(flipIdx){ + vectorToTexture(&t1); + } + else{ + vectorToTexture(&t2); + } + flipIdx++; + flipIdx%=2; + } +} + diff --git a/Receiver/Displayer.hpp b/Receiver/Displayer.hpp new file mode 100644 index 0000000..a8f13c7 --- /dev/null +++ b/Receiver/Displayer.hpp @@ -0,0 +1,104 @@ +#include "main.hpp" +#define DISPLAYER_HPP +class Displayer { + private: + SDL_Window* window; + SDL_Renderer* renderer; + SDL_RWops* imageRwops; + + SDL_Surface* imageSurface; + + SDL_Texture* texture1; + SDL_Texture* texture2; + SDL_Texture* texture3; + + int currentTextureIndex = 0; + std::mutex currentTextureIndexMutex; + + public: + int createWindow(); + int renderWindow(); + + int imageFromVector(std::vector* img); + int createImageSurface(); + int textureFromSurface(); + + int vectorToTexture(std::vector* img); + + int windowDestroy(); + + int windowLoop(); + + int flipThroughTextures(); + +}; + +static std::vector t1{ + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x92, 0x8a, 0x00, + 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, + 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, + 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, + 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, + 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, + 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, + 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, + 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, + 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, + 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, + 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, + 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, + 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, + 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, + 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, + 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, + 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, + 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, + 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, + 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, + 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0xff, 0xd9 +}; + +static std::vector t2{ + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x6d, 0x14, 0x8d, + 0x04, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, + 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, + 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, + 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, + 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, + 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, + 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, + 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, + 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, + 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, + 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, + 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, + 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, + 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, + 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, + 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, + 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, + 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x7f, 0xff, 0xd9 +}; \ No newline at end of file diff --git a/Receiver/ImageView.cpp b/Receiver/ImageView.cpp new file mode 100644 index 0000000..c405a00 --- /dev/null +++ b/Receiver/ImageView.cpp @@ -0,0 +1,138 @@ +#include "ImageView.hpp" + +int createWindow(SDL_Window** windowPtr){ + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to initialize SDL: %s", SDL_GetError()); + return 1; + } + + // Create a window + SDL_Window* window = SDL_CreateWindow("Image Viewer", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1920, 1080, SDL_WINDOW_SHOWN); + if (!window) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create window: %s", SDL_GetError()); + SDL_Quit(); + return 1; + } + + *windowPtr = window; + + return 0; +} +int renderWindow(SDL_Renderer** rendererPtr, SDL_Window* window){ + SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0); + if (!renderer) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create renderer: %s", SDL_GetError()); + SDL_DestroyWindow(window); + SDL_Quit(); + return 1; + } + + *rendererPtr = renderer; + return 0; +} + +int imageFromVector(SDL_RWops** imageRwopsPtr, std::vector* img){ + SDL_RWops* imageRwops = SDL_RWFromMem(img->data(), img->size()); + + *imageRwopsPtr = imageRwops; + return 0; +} + +int createImageSurface(SDL_Surface** imageSurfacePtr, SDL_RWops* imageRwops){ + SDL_Surface* imageSurface = IMG_Load_RW(imageRwops, 0); + if (!imageSurface) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to load image: %s", IMG_GetError()); + //SDL_DestroyRenderer(renderer); + //SDL_DestroyWindow(window); + SDL_Quit(); + return 1; + } + + *imageSurfacePtr = imageSurface; + return 0; +} + +int textureFromSurface(SDL_Texture** texturePtr, SDL_Renderer** renderer, SDL_Surface** imageSurface){ + SDL_Texture* texture = SDL_CreateTextureFromSurface(*renderer, *imageSurface); + SDL_FreeSurface(*imageSurface); + if (!texture) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create texture: %s", SDL_GetError()); + //SDL_DestroyRenderer(renderer); + //SDL_DestroyWindow(window); + SDL_Quit(); + return 1; + } + + *texturePtr = texture; + return 0; +} + +int windowDestroy(SDL_Window** windowPtr, SDL_Texture** texturePtr, SDL_Renderer** rendererPtr){ + SDL_DestroyTexture(*texturePtr); + SDL_DestroyRenderer(*rendererPtr); + SDL_DestroyWindow(*windowPtr); + SDL_Quit(); + return 0; +} + + +int windowLoop(SDL_Renderer** rendererPtr, + int* currentBufferIndex, + std::mutex& currentBufferIndexMutex, + SDL_Texture** texturePtr1, + SDL_Texture** texturePtr2, + SDL_Texture** texturePtr3){ + bool quit = false; + while (!quit) { + SDL_Event event; + while (SDL_PollEvent(&event)) { + if (event.type == SDL_QUIT) { + quit = true; + } + } + + SDL_RenderClear(*rendererPtr); + currentBufferIndexMutex.lock(); + switch(*currentBufferIndex) { + case 0: + SDL_RenderCopy(*rendererPtr, *texturePtr1, NULL, NULL); + break; + case 1: + SDL_RenderCopy(*rendererPtr, *texturePtr2, NULL, NULL); + break; + case 2: + SDL_RenderCopy(*rendererPtr, *texturePtr3, NULL, NULL); + break; + default: + std::cout << "error 18" << std::endl; + break; + } + currentBufferIndexMutex.unlock(); + + SDL_RenderPresent(*rendererPtr); + } + + return 0; +} + +int vectorToTexture(SDL_Renderer** rendererPtr, + SDL_RWops** imageRwopsPtr, + SDL_Surface** imageSurfacePtr, + SDL_Texture** texturePtr, + std::vector* img){ + + imageFromVector(imageRwopsPtr, img); + createImageSurface(imageSurfacePtr, *imageRwopsPtr); + textureFromSurface(texturePtr, rendererPtr, imageSurfacePtr); + + return 0; +} + +int flipThroughTextures(int * currentTexture, std::mutex& currentTextureMutex){ + while(1){ + currentTextureMutex.lock(); + *currentTexture = *currentTexture + 1; + *currentTexture %=3; + currentTextureMutex.unlock(); + } +} \ No newline at end of file diff --git a/Receiver/ImageView.hpp b/Receiver/ImageView.hpp new file mode 100644 index 0000000..7402cd4 --- /dev/null +++ b/Receiver/ImageView.hpp @@ -0,0 +1,23 @@ +#include "main.hpp" + +int createWindow(SDL_Window** windowPtr); +int renderWindow(SDL_Renderer** rendererPtr, SDL_Window* window); +int imageFromVector(SDL_RWops** imageRwopsPtr, std::vector* img); +int createImageSurface(SDL_Surface** imageSurfacePtr, SDL_RWops* imageRwops); +int textureFromSurface(SDL_Texture** texturePtr, SDL_Renderer** renderer, SDL_Surface** imageSurface); + +int windowDestroy(SDL_Window** windowPtr, SDL_Texture** texturePtr, SDL_Renderer** rendererPtr); +int windowLoop( SDL_Renderer** rendererPtr, + int* currentBufferIndex, + std::mutex& currentBufferIndexMutex, + SDL_Texture** texturePtr1, + SDL_Texture** texturePtr2, + SDL_Texture** texturePtr3); + +int vectorToTexture(SDL_Renderer** rendererPtr, + SDL_RWops** imageRwopsPtr, + SDL_Surface** imageSurfacePtr, + SDL_Texture** texturePtr, + std::vector* img); + +int flipThroughTextures(int * currentTexture, std::mutex& currentTextureMutex); \ No newline at end of file diff --git a/Receiver/Makefile b/Receiver/Makefile new file mode 100644 index 0000000..d2e6738 --- /dev/null +++ b/Receiver/Makefile @@ -0,0 +1,17 @@ +CC = g++ +CFLAGS = -pthread -std=c++11 -Wall -Wextra -pedantic +LDLIBS = -lSDL2 -lSDL2_image +SRCS = $(wildcard *.cpp) + +OBJS = $(SRCS:.cpp=.o) + +all: main + +main: $(OBJS) + $(CC) $(CFLAGS) $(OBJS) -o main $(LDLIBS) + +%.o: %.cpp + $(CC) $(CFLAGS) -c $< -o $@ + +clean: + rm -f $(OBJS) main diff --git a/Receiver/Receiver.cpp b/Receiver/Receiver.cpp new file mode 100644 index 0000000..ed8b69a --- /dev/null +++ b/Receiver/Receiver.cpp @@ -0,0 +1,214 @@ +#include "Receiver.hpp" + +Receiver::Receiver(Displayer *displayerPtr){ + dis = displayerPtr; +} + +void Receiver::printHex(unsigned char value) { + std::cout << "0x" << std::hex << std::setfill('0') << std::setw(2) << static_cast(value); +} + +void Receiver::openStream(){ + while(1){ + // Open the CDC device file for reading + cdcFile = open("/dev/ttyACM2", O_RDWR | O_NOCTTY); + if (cdcFile == -1) { + std::cerr << "Failed to open CDC device file" << std::endl; + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + continue; + } + std::cout << "successfully opened stream" << cdcFile << std::endl; + break; + } +} + +int Receiver::initSerial(){ + memset(&tty, 0, sizeof(tty)); + if (tcgetattr(cdcFile, &tty) != 0) { + std::cerr << "Error in tcgetattr" << std::endl; + return -1; + } + tcflush(cdcFile, TCIFLUSH); + cfsetospeed(&tty, B115200); + cfsetispeed(&tty, B115200); + tty.c_cflag |= (CLOCAL | CREAD); + tty.c_cflag &= ~CSIZE; + tty.c_cflag |= CS8; + tty.c_cflag &= ~PARENB; + tty.c_cflag &= ~CSTOPB; + tty.c_cflag &= ~CRTSCTS; + tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); + tty.c_iflag &= ~(IXON | IXOFF | IXANY); + tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL); + tty.c_oflag &= ~OPOST; + tty.c_cc[VMIN] = 1; + tty.c_cc[VTIME] = 0; + if (tcsetattr(cdcFile, TCSANOW, &tty) != 0) { + std::cerr << "Error in tcsetattr" << std::endl; + return -1; + } + + std::cout << "OPENED!" << std::endl; + tcflush(cdcFile, TCIFLUSH); + return 1; +} + +int Receiver::readCdcData(unsigned char (*character)[10]) { + memset(*character, 0x00, 10); + int bytesRead = read(cdcFile, character, 10); + if (bytesRead == -1) { + std::cerr << "Error in read" << std::endl; + return -1; + } + if (bytesRead == -1) { + std::cerr << "Error in read" << std::endl; + return -1; + } + /* + for(int i = 0; i<10; i++) + { + printHex((*character)[i]); + //std::cout << unsigned(character[i]); + std::cout << " "; + }*/ + + + return 0; +} + +int Receiver::simulateRead(unsigned char (*character)[10]){ + memset(*character, 0x00, 10); + + int firstLen = (int)t1.size(); + int secondLen = (int)t2.size(); + int completeLen = firstLen + secondLen; + + int vecId; + if(Receiver::simulateIdx < firstLen){ + vecId = 1; + } + else{ + vecId = 2; + } + + for(int i=0; i<10; i++){ + if(vecId == 1){ + if(simulateIdx > firstLen){ + (*character)[i] = 0x00; + } + else{ + (*character)[i] = t1[simulateIdx]; + simulateIdx++; + } + } + else{ + if(simulateIdx > completeLen){ + (*character)[i] = 0x00; + } + else{ + //printHex(t1[simulateIdx-firstLen]); + (*character)[i] = t2[simulateIdx-firstLen-1]; + simulateIdx++; + } + } + } + if(simulateIdx>completeLen) simulateIdx = 0; + return 0; +} + +int Receiver::fillBuffer(){ + unsigned char character[10]; + std::vector tempVec{}; + + Receiver::readCdcData(&character); + + //Receiver::simulateRead(&character); + + while(Receiver::findStart(&character) == -1) Receiver::readCdcData(&character); //Receiver::simulateRead(&character); + + tempVec.insert(tempVec.end(), character, character + sizeof(character)); + + do{ + Receiver::readCdcData(&character); + //Receiver::simulateRead(&character); + tempVec.insert(tempVec.end(), character, character + sizeof(character)); + } + while(findEnd(&character) == -1); + currentBufferIndexMutex.lock(); + + currentBufferIndex++; + currentBufferIndex %= 3; + + currentBufferIndexMutex.unlock(); + std::cout << "=" << currentBufferIndex; + switch(currentBufferIndex){ + case 0: + buffer1 = tempVec; + break; + case 1: + buffer2 = tempVec; + break; + case 2: + buffer3 = tempVec; + break; + default: + std::cout << "error 25" << std::endl; + } + + //for(int i=0; i<(int)tempVec.size(); i++) printHex(tempVec[i]); + //std::cout << std::endl; + return 1; +} + +void Receiver::bufferToDisplay(){ + currentBufferIndexMutex.lock(); + int buffIdx = currentBufferIndex; + currentBufferIndexMutex.unlock(); + switch(buffIdx){ + case 0: + dis->vectorToTexture(&buffer1); + break; + case 1: + dis->vectorToTexture(&buffer2); + break; + case 2: + dis->vectorToTexture(&buffer3); + break; + default: + std::cout << "error 86" << std::endl; + } +} + +int Receiver::findSequence(unsigned char (*str)[10], unsigned char ch1, unsigned char ch2){ + if(sequenceEndedFF){ + sequenceEndedFF = 0; + if((*str)[0] == ch2){ + return 0; + } + } + for(int i=0; i<10; i++){ + if((*str)[i] == ch1 && i < 10){ + if((*str)[i+1] == ch2){ + return i; + } + } + } + + if((*str)[9] == 0xFF) sequenceEndedFF = 1; + + return -1; +} + +int Receiver::findStart(unsigned char (*str)[10]){ + int res = findSequence(str, 0xFF, 0xD8); + //if(res != -1)std::cout << "s"; + return res; + //return findSequence(str, 0xFF, 0xD8); +} + +int Receiver::findEnd(unsigned char (*str)[10]){ + int res = findSequence(str, 0xFF, 0xD9); + //if(res != -1)std::cout << "f"; + return res; + //return findSequence(str, 0xFF, 0xD9); +} diff --git a/Receiver/Receiver.hpp b/Receiver/Receiver.hpp new file mode 100644 index 0000000..615743f --- /dev/null +++ b/Receiver/Receiver.hpp @@ -0,0 +1,37 @@ +#include "main.hpp" + +#ifndef DISPLAYER_HPP +#include "Displayer.hpp" +#endif + +class Receiver{ + private: + int cdcFile; + struct termios tty; + int currentBufferIndex = 0; + std::mutex currentBufferIndexMutex; + std::vector buffer1; + std::vector buffer2; + std::vector buffer3; + Displayer *dis; + + int sequenceEndedFF = 0; + int simulateIdx = 0; + + public: + Receiver(Displayer *displayerPtr); + void openStream(); + int initSerial(); + int readCdcData(unsigned char (*character)[10]); + + void printHex(unsigned char value); + int fillBuffer(); + + void bufferToDisplay(); + + int findSequence(unsigned char (*str)[10], unsigned char ch1, unsigned char ch2); + int findStart(unsigned char (*str)[10]); + int findEnd(unsigned char (*str)[10]); + + int simulateRead(unsigned char (*character)[10]); +}; \ No newline at end of file diff --git a/Receiver/Transfer.cpp b/Receiver/Transfer.cpp new file mode 100644 index 0000000..646dbca --- /dev/null +++ b/Receiver/Transfer.cpp @@ -0,0 +1,70 @@ +#include "Transfer.hpp" + +void printHex(unsigned char value) { + std::cout << "0x" << std::hex << std::setfill('0') << std::setw(2) << static_cast(value); +} + +void openStream(int *cdcFile){ + while(1){ + // Open the CDC device file for reading + *cdcFile = open("/dev/ttyACM1", O_RDWR | O_NOCTTY); + if (*cdcFile != -1) { + return; + } + std::cerr << "Failed to open CDC device file" << std::endl; + } +} + +int initSerial(struct termios *tty, int *cdcFile){ + memset(tty, 0, sizeof(*tty)); + if (tcgetattr(*cdcFile, tty) != 0) { + std::cerr << "Error in tcgetattr" << std::endl; + return -1; + } + tcflush(*cdcFile, TCIFLUSH); + cfsetospeed(tty, B115200); + cfsetispeed(tty, B115200); + tty->c_cflag |= (CLOCAL | CREAD); + tty->c_cflag &= ~CSIZE; + tty->c_cflag |= CS8; + tty->c_cflag &= ~PARENB; + tty->c_cflag &= ~CSTOPB; + tty->c_cflag &= ~CRTSCTS; + tty->c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); + tty->c_iflag &= ~(IXON | IXOFF | IXANY); + tty->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL); + tty->c_oflag &= ~OPOST; + tty->c_cc[VMIN] = 1; + tty->c_cc[VTIME] = 0; + if (tcsetattr(*cdcFile, TCSANOW, tty) != 0) { + std::cerr << "Error in tcsetattr" << std::endl; + return -1; + } + + std::cout << "OPENED!" << std::endl; + tcflush(*cdcFile, TCIFLUSH); + return 1; +} + +int readCdcData(int * cdcFile) { + + unsigned char character[10]; + memset(character, 0x00, 10); + // Read data from the CDC device file into the buffer + int bytesRead = read(*cdcFile, character, 10); + if (bytesRead == -1) { + std::cerr << "Error in read" << std::endl; + return -1; + } + for(int i = 0; i<10; i++) + { + printHex(character[i]); + //std::cout << unsigned(character[i]); + std::cout << " "; + } + + std::cout << std::endl; + std::cout << std::endl; + + return bytesRead; +} diff --git a/Receiver/Transfer.hpp b/Receiver/Transfer.hpp new file mode 100644 index 0000000..fd6bd7b --- /dev/null +++ b/Receiver/Transfer.hpp @@ -0,0 +1,6 @@ +#include "main.hpp" + +void printHex(unsigned char value); +void openStream(int *cdcFile); +int initSerial(struct termios *tty, int *cdcFile); +int readCdcData(int * cdcFile); \ No newline at end of file diff --git a/Receiver/main.cpp b/Receiver/main.cpp new file mode 100644 index 0000000..494d30b --- /dev/null +++ b/Receiver/main.cpp @@ -0,0 +1,59 @@ +#include "main.hpp" +#include "Receiver.hpp" + +#ifndef DISPLAYER_HPP +#include "Displayer.hpp" +#endif + +#include "Transfer.hpp" + + int cdcFile; + struct termios tty; +void readLoop(){ + openStream(&cdcFile); + initSerial(&tty, &cdcFile); + + while (true) { + readCdcData(&cdcFile); + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + } + + close(cdcFile); +} + + +void windowFlipThread(Displayer * displayerPtr){ + displayerPtr->flipThroughTextures(); +} + +void receiverLoop(Receiver ** receiverPtr){ + while(1){ + (*receiverPtr)->fillBuffer(); + (*receiverPtr)->bufferToDisplay(); + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + } +} + +int main() +{ + + Displayer dis; + dis.createWindow(); + dis.renderWindow(); + + Receiver *rec = new Receiver(&dis); + rec->openStream(); + rec->initSerial(); + rec->fillBuffer(); + rec->bufferToDisplay(); + + std::thread t1(receiverLoop, &rec); + + dis.windowLoop(); + + t1.join(); + + + //readLoop(); + return 0; +} diff --git a/Receiver/main.hpp b/Receiver/main.hpp new file mode 100644 index 0000000..63a1d39 --- /dev/null +++ b/Receiver/main.hpp @@ -0,0 +1,15 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include \ No newline at end of file