/* * An unnamed project – client module * * Copyright (C) 2017 Gediminas Jakutis * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; version 2.1 * of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include static void init(const unsigned int port, int *sock); static int getpacket(char *data, size_t buffsize, int *sock, struct sockaddr_in *sender); static void draw_idle(void); static void draw_busy(const char * const data); static float digest_mpu_temp(const short int rawdata); static float digest_thermistor_voltage(const short int rawdata); int main(void) { static const char servermagic[] = "I love coffee!"; static const char clientmagic[] = "I love tea!"; struct sockaddr_in srvaddr = {0}; char buff[9001] = {0}; int sock; int pstatus; struct timespec lastreply; struct timespec now; init(2191, &sock); clock_gettime(CLOCK_MONOTONIC_RAW, &now); lastreply = now; lastreply.tv_sec -= 5; do { clock_gettime(CLOCK_MONOTONIC_RAW, &now); pstatus = getpacket(buff, sizeof(buff), &sock, &srvaddr); switch (pstatus) { case 0: if ((now.tv_sec - lastreply.tv_sec) >= 5) { draw_idle(); } break; case 1: lastreply = now; if (buff[0] == 'I') { if (!(strcmp(buff, servermagic))) { sendto(sock, clientmagic, sizeof(clientmagic), MSG_DONTWAIT, (struct sockaddr *) &srvaddr, sizeof(srvaddr)); } draw_idle(); continue; } draw_busy(buff); break; default: ; /* noop */ } } while (getch() != 'q' && pstatus >= 0); close(sock); endwin(); return 0; } static void init(const unsigned int port, int *sock) { struct sockaddr_in bindaddress = {0}; bindaddress.sin_family = AF_INET; bindaddress.sin_port = htons(port); *sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); bind(*sock, (struct sockaddr*) &bindaddress, sizeof(bindaddress)); initscr(); nodelay(stdscr, 1); noecho(); } static int getpacket(char *data, size_t buffsize, int *sock, struct sockaddr_in *sender) { static struct pollfd pfd = {0}; int ret; socklen_t sender_len = sizeof(*sender); if (!pfd.fd) { pfd.fd = *sock; pfd.events = POLLIN; pfd.revents = 0; } ret = poll(&pfd, 1, 25); if (ret <= 0) { return ret; } if (pfd.revents & POLLIN) { recvfrom(*sock, data, buffsize, MSG_DONTWAIT, (struct sockaddr *) sender, &sender_len); ret = 1; } else { ret = 0; } return ret; } static void draw_idle(void) { move(0, 0); clrtoeol(); printw("sequence: [waiting for ESP8266...]"); move(1, 0); clrtoeol(); mvprintw(1, 0, "mpu temp: [waiting for ESP8266...]"); move(2, 0); clrtoeol(); mvprintw(2, 0, "thermistor voltage: [waiting for ESP8266...]"); move(3, 0); clrtoeol(); mvprintw(3, 0, "press 'q' to exit"); refresh(); } static void draw_busy(const char * const data) { unsigned int sequence; short int mpu_data; short int thermistor_data; float mpu_temp; float thermistor_voltage; memcpy(&sequence, data + 2, sizeof(sequence)); memcpy(&mpu_data, data + 6, sizeof(mpu_data)); memcpy(&thermistor_data, data + 8, sizeof(thermistor_data)); mpu_temp = digest_mpu_temp(mpu_data); thermistor_voltage = digest_thermistor_voltage(thermistor_data); move(0, 0); clrtoeol(); printw("sequence: %u", sequence); move(1, 0); clrtoeol(); mvprintw(1, 0, "mpu temp: %.3fC", mpu_temp); move(2, 0); clrtoeol(); mvprintw(2, 0, "thermistor voltage: %.3fV", thermistor_voltage); move(3, 0); clrtoeol(); mvprintw(3, 0, "press 'q' to exit"); refresh(); } static float digest_mpu_temp(const short int rawdata) { float ret; ret = rawdata / 340.0f + 36.53f; return ret; } static float digest_thermistor_voltage(const short int rawdata) { float ret; ret = rawdata * 0.003222656f; return ret; }