/** * \brief Send a JSON string representing the board status. * * \param name Not used. * \param recv_buf Receive buffer. * \param recv_len Receive buffer length. * * \return 0. */ static int cgi_status(const char *name, char *recv_buf, size_t recv_len) { UNUSED(recv_buf); UNUSED(recv_len); UNUSED(name); volatile uint16_t volt; uint32_t length = 0; uint32_t i; status.tot_req++; volt = afec_channel_get_value(AFEC0, AFEC_CHANNEL_5); status.up_time = xTaskGetTickCount() / 1000; /* Update board status. */ sprintf(status.last_connected_ip, "%d.%d.%d.%d", IP_ADDR_TO_INT_TUPLE(g_pcb->remote_ip.addr)); sprintf(status.local_ip, "%d.%d.%d.%d", IP_ADDR_TO_INT_TUPLE(g_pcb->local_ip.addr)); length += sprintf((char *)tx_buf, "{\"local_ip\":\"%s\",\"last_connected_ip\":\"%s\", \"temp\":%d.%d, \"mag\":\"", status.local_ip, status.last_connected_ip, status.internal_temp / 100, status.internal_temp % 100); /* Update magnitude graph (98 + 1). */ for (i = 0; i < 98; ++i) { length += sprintf((char *)tx_buf + length, "%d|", mag_in_buffer_int[i]); } length += sprintf((char *)tx_buf + length, "%d\"", mag_in_buffer_int[i]); /* Remaining board status. */ length += sprintf((char *)tx_buf + length, ",\"volt\":%d,\"up_time\":%ld,\"tot_req\":%d, \"leds\":{ \"0\":\"%d\", \"1\":\"%d\", \"2\":\"%d\"}}", volt, status.up_time, status.tot_req, GET_LED_STATUS(status.led_status, 0), GET_LED_STATUS(status.led_status, 1), GET_LED_STATUS(status.led_status, 2)); /* Send answer. */ http_sendOk(HTTP_CONTENT_JSON); http_write((char const *)tx_buf, strlen((char *)tx_buf)); return 0; }
static bool tcpsocket_reconnect(TcpSocket *socket) { LOG_ERR("Reconnecting..\n"); /* Close socket if was open */ close_socket(socket); /* If we are in server mode we do nothing */ if (socket->handler) return false; /* Start with new connection */ socket->sock = netconn_new(NETCONN_TCP); if(!socket->sock) { LOG_ERR("Unabe to alloc new connection\n"); socket->error = -1; goto error; } socket->error = netconn_bind(socket->sock, socket->local_addr, socket->port); if(socket->error != ERR_OK) { LOG_ERR("Connection error\n"); goto error; } socket->error = netconn_connect(socket->sock, socket->remote_addr, socket->port); if(socket->error != ERR_OK) { LOG_ERR("Cannot create socket\n"); goto error; } LOG_INFO("connected ip=%d.%d.%d.%d\n", IP_ADDR_TO_INT_TUPLE(socket->remote_addr->addr)); return true; error: netconn_delete(socket->sock); socket->sock = NULL; return false; }
/** * \brief Send a JSON string representing the board status. * * \param name Not used. * \param recv_buf Receive buffer. * \param recv_len Receive buffer length. * * \return 0. */ static int cgi_status(struct netconn *client, const char *name, char *recv_buf, size_t recv_len) { (void)recv_buf; (void)recv_len; (void)name; uint32_t length = 0; uint32_t nb = 11; uint32_t i, count, new_entry; #if LWIP_STATS extern uint32_t lwip_tx_rate; extern uint32_t lwip_rx_rate; #else volatile uint32_t lwip_tx_rate = 0; volatile uint32_t lwip_rx_rate = 0; #endif /* Protect tx_buf buffer from concurrent access. */ sys_arch_sem_wait(&cgi_sem, 0); status.tot_req++; status.up_time = xTaskGetTickCount() / 1000; /* Update board status. */ sprintf(status.last_connected_ip, "%d.%d.%d.%d", IP_ADDR_TO_INT_TUPLE(client->pcb.ip->remote_ip.addr)); sprintf(status.local_ip, "%d.%d.%d.%d", IP_ADDR_TO_INT_TUPLE(client->pcb.ip->local_ip.addr)); length += sprintf((char *)tx_buf, "{\"board_ip\":\"%s\",\"remote_ip\":\"%s\",\"download\":%u,\"upload\":%u", status.local_ip, status.last_connected_ip, lwip_rx_rate, lwip_tx_rate); /* Turn FreeRTOS stats into JSON. */ vTaskGetRunTimeStats(freertos_stats); length += sprintf((char *)tx_buf + length, ",\"rtos\":{\"10"); // i = 2 to skip first 13 10 sequence. for (i = 2, count = 0, new_entry = 0; i < FREERTOS_STATS_BUFLEN && freertos_stats[i]; ++i) { if (freertos_stats[i] == 13) { tx_buf[length++] = '\"'; new_entry = 1; continue; } if (freertos_stats[i] == 10) continue; if (freertos_stats[i] == 9) { count += 1; if (count == 4) { tx_buf[length++] = '\"'; tx_buf[length++] = ':'; tx_buf[length++] = '\"'; count = 0; continue; } } if (count != 0) continue; if (new_entry == 1) { new_entry = 0; tx_buf[length++] = ','; tx_buf[length++] = '\"'; /* Append ID to task name since JSON id must be unique. */ tx_buf[length++] = '0' + nb / 10; tx_buf[length++] = '0' + nb % 10; nb++; } tx_buf[length++] = freertos_stats[i]; } tx_buf[length++] = '}'; char * memp_names[] = { #define LWIP_MEMPOOL(name,num,size,desc) desc, #include "lwip/memp_std.h" }; length += sprintf((char *)tx_buf + length, ",\"lwip\":{"); #if MEM_STATS || MEMP_STATS length += sprintf((char *)tx_buf + length, "\"HEAP\":{\"Cur\":%d,\"Size\":%d,\"Max\":%d,\"Err\":%u}", lwip_stats.mem.used, lwip_stats.mem.avail, lwip_stats.mem.max, lwip_stats.mem.err); if (MEMP_MAX > 0) tx_buf[length++] = ','; #endif for (uint32_t z= 0; z < MEMP_MAX; ++z) { length += sprintf((char *)tx_buf + length, "\"%s\":{\"Cur\":%d,\"Size\":%d,\"Max\":%d,\"Err\":%u}", memp_names[z], lwip_stats.memp[z].used, lwip_stats.memp[z].avail, lwip_stats.memp[z].max, lwip_stats.memp[z].err); if (z + 1 < MEMP_MAX) tx_buf[length++] = ','; } tx_buf[length++] = '}'; /* Remaining board status. */ length += sprintf((char *)tx_buf + length, ",\"up_time\":%u,\"tot_req\":%u}", status.up_time, status.tot_req); /* Send answer. */ http_sendOk(client, HTTP_CONTENT_JSON); /* Use NETCONN_COPY to avoid corrupting the buffer after releasing the semaphore. */ netconn_write(client, tx_buf, strlen((char *)tx_buf), NETCONN_COPY); /* Release semaphore to allow further use of tx_buf. */ sys_sem_signal(&cgi_sem); return 0; }