int8_t set_handler(uint8_t *buf) { /* number of valid bytes in buf, -1 signifies error */ int8_t ret = 3; uint8_t idx; uint8_t tmp[SIZEOF_IR]; switch ((enum command) buf[2]) { case CMD_EMIT: delay_ms(130); irsnd_send_data((IRMP_DATA *) &buf[3], 1); break; case CMD_ALARM: memcpy(&AlarmValue, &buf[3], sizeof(AlarmValue)); break; case CMD_MACRO: idx = (MACRO_DEPTH + 1) * SIZEOF_IR/2 * buf[3] + SIZEOF_IR/2 * buf[4]; eeprom_store(idx, &buf[5]); /* validate stored value in eeprom */ eeprom_restore(tmp, idx); if (memcmp(&buf[5], tmp, sizeof(tmp))) ret = -1; break; case CMD_WAKE: idx = (MACRO_DEPTH + 1) * SIZEOF_IR/2 * MACRO_SLOTS + SIZEOF_IR/2 * buf[3]; eeprom_store(idx, &buf[4]); /* validate stored value in eeprom */ eeprom_restore(tmp, idx); if (memcmp(&buf[4], tmp, sizeof(tmp))) ret = -1; break; default: ret = -1; } return ret; }
int8_t get_handler(uint8_t *buf) { /* number of valid bytes in buf, -1 signifies error */ int8_t ret = 3; uint8_t idx; switch ((enum command) buf[2]) { case CMD_CAPS: /* in first query we give information about slots and depth */ if (!buf[3]) { buf[3] = MACRO_SLOTS; buf[4] = MACRO_DEPTH; buf[5] = WAKE_SLOTS; ret += 3; break; } /* in later queries we give information about supported protocols and firmware */ idx = BYTES_PER_QUERY * (buf[3] - 1); if (idx < sizeof(supported_protocols)) { strncpy((char *) &buf[3], &supported_protocols[idx], BYTES_PER_QUERY); /* actually this is not true for the last transmission, * but it doesn't matter since it's NULL terminated */ ret = HID_IN_BUFFER_SIZE-1; break; } if (idx >= sizeof(firmware) + (sizeof(supported_protocols) / BYTES_PER_QUERY + 1) * BYTES_PER_QUERY) return -1; strncpy((char *) &buf[3], &firmware[idx - (sizeof(supported_protocols) / BYTES_PER_QUERY + 1) * BYTES_PER_QUERY], BYTES_PER_QUERY); ret = HID_IN_BUFFER_SIZE-1; break; case CMD_ALARM: /* AlarmValue -> buf[3-6] */ memcpy(&buf[3], &AlarmValue, sizeof(AlarmValue)); ret += sizeof(AlarmValue); break; case CMD_MACRO: idx = (MACRO_DEPTH + 1) * SIZEOF_IR/2 * buf[3] + SIZEOF_IR/2 * buf[4]; eeprom_restore(&buf[3], idx); ret += SIZEOF_IR; break; case CMD_WAKE: idx = (MACRO_DEPTH + 1) * SIZEOF_IR/2 * MACRO_SLOTS + SIZEOF_IR/2 * buf[3]; eeprom_restore(&buf[3], idx); ret += SIZEOF_IR; break; default: ret = -1; } return ret; }
void sms77_init(void) { #ifdef SMS77_EEPROM_SUPPORT eeprom_restore(sms77_username, &sms77_user, SMS77_VALUESIZE); eeprom_restore(sms77_password, &sms77_pass, SMS77_VALUESIZE); eeprom_restore(sms77_receiver, &sms77_recv, SMS77_VALUESIZE); eeprom_restore(sms77_type, &sms77_type, SMS77_VALUESIZE); #else sprintf(sms77_user, "%s", CONF_SMS77_USER); sprintf(sms77_pass, "%s", CONF_SMS77_PASS); sprintf(sms77_recv, "%s", CONF_SMS77_TO); sprintf(sms77_type, "%s", CONF_SMS77_TYPE); #endif }
void stella_loadFromEEROM(void) { eeprom_restore(stella_channel_values, stella_fade, STELLA_CHANNELS); memcpy(stella_brightness, stella_fade, STELLA_CHANNELS); stella_sync = UPDATE_VALUES; }
void stella_loadFromEEROM() { eeprom_restore(stella_channel_values, stella_fade, 8); memcpy(stella_brightness, stella_fade, 8); stella_sync = UPDATE_VALUES; }
/* If enabled in menuconfig, this function is called during boot up of ethersex */ int16_t rainmaster_init(void) { RAINMASTERDEBUG ("init\n"); // Handler für Taster initialisieren und gemäß Menu zuweisen hook_buttons_input_register(default_button_handler); // LCD Menu initialisieren und Startbildschirm anzeigen init_menu(); // Sensoren initialisieren //init_sensors(); // Parameter aus dem EEPROM wiederherstellen eeprom_restore(rainmaster_params, &rainmaster_params_ram, sizeof(rainmaster_params_t)); // Init all standard pumping cycles //aqualoop_pumps_cycle_init(); // Init chemical cleaning cycle //aqualoop_cleaning_cycle_init(); // Init MONITOR networking //init_networking(); return ECMD_FINAL_OK; }
void network_config_load (void) { /* load settings from eeprom */ #ifdef EEPROM_SUPPORT eeprom_restore(mac, uip_ethaddr.addr, 6); #else memcpy_P(uip_ethaddr.addr, PSTR(CONF_ETHERRAPE_MAC), 6); #endif #if defined(BOOTP_SUPPORT) \ || (IPV6_SUPPORT && !defined(IPV6_STATIC_SUPPORT)) \ || DHCP_SUPPORT return; #else uip_ipaddr_t ip; (void) ip; /* Keep GCC quiet. */ /* Configure the IP address. */ #ifdef EEPROM_SUPPORT /* Please Note: ip and &ip are NOT the same (cpp hell) */ eeprom_restore_ip(ip, &ip); #else set_CONF_ETHERRAPE_IP(&ip); #endif uip_sethostaddr(&ip); /* Configure prefix length (IPv6). */ #ifdef IPV6_SUPPORT uip_setprefixlen(CONF_ENC_IP6_PREFIX_LEN); #endif #ifdef IPV4_SUPPORT /* Configure the netmask (IPv4). */ #ifdef EEPROM_SUPPORT /* Please Note: ip and &ip are NOT the same (cpp hell) */ eeprom_restore_ip(netmask, &ip); #else set_CONF_ETHERRAPE_IP4_NETMASK(&ip); #endif uip_setnetmask(&ip); #endif /* IPV4_SUPPORT */ /* Configure the default gateway */ #ifdef EEPROM_SUPPORT /* Please Note: ip and &ip are NOT the same (cpp hell) */ eeprom_restore_ip(gateway, &ip); #else set_CONF_ETHERRAPE_GATEWAY(&ip); #endif uip_setdraddr(&ip); #endif /* No autoconfiguration. */ }
/* is received ir-code in the last wakeup-slot? reboot µC if true */ void check_reboot(IRMP_DATA *ir) { uint8_t idx; uint8_t buf[SIZEOF_IR]; idx = (MACRO_DEPTH + 1) * SIZEOF_IR/2 * MACRO_SLOTS + SIZEOF_IR/2 * (WAKE_SLOTS - 1); if (!eeprom_restore(buf, idx)) { if (!memcmp(buf, ir, sizeof(buf))) reboot(); } }
void network_config_load (void) { /* load settings from eeprom */ #ifdef EEPROM_SUPPORT eeprom_restore (mac, uip_ethaddr.addr, 6); #else #if defined(BOOTLOADER_SUPPORT) && BOOTLOADER_START_ADDRESS > UINT16_MAX uint_farptr_t src = pgm_get_far_address (conf_mac); uint8_t *dst = uip_ethaddr.addr; for (uint8_t i = 6; i; i--) *dst++ = pgm_read_byte_far (src++); #else memcpy_P (uip_ethaddr.addr, conf_mac, 6); #endif #endif #if (defined(IPV4_SUPPORT) && !defined(BOOTP_SUPPORT) && !defined(DHCP_SUPPORT)) || defined(IPV6_STATIC_SUPPORT) uip_ipaddr_t ip; /* Configure the IP address. */ #ifdef EEPROM_SUPPORT /* Please Note: ip and &ip are NOT the same (cpp hell) */ eeprom_restore_ip (ip, &ip); #else set_CONF_ETHERRAPE_IP (&ip); #endif uip_sethostaddr (&ip); /* Configure prefix length (IPv6). */ #ifdef IPV6_SUPPORT uip_setprefixlen (CONF_ENC_IP6_PREFIX_LEN); #endif #ifdef IPV4_SUPPORT /* Configure the netmask (IPv4). */ #ifdef EEPROM_SUPPORT /* Please Note: ip and &ip are NOT the same (cpp hell) */ eeprom_restore_ip (netmask, &ip); #else set_CONF_ETHERRAPE_IP4_NETMASK (&ip); #endif uip_setnetmask (&ip); #endif /* IPV4_SUPPORT */ /* Configure the default gateway */ #ifdef EEPROM_SUPPORT /* Please Note: ip and &ip are NOT the same (cpp hell) */ eeprom_restore_ip (gateway, &ip); #else set_CONF_ETHERRAPE_GATEWAY (&ip); #endif uip_setdraddr (&ip); #endif /* No autoconfiguration. */ }
/* is received ir-code in one of the wakeup-slots? wakeup if true */ void check_wakeups(IRMP_DATA *ir) { uint8_t i, idx; uint8_t buf[SIZEOF_IR]; for (i=0; i < WAKE_SLOTS; i++) { idx = (MACRO_DEPTH + 1) * SIZEOF_IR/2 * MACRO_SLOTS + SIZEOF_IR/2 * i; eeprom_restore(buf, idx); if (!memcmp(buf, ir, sizeof(buf))) Wakeup(); } }
/* is received ir-code (trigger) in one of the macro-slots? transmit_macro if true */ void check_macros(IRMP_DATA *ir) { uint8_t i, idx; uint8_t buf[SIZEOF_IR]; for (i=0; i < MACRO_SLOTS; i++) { idx = (MACRO_DEPTH + 1) * SIZEOF_IR/2 * i; eeprom_restore(buf, idx); if (!memcmp(buf, ir, sizeof(buf))) transmit_macro(i); } }
/* is received ir-code in one of the upper wakeup-slots except last one? reset if true */ void check_resets(IRMP_DATA *ir) { uint8_t i, idx; uint8_t buf[SIZEOF_IR]; for (i=WAKE_SLOTS/2; i < WAKE_SLOTS - 1; i++) { idx = (MACRO_DEPTH + 1) * SIZEOF_IR/2 * MACRO_SLOTS + SIZEOF_IR/2 * i; if (!eeprom_restore(buf, idx)) { if (!memcmp(buf, ir, sizeof(buf))) Reset(); } } }
void store_wakeup(IRMP_DATA *ir) { uint8_t idx; uint8_t tmp[SIZEOF_IR]; uint8_t zeros[SIZEOF_IR] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; idx = (MACRO_DEPTH + 1) * SIZEOF_IR/2 * MACRO_SLOTS; eeprom_restore(tmp, idx); if (!memcmp(tmp, zeros, SIZEOF_IR)) { /* store received wakeup IRData in first wakeup slot */ eeprom_store(idx, (uint8_t *) ir); fast_toggle(); } }
void jabber_init(void) { JABDEBUG("initializing client\n"); uip_ipaddr_t ip; set_CONF_JABBER_IP(&ip); jabber_conn = uip_connect(&ip, HTONS(5222), jabber_main); if (!jabber_conn) { JABDEBUG("no uip_conn available.\n"); return; } #ifdef JABBER_EEPROM_SUPPORT eeprom_restore(jabber_username, &jabber_user, JABBER_VALUESIZE); eeprom_restore(jabber_password, &jabber_pass, JABBER_VALUESIZE); eeprom_restore(jabber_resource, &jabber_resrc, JABBER_VALUESIZE); eeprom_restore(jabber_hostname, &jabber_host, JABBER_VALUESIZE); #endif }
/* is received ir-code in one of the lower wakeup-slots? wakeup if true */ void check_wakeups(IRMP_DATA *ir) { if(host_running()) return; uint8_t i, idx; uint8_t buf[SIZEOF_IR]; for (i=0; i < WAKE_SLOTS/2; i++) { idx = (MACRO_DEPTH + 1) * SIZEOF_IR/2 * MACRO_SLOTS + SIZEOF_IR/2 * i; if (!eeprom_restore(buf, idx)) { if (!memcmp(buf, ir, sizeof(buf))) Wakeup(); } } }
void ntp_init() { #ifdef DNS_SUPPORT uip_ipaddr_t *ipaddr; if (!(ipaddr = resolv_lookup(NTP_SERVER))) resolv_query(NTP_SERVER, ntp_dns_query_cb); else ntp_conf(ipaddr); #else /* ! DNS_SUPPORT */ uip_ipaddr_t ip; // set_NTP_SERVER_IP(&ip); eeprom_restore(ntp_server, &ip, IPADDR_LEN); ntp_conf(&ip); #endif }
void transmit_macro(uint8_t macro) { uint8_t i, idx; uint8_t buf[SIZEOF_IR]; uint8_t zeros[SIZEOF_IR] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; //{0}; /* we start from 1, since we don't want to tx the trigger code of the macro*/ for (i=1; i < MACRO_DEPTH + 1; i++) { idx = (MACRO_DEPTH + 1) * SIZEOF_IR/2 * macro + SIZEOF_IR/2 * i; eeprom_restore(buf, idx); /* first encounter of zero in macro means end of macro */ if (!memcmp(buf, &zeros, sizeof(zeros))) break; /* Depending on the protocol we need a pause between the trigger and the transmission * and between two transmissions. The highest known pause is 130 ms for Denon. */ delay_ms(130); irsnd_send_data((IRMP_DATA *) buf, 1); } }
void transmit_macro(uint8_t macro) { uint8_t i, idx; uint8_t buf[SIZEOF_IR]; uint8_t zeros[SIZEOF_IR] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; /* we start from 1, since we don't want to tx the trigger code of the macro*/ for (i=1; i < MACRO_DEPTH + 1; i++) { idx = (MACRO_DEPTH + 1) * SIZEOF_IR/2 * macro + SIZEOF_IR/2 * i; eeprom_restore(buf, idx); /* first encounter of zero in macro means end of macro */ if (!memcmp(buf, &zeros, sizeof(zeros))) break; /* if macros are sent already, while the trigger IR data are still repeated, * the receiving device may crash * Depending on the protocol we need a pause between the trigger and the transmission * and between two transmissions. The highest known pause is 130 ms for Denon. */ yellow_short_on(); irsnd_send_data((IRMP_DATA *) buf, 1); } }
void httpd_handle_solometer (void) { static int8_t i = 0; static uint8_t cont_send = 0, parsing = 0; uint16_t mss,page_size; static uip_ipaddr_t hostaddr, dnsserver; //char *buf; static uint16_t ppos; uint16_t lpos,wslen; uint8_t p_par,pct,send_packet,buf[64]; uip_gethostaddr(&hostaddr); #ifdef DNS_SUPPORT eeprom_restore(dns_server, &dnsserver, IPADDR_LEN); #endif #define NUM_PAR 16 PARAM p[NUM_PAR] = { {PR_U8,"%u",(uint8_t *)&hostaddr}, {PR_U8,"%u",((uint8_t *)&hostaddr)+1}, {PR_U8,"%u",((uint8_t *)&hostaddr)+2}, {PR_U8,"%u",((uint8_t *)&hostaddr)+3}, {PR_U8,"%u",&WRID[0]}, {PR_STRING,"%s",post_cookie}, {PR_STRING,"%s",post_hostname}, {PR_U8,"%u",(uint8_t *)&post_hostip}, {PR_U8,"%u",((uint8_t *)&post_hostip)+1}, {PR_U8,"%u",((uint8_t *)&post_hostip)+2}, {PR_U8,"%u",((uint8_t *)&post_hostip)+3}, {PR_STRING,"%s",post_scriptname}, {PR_U8,"%u",(uint8_t *)&dnsserver}, {PR_U8,"%u",((uint8_t *)&dnsserver)+1}, {PR_U8,"%u",((uint8_t *)&dnsserver)+2}, {PR_U8,"%u",((uint8_t *)&dnsserver)+3} }; //debug_printf("Handle_solometer called.\n"); mss = uip_mss(); if(mss > 400) mss = 400; wslen = strlen_P(website); if (uip_newdata()) { /* We've received new data (maybe even the first time). We'll receive something like this: GET /solometer[?...] */ /* Make sure it's zero-terminated, so we can safely use strstr */ char *ptr = (char *)uip_appdata; ptr[uip_len] = 0; //debug_printf("Newdata: ---------\n%s\n-----------\n",ptr); if(strncasecmp_P (uip_appdata, PSTR ("GET /solometer"),14) == 0) { //debug_printf("This is the GET request header...\n"); ptr = strstr_P (uip_appdata, PSTR("?")) + 1; if(!ptr || *ptr == 0) { //debug_printf("This is a request only. Send page.\n"); i = 0; } else { //debug_printf("This is a set operation. Parsing...\n"); i = solometer_parse(ptr); } //debug_printf("Setze Parsing auf 1.\n"); parsing = 1; } if (parsing == 1) { // Do not start answering until all packets have arrived //debug_printf("Parsing = 1\n"); ptr = strstr_P (uip_appdata, PSTR("\r\n\r\n")); if (ptr) { //debug_printf("Setze Parsing auf 2.\n"); parsing = 2; } else { //debug_printf("Double NL not found. Waiting...\n"); return; } } if (parsing == 2) { //debug_printf("Parsing = 2. Sende Antwort.\n"); PASTE_RESET (); if(i || mss < 200) { PASTE_P (httpd_header_500_smt); cont_send = 0; } else { page_size = wslen); for(i=0;i<NUM_PAR;i++) if(p[i].typ == PR_STRING) page_size += sprintf(buf,p[i].s2,p[i].s3); else page_size += sprintf(buf,p[i].s2,*(uint8_t *)p[i].s3); PASTE_P (p1); sprintf(uip_appdata+uip_len,"%u\n",page_size); PASTE_P (p2); cont_send = 1; ppos = 0; } //debug_printf("%d: %s\n",cont_send,uip_appdata); PASTE_SEND (); parsing = 0; return; } }
int main(void) { uint8_t buf[HID_OUT_BUFFER_SIZE-1], RepeatCounter = 0; IRMP_DATA myIRData; int8_t ret; /* first wakeup slot empty? */ uint8_t learn_wakeup = eeprom_restore(buf, (MACRO_DEPTH + 1) * SIZEOF_IR/2 * MACRO_SLOTS); USB_HID_Init(); LED_Switch_init(); IRMP_Init(); irsnd_init(); FLASH_Unlock(); EE_Init(); Systick_Init(); while (1) { if (!AlarmValue) Wakeup(); wakeup_reset(); /* test if USB is connected to PC and command is received */ if (USB_HID_GetStatus() == USB_HID_CONNECTED && USB_HID_ReceiveData(buf) == RX_READY && buf[0] == STAT_CMD) { switch ((enum access) buf[1]) { case ACC_GET: ret = get_handler(buf); break; case ACC_SET: ret = set_handler(buf); break; case ACC_RESET: ret = reset_handler(buf); break; default: ret = -1; } if (ret == -1) { buf[0] = STAT_FAILURE; ret = 3; } else { buf[0] = STAT_SUCCESS; } /* send configuration data */ USB_HID_SendData(REPORT_ID_CONFIG, buf, ret); toggle_LED(); } /* poll IR-data */ if (irmp_get_data(&myIRData)) { if (learn_wakeup) { /* store received wakeup IRData in first wakeup slot */ eeprom_store((MACRO_DEPTH + 1) * SIZEOF_IR/2 * MACRO_SLOTS, (uint8_t *) &myIRData); learn_wakeup = 0; } if (!(myIRData.flags)) { RepeatCounter = 0; } else { RepeatCounter++; } if (RepeatCounter == 0 || RepeatCounter >= MIN_REPEATS) { toggle_LED(); /* if macros are sent already, while the trigger IR data are still repeated, * the receiving device may crash */ check_macros(&myIRData); check_wakeups(&myIRData); } /* send IR-data */ memcpy(buf, &myIRData, sizeof(myIRData)); USB_HID_SendData(REPORT_ID_IR, buf, sizeof(myIRData)); } } }
void stella_loadFromEEROMFading() { eeprom_restore(stella_channel_values, stella_fade, 8); }
static void httpd_handle_input (void) { char *ptr = (char *) uip_appdata; #ifdef HTTPD_AUTH_SUPPORT char *start_ptr; if (STATE->header_reparse) { printf("reparse next part of the header\n"); goto start_auth; } #endif /* HTTPD_AUTH_SUPPORT */ if (uip_len < 6) { printf ("httpd: received request to short (%d bytes).\n", uip_len); STATE->handler = httpd_handle_400; return; } if (strncasecmp_P (uip_appdata, PSTR ("GET /"), 5)) { printf ("httpd: received request is not GET.\n"); STATE->handler = httpd_handle_400; return; } char *filename = uip_appdata + 5; /* beyond slash */ ptr = strchr (filename, ' '); if (ptr == NULL) { printf ("httpd: space after filename not found.\n"); STATE->handler = httpd_handle_400; return; } *ptr = 0; /* Terminate filename. */ /* * Successfully parsed the GET request, * possibly check authentication. */ #ifdef HTTPD_AUTH_SUPPORT ptr ++; /* Increment pointer to the end of the GET */ start_auth: start_ptr = ptr; ptr = strstr_P(ptr, PSTR("Authorization: ")); if (ptr == NULL) { if (strstr_P(start_ptr, PSTR("\r\n\r\n"))) { printf ("Authorization-header not found.\n"); printf("%s\n", start_ptr); goto auth_failed; } else { ptr = start_ptr; /* Skip all Lines before the last one */ while (1) { ptr = strstr_P(start_ptr, PSTR("\r\n")); if (ptr) start_ptr = ptr + 2; else break; } if (!strncmp(start_ptr, PSTR("Authorization: "), strlen(start_ptr))) { printf("Authorization header is split over two packages, damn"); printf("%s\n", start_ptr); goto auth_failed; } else { STATE->header_reparse = 1; goto after_auth; } } } ptr += 15; /* Skip `Authorization: ' header. */ if (strncmp_P(ptr, PSTR("Basic "), 6)) { printf ("auth: method is not basic.\n"); goto auth_failed; } ptr += 6; /* Skip `Basic ' string. */ char *nl = strchr (ptr, '\n'); if (nl == NULL) { printf ("auth: newline not found.\n"); goto auth_failed; } *nl = 0; /* Zero-terminate BASE64-string. */ base64_str_decode (ptr); printf ("auth: decoded auth string: '%s'.\n", ptr); if (strncmp_P (ptr, PSTR(CONF_HTTPD_USERNAME ":"******":")) != 0) { printf ("auth: username mismatch!\n"); goto auth_failed; } char pwd[sizeof(((struct eeprom_config_t *) 0)->httpd_auth_password) + 1]; eeprom_restore(httpd_auth_password, pwd, sizeof(pwd)); if (strncmp(pwd, ptr + strlen(CONF_HTTPD_USERNAME ":"******"auth: wrong passphrase, %s != %s.\n", pwd, ptr + strlen(CONF_HTTPD_USERNAME ":"******"?")); if (strncmp_P (filename, PSTR(ECMD_INDEX "?"), offset) == 0) { httpd_handle_ecmd_setup (filename + offset); return; } #endif /* ECMD_PARSER_SUPPORT */ #ifdef VFS_SUPPORT /* Keep content-type identifing char. */ STATE->u.vfs.content_type = *filename; STATE->u.vfs.fd = vfs_open (filename); if (STATE->u.vfs.fd) { STATE->handler = httpd_handle_vfs; return; } /* Now try appending the index.html document name */ ptr = filename + strlen (filename); #ifdef HTTP_SD_DIR_SUPPORT uint8_t lastchar = ptr[-1]; #endif if (ptr[-1] != '/') *(ptr ++) = '/'; strcpy_P (ptr, PSTR (HTTPD_INDEX)); STATE->u.vfs.fd = vfs_open (filename); if (STATE->u.vfs.fd) { STATE->handler = httpd_handle_vfs; return; } if (ptr == filename) /* Make sure not to strip initial slash. */ ptr[0] = 0; else ptr[-1] = 0; /* Strip index filename again, including the last slash. */ #endif /* VFS_SUPPORT */ #ifdef HTTP_SD_DIR_SUPPORT if ((STATE->u.dir.handle = vfs_sd_chdir (filename - 1))) { strncpy (STATE->u.dir.dirname, filename - 1, SD_DIR_MAX_DIRNAME_LEN); STATE->u.dir.dirname[SD_DIR_MAX_DIRNAME_LEN - 1] = 0; if (lastchar != '/') { STATE->handler = httpd_handle_sd_dir_redirect; fat_close_dir (STATE->u.dir.handle); } else STATE->handler = httpd_handle_sd_dir; return; } #endif /* HTTP_SD_DIR_SUPPORT */ /* Fallback, send 404. */ STATE->handler = httpd_handle_404; }
void stella_loadFromEEROMFading(void) { eeprom_restore(stella_channel_values, stella_fade, STELLA_CHANNELS); }