#include #include "app_serv.h" #include "host_app.h" #if defined(CONFIG_HOST_ETHERNET_TASK_ENABLE) static OS_STK HodtTaskStk[HOST_TASK_STK_SIZE]; #endif #define HOST_TCP_BUF_SIZE 128 static char host_tcp_buf[HOST_TCP_BUF_SIZE]; int host_conn_ctr_all = 0; int host_conn_ctr_ok = 0; /// переключение канала Ethernet-реле RODOS-10 по http int HostRodosSwitch(CPU_INT32U ip_addr, CPU_INT16U port, CPU_INT08U channel, CPU_INT08U state, CPU_INT32U timeout) { static const char http_raw_1_on[] = "GET /rb%dn.cgi HTTP/1.1\r\n"; static const char http_raw_1_off[] = "GET /rb%df.cgi HTTP/1.1\r\n"; static const char http_raw_2[] = "User-Agent: solarium web client\r\nAccept: */*\r\nAccept-Encoding: identity\r\n"; static const char http_raw_3[] = "Host: "; static const char http_raw_4[] = "\r\nConnection: Keep-Alive\r\n\r\n"; static const char http_ok[] = "HTTP/1.1 200 OK"; NET_ERR err; NET_SOCK_ID sock = HostConnectSocket(ip_addr, port, timeout, &err); if (err != NET_SOCK_ERR_NONE) { return -1; } memset(host_tcp_buf, 0, HOST_TCP_BUF_SIZE); if (state == RELAY_ON) sprintf(host_tcp_buf, http_raw_1_on, (int)channel); else sprintf(host_tcp_buf, http_raw_1_off, (int)channel); if (HostWriteStr(sock, host_tcp_buf) != strlen(host_tcp_buf)) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return -3; } strcpy(host_tcp_buf, http_raw_2); if (HostWriteStr(sock, host_tcp_buf) != strlen(host_tcp_buf)) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return -3; } strcpy(host_tcp_buf, http_raw_3); NetASCII_IP_to_Str(ip_addr, (CPU_CHAR*)&host_tcp_buf[strlen(host_tcp_buf)], DEF_NO, &err); strcat(host_tcp_buf, http_raw_4); if (HostWriteStr(sock, host_tcp_buf) != strlen(host_tcp_buf)) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return -3; } memset(host_tcp_buf, 0, HOST_TCP_BUF_SIZE); int len = HostReadLine(sock, host_tcp_buf, HOST_TCP_BUF_SIZE - 1, timeout, &err); if (err != NET_SOCK_ERR_NONE) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return -4; } if ((len <= 0) || (strcmp(host_tcp_buf, http_ok) != 0)) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return -5; } // Connection: close\n // Content-Type: text/html\n // Cache-Control: no-cache\n // \n len = 4; while (len--) { if ((HostReadLine(sock, host_tcp_buf, HOST_TCP_BUF_SIZE - 1, timeout, &err) <= 0) || (err != NET_SOCK_ERR_NONE)) { break; } } NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return 0; } /// int http_get(CPU_INT32U ip_addr, CPU_INT16U port, const char* url, char* response, CPU_INT32U maxlen, CPU_INT32U timeout) { static const char http_raw_url_1[] = "GET "; static const char http_raw_url_2[] = " HTTP/1.1\r\n"; static const char http_raw_2[] = "User-Agent: solarium web client\r\nAccept: */*\r\nAccept-Encoding: identity\r\n"; static const char http_raw_3[] = "Host: "; static const char http_raw_4[] = "\r\nConnection: Keep-Alive\r\n\r\n"; static const char http_ok[] = "HTTP/1.1 200 OK"; NET_ERR err; NET_SOCK_ID sock = HostConnectSocket(ip_addr, port, timeout, &err); if (err != NET_SOCK_ERR_NONE) { return -1; } memset(host_tcp_buf, 0, HOST_TCP_BUF_SIZE); strcpy(host_tcp_buf, http_raw_url_1); strcat(host_tcp_buf, url); strcat(host_tcp_buf, http_raw_url_2); if (HostWriteStr(sock, host_tcp_buf) != strlen(host_tcp_buf)) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return -3; } strcpy(host_tcp_buf, http_raw_2); if (HostWriteStr(sock, host_tcp_buf) != strlen(host_tcp_buf)) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return -3; } strcpy(host_tcp_buf, http_raw_3); NetASCII_IP_to_Str(ip_addr, (CPU_CHAR*)&host_tcp_buf[strlen(host_tcp_buf)], DEF_NO, &err); strcat(host_tcp_buf, http_raw_4); if (HostWriteStr(sock, host_tcp_buf) != strlen(host_tcp_buf)) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return -3; } memset(host_tcp_buf, 0, HOST_TCP_BUF_SIZE); int len = HostReadLine(sock, host_tcp_buf, HOST_TCP_BUF_SIZE - 1, timeout, &err); if (err != NET_SOCK_ERR_NONE) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return -4; } if ((len <= 0) || (strcmp(host_tcp_buf, http_ok) != 0)) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return -5; } // Connection: close\n // Content-Type: text/html\n // Cache-Control: no-cache\n // \n int content_len = -1; static const char http_content_len[] = "Content-Length: %d"; int resp_lines = 16; while (resp_lines--) { int len = HostReadLine(sock, host_tcp_buf, HOST_TCP_BUF_SIZE - 1, timeout, &err); if ((err != NET_SOCK_ERR_NONE) || (len < 0)) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return -6; } if (len == 0) { break; } int contlen = -1; if (sscanf(host_tcp_buf, http_content_len, &contlen) == 1) { content_len = contlen; } } if (content_len > 0) { int len = HostReadLine(sock, host_tcp_buf, HOST_TCP_BUF_SIZE - 1, timeout, &err); if ((err != NET_SOCK_ERR_NONE) || (len < 0)) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return -7; } strncpy(response, host_tcp_buf, maxlen); } NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return 0; } /// запуск музыки на raspberry по http int HostMusicPlay(CPU_INT32U sound_ip, int file_index) { char url_str[16]; char response[17]; sprintf(url_str, "/play/%d", file_index); return http_get(sound_ip, 80, (const char*)url_str, response, 16, 500); } /// запись громкости в плеер по http int HostSetVolume(CPU_INT32U sound_ip, int volume) { char url_str[16]; char response[17]; sprintf(url_str, "/volume/%d", volume); return http_get(sound_ip, 80, (const char*)url_str, response, 16, 500); } /// состояние проигрывания музыки на raspberry по http int HostIsMusicPlaying(CPU_INT32U sound_ip) { static const char url_str[] = "/status"; static const char playing_str[] = "Playing file "; char response[33]; int res; res = http_get(sound_ip, 80, (const char*)url_str, response, 32, 500); if (res < 0) return 0; if (strstr(response, playing_str) != NULL) { return 1; } return 0; } /// int HostMusicStop(CPU_INT32U sound_ip) { static const char url_str[] = "/stop"; char response[17]; int res; res = http_get(sound_ip, 80, (const char*)url_str, response, 16, 500); return res; } /// int HostWriteData(NET_SOCK_ID sock, char* str, int len) { int tx_ctr = 0; while (tx_ctr < len) { NET_ERR err; int tx_size = NetSock_TxData(sock, &str[tx_ctr], len - tx_ctr, NET_SOCK_FLAG_NONE, &err); OSTimeDly(10); if (tx_size > 0) { tx_ctr += tx_size; } else { return -1; } } return tx_ctr; } /// int HostWriteDataTimeout(NET_SOCK_ID sock, char* str, int len, CPU_INT32U timeout) { CPU_INT32U time_stamp = OSTimeGet(); int tx_ctr = 0; while (tx_ctr < len) { NET_ERR err; int tx_size = NetSock_TxData(sock, &str[tx_ctr], len - tx_ctr, NET_SOCK_FLAG_NONE, &err); OSTimeDly(10); if (tx_size > 0) { tx_ctr += tx_size; } else { if ((OSTimeGet() - time_stamp) > timeout) { return -1; } } } return tx_ctr; } /// int HostWriteStr(NET_SOCK_ID sock, char* str) { int tx_ctr = 0; int len = strlen(str); while (tx_ctr < len) { NET_ERR err; int tx_size = NetSock_TxData(sock, &str[tx_ctr], len - tx_ctr, NET_SOCK_FLAG_NONE, &err); OSTimeDly(10); if (tx_size > 0) { tx_ctr += tx_size; } else { return -1; } } return tx_ctr; } /// int HostReadLine(NET_SOCK_ID sock, char *str, CPU_INT32U maxlen, CPU_INT32U timeout, NET_ERR *err) { CPU_INT32U time_stamp; char *str_ptr = str; CPU_INT32U len = 0; CPU_INT08U exit_while; time_stamp = OSTimeGet(); do { char c; NET_SOCK_RTN_CODE ret_code; exit_while = 0; if (NetNIC_ConnStatusGet() != DEF_ON) { *err = NET_SOCK_ERR_FAULT; break; } ret_code = NetSock_RxData(sock, &c, 1, NET_SOCK_FLAG_RX_NO_BLOCK, err); switch (*err) { case NET_SOCK_ERR_NONE: if (ret_code) { time_stamp = OSTimeGet(); *str_ptr++ = c; len++; if (c == '\n') { char *ptr = strrchr(str, '\n'); if (ptr) *ptr = 0; ptr = strrchr(str, '\r'); if (ptr) *ptr = 0; len = strlen(str); *err = NET_SOCK_ERR_NONE; exit_while = 1; } } break; case NET_SOCK_ERR_RX_Q_EMPTY: if (OSTimeGet() - time_stamp < timeout) { OSTimeDly(2); *err = NET_SOCK_ERR_NONE; } break; case NET_SOCK_ERR_INVALID_DATA_SIZE: case NET_ERR_INIT_INCOMPLETE: case NET_SOCK_ERR_NULL_PTR: case NET_SOCK_ERR_NULL_SIZE: case NET_SOCK_ERR_NOT_USED: case NET_SOCK_ERR_CLOSED: case NET_SOCK_ERR_FAULT: case NET_SOCK_ERR_INVALID_SOCK: case NET_SOCK_ERR_INVALID_FAMILY: case NET_SOCK_ERR_INVALID_PROTOCOL: case NET_SOCK_ERR_INVALID_TYPE: case NET_SOCK_ERR_INVALID_STATE: case NET_SOCK_ERR_INVALID_OP: case NET_SOCK_ERR_INVALID_FLAG: case NET_SOCK_ERR_INVALID_ADDR_LEN: case NET_SOCK_ERR_RX_Q_CLOSED: case NET_ERR_RX: case NET_CONN_ERR_INVALID_CONN: case NET_CONN_ERR_NOT_USED: case NET_CONN_ERR_NULL_PTR: case NET_CONN_ERR_INVALID_ADDR_LEN: case NET_CONN_ERR_ADDR_NOT_USED: case NET_OS_ERR_LOCK: break; default: *err = NET_ERR_RX; break; } } while ((*err == NET_SOCK_ERR_NONE) && (!exit_while)); return len; } /// int HostReadData(NET_SOCK_ID sock, char *str, CPU_INT32U maxlen, CPU_INT32U timeout, NET_ERR *err) { CPU_INT32U time_stamp; char *str_ptr = str; CPU_INT32U len = 0; CPU_INT08U exit_while; time_stamp = OSTimeGet(); do { char c; NET_SOCK_RTN_CODE ret_code; exit_while = 0; if (NetNIC_ConnStatusGet() != DEF_ON) { *err = NET_SOCK_ERR_FAULT; break; } ret_code = NetSock_RxData(sock, &c, 1, NET_SOCK_FLAG_RX_NO_BLOCK, err); switch (*err) { case NET_SOCK_ERR_NONE: if (ret_code) { time_stamp = OSTimeGet(); *str_ptr++ = c; len++; if (c == '\n') { char *ptr = strrchr(str, '\n'); if (ptr) *ptr = 0; ptr = strrchr(str, '\r'); if (ptr) *ptr = 0; len = strlen(str); *err = NET_SOCK_ERR_NONE; exit_while = 1; } } break; case NET_SOCK_ERR_RX_Q_EMPTY: if (OSTimeGet() - time_stamp < timeout) { OSTimeDly(2); if (len > 0) { exit_while = 1; } *err = NET_SOCK_ERR_NONE; } break; case NET_SOCK_ERR_INVALID_DATA_SIZE: case NET_ERR_INIT_INCOMPLETE: case NET_SOCK_ERR_NULL_PTR: case NET_SOCK_ERR_NULL_SIZE: case NET_SOCK_ERR_NOT_USED: case NET_SOCK_ERR_CLOSED: case NET_SOCK_ERR_FAULT: case NET_SOCK_ERR_INVALID_SOCK: case NET_SOCK_ERR_INVALID_FAMILY: case NET_SOCK_ERR_INVALID_PROTOCOL: case NET_SOCK_ERR_INVALID_TYPE: case NET_SOCK_ERR_INVALID_STATE: case NET_SOCK_ERR_INVALID_OP: case NET_SOCK_ERR_INVALID_FLAG: case NET_SOCK_ERR_INVALID_ADDR_LEN: case NET_SOCK_ERR_RX_Q_CLOSED: case NET_ERR_RX: case NET_CONN_ERR_INVALID_CONN: case NET_CONN_ERR_NOT_USED: case NET_CONN_ERR_NULL_PTR: case NET_CONN_ERR_INVALID_ADDR_LEN: case NET_CONN_ERR_ADDR_NOT_USED: case NET_OS_ERR_LOCK: break; default: *err = NET_ERR_RX; break; } } while ((*err == NET_SOCK_ERR_NONE) && (!exit_while)); return len; } /// NET_SOCK_ID HostConnectSocket(CPU_INT32U ip_addr, CPU_INT16U port, CPU_INT32U timeout, NET_ERR* err) { NET_SOCK_ID sock; NET_SOCK_ADDR_IP server_sock_addr_ip; CPU_INT32U time_stamp = OSTimeGet(); sock = NetSock_Open(NET_SOCK_ADDR_FAMILY_IP_V4, NET_SOCK_TYPE_STREAM, NET_SOCK_PROTOCOL_TCP, err); if ((*err != NET_SOCK_ERR_NONE) || (sock < 0)) { return -1; } memset(&server_sock_addr_ip, 0, sizeof(server_sock_addr_ip)); server_sock_addr_ip.Family = NET_SOCK_ADDR_FAMILY_IP_V4; server_sock_addr_ip.Addr = NET_UTIL_HOST_TO_NET_32(ip_addr); server_sock_addr_ip.Port = NET_UTIL_HOST_TO_NET_16(port); NetSock_Conn((NET_SOCK_ID)sock, (NET_SOCK_ADDR *)&server_sock_addr_ip, (NET_SOCK_ADDR_LEN)sizeof(server_sock_addr_ip), err); while (NetSock_IsConn((NET_SOCK_ID)sock, err) != DEF_YES) { if ((*err != NET_SOCK_ERR_CONN_IN_PROGRESS) && (*err != NET_SOCK_ERR_NONE)) { break; } if (OSTimeGet() - time_stamp > timeout) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return -1; } OSTimeDly(2); } if (*err != NET_SOCK_ERR_NONE) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return -1; } return sock; } /// int HostCheckIpDevice(CPU_INT32U ip_addr, CPU_INT16U port, CPU_INT32U timeout) { int res = -1; NET_ERR err; NET_SOCK_ID sock = HostConnectSocket(ip_addr, port, timeout, &err); if (err != NET_SOCK_ERR_NONE) { return -1; } memset(host_tcp_buf, 0, HOST_TCP_BUF_SIZE); int len = HostReadLine(sock, host_tcp_buf, HOST_TCP_BUF_SIZE - 1, timeout, &err); if (err != NET_SOCK_ERR_NONE) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return -2; } if (len > 0) { if (strcmp(host_tcp_buf, "Welcome to control console!") == 0) { res = 0; } } NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return res; } /// запись параметра int HostWriteParam(CPU_INT32U ip_addr, CPU_INT16U port, char* param_str, char* param_val, CPU_INT32U timeout) { int res = -1; NET_ERR err; NET_SOCK_ID sock = HostConnectSocket(ip_addr, port, timeout, &err); if (err != NET_SOCK_ERR_NONE) { return -1; } memset(host_tcp_buf, 0, HOST_TCP_BUF_SIZE); int len = HostReadLine(sock, host_tcp_buf, HOST_TCP_BUF_SIZE - 1, timeout, &err); if (err != NET_SOCK_ERR_NONE) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return -2; } if (len > 0) { if (strcmp(host_tcp_buf, "Welcome to control console!") == 0) { res = 0; } } if (res != 0) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return res; } strcpy(host_tcp_buf, "SET "); strcat(host_tcp_buf, param_str); strcat(host_tcp_buf, " "); strcat(host_tcp_buf, param_val); strcat(host_tcp_buf, "\n"); if (HostWriteStr(sock, host_tcp_buf) != strlen(host_tcp_buf)) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return -3; } memset(host_tcp_buf, 0, HOST_TCP_BUF_SIZE); len = HostReadLine(sock, host_tcp_buf, HOST_TCP_BUF_SIZE - 1, timeout, &err); if (err != NET_SOCK_ERR_NONE) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return -4; } if ((len <= 0) || (strcmp(host_tcp_buf, "OK") != 0)) { res = -5; } NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return res; } int HostReadParam(CPU_INT32U ip_addr, CPU_INT16U port, char* param_str, char* param_val, CPU_INT08U maxlen, CPU_INT32U timeout) { int res = -1; NET_ERR err; NET_SOCK_ID sock = HostConnectSocket(ip_addr, port, timeout, &err); if (err != NET_SOCK_ERR_NONE) { return -1; } memset(host_tcp_buf, 0, HOST_TCP_BUF_SIZE); int len = HostReadLine(sock, host_tcp_buf, HOST_TCP_BUF_SIZE - 1, timeout, &err); if (err != NET_SOCK_ERR_NONE) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return -2; } if (len > 0) { if (strcmp(host_tcp_buf, "Welcome to control console!") == 0) { res = 0; } } if (res != 0) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return res; } strcpy(host_tcp_buf, "GET "); strcat(host_tcp_buf, param_str); strcat(host_tcp_buf, "\n"); if (HostWriteStr(sock, host_tcp_buf) != strlen(host_tcp_buf)) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return -3; } memset(host_tcp_buf, 0, HOST_TCP_BUF_SIZE); len = HostReadLine(sock, host_tcp_buf, HOST_TCP_BUF_SIZE - 1, timeout, &err); if (err != NET_SOCK_ERR_NONE) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return -4; } if (len <= 0) { res = -5; } char *ptr = host_tcp_buf; while (maxlen-- && len--) { *param_val++ = *ptr++; } memset(host_tcp_buf, 0, HOST_TCP_BUF_SIZE); len = HostReadLine(sock, host_tcp_buf, HOST_TCP_BUF_SIZE - 1, timeout, &err); if (err != NET_SOCK_ERR_NONE) { NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return -4; } if ((len <= 0) || (strcmp(host_tcp_buf, "OK") != 0)) { res = -5; } NET_ERR err_close; NetSock_Close(sock, &err_close); OSTimeDly(100); return res; } /// запись импульсов int HostWritePulses(CPU_INT32U ip_addr, CPU_INT32U count, CPU_INT32U len_ms, CPU_INT32U len_pause_ms, CPU_INT32U pause, CPU_INT32U timer) { char str[32]; if (len_pause_ms > 0) { sprintf(str, "%d,%d,%d,%d,%d", (int)count, (int)len_ms, (int)len_pause_ms, (int)pause, (int)timer); } else if (timer > 0) { sprintf(str, "%d,%d,%d,%d", (int)count, (int)len_ms, (int)pause, (int)timer); } else { sprintf(str, "%d,%d,%d", (int)count, (int)len_ms, (int)pause); } return HostWriteParam(ip_addr, CONSOLE_TCP_DEFAULT_PORT, "PULSEOUT", str, HOST_SOCKET_DEFAULT_TIMEOUT); } /// задача опроса контроллеров постов по сети void HostAppTask(void *p_arg) { while (1) { OSTimeDly(1000); host_conn_ctr_all++; if (HostCheckIpDevice(0xC0A8008C, CONSOLE_TCP_DEFAULT_PORT, HOST_SOCKET_DEFAULT_TIMEOUT) == 0) { host_conn_ctr_ok++; } } } void InitHostApp() { #if defined(CONFIG_HOST_ETHERNET_TASK_ENABLE) OSTaskCreate(HostAppTask, (void *)0, (OS_STK *)&HodtTaskStk[HOST_TASK_STK_SIZE-1], HOST_TASK_PRIO); INT8U err; OSTaskNameSet(HOST_TASK_PRIO, "Host App Task", &err); #endif }