Files
klingelPiServer/main.cpp
Your Name 30db0c9eb1 aaaaaa
2022-03-16 19:54:23 +01:00

229 lines
5.0 KiB
C++

#include <iostream>
#include <vector>
#include "server_tcp_lib.h"
#include <pthread.h>
#include <unistd.h>
#include <wiringPi.h>
pthread_mutex_t mutexList;
const int input_pin = 3;
struct DATA {
DATA(int socket, std::vector<CLIENT*> * cliL)
: s(socket), cliL(cliL)
{
pthread_mutex_init(&m, nullptr);
refs = 0;
}
~DATA() {
pthread_mutex_destroy(&m);
perror("~DATA");
}
void addRef() {
std::string msg;
for(int i = 0;i <= refs; i++)
msg += " ";
std::cerr << std::string( msg + "addRef++\n") << std::flush;
pthread_mutex_lock(&m);
refs++;
pthread_mutex_unlock(&m);
}
void removeRef() {
std::string msg;
for(int i = 0;i < refs ; i++)
msg += " ";
std::cerr << std::string( msg + "~removeRef--\n") << std::flush;
pthread_mutex_lock(&m);
refs--;
pthread_mutex_unlock(&m);
if(refs <= 0)
delete this;
return;
}
int s;
std::vector<CLIENT*> *cliL;
int refs;
pthread_t thread;
pthread_mutex_t m;
};
int gpio_get( int pin ) {
// std::cout << digitalRead(pin) << std::endl;
return digitalRead(pin);
}
void removeFromList( DATA * d, int s ) {
d->addRef();
for(unsigned i= 0; i < d->cliL->size() ; ++i) {
if(d->cliL->at(i)->getSocket() == s ) {
perror("~delete client");
delete d->cliL->at(i);
d->cliL->erase(d->cliL->begin() + i);
//alles rückt 1 auf -> gleiches nochmal testen
i--;
}
}
d->removeRef();
}
void * sendRequest(void *dat)
{
auto *d = reinterpret_cast<DATA*>(dat);
d->addRef();
bool sended = false;
while (true){
pthread_mutex_lock(&mutexList);
if( d->cliL->size() )
pthread_mutex_unlock(&mutexList);
usleep(1000);
if((gpio_get( input_pin ) == 1) ){
if(sended)
continue;
else
sended = true;
for(unsigned i = 0;i < 999999; i++){
pthread_mutex_lock(&mutexList);
if( i < d->cliL->size() )
break;
if( send(d->cliL->at(i)->getSocket(), "openpls=|", strlen("openpls=|"), 0) <= 0 ) {
std::cout << "send2 failed" << std::endl;
removeFromList(d, d->cliL->at(i)->getSocket() );
}
pthread_mutex_unlock(&mutexList);
}
pthread_mutex_unlock(&mutexList);
} else{
sended = false;
}
}
d->removeRef();
}
void * redirektThread(void *dat)
{
auto d = reinterpret_cast<DATA*>(dat);
d->addRef();
std::string msg;
char c;
while (true) {
msg = "";
while (true){
if(recv(d->s, &c, 1, 0) <= 0 ) {
std::cout << "recv failed" << std::endl;
pthread_mutex_lock(&mutexList);
removeFromList(d, d->s);
pthread_mutex_unlock(&mutexList);
d->removeRef();
return nullptr;
}
msg.push_back(c);
if( c == '|' )
break;
}
std::cout << "SEND ALL" << msg << std::endl;
for ( unsigned i=0; i < 9999999; i++) {
pthread_mutex_lock(&mutexList);
if( i < d->cliL->size() )
break;
if(send(d->cliL->at(i)->getSocket(), msg.c_str(), msg.length(), 0) <= 0) {
std::cout << "send failed" << std::endl;
removeFromList( d, d->cliL->at(i)->getSocket() );
i--;
}
}
pthread_mutex_unlock(&mutexList);
}
d->removeRef();
return nullptr;
}
int main(){
TCP_SERVER server;
std::vector<CLIENT*> clients;
if( wiringPiSetup () != 0 ) {
perror("failed setup pi");
return 1;
}
pinMode (input_pin, INPUT);
while ( server.startListening(50000, 20) != 0 )
sleep(1);
std::cout << "Server started" << std::endl;
pthread_t sendR;
if (pthread_create(&sendR, nullptr, sendRequest, reinterpret_cast<void*>( new DATA(0, &clients))) != 0){
perror("cant start thread");
return 12;
}
while (true){
std::cout << "WAit for client" << std::endl;
CLIENT * cli = new CLIENT();
if(server.acceptClient(*cli) != 0) {
delete cli;
std::cout << "WAit for client failed: " << server.getLastError() << std::endl;
cli = nullptr;
continue;
}
std::cout << "new client" << std::endl;
pthread_mutex_lock(&mutexList);
clients.push_back( cli );
pthread_mutex_unlock(&mutexList);
DATA * data = new DATA(cli->getSocket(), &clients);
if (pthread_create(&data->thread, nullptr, redirektThread, reinterpret_cast<void*>(data)) != 0){
perror("cant start thread");
}
}
}