/** * \brief Send the chip ID information. * * \param name Not used. * \param recv_buf Receive buffer. * \param recv_len Receive buffer length. * * \return 0. */ static int cgi_chipInfo(struct netconn *client, const char *name, char *recv_buf, size_t recv_len) { (void)recv_buf; (void)recv_len; (void)name; /* Protect tx_buf buffer from concurrent access. */ sys_arch_sem_wait(&cgi_sem, 0); sprintf((char *)tx_buf, "{\"core_name\":\"%s\",\"arch_name\":\"%s\",\"sram_size\":\"%s\",\"flash_size\":\"%s\"}", chipid_eproc_name(CHIPID_EPRCOC), chipid_archnames(CHIPID_ARCH), chipid_sramsize(CHIPID_SRAMSIZ), chipid_nvpsize(CHIPID_NVPSIZ)); /* 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; }
/** * \brief Send back the input string. * * \param name Not used. * \param recv_buf Receive buffer to send back. * \param recv_len Receive buffer length. * * \return 0. */ static int cgi_echo(const char *name, char *recv_buf, size_t recv_len) { UNUSED(name); http_sendOk(HTTP_CONTENT_PLAIN); http_write(recv_buf, recv_len); return 0; }
/** * \brief Set the led status and send back the new status. * * \param name String containing the led status request. * \param recv_buf Receive buffer. * \param recv_len Receive buffer length. * * \return 0. */ static int cgi_led(const char *name, char *recv_buf, size_t recv_len) { UNUSED(recv_buf); UNUSED(recv_len); UNUSED(name); char *query_str = strstr(name, "?") + 1; size_t query_str_len = strlen(query_str); int led_id; int led_pio; int led_cmd; http_tokenizeGetRequest(query_str, query_str_len); if (http_getValue(query_str, query_str_len, CGI_LED_ID_KEY, key_value, sizeof(key_value)) < 0) { goto error; } led_id = atoi(key_value); if (http_getValue(query_str, query_str_len, CGI_LED_CMD_KEY, key_value, sizeof(key_value)) < 0) { goto error; } led_cmd = atoi(key_value); if (led_id == 0) { led_pio = LED2_GPIO; } else if (led_id == 1) { led_pio = LED1_GPIO; } else if (led_id == 2) { led_pio = LED0_GPIO; } else if (led_id == 3) { led_pio = LED3_GPIO; } if (led_cmd) { ioport_set_pin_level(led_pio, LED2_ACTIVE_LEVEL); SET_LED_STATUS(status.led_status, led_id); } else { ioport_set_pin_level(led_pio, LED2_INACTIVE_LEVEL); CLEAR_LED_STATUS(status.led_status, led_id); } sprintf((char *)tx_buf, "{\"n\":%d, \"set\":,%d}", led_id, led_cmd); http_sendOk(HTTP_CONTENT_JSON); http_write((const char *)tx_buf, strlen((char *)tx_buf)); return 0; error: http_sendInternalErr(HTTP_CONTENT_JSON); return 0; }
/** * \brief Send system uptime. * * \param name Not used. * \param recv_buf Receive buffer. * \param recv_len Receive buffer length. * * \return 0. */ static int cgi_uptime(const char *name, char *recv_buf, size_t recv_len) { UNUSED(recv_buf); UNUSED(recv_len); UNUSED(name); sec_to_strDhms(status.up_time, (char *)tx_buf, sizeof(tx_buf)); http_sendOk(HTTP_CONTENT_JSON); http_write((const char *)tx_buf, strlen((char *)tx_buf)); return 0; }
/** * \brief Send the internal core temperature in string format. * * \param name Not used. * \param recv_buf Receive buffer. * \param recv_len Receive buffer length. * * \return 0. */ static int cgi_temp(const char *name, char *recv_buf, size_t recv_len) { UNUSED(recv_buf); UNUSED(recv_len); UNUSED(name); sprintf((char *)tx_buf, "[%d.%d]", status.internal_temp / 100, status.internal_temp % 100); http_sendOk(HTTP_CONTENT_JSON); http_write((const char *)tx_buf, strlen((char *)tx_buf)); return 0; }
/** * \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; }
/** * \brief Send the led status. * * \param name Not used. * \param recv_buf Receive buffer. * \param recv_len Receive buffer length. * * \return 0. */ static int cgi_ledStatus(const char *name, char *recv_buf, size_t recv_len) { UNUSED(recv_buf); UNUSED(recv_len); UNUSED(name); sprintf((char *)tx_buf, "{ \"0\":\"%d\", \"1\":\"%d\", \"2\":\"%d\"}", GET_LED_STATUS(status.led_status, 0), GET_LED_STATUS(status.led_status, 1), GET_LED_STATUS(status.led_status, 2)); http_sendOk(HTTP_CONTENT_JSON); http_write((const char *)tx_buf, strlen((char *)tx_buf)); return 0; }
/** * \brief Send the potentiometer voltage. * * \param name Not used. * \param recv_buf Receive buffer. * \param recv_len Receive buffer length. * * \return 0. */ static int cgi_resistor(const char *name, char *recv_buf, size_t recv_len) { UNUSED(recv_buf); UNUSED(recv_len); UNUSED(name); u16_t volt; volt = afec_channel_get_value(AFEC0, AFEC_CHANNEL_5) * 10000 / 4096; sprintf((char *)tx_buf, "[ \"%d.%dV\" ]", volt / 1000, volt % 1000); http_sendOk(HTTP_CONTENT_JSON); http_write((const char *)tx_buf, strlen((char *)tx_buf)); return 0; }
/** * \brief Send the chip ID information. * * \param name Not used. * \param recv_buf Receive buffer. * \param recv_len Receive buffer length. * * \return 0. */ static int cgi_chipInfo(const char *name, char *recv_buf, size_t recv_len) { UNUSED(recv_buf); UNUSED(recv_len); UNUSED(name); sprintf((char *)tx_buf, "{ \"core_name\":\"%s\", \"arch_name\":\"%s\", \"sram_size\":\"%s\",\"flash_size\":\"%s\", \"mem_boot_type\":\"%s\" }", chipid_eproc_name(CHIPID_EPRCOC), chipid_archnames(CHIPID_ARCH), chipid_sramsize(CHIPID_SRAMSIZ), chipid_nvpsize(CHIPID_NVPSIZ), chipid_nvptype(CHIPID_NVTYP)); http_sendOk(HTTP_CONTENT_JSON); http_write((const char *)tx_buf, strlen((char *)tx_buf)); return 0; }
/** * \brief Read a message. * * \param name Request containing the message. * \param recv_buf Receive buffer. * \param recv_len Receive buffer length. * * \return 0. */ static int cgi_displayMsg(const char *name, char *recv_buf, size_t recv_len) { UNUSED(recv_buf); UNUSED(recv_len); UNUSED(name); char *query_str = strstr(name, "?") + 1; size_t query_str_len = strlen(query_str); http_tokenizeGetRequest(query_str, query_str_len); if (http_getValue(query_str, query_str_len, CGI_MSG_CMD_KEY, key_value, sizeof(key_value)) > 0) { http_sendOk(HTTP_CONTENT_JSON); return 0; } http_sendInternalErr(HTTP_CONTENT_JSON); return 0; }
/** * \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; }