diff --git a/src/av.c b/src/av.c index 851c99f..ddff4fa 100644 --- a/src/av.c +++ b/src/av.c @@ -12,6 +12,7 @@ #include "decoder.h" #include #include +#include extern atomic_bool a_running; extern atomic_bool v_running; @@ -37,53 +38,74 @@ SOCKET GetConnection(void) { // Battry Check thread void *BatteryThreadProc(__attribute__((__unused__)) void *args) { SOCKET socket = INVALID_SOCKET; - char buf[128]; - char battery_value[32]; - int i, j; + char buf[96]; + char battery_value[5] = {0}; + struct timeval tv = {0}; + tv.tv_sec = 1; - memset(battery_value, 0, sizeof(battery_value)); dbgprint("Battery Thread Start\n"); usleep(500000); while (v_running || a_running) { - socket = GetConnection(); - if (socket == INVALID_SOCKET) { - goto LOOP; + uint8_t battery_value_pos = 0; + size_t percent_len = 0; + + socket = GetConnection(); + if (socket == INVALID_SOCKET) { + goto LOOP; + } + + if (setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, + sizeof(tv)) == -1) { + goto LOOP; + }; + + if (!Send(BATTERY_REQ, CSTR_LEN(BATTERY_REQ), socket)) { + errprint("error sending battery status request\n"); + goto LOOP; + } + + memset(buf, 0, sizeof(buf)); + if (RecvAll(buf, sizeof(buf), socket) <= 0) { + goto LOOP; + } + + for (uint8_t i = 0; i < (sizeof(buf) - 4); i += 4) { + char *tmp = memchr(&buf[i], '\r', sizeof(buf)); + if (!tmp) { + goto LOOP; } - - if (Send(BATTERY_REQ, CSTR_LEN(BATTERY_REQ), socket) <= 0) { - errprint("error sending battery status request\n"); - goto LOOP; - } - - memset(buf, 0, sizeof(buf)); - if (Recv(buf, sizeof(buf), socket) <= 0) { - goto LOOP; + if (memcmp(tmp + 1, "\n\r\n", 3) == 0) { + battery_value_pos = (tmp - buf) + 4; + break; } - - for (i = 0; i < (sizeof(buf)-4); i++) { - if (buf[i] == '\r' && buf[i+1] == '\n' && buf[i+2] == '\r' && buf[i+3] == '\n') { - i += 4; - break; - } + } + if (!battery_value_pos || battery_value_pos > (sizeof(buf) - (4 + 1)) || + buf[battery_value_pos] == '0') { + goto LOOP; + } + + for (uint8_t j = 0; j < 3; j++) { + if (buf[battery_value_pos + j] >= '0' && + buf[battery_value_pos + j] <= '9') { + battery_value[j] = buf[battery_value_pos + j]; + percent_len++; + } else { + break; } + } - j = 0; - while (i < sizeof(buf) && j < (sizeof(battery_value)-2) && buf[i] >= '0' && buf[i] <= '9') - battery_value[j++] = buf[i++]; - - if (j == 0) - battery_value[j++] = '-'; + if (percent_len == 0) + battery_value[0] = '-'; - battery_value[j++] = '%'; - battery_value[sizeof(battery_value) - 1] = 0; - dbgprint("battery_value: %s\n", battery_value); - UpdateBatteryLabel(battery_value); + battery_value[percent_len] = '%'; + dbgprint("battery_value: %s\n", battery_value); + UpdateBatteryLabel(battery_value); LOOP: - disconnect(socket); - for (j = 0; j < 30000 && (v_running || a_running); j++) - usleep(1000); + disconnect(socket); + for (uint16_t i = 0; i < 30000 && (v_running || a_running); i++) + usleep(1000); } dbgprint("Battery Thread End\n"); @@ -120,7 +142,7 @@ void *VideoThreadProc(void *args) { } len = snprintf(buf, sizeof(buf), VIDEO_REQ, decoder_get_video_width(), decoder_get_video_height()); - if (Send(buf, len, videoSocket) <= 0){ + if (!Send(buf, len, videoSocket)){ MSG_ERROR("Error sending request, DroidCam might be busy with another client."); goto early_out; } @@ -229,7 +251,7 @@ void *AudioThreadProc(void *arg) { return 0; } - if (Send(AUDIO_REQ, CSTR_LEN(AUDIO_REQ), socket) <= 0) { + if (!Send(AUDIO_REQ, CSTR_LEN(AUDIO_REQ), socket)) { MSG_ERROR("Error sending audio request"); goto early_out; } diff --git a/src/connection.c b/src/connection.c index 5a923f5..e5b8efc 100644 --- a/src/connection.c +++ b/src/connection.c @@ -85,41 +85,41 @@ SOCKET Connect(const char* ip, int port, const char **errormsg) { return sock; } -int Send(const char * buffer, int bytes, SOCKET s) { +bool Send(const char * buffer, int bytes, SOCKET s) { ssize_t w = 0; char *ptr = (char*) buffer; while (bytes > 0) { w = send(s, ptr, bytes, 0); if (w <= 0) { - return -1; + return false; } bytes -= w; ptr += w; } - return 1; + return true; } -int Recv(const char* buffer, int bytes, SOCKET s) { +ssize_t Recv(const char* buffer, int bytes, SOCKET s) { return recv(s, (char*)buffer, bytes, 0); } -int RecvAll(const char* buffer, int bytes, SOCKET s) { +ssize_t RecvAll(const char* buffer, int bytes, SOCKET s) { return recv(s, (char*)buffer, bytes, MSG_WAITALL); } -int RecvNonBlock(char * buffer, int bytes, SOCKET s) { +ssize_t RecvNonBlock(char * buffer, int bytes, SOCKET s) { int res = recv(s, buffer, bytes, MSG_DONTWAIT); return (res < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) ? 0 : res; } -int RecvNonBlockUDP(char * buffer, int bytes, SOCKET s) { +ssize_t RecvNonBlockUDP(char * buffer, int bytes, SOCKET s) { struct sockaddr_in from; socklen_t fromLen = sizeof(from); int res = recvfrom(s, buffer, bytes, MSG_DONTWAIT, (struct sockaddr *)&from, &fromLen); return (res < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) ? 0 : res; } -int SendUDPMessage(SOCKET s, const char *message, int length, char *ip, int port) { +ssize_t SendUDPMessage(SOCKET s, const char *message, int length, char *ip, int port) { struct sockaddr_in sin; sin.sin_port = htons((uint16_t)port); sin.sin_family = AF_INET; diff --git a/src/connection.h b/src/connection.h index 37a2668..f00afb8 100644 --- a/src/connection.h +++ b/src/connection.h @@ -9,6 +9,9 @@ #ifndef __CONN_H__ #define __CONN_H__ +#include +#include + #define INVALID_SOCKET -1 typedef int SOCKET; typedef long int SOCKET_PTR; @@ -19,11 +22,11 @@ void disconnect(SOCKET s); SOCKET accept_connection(int port); SOCKET CreateUdpSocket(void); -int Send(const char * buffer, int bytes, SOCKET s); -int Recv(const char * buffer, int bytes, SOCKET s); -int RecvAll(const char * buffer, int bytes, SOCKET s); -int RecvNonBlock(char * buffer, int bytes, SOCKET s); -int RecvNonBlockUDP(char * buffer, int bytes, SOCKET s); -int SendUDPMessage(SOCKET s, const char *message, int length, char *ip, int port); +bool Send(const char * buffer, int bytes, SOCKET s); +ssize_t Recv(const char * buffer, int bytes, SOCKET s); +ssize_t RecvAll(const char * buffer, int bytes, SOCKET s); +ssize_t RecvNonBlock(char * buffer, int bytes, SOCKET s); +ssize_t RecvNonBlockUDP(char * buffer, int bytes, SOCKET s); +ssize_t SendUDPMessage(SOCKET s, const char *message, int length, char *ip, int port); #endif diff --git a/src/droidcam.c b/src/droidcam.c index 9a466b6..cf10336 100644 --- a/src/droidcam.c +++ b/src/droidcam.c @@ -105,7 +105,7 @@ void UpdateBatteryLabel(char *battery_value) { gtk_label_set_text(GTK_LABEL(batteryText), battery_value); } -static void Stop(void) { +static void stop_av(void) { a_running = false; v_running = false; dbgprint("join\n"); @@ -125,7 +125,9 @@ static void Stop(void) { g_thread_join(hBatteryThread); hBatteryThread = NULL; } +} +static void reset_ui(void) { gtk_widget_set_sensitive(GTK_WIDGET(elButton), FALSE); gtk_widget_set_sensitive(GTK_WIDGET(wbButton), FALSE); gtk_widget_set_sensitive(GTK_WIDGET(menuButton), FALSE); @@ -255,7 +257,8 @@ static void the_callback(GtkWidget* widget, gpointer extra) switch (cb) { case CB_BUTTON: if (v_running || a_running) { - Stop(); + reset_ui(); + stop_av(); cb = (int)g_settings.connection; goto _up; } @@ -664,7 +667,7 @@ int main(int argc, char *argv[]) g_signal_connect(window, "delete-event", G_CALLBACK(delete_window_callback), window); gtk_widget_show_all(window); - Stop(); // reset the UI + reset_ui(); LoadSettings(&g_settings); if (argc >= 1) { parse_args(argc, argv); @@ -711,7 +714,7 @@ int main(int argc, char *argv[]) // main loop gtk_main(); - Stop(); + stop_av(); decoder_fini(); connection_cleanup(); SaveSettings(&g_settings);