diff --git a/src/av.c b/src/av.c index 991e594..103d954 100644 --- a/src/av.c +++ b/src/av.c @@ -12,6 +12,8 @@ #include "decoder.h" #include #include +#include +#include extern int a_active; extern int v_active; @@ -39,56 +41,81 @@ SOCKET GetConnection(void) { // Battry Check thread void *BatteryThreadProc(__attribute__((__unused__)) void *args) { SOCKET socket = INVALID_SOCKET; - char buf[128] = {0}; - char battery_value[32] = {0}; - int i, j; + char buf[96]; + char battery_value[5]; + struct timeval tv = {0}; + tv.tv_sec = 1; dbgprint("Battery Thread Start\n"); while (v_running || a_running) { - if (!v_active && !a_active) { + if (!v_active && !a_active) { usleep(50000); continue; } + uint8_t battery_value_pos = 0; + size_t percent_len = 0; + socket = GetConnection(); if (socket == INVALID_SOCKET) { goto LOOP; } - if (Send(BATTERY_REQ, CSTR_LEN(BATTERY_REQ), socket) <= 0) { - errprint("error sending battery status request: (%d) '%s'\n", - errno, strerror(errno)); + 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: (%d) '%s'\n", errno, + strerror(errno)); goto LOOP; } memset(buf, 0, sizeof(buf)); + memset(battery_value, 0, sizeof(battery_value)); if (RecvAll(buf, sizeof(buf), socket) <= 0) { goto LOOP; } - 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; + for (uint8_t i = 0; i < (sizeof(buf) - 4); i += 4) { + char *tmp = memchr(&buf[i], '\r', sizeof(buf)); + if (!tmp) { + goto LOOP; + } + if (memcmp(tmp + 1, "\n\r\n", 3) == 0) { + battery_value_pos = (tmp - buf) + 4; break; } } + if (!battery_value_pos || battery_value_pos > (sizeof(buf) - (4 + 1)) || + buf[battery_value_pos] == '0') { + goto LOOP; + } - j = 0; - while (i < sizeof(buf) && j < (sizeof(battery_value)-2) && buf[i] >= '0' && buf[i] <= '9') - battery_value[j++] = buf[i++]; + 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; + } + } - if (j == 0) - battery_value[j++] = '-'; + if (percent_len == 0) { + battery_value[0] = '-'; + percent_len = 1; + } - battery_value[j++] = '%'; - battery_value[j++] = 0; + 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++) + for (uint16_t i = 0; i < 30000 && (v_running || a_running); i++) usleep(1000); } @@ -126,8 +153,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){ - errprint("send error (%d) '%s'\n", errno, strerror(errno)); + if (!Send(buf, len, videoSocket)){ MSG_ERROR("Error sending request, DroidCam might be busy with another client."); goto early_out; } @@ -246,9 +272,8 @@ 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)) { errprint("send error (audio) (%d) '%s'\n", errno, strerror(errno)); - MSG_ERROR("Error sending audio request"); goto early_out; } diff --git a/src/connection.c b/src/connection.c index a320c34..2d898e4 100644 --- a/src/connection.c +++ b/src/connection.c @@ -86,41 +86,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 086234b..6dba68a 100644 --- a/src/droidcam.c +++ b/src/droidcam.c @@ -106,7 +106,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"); @@ -126,9 +126,9 @@ static void Stop(void) { g_thread_join(hBatteryThread); hBatteryThread = NULL; } +} - a_active = false; - v_active = false; +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); @@ -260,7 +260,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; } @@ -669,7 +670,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); @@ -716,7 +717,7 @@ int main(int argc, char *argv[]) // main loop gtk_main(); - Stop(); + stop_av(); decoder_fini(); connection_cleanup(); SaveSettings(&g_settings);