Function bodies 132 total
parse_reset_time function · c · L21-L59 (39 LOC)components/api_client/api_client.c
static time_t parse_reset_time(const char *iso, char *out, size_t out_size)
{
int year, month, day, hour, minute, second;
if (sscanf(iso, "%d-%d-%dT%d:%d:%d", &year, &month, &day, &hour, &minute, &second) >= 5) {
struct tm utc = {
.tm_year = year - 1900,
.tm_mon = month - 1,
.tm_mday = day,
.tm_hour = hour,
.tm_min = minute,
.tm_sec = second,
};
/* mktime_utc: temporarily set TZ to UTC for mktime */
char *old_tz = getenv("TZ");
char saved_tz[72] = {0};
if (old_tz) strncpy(saved_tz, old_tz, sizeof(saved_tz) - 1);
setenv("TZ", "UTC0", 1);
tzset();
time_t t = mktime(&utc);
if (old_tz) setenv("TZ", saved_tz, 1);
else unsetenv("TZ");
tzset();
struct tm local;
localtime_r(&t, &local);
static const char *months[] = {
"Jan","Feb","Mar","Apr","May","Jun",
"Jul","Aug","Sep",parse_tier function · c · L60-L78 (19 LOC)components/api_client/api_client.c
static void parse_tier(cJSON *obj, api_usage_tier_t *tier)
{
tier->utilization = 0;
tier->resets_at[0] = '\0';
if (!obj || !cJSON_IsObject(obj)) return;
cJSON *util = cJSON_GetObjectItem(obj, "utilization");
if (util && cJSON_IsNumber(util)) {
tier->utilization = (float)cJSON_GetNumberValue(util);
}
cJSON *resets = cJSON_GetObjectItem(obj, "resets_at");
if (resets && cJSON_IsString(resets)) {
tier->resets_at_epoch = parse_reset_time(cJSON_GetStringValue(resets),
tier->resets_at, sizeof(tier->resets_at));
}
}http_get_with_auth function · c · L84-L128 (45 LOC)components/api_client/api_client.c
static int http_get_with_auth(const char *url, const char *token,
char *resp_buf, size_t resp_size)
{
char auth_header[300];
snprintf(auth_header, sizeof(auth_header), "Bearer %s", token);
esp_http_client_config_t config = {
.url = url,
.method = HTTP_METHOD_GET,
.timeout_ms = 10000,
.crt_bundle_attach = esp_crt_bundle_attach,
};
esp_http_client_handle_t client = esp_http_client_init(&config);
if (!client) return -1;
esp_http_client_set_header(client, "Authorization", auth_header);
esp_http_client_set_header(client, "Content-Type", "application/json");
esp_http_client_set_header(client, "anthropic-beta", "oauth-2025-04-20");
esp_http_client_set_header(client, "User-Agent", "claude-monitor/1.0");
esp_err_t err = esp_http_client_open(client, 0);
if (err != ESP_OK) {
ESP_LOGE(TAG, "HTTP open failed: %s", esp_err_to_name(err));
esp_http_client_cleanup(client);
refresh_access_token function · c · L134-L233 (100 LOC)components/api_client/api_client.c
static esp_err_t refresh_access_token(const char *refresh_token,
char *new_access_out, size_t out_size)
{
ESP_LOGI(TAG, "Refreshing access token...");
cJSON *body = cJSON_CreateObject();
cJSON_AddStringToObject(body, "grant_type", "refresh_token");
cJSON_AddStringToObject(body, "refresh_token", refresh_token);
cJSON_AddStringToObject(body, "client_id", CLIENT_ID);
char *post_data = cJSON_PrintUnformatted(body);
cJSON_Delete(body);
if (!post_data) return ESP_ERR_NO_MEM;
esp_http_client_config_t config = {
.url = TOKEN_URL,
.method = HTTP_METHOD_POST,
.timeout_ms = 10000,
.crt_bundle_attach = esp_crt_bundle_attach,
};
esp_http_client_handle_t client = esp_http_client_init(&config);
if (!client) {
free(post_data);
return ESP_FAIL;
}
esp_http_client_set_header(client, "Content-Type", "application/json");
int post_len = strlen(post_data);
api_client_get_usage function · c · L234-L310 (77 LOC)components/api_client/api_client.c
esp_err_t api_client_get_usage(const char *access_token, const char *refresh_token,
api_usage_t *out)
{
memset(out, 0, sizeof(*out));
if (!refresh_token || strlen(refresh_token) == 0) {
snprintf(out->error, sizeof(out->error), "No token configured");
return ESP_FAIL;
}
char *response_buf = malloc(MAX_RESPONSE_SIZE);
if (!response_buf) {
snprintf(out->error, sizeof(out->error), "Out of memory");
return ESP_FAIL;
}
/* If no access token, refresh first */
const char *token = access_token;
char new_token[256] = {0};
if (!token || strlen(token) == 0) {
ESP_LOGI(TAG, "No access token — refreshing");
if (refresh_access_token(refresh_token, new_token, sizeof(new_token)) == ESP_OK) {
token = new_token;
} else {
snprintf(out->error, sizeof(out->error), "Token refresh failed");
free(response_buf);
return ESP_FAIL;
chsc6x_init function · c · L16-L50 (35 LOC)components/chsc6x/chsc6x.c
esp_err_t chsc6x_init(const chsc6x_config_t *config, chsc6x_handle_t *handle)
{
struct chsc6x_dev_t *dev = calloc(1, sizeof(struct chsc6x_dev_t));
if (!dev) return ESP_ERR_NO_MEM;
dev->int_gpio_num = config->int_gpio_num;
/* INT pin as input with pull-up (active LOW when touched) */
if (dev->int_gpio_num >= 0) {
gpio_config_t int_cfg = {
.pin_bit_mask = 1ULL << dev->int_gpio_num,
.mode = GPIO_MODE_INPUT,
.pull_up_en = GPIO_PULLUP_ENABLE,
};
gpio_config(&int_cfg);
}
/* Add I2C device */
i2c_device_config_t dev_cfg = {
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
.device_address = CHSC6X_ADDR,
.scl_speed_hz = 400000,
};
esp_err_t ret = i2c_master_bus_add_device(config->i2c_bus, &dev_cfg, &dev->i2c_dev);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "failed to add I2C device: %s", esp_err_to_name(ret));
free(dev);
return ret;
}
ESP_LOGI(TAG, "chsc6x_read function · c · L51-L76 (26 LOC)components/chsc6x/chsc6x.c
esp_err_t chsc6x_read(chsc6x_handle_t handle, chsc6x_touch_data_t *data)
{
memset(data, 0, sizeof(*data));
/* Check INT pin — LOW means touch is active */
if (handle->int_gpio_num >= 0 && gpio_get_level(handle->int_gpio_num) != 0) {
return ESP_OK; /* No touch */
}
/* Read 5 bytes from the controller */
uint8_t buf[CHSC6X_READ_LEN] = {0};
esp_err_t ret = i2c_master_receive(handle->i2c_dev, buf, CHSC6X_READ_LEN, 50);
if (ret != ESP_OK) {
return ret;
}
/* buf[0] == 0x01 means valid touch */
if (buf[0] == 0x01) {
data->touched = true;
data->x = 239 - buf[2];
data->y = buf[4];
}
return ESP_OK;
}Repobility (the analyzer behind this table) · https://repobility.com
chsc6x_del function · c · L77-L86 (10 LOC)components/chsc6x/chsc6x.c
esp_err_t chsc6x_del(chsc6x_handle_t handle)
{
if (handle) {
i2c_master_bus_rm_device(handle->i2c_dev);
if (handle->int_gpio_num >= 0) gpio_reset_pin(handle->int_gpio_num);
free(handle);
}
return ESP_OK;
}display_text_draw_char function · c · L9-L52 (44 LOC)components/display_text/display_text.c
void display_text_draw_char(esp_lcd_panel_handle_t panel, int x, int y,
char c, uint16_t fg, uint16_t bg, int scale)
{
if (c < 0x20 || c > 0x7E) c = '?';
const uint8_t *glyph = font_5x7[c - 0x20];
int char_w = FONT_CHAR_WIDTH * scale;
int char_h = FONT_CHAR_HEIGHT * scale;
/* Clip: skip if entirely off-screen */
if (x + char_w <= 0 || x >= LCD_WIDTH || y + char_h <= 0 || y >= LCD_WIDTH)
return;
uint16_t fg_s = swap16(fg);
uint16_t bg_s = swap16(bg);
/* Render one row of scaled pixels at a time via DMA buffer */
uint16_t *buf = heap_caps_malloc(char_w * sizeof(uint16_t), MALLOC_CAP_DMA);
if (!buf) return;
for (int row = 0; row < FONT_CHAR_HEIGHT; row++) {
/* Build one row of the character */
for (int col = 0; col < FONT_CHAR_WIDTH; col++) {
uint16_t pixel = (glyph[col] & (1 << row)) ? fg_s : bg_s;
for (int sx = 0; sx < scale; sx++) {
buf[col *display_text_draw_string function · c · L53-L61 (9 LOC)components/display_text/display_text.c
void display_text_draw_string(esp_lcd_panel_handle_t panel, int x, int y,
const char *str, uint16_t fg, uint16_t bg, int scale)
{
int step = (FONT_CHAR_WIDTH + FONT_CHAR_SPACING) * scale;
for (int i = 0; str[i] != '\0'; i++) {
display_text_draw_char(panel, x + i * step, y, str[i], fg, bg, scale);
}
}display_text_draw_string_centered function · c · L62-L71 (10 LOC)components/display_text/display_text.c
void display_text_draw_string_centered(esp_lcd_panel_handle_t panel, int y,
const char *str, uint16_t fg, uint16_t bg, int scale)
{
int len = strlen(str);
int step = (FONT_CHAR_WIDTH + FONT_CHAR_SPACING) * scale;
int total_w = len * step - FONT_CHAR_SPACING * scale;
int x = (LCD_WIDTH - total_w) / 2;
display_text_draw_string(panel, x, y, str, fg, bg, scale);
}parse_dns_request function · c · L100-L184 (85 LOC)components/dns_server/dns_server.c
static int parse_dns_request(char *req, size_t req_len, char *dns_reply, size_t dns_reply_max_len, dns_server_handle_t h)
{
if (req_len > dns_reply_max_len) {
return -1;
}
// Prepare the reply
memset(dns_reply, 0, dns_reply_max_len);
memcpy(dns_reply, req, req_len);
// Endianess of NW packet different from chip
dns_header_t *header = (dns_header_t *)dns_reply;
ESP_LOGD(TAG, "DNS query with header id: 0x%X, flags: 0x%X, qd_count: %d",
ntohs(header->id), ntohs(header->flags), ntohs(header->qd_count));
// Not a standard query
if ((header->flags & OPCODE_MASK) != 0) {
return 0;
}
// Set question response flag
header->flags |= QR_FLAG;
uint16_t qd_count = ntohs(header->qd_count);
header->an_count = htons(qd_count);
int reply_len = qd_count * sizeof(dns_answer_t) + req_len;
if (reply_len > dns_reply_max_len) {
return -1;
}
// Pointer to current answer and question
char dns_server_task function · c · L190-L268 (79 LOC)components/dns_server/dns_server.c
void dns_server_task(void *pvParameters)
{
char rx_buffer[128];
char addr_str[128];
int addr_family;
int ip_protocol;
dns_server_handle_t handle = pvParameters;
while (handle->started) {
struct sockaddr_in dest_addr;
dest_addr.sin_addr.s_addr = htonl(INADDR_ANY);
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(DNS_PORT);
addr_family = AF_INET;
ip_protocol = IPPROTO_IP;
inet_ntoa_r(dest_addr.sin_addr, addr_str, sizeof(addr_str) - 1);
int sock = socket(addr_family, SOCK_DGRAM, ip_protocol);
if (sock < 0) {
ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
break;
}
ESP_LOGI(TAG, "Socket created");
int err = bind(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
if (err < 0) {
ESP_LOGE(TAG, "Socket unable to bind: errno %d", errno);
}
ESP_LOGI(TAG, "Socket bound, port %d", DNS_PORT)start_dns_server function · c · L269-L281 (13 LOC)components/dns_server/dns_server.c
dns_server_handle_t start_dns_server(dns_server_config_t *config)
{
dns_server_handle_t handle = calloc(1, sizeof(struct dns_server_handle) + config->num_of_entries * sizeof(dns_entry_pair_t));
ESP_RETURN_ON_FALSE(handle, NULL, TAG, "Failed to allocate dns server handle");
handle->started = true;
handle->num_of_entries = config->num_of_entries;
memcpy(handle->entry, config->item, config->num_of_entries * sizeof(dns_entry_pair_t));
xTaskCreate(dns_server_task, "dns_server", 4096, handle, 5, &handle->task);
return handle;
}stop_dns_server function · c · L282-L290 (9 LOC)components/dns_server/dns_server.c
void stop_dns_server(dns_server_handle_t handle)
{
if (handle) {
handle->started = false;
vTaskDelete(handle->task);
free(handle);
}
}Open data scored by Repobility · https://repobility.com
esp_lcd_new_panel_gc9a01 function · c · L33-L77 (45 LOC)components/gc9a01/gc9a01.c
esp_err_t esp_lcd_new_panel_gc9a01(const esp_lcd_panel_io_handle_t io,
const esp_lcd_panel_dev_config_t *panel_dev_config,
esp_lcd_panel_handle_t *ret_panel)
{
ESP_RETURN_ON_FALSE(io && panel_dev_config && ret_panel, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
gc9a01_panel_t *gc9a01 = calloc(1, sizeof(gc9a01_panel_t));
ESP_RETURN_ON_FALSE(gc9a01, ESP_ERR_NO_MEM, TAG, "no mem for gc9a01 panel");
gc9a01->io = io;
gc9a01->reset_gpio_num = panel_dev_config->reset_gpio_num;
switch (panel_dev_config->bits_per_pixel) {
case 16:
gc9a01->colmod = 0x55;
break;
case 18:
gc9a01->colmod = 0x66;
break;
default:
ESP_LOGE(TAG, "unsupported pixel width");
free(gc9a01);
return ESP_ERR_NOT_SUPPORTED;
}
gc9a01->madctl = 0;
if (panel_dev_config->rgb_ele_order == LCD_RGB_ELEMENT_ORDER_BGR) {
gc9a01->madctl |= (1 << 3); /panel_gc9a01_del function · c · L78-L87 (10 LOC)components/gc9a01/gc9a01.c
static esp_err_t panel_gc9a01_del(esp_lcd_panel_t *panel)
{
gc9a01_panel_t *gc9a01 = __containerof(panel, gc9a01_panel_t, base);
if (gc9a01->reset_gpio_num >= 0) {
gpio_reset_pin(gc9a01->reset_gpio_num);
}
free(gc9a01);
return ESP_OK;
}panel_gc9a01_reset function · c · L88-L106 (19 LOC)components/gc9a01/gc9a01.c
static esp_err_t panel_gc9a01_reset(esp_lcd_panel_t *panel)
{
gc9a01_panel_t *gc9a01 = __containerof(panel, gc9a01_panel_t, base);
if (gc9a01->reset_gpio_num >= 0) {
gpio_set_direction(gc9a01->reset_gpio_num, GPIO_MODE_OUTPUT);
gpio_set_level(gc9a01->reset_gpio_num, !gc9a01->reset_level);
vTaskDelay(pdMS_TO_TICKS(10));
gpio_set_level(gc9a01->reset_gpio_num, gc9a01->reset_level);
vTaskDelay(pdMS_TO_TICKS(10));
gpio_set_level(gc9a01->reset_gpio_num, !gc9a01->reset_level);
vTaskDelay(pdMS_TO_TICKS(120));
} else {
/* Software reset */
esp_lcd_panel_io_tx_param(gc9a01->io, 0x01, NULL, 0); /* SWRESET */
vTaskDelay(pdMS_TO_TICKS(120));
}
return ESP_OK;
}panel_gc9a01_init function · c · L107-L184 (78 LOC)components/gc9a01/gc9a01.c
static esp_err_t panel_gc9a01_init(esp_lcd_panel_t *panel)
{
gc9a01_panel_t *gc9a01 = __containerof(panel, gc9a01_panel_t, base);
esp_lcd_panel_io_handle_t io = gc9a01->io;
/* GC9A01 initialization sequence */
/* Enable inter-register access */
esp_lcd_panel_io_tx_param(io, 0xEF, NULL, 0);
esp_lcd_panel_io_tx_param(io, 0xEB, (uint8_t[]){0x14}, 1);
esp_lcd_panel_io_tx_param(io, 0xFE, NULL, 0);
esp_lcd_panel_io_tx_param(io, 0xEF, NULL, 0);
esp_lcd_panel_io_tx_param(io, 0xEB, (uint8_t[]){0x14}, 1);
esp_lcd_panel_io_tx_param(io, 0x84, (uint8_t[]){0x40}, 1);
esp_lcd_panel_io_tx_param(io, 0x85, (uint8_t[]){0xFF}, 1);
esp_lcd_panel_io_tx_param(io, 0x86, (uint8_t[]){0xFF}, 1);
esp_lcd_panel_io_tx_param(io, 0x87, (uint8_t[]){0xFF}, 1);
esp_lcd_panel_io_tx_param(io, 0x88, (uint8_t[]){0x0A}, 1);
esp_lcd_panel_io_tx_param(io, 0x89, (uint8_t[]){0x21}, 1);
esp_lcd_panel_io_tx_param(io, 0x8A, (uint8_t[]){0x00}, 1);
esp_lcd_panel_iopanel_gc9a01_draw_bitmap function · c · L185-L212 (28 LOC)components/gc9a01/gc9a01.c
static esp_err_t panel_gc9a01_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int y_start, int x_end, int y_end, const void *color_data)
{
gc9a01_panel_t *gc9a01 = __containerof(panel, gc9a01_panel_t, base);
esp_lcd_panel_io_handle_t io = gc9a01->io;
x_start += gc9a01->x_gap;
x_end += gc9a01->x_gap;
y_start += gc9a01->y_gap;
y_end += gc9a01->y_gap;
/* Column address set */
esp_lcd_panel_io_tx_param(io, 0x2A, (uint8_t[]){
(x_start >> 8) & 0xFF, x_start & 0xFF,
((x_end - 1) >> 8) & 0xFF, (x_end - 1) & 0xFF,
}, 4);
/* Row address set */
esp_lcd_panel_io_tx_param(io, 0x2B, (uint8_t[]){
(y_start >> 8) & 0xFF, y_start & 0xFF,
((y_end - 1) >> 8) & 0xFF, (y_end - 1) & 0xFF,
}, 4);
/* Memory write */
size_t len = (x_end - x_start) * (y_end - y_start) * 2; /* 16-bit color */
esp_lcd_panel_io_tx_color(io, 0x2C, color_data, len);
return ESP_OK;
}esp_lcd_panel_io_tx_param function · c · L197-L200 (4 LOC)components/gc9a01/gc9a01.c
esp_lcd_panel_io_tx_param(io, 0x2A, (uint8_t[]){
(x_start >> 8) & 0xFF, x_start & 0xFF,
((x_end - 1) >> 8) & 0xFF, (x_end - 1) & 0xFF,
}, 4);esp_lcd_panel_io_tx_param function · c · L203-L206 (4 LOC)components/gc9a01/gc9a01.c
esp_lcd_panel_io_tx_param(io, 0x2B, (uint8_t[]){
(y_start >> 8) & 0xFF, y_start & 0xFF,
((y_end - 1) >> 8) & 0xFF, (y_end - 1) & 0xFF,
}, 4);panel_gc9a01_invert_color function · c · L213-L220 (8 LOC)components/gc9a01/gc9a01.c
static esp_err_t panel_gc9a01_invert_color(esp_lcd_panel_t *panel, bool invert)
{
gc9a01_panel_t *gc9a01 = __containerof(panel, gc9a01_panel_t, base);
uint8_t cmd = invert ? 0x21 : 0x20;
esp_lcd_panel_io_tx_param(gc9a01->io, cmd, NULL, 0);
return ESP_OK;
}Source: Repobility analyzer · https://repobility.com
panel_gc9a01_mirror function · c · L221-L230 (10 LOC)components/gc9a01/gc9a01.c
static esp_err_t panel_gc9a01_mirror(esp_lcd_panel_t *panel, bool mirror_x, bool mirror_y)
{
gc9a01_panel_t *gc9a01 = __containerof(panel, gc9a01_panel_t, base);
gc9a01->madctl &= ~(0x40 | 0x80);
if (mirror_x) gc9a01->madctl |= 0x40;
if (mirror_y) gc9a01->madctl |= 0x80;
esp_lcd_panel_io_tx_param(gc9a01->io, 0x36, (uint8_t[]){gc9a01->madctl}, 1);
return ESP_OK;
}panel_gc9a01_swap_xy function · c · L231-L239 (9 LOC)components/gc9a01/gc9a01.c
static esp_err_t panel_gc9a01_swap_xy(esp_lcd_panel_t *panel, bool swap)
{
gc9a01_panel_t *gc9a01 = __containerof(panel, gc9a01_panel_t, base);
gc9a01->madctl &= ~0x20;
if (swap) gc9a01->madctl |= 0x20;
esp_lcd_panel_io_tx_param(gc9a01->io, 0x36, (uint8_t[]){gc9a01->madctl}, 1);
return ESP_OK;
}panel_gc9a01_set_gap function · c · L240-L247 (8 LOC)components/gc9a01/gc9a01.c
static esp_err_t panel_gc9a01_set_gap(esp_lcd_panel_t *panel, int x_gap, int y_gap)
{
gc9a01_panel_t *gc9a01 = __containerof(panel, gc9a01_panel_t, base);
gc9a01->x_gap = x_gap;
gc9a01->y_gap = y_gap;
return ESP_OK;
}panel_gc9a01_disp_on_off function · c · L248-L255 (8 LOC)components/gc9a01/gc9a01.c
static esp_err_t panel_gc9a01_disp_on_off(esp_lcd_panel_t *panel, bool on)
{
gc9a01_panel_t *gc9a01 = __containerof(panel, gc9a01_panel_t, base);
uint8_t cmd = on ? 0x29 : 0x28;
esp_lcd_panel_io_tx_param(gc9a01->io, cmd, NULL, 0);
return ESP_OK;
}spx function · c · L22-L28 (7 LOC)components/polar_graph/polar_graph.c
static inline void spx(uint16_t *strip, int sy, int sh, int x, int y, uint16_t c)
{
int ly = y - sy;
if ((unsigned)x < W && (unsigned)ly < (unsigned)sh)
strip[ly * W + x] = c;
}sline function · c · L29-L43 (15 LOC)components/polar_graph/polar_graph.c
static void sline(uint16_t *strip, int sy, int sh,
int x0, int y0, int x1, int y1, uint16_t c)
{
int dx = abs(x1 - x0), step_x = x0 < x1 ? 1 : -1;
int dy = -abs(y1 - y0), step_y = y0 < y1 ? 1 : -1;
int err = dx + dy;
for (;;) {
spx(strip, sy, sh, x0, y0, c);
if (x0 == x1 && y0 == y1) break;
int e2 = 2 * err;
if (e2 >= dy) { err += dy; x0 += step_x; }
if (e2 <= dx) { err += dx; y0 += step_y; }
}
}draw_circle function · c · L46-L58 (13 LOC)components/polar_graph/polar_graph.c
static void draw_circle(uint16_t *strip, int sy, int sh, int r, uint16_t c)
{
int x = r, y = 0, d = 1 - r;
while (x >= y) {
spx(strip, sy, sh, CX+x, CY+y, c); spx(strip, sy, sh, CX-x, CY+y, c);
spx(strip, sy, sh, CX+x, CY-y, c); spx(strip, sy, sh, CX-x, CY-y, c);
spx(strip, sy, sh, CX+y, CY+x, c); spx(strip, sy, sh, CX-y, CY+x, c);
spx(strip, sy, sh, CX+y, CY-x, c); spx(strip, sy, sh, CX-y, CY-x, c);
y++;
if (d <= 0) d += 2 * y + 1;
else { x--; d += 2 * (y - x) + 1; }
}
}polar_xy function · c · L59-L64 (6 LOC)components/polar_graph/polar_graph.c
static inline void polar_xy(float angle, float r, int *x, int *y)
{
*x = CX + (int)(r * sinf(angle));
*y = CY - (int)(r * cosf(angle));
}Same scanner, your repo: https://repobility.com — Repobility
burn_rate_at function · c · L67-L73 (7 LOC)components/polar_graph/polar_graph.c
static inline float burn_rate_at(time_t ts, time_t week_start, int psecs)
{
float frac = (float)(ts - week_start) / psecs;
if (frac < 0.0f) frac = 0.0f;
if (frac > 1.0f) frac = 1.0f;
return frac * 100.0f;
}polar_graph_draw function · c · L90-L247 (158 LOC)components/polar_graph/polar_graph.c
void polar_graph_draw(esp_lcd_panel_handle_t panel,
const usage_data_point_t *points, int num_points,
int period_secs, int num_rotations, int num_ticks,
time_t period_end, time_t now)
{
/* Pre-compute per-point: screen coords, week index, color.
* int16_t for coords (0–239 range) to halve memory vs int. */
if (num_rotations > MAX_ROTATIONS) num_rotations = MAX_ROTATIONS;
int16_t *scr_x = NULL, *scr_y = NULL;
uint8_t *pt_week = NULL;
uint16_t *pt_color = NULL;
if (num_points > 0) {
scr_x = malloc(num_points * sizeof(int16_t));
scr_y = malloc(num_points * sizeof(int16_t));
pt_week = malloc(num_points);
pt_color = malloc(num_points * sizeof(uint16_t));
if (!scr_x || !scr_y || !pt_week || !pt_color) {
free(scr_x); free(scr_y); free(pt_week); free(pt_color);
ESP_LOGE(TAG, "Failed to alloc point arrays");
return;
qrcodegen_encodeText function · c · L132-L166 (35 LOC)components/qr_display/qrcodegen.c
bool qrcodegen_encodeText(const char *text, uint8_t tempBuffer[], uint8_t qrcode[],
enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl) {
size_t textLen = strlen(text);
if (textLen == 0)
return qrcodegen_encodeSegmentsAdvanced(NULL, 0, ecl, minVersion, maxVersion, mask, boostEcl, tempBuffer, qrcode);
size_t bufLen = (size_t)qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion);
struct qrcodegen_Segment seg;
if (qrcodegen_isNumeric(text)) {
if (qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_NUMERIC, textLen) > bufLen)
goto fail;
seg = qrcodegen_makeNumeric(text, tempBuffer);
} else if (qrcodegen_isAlphanumeric(text)) {
if (qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_ALPHANUMERIC, textLen) > bufLen)
goto fail;
seg = qrcodegen_makeAlphanumeric(text, tempBuffer);
} else {
if (textLen > bufLen)
goto fail;
for (size_t i = 0; i < textLen; i++)
tempBuffer[i] = (uint8_t)text[i];
seg.mode = qrcodegen_Mode_BYTE;
segqrcodegen_encodeBinary function · c · L170-L183 (14 LOC)components/qr_display/qrcodegen.c
bool qrcodegen_encodeBinary(uint8_t dataAndTemp[], size_t dataLen, uint8_t qrcode[],
enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl) {
struct qrcodegen_Segment seg;
seg.mode = qrcodegen_Mode_BYTE;
seg.bitLength = calcSegmentBitLength(seg.mode, dataLen);
if (seg.bitLength == LENGTH_OVERFLOW) {
qrcode[0] = 0; // Set size to invalid value for safety
return false;
}
seg.numChars = (int)dataLen;
seg.data = dataAndTemp;
return qrcodegen_encodeSegmentsAdvanced(&seg, 1, ecl, minVersion, maxVersion, mask, boostEcl, dataAndTemp, qrcode);
}appendBitsToBuffer function · c · L188-L192 (5 LOC)components/qr_display/qrcodegen.c
testable void appendBitsToBuffer(unsigned int val, int numBits, uint8_t buffer[], int *bitLen) {
assert(0 <= numBits && numBits <= 16 && (unsigned long)val >> numBits == 0);
for (int i = numBits - 1; i >= 0; i--, (*bitLen)++)
buffer[*bitLen >> 3] |= ((val >> i) & 1) << (7 - (*bitLen & 7));
}qrcodegen_encodeSegments function · c · L199-L203 (5 LOC)components/qr_display/qrcodegen.c
bool qrcodegen_encodeSegments(const struct qrcodegen_Segment segs[], size_t len,
enum qrcodegen_Ecc ecl, uint8_t tempBuffer[], uint8_t qrcode[]) {
return qrcodegen_encodeSegmentsAdvanced(segs, len, ecl,
qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true, tempBuffer, qrcode);
}qrcodegen_encodeSegmentsAdvanced function · c · L207-L287 (81 LOC)components/qr_display/qrcodegen.c
bool qrcodegen_encodeSegmentsAdvanced(const struct qrcodegen_Segment segs[], size_t len, enum qrcodegen_Ecc ecl,
int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl, uint8_t tempBuffer[], uint8_t qrcode[]) {
assert(segs != NULL || len == 0);
assert(qrcodegen_VERSION_MIN <= minVersion && minVersion <= maxVersion && maxVersion <= qrcodegen_VERSION_MAX);
assert(0 <= (int)ecl && (int)ecl <= 3 && -1 <= (int)mask && (int)mask <= 7);
// Find the minimal version number to use
int version, dataUsedBits;
for (version = minVersion; ; version++) {
int dataCapacityBits = getNumDataCodewords(version, ecl) * 8; // Number of data bits available
dataUsedBits = getTotalBits(segs, len, version);
if (dataUsedBits != LENGTH_OVERFLOW && dataUsedBits <= dataCapacityBits)
break; // This version number is found to be suitable
if (version >= maxVersion) { // All versions in the range could not fit the given data
qrcode[0] = 0; // Set size to invalid value for safeaddEccAndInterleave function · c · L297-L325 (29 LOC)components/qr_display/qrcodegen.c
testable void addEccAndInterleave(uint8_t data[], int version, enum qrcodegen_Ecc ecl, uint8_t result[]) {
// Calculate parameter numbers
assert(0 <= (int)ecl && (int)ecl < 4 && qrcodegen_VERSION_MIN <= version && version <= qrcodegen_VERSION_MAX);
int numBlocks = NUM_ERROR_CORRECTION_BLOCKS[(int)ecl][version];
int blockEccLen = ECC_CODEWORDS_PER_BLOCK [(int)ecl][version];
int rawCodewords = getNumRawDataModules(version) / 8;
int dataLen = getNumDataCodewords(version, ecl);
int numShortBlocks = numBlocks - rawCodewords % numBlocks;
int shortBlockDataLen = rawCodewords / numBlocks - blockEccLen;
// Split data into blocks, calculate ECC, and interleave
// (not concatenate) the bytes into a single sequence
uint8_t rsdiv[qrcodegen_REED_SOLOMON_DEGREE_MAX];
reedSolomonComputeDivisor(blockEccLen, rsdiv);
const uint8_t *dat = data;
for (int i = 0; i < numBlocks; i++) {
int datLen = shortBlockDataLen + (i < numShortBlocks ? 0 : 1);
uint8_t *ecc = &data[dataLen]; // TemporRepobility (the analyzer behind this table) · https://repobility.com
getNumDataCodewords function · c · L330-L336 (7 LOC)components/qr_display/qrcodegen.c
testable int getNumDataCodewords(int version, enum qrcodegen_Ecc ecl) {
int v = version, e = (int)ecl;
assert(0 <= e && e < 4);
return getNumRawDataModules(v) / 8
- ECC_CODEWORDS_PER_BLOCK [e][v]
* NUM_ERROR_CORRECTION_BLOCKS[e][v];
}getNumRawDataModules function · c · L342-L353 (12 LOC)components/qr_display/qrcodegen.c
testable int getNumRawDataModules(int ver) {
assert(qrcodegen_VERSION_MIN <= ver && ver <= qrcodegen_VERSION_MAX);
int result = (16 * ver + 128) * ver + 64;
if (ver >= 2) {
int numAlign = ver / 7 + 2;
result -= (25 * numAlign - 10) * numAlign - 55;
if (ver >= 7)
result -= 36;
}
assert(208 <= result && result <= 29648);
return result;
}reedSolomonComputeDivisor function · c · L361-L381 (21 LOC)components/qr_display/qrcodegen.c
testable void reedSolomonComputeDivisor(int degree, uint8_t result[]) {
assert(1 <= degree && degree <= qrcodegen_REED_SOLOMON_DEGREE_MAX);
// Polynomial coefficients are stored from highest to lowest power, excluding the leading term which is always 1.
// For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as the uint8 array {255, 8, 93}.
memset(result, 0, (size_t)degree * sizeof(result[0]));
result[degree - 1] = 1; // Start off with the monomial x^0
// Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}),
// drop the highest monomial term which is always 1x^degree.
// Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D).
uint8_t root = 1;
for (int i = 0; i < degree; i++) {
// Multiply the current product by (x - r^i)
for (int j = 0; j < degree; j++) {
result[j] = reedSolomonMultiply(result[j], root);
if (j + 1 < degree)
result[j] ^= result[j + 1];
}
root = reedSolomonMultiply(root, 0reedSolomonComputeRemainder function · c · L387-L398 (12 LOC)components/qr_display/qrcodegen.c
testable void reedSolomonComputeRemainder(const uint8_t data[], int dataLen,
const uint8_t generator[], int degree, uint8_t result[]) {
assert(1 <= degree && degree <= qrcodegen_REED_SOLOMON_DEGREE_MAX);
memset(result, 0, (size_t)degree * sizeof(result[0]));
for (int i = 0; i < dataLen; i++) { // Polynomial division
uint8_t factor = data[i] ^ result[0];
memmove(&result[0], &result[1], (size_t)(degree - 1) * sizeof(result[0]));
result[degree - 1] = 0;
for (int j = 0; j < degree; j++)
result[j] ^= reedSolomonMultiply(generator[j], factor);
}
}reedSolomonMultiply function · c · L405-L413 (9 LOC)components/qr_display/qrcodegen.c
testable uint8_t reedSolomonMultiply(uint8_t x, uint8_t y) {
// Russian peasant multiplication
uint8_t z = 0;
for (int i = 7; i >= 0; i--) {
z = (uint8_t)((z << 1) ^ ((z >> 7) * 0x11D));
z ^= ((y >> i) & 1) * x;
}
return z;
}initializeFunctionModules function · c · L421-L452 (32 LOC)components/qr_display/qrcodegen.c
testable void initializeFunctionModules(int version, uint8_t qrcode[]) {
// Initialize QR Code
int qrsize = version * 4 + 17;
memset(qrcode, 0, (size_t)((qrsize * qrsize + 7) / 8 + 1) * sizeof(qrcode[0]));
qrcode[0] = (uint8_t)qrsize;
// Fill horizontal and vertical timing patterns
fillRectangle(6, 0, 1, qrsize, qrcode);
fillRectangle(0, 6, qrsize, 1, qrcode);
// Fill 3 finder patterns (all corners except bottom right) and format bits
fillRectangle(0, 0, 9, 9, qrcode);
fillRectangle(qrsize - 8, 0, 8, 9, qrcode);
fillRectangle(0, qrsize - 8, 9, 8, qrcode);
// Fill numerous alignment patterns
uint8_t alignPatPos[7];
int numAlign = getAlignmentPatternPositions(version, alignPatPos);
for (int i = 0; i < numAlign; i++) {
for (int j = 0; j < numAlign; j++) {
// Don't draw on the three finder corners
if (!((i == 0 && j == 0) || (i == 0 && j == numAlign - 1) || (i == numAlign - 1 && j == 0)))
fillRectangle(alignPatPos[i] - 2, alignPatPos[j] - 2, 5, 5, qrcode);
drawLightFunctionModules function · c · L458-L513 (56 LOC)components/qr_display/qrcodegen.c
static void drawLightFunctionModules(uint8_t qrcode[], int version) {
// Draw horizontal and vertical timing patterns
int qrsize = qrcodegen_getSize(qrcode);
for (int i = 7; i < qrsize - 7; i += 2) {
setModuleBounded(qrcode, 6, i, false);
setModuleBounded(qrcode, i, 6, false);
}
// Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules)
for (int dy = -4; dy <= 4; dy++) {
for (int dx = -4; dx <= 4; dx++) {
int dist = abs(dx);
if (abs(dy) > dist)
dist = abs(dy);
if (dist == 2 || dist == 4) {
setModuleUnbounded(qrcode, 3 + dx, 3 + dy, false);
setModuleUnbounded(qrcode, qrsize - 4 + dx, 3 + dy, false);
setModuleUnbounded(qrcode, 3 + dx, qrsize - 4 + dy, false);
}
}
}
// Draw numerous alignment patterns
uint8_t alignPatPos[7];
int numAlign = getAlignmentPatternPositions(version, alignPatPos);
for (int i = 0; i < numAlign; i++) {
for (int j = 0; j < numAlign; j++) {
if ((i == 0 && j == 0) || (i == 0 && jdrawFormatBits function · c · L519-L546 (28 LOC)components/qr_display/qrcodegen.c
static void drawFormatBits(enum qrcodegen_Ecc ecl, enum qrcodegen_Mask mask, uint8_t qrcode[]) {
// Calculate error correction code and pack bits
assert(0 <= (int)mask && (int)mask <= 7);
static const int table[] = {1, 0, 3, 2};
int data = table[(int)ecl] << 3 | (int)mask; // errCorrLvl is uint2, mask is uint3
int rem = data;
for (int i = 0; i < 10; i++)
rem = (rem << 1) ^ ((rem >> 9) * 0x537);
int bits = (data << 10 | rem) ^ 0x5412; // uint15
assert(bits >> 15 == 0);
// Draw first copy
for (int i = 0; i <= 5; i++)
setModuleBounded(qrcode, 8, i, getBit(bits, i));
setModuleBounded(qrcode, 8, 7, getBit(bits, 6));
setModuleBounded(qrcode, 8, 8, getBit(bits, 7));
setModuleBounded(qrcode, 7, 8, getBit(bits, 8));
for (int i = 9; i < 15; i++)
setModuleBounded(qrcode, 14 - i, 8, getBit(bits, i));
// Draw second copy
int qrsize = qrcodegen_getSize(qrcode);
for (int i = 0; i < 8; i++)
setModuleBounded(qrcode, qrsize - 1 - i, 8, getBit(bits, i));
for (int i = 8; i Open data scored by Repobility · https://repobility.com
getAlignmentPatternPositions function · c · L553-L562 (10 LOC)components/qr_display/qrcodegen.c
testable int getAlignmentPatternPositions(int version, uint8_t result[7]) {
if (version == 1)
return 0;
int numAlign = version / 7 + 2;
int step = (version * 8 + numAlign * 3 + 5) / (numAlign * 4 - 4) * 2;
for (int i = numAlign - 1, pos = version * 4 + 10; i >= 1; i--, pos -= step)
result[i] = (uint8_t)pos;
result[0] = 6;
return numAlign;
}fillRectangle function · c · L566-L571 (6 LOC)components/qr_display/qrcodegen.c
static void fillRectangle(int left, int top, int width, int height, uint8_t qrcode[]) {
for (int dy = 0; dy < height; dy++) {
for (int dx = 0; dx < width; dx++)
setModuleBounded(qrcode, left + dx, top + dy, true);
}
}drawCodewords function · c · L579-L602 (24 LOC)components/qr_display/qrcodegen.c
static void drawCodewords(const uint8_t data[], int dataLen, uint8_t qrcode[]) {
int qrsize = qrcodegen_getSize(qrcode);
int i = 0; // Bit index into the data
// Do the funny zigzag scan
for (int right = qrsize - 1; right >= 1; right -= 2) { // Index of right column in each column pair
if (right == 6)
right = 5;
for (int vert = 0; vert < qrsize; vert++) { // Vertical counter
for (int j = 0; j < 2; j++) {
int x = right - j; // Actual x coordinate
bool upward = ((right + 1) & 2) == 0;
int y = upward ? qrsize - 1 - vert : vert; // Actual y coordinate
if (!getModuleBounded(qrcode, x, y) && i < dataLen * 8) {
bool dark = getBit(data[i >> 3], 7 - (i & 7));
setModuleBounded(qrcode, x, y, dark);
i++;
}
// If this QR Code has any remainder bits (0 to 7), they were assigned as
// 0/false/light by the constructor and are left unchanged by this method
}
}
}
assert(i == dataLen * 8);
}page 1 / 3next ›