int16_t parse_cmd_fs_list (char *cmd, char *output, uint16_t len) { char name[FS_FILENAME + 1]; if (cmd[0] != 0x05) { /* first function entry */ cmd[0] = 0x05; /* set magic byte ... */ cmd[1] = 0x00; return ECMD_AGAIN(snprintf_P(output, len, PSTR("name :inode :size\n" "----------------------"))); } else { if (fs_list (&fs, NULL, name, cmd[1] ++) != FS_OK) return ECMD_FINAL_OK; /* no repare, out. */ name[FS_FILENAME] = 0; fs_inode_t inode = fs_get_inode (&fs, name); fs_size_t size = fs_size (&fs, inode); return ECMD_AGAIN(snprintf_P(output, len, PSTR("%-6s:0x%04x:0x%04x"), name, inode, size)); } }
int16_t parse_cmd_free(char *cmd, char *output, uint16_t len) { /* trick: use bytes on cmd as "connection specific static variables" */ if (cmd[0] != ECMD_STATE_MAGIC) { /* indicator flag: real invocation: 0 */ cmd[0] = ECMD_STATE_MAGIC; /* continuing call: 23 */ cmd[1] = 0; /* counter for output lines */ } /* Docu March 2009: http://www.nongnu.org/avr-libc/user-manual/malloc.html * Stack size: RAMEND-SP * Heap size: __brkval-__heap_start * Space between stack and heap: SP-__brkval * Caution: __brkval is 0 when malloc was not called yet (use __heap_start instead) * * Size of network packet frames is stored in NET_MAX_FRAME_LENGTH */ size_t f = (size_t) (__brkval ? (size_t) __brkval : (size_t) & __heap_start); /* we want an output like this: * free: 16234/32768 * heap: 10234 * net: 500 */ switch (cmd[1]++) { case 0: return ECMD_AGAIN(snprintf_P(output, len, PSTR("free: %u/%u"), SP - f, RAM_SIZE)); #ifndef UIP_SUPPORT default: return ECMD_FINAL(snprintf_P(output, len, PSTR("heap: %u"), f - (size_t) & __heap_start)); #else case 1: return ECMD_AGAIN(snprintf_P(output, len, PSTR("heap: %u"), f - (size_t) & __heap_start)); default: return ECMD_FINAL(snprintf_P(output, len, PSTR("net: " xstr(NET_MAX_FRAME_LENGTH)))); #endif } }
void ecmd_lufa_periodic(void) { if (!must_parse) ecmd_lufa_rx(); if (must_parse && write_len == 0) { must_parse = 0; if (recv_len <= 1) { recv_len = 0; return; } write_len = ecmd_parse_command(recv_buffer, write_buffer, sizeof(write_buffer)); if (is_ECMD_AGAIN(write_len)) { /* convert ECMD_AGAIN back to ECMD_FINAL */ write_len = ECMD_AGAIN(write_len); must_parse = 1; } else if (is_ECMD_ERR(write_len)) return; else { recv_len = 0; } write_buffer[write_len++] = '\r'; write_buffer[write_len++] = '\n'; } if (write_len) ecmd_lufa_tx(); }
static void jabber_parse_ecmd(char *message) { int16_t remain = sizeof(STATE->outbuf) - 1; int16_t written = 0; while (remain > 0) { int16_t len = ecmd_parse_command(message, STATE->outbuf + written, remain); if (is_ECMD_AGAIN(len)) { len = ECMD_AGAIN(len); written += len; remain -= len; if (remain) { STATE->outbuf[written++] = '\n'; remain--; } continue; } else if (is_ECMD_ERR(len)) { strncpy_P(STATE->outbuf, PSTR("parse error"), sizeof(STATE->outbuf)); len = 11; } written = len; break; } STATE->outbuf[written] = 0; }
int16_t parse_cmd_dmx_get_universe(char *cmd, char *output, uint16_t len) { uint16_t ret=0, universe=0; uint8_t value=0; if (cmd[0]!=0) ret = sscanf_P(cmd, PSTR("%u"), &universe); if(ret == 1 && universe < DMX_STORAGE_UNIVERSES) { ret=0; static uint16_t chan = 0; value=get_dmx_channel(universe,chan); output[ret+2] = value%10 +48; value /= 10; output[ret+1] = value%10 +48; value /= 10; output[ret+0] = value%10 +48; ret+=3; if(chan < DMX_STORAGE_CHANNELS-1) { chan++; return ECMD_AGAIN(ret); } else { chan=0; return ECMD_FINAL(ret); } } else return ECMD_ERR_PARSE_ERROR; }
int16_t parse_cmd_i2c_24CXX_dir(char *cmd, char *output, uint16_t len) { unsigned char buf[SFS_PAGE_SIZE]; vfs_eeprom_inode_t inode; if (cmd[0] != ECMD_STATE_MAGIC) { cmd[0] = ECMD_STATE_MAGIC; if (!i2c_24CXX_read_block(0, buf, sizeof(struct vfs_eeprom_page_superblock))) goto read_error; inode = ((struct vfs_eeprom_page_superblock *) buf)->next_file; if (!inode) return ECMD_FINAL_OK; } else { inode = *((vfs_eeprom_inode_t *) & cmd[1]); } struct vfs_eeprom_page_file *file = (struct vfs_eeprom_page_file *) buf; if (!i2c_24CXX_read_block(inode * SFS_PAGE_SIZE, buf, SFS_PAGE_SIZE) || file->magic != SFS_MAGIC_FILE) { read_error: return ECMD_FINAL(snprintf_P(output, len, PSTR("read error"))); } int16_t l = snprintf_P(output, len, PSTR("%s"), file->filename); *((vfs_eeprom_inode_t *) & cmd[1]) = file->next_file; return (file->next_file == 0 ? ECMD_FINAL(l) : ECMD_AGAIN(l)); }
int16_t parse_cmd_msr1_get(char *cmd, char *output, uint16_t len) { uint8_t i; MSR1_DEBUG("called msr1 get ecmd"); while(*cmd == ' ') cmd ++; if (*cmd == 0 || *cmd == '0') { for (i = 0; i < 21; i++) { output = output + sprintf(output, "%02x", e8_data.data[i]); } return ECMD_FINAL(21 * 2); } else if (*cmd == '1') { /* trick: use bytes on cmd as "connection specific static variables" */ if (cmd[1] != 23) { /* indicator flag: real invocation: 0 */ cmd[1] = 23; /* continuing call: 23 */ cmd[2] = 0; /* counter for data blocks */ } for (i = 0; i < 20; i++) { sprintf(output, "%02x", c0_data.data[cmd[2] * 20 + i]); output += 2; } cmd[2] ++; if (cmd[2] == 4) { return ECMD_FINAL(15 * 2); } else return ECMD_AGAIN(20 * 2 + 1); } return ECMD_ERR_PARSE_ERROR; }
int16_t parse_cmd_alias_list(char *cmd, char *output, uint16_t len) { if (cmd[0] != 0x05) { cmd[0] = 0x05; //magic byte cmd[1] = 0x00; return ECMD_AGAIN(snprintf_P(output, len, PSTR("aliases:"))); } else { char aliasname[20]; char aliascmd[50]; int i = cmd[1]++; if (aliascmd_list(i, aliasname, aliascmd) == 0) return ECMD_FINAL_OK; return ECMD_AGAIN(snprintf_P(output, len, PSTR("%s -> %s"), aliasname, aliascmd)); } }
int16_t parse_cmd_mcuf_modul_list(char *cmd, char *output, uint16_t len) { char title[15]; if (cmd[0] != ECMD_STATE_MAGIC) { cmd[0] = ECMD_STATE_MAGIC; //magic byte cmd[1] = 0x00; return ECMD_AGAIN(snprintf_P(output, len, PSTR("available modules:\n"))); } else { int i = cmd[1]++; if (mcuf_list_modul(title, i) == 0){ return ECMD_FINAL_OK; } return ECMD_AGAIN(snprintf_P(output, len, PSTR("%i. %s"), i, title)); } }
int16_t parse_cmd_dmx_get_universe(char *cmd, char *output, uint16_t len) { uint16_t ret = 0; uint8_t value = 0, universe = 0; /* trick: use bytes on cmd as "connection specific static variables" */ if (cmd[0] != ECMD_STATE_MAGIC) /* indicator flag: real invocation: 0 */ { /* read universe */ ret = sscanf_P(cmd, PSTR("%hhu"), &universe); if (ret != 1 || universe >= DMX_STORAGE_UNIVERSES) return ECMD_ERR_PARSE_ERROR; cmd[0] = ECMD_STATE_MAGIC; /* continuing call: 23 */ cmd[1] = universe; /* universe */ cmd[2] = 0; /* reserved for chan */ cmd[3] = 0; /* reserved for chan */ } /* retrieve universe from *cmd */ universe = cmd[1]; /* retrieve chan from *cmd. chan is 16 bit. cmd[1] in 16 bit is cmd[2] and cmd[3] in 8-bit */ uint16_t chan = *((uint16_t *) (cmd) + 1); /* request value from dmx-storage */ value = get_dmx_channel(universe, chan); /* write the value to *output with leading 0 so that the output will be like this: 255 044 003 000 */ /* ones */ output[2] = value % 10 + 48; value /= 10; /* tens */ output[1] = value % 10 + 48; value /= 10; /* hundreds */ output[0] = value % 10 + 48; /* Newline to be better parseable with http */ output[3] = '\n' ; /* terminate string */ output[4] = '\0'; ret = 5; if (chan < DMX_STORAGE_CHANNELS - 1) { chan++; *((uint16_t *) (cmd) + 1) = chan; return ECMD_AGAIN(ret); } else return ECMD_FINAL(ret); }
int16_t parse_cmd_ntp_status(char *cmd, char *output, uint16_t len) { /* trick: use bytes on cmd as "connection specific static variables" */ if (cmd[0] != ECMD_STATE_MAGIC) { /* indicator flag: real invocation: 0 */ cmd[0] = ECMD_STATE_MAGIC; /* continuing call: 23 */ cmd[1] = 0; /* counter for output lines */ } else { cmd[1]++; /* iterate to next output line */ } enum { CNT_UPDATE = 0, CNT_DELTA, CNT_OCR1A, CNT_DCFNTP, CNT_RESYN, CNT_LAST = CNT_RESYN }; switch (cmd[1]) { case CNT_UPDATE: return ECMD_AGAIN(snprintf_P(output, len, PSTR("Update: %lu"), clock_last_sync())); case CNT_DELTA: return ECMD_AGAIN(snprintf_P(output, len, PSTR("Delta: %+d"), clock_last_delta())); case CNT_OCR1A: return ECMD_AGAIN(snprintf_P(output, len, PSTR("OCR1A: %u"), TC1_COUNTER_COMPARE)); case CNT_DCFNTP: return ECMD_AGAIN(snprintf_P(output, len, PSTR("DCF/NTP: %u/%u"), clock_dcf_count(), clock_ntp_count())); case CNT_RESYN: return ECMD_FINAL(snprintf_P(output, len, PSTR("Resync: %u"), clock_last_ntp())); } return ECMD_FINAL_OK; /* never reached */ }
void debug_process_uart (void) { #if defined(ECMD_PARSER_SUPPORT) && !defined(SOFT_UART_SUPPORT) #define LEN 60 #define OUTPUTLEN 40 static char buf[LEN+1]; static char *ptr = buf; if (usart(UCSR,A) & _BV(usart(RXC))) { char data = usart(UDR); if (data == '\n' || data == '\r') { char *output = malloc(OUTPUTLEN); if (output == NULL) debug_printf("malloc() failed!\n"); *ptr = '\0'; printf_P(PSTR("\n")); #ifdef DEBUG_ECMD debug_printf("parsing command '%s'\n", buf); #endif int l; do { l = ecmd_parse_command(buf, output, LEN); if (is_ECMD_FINAL(l) || is_ECMD_AGAIN(l)) { output[is_ECMD_AGAIN(l) ? ECMD_AGAIN(l) : l] = 0; printf_P(PSTR("%s\n"), output); } } while (is_ECMD_AGAIN(l)); free(output); ptr = buf; } else { debug_uart_put(data, stdout); if (data == '\b') {if (ptr > &buf[0]) ptr--;} else { if (ptr < &buf[LEN-1]) *ptr++ = data; else debug_printf("not enough space for storing '%c'\n", data); } } } #endif /* ECMD_PARSER_SUPPORT && !SOFT_UART_SUPPORT*/ }
void uecmd_net_main() { if (!uip_newdata()) return; char *p = (char *) uip_appdata; /* This may be 1-2 chars too big in case there is a \r or \n, but it saves us a counting loop */ char cmd[uip_datalen() + 1]; char *dp = cmd; /* Copy over into temporary buffer, remove \r \n if present, add \0 */ while (p < (char *) uip_appdata + uip_datalen()) { if (*p == '\r' || *p == '\n') break; *dp++ = *p++; } *dp = 0; uip_slen = 0; while (uip_slen < UIP_BUFSIZE - UIP_IPUDPH_LEN) { int16_t len = ecmd_parse_command(cmd, ((char *) uip_appdata) + uip_slen, (UIP_BUFSIZE - UIP_IPUDPH_LEN) - uip_slen); uint8_t real_len = len; if (!is_ECMD_FINAL(len)) { /* what about the errors ? */ /* convert ECMD_AGAIN back to ECMD_FINAL */ real_len = (uint8_t) ECMD_AGAIN(len); } uip_slen += real_len + 1; ((char *) uip_appdata)[uip_slen - 1] = '\n'; if (real_len == len || len == 0) break; } /* Sent data out */ uip_udp_conn_t echo_conn; uip_ipaddr_copy(echo_conn.ripaddr, BUF->srcipaddr); echo_conn.rport = BUF->srcport; echo_conn.lport = HTONS(ECMD_UDP_PORT); uip_udp_conn = &echo_conn; uip_process(UIP_UDP_SEND_CONN); router_output(); uip_slen = 0; }
int16_t parse_cmd_i2c_detect(char *cmd, char *output, uint16_t len) { /* First call, we initialize our magic bytes*/ if (cmd[0] != 0x23) { cmd[0] = 0x23; cmd[1] = 0; } uint8_t next_address = i2c_master_detect(cmd[1], 127); cmd[1] = next_address + 1; if (next_address > 127) /* End of scaning */ return ECMD_FINAL_OK; else return ECMD_AGAIN(snprintf_P(output, len, PSTR("detected at: 0x%x (%d)"), next_address, next_address)); }
void uecmd_net_main() { if (!uip_newdata ()) return; char *p = (char *)uip_appdata; /* Add \0 to the data and remove \n from the data */ do { if (*p == '\r' || *p == '\n') { break; } } while ( ++p <= ((char *)uip_appdata + uip_datalen())); /* Parse the Data */ *p = 0; char cmd[p - (char *)uip_appdata]; strncpy(cmd, uip_appdata, p - (char *)uip_appdata + 1); uip_slen = 0; while (uip_slen < UIP_BUFSIZE - UIP_IPUDPH_LEN) { int16_t len = ecmd_parse_command(cmd, ((char *)uip_appdata) + uip_slen, (UIP_BUFSIZE - UIP_IPUDPH_LEN) - uip_slen); uint8_t real_len = len; if (!is_ECMD_FINAL(len)) { /* what about the errors ? */ /* convert ECMD_AGAIN back to ECMD_FINAL */ real_len = (uint8_t) ECMD_AGAIN(len); } uip_slen += real_len + 1; ((char *)uip_appdata)[uip_slen - 1] = '\n'; if (real_len == len || len == 0) break; } /* Sent data out */ uip_udp_conn_t echo_conn; uip_ipaddr_copy(echo_conn.ripaddr, BUF->srcipaddr); echo_conn.rport = BUF->srcport; echo_conn.lport = HTONS(ECMD_UDP_PORT); uip_udp_conn = &echo_conn; uip_process(UIP_UDP_SEND_CONN); router_output(); uip_slen = 0; }
int16_t parse_cmd_onewire_list(char *cmd, char *output, uint16_t len) { int8_t list_type; while (*cmd == ' ') cmd++; switch (*cmd) { case 't': list_type = OW_LIST_TYPE_TEMP_SENSOR; break; case 'e': list_type = OW_LIST_TYPE_EEPROM; break; case '\0': list_type = OW_LIST_TYPE_ALL; break; default: return ECMD_ERR_PARSE_ERROR; } static uint8_t i=0; if(i>=OW_SENSORS_COUNT) { i=0; return ECMD_FINAL_OK; } int16_t ret=0; do { if(ow_sensors[i].ow_rom_code.raw != 0) { if ((list_type == OW_LIST_TYPE_ALL) || (list_type == OW_LIST_TYPE_TEMP_SENSOR && ow_temp_sensor(&ow_sensors[i].ow_rom_code)) || (list_type == OW_LIST_TYPE_EEPROM && ow_eeprom(&ow_sensors[i].ow_rom_code))) { ret = snprintf_P(output, len, PSTR("%02x%02x%02x%02x%02x%02x%02x%02x"), ow_sensors[i].ow_rom_code.bytewise[0], ow_sensors[i].ow_rom_code.bytewise[1], ow_sensors[i].ow_rom_code.bytewise[2], ow_sensors[i].ow_rom_code.bytewise[3], ow_sensors[i].ow_rom_code.bytewise[4], ow_sensors[i].ow_rom_code.bytewise[5], ow_sensors[i].ow_rom_code.bytewise[6], ow_sensors[i].ow_rom_code.bytewise[7] ); } } i++; } while(ret == 0 && i<OW_SENSORS_COUNT); return ECMD_AGAIN(ret); }
void cron_execute(struct cron_event_linkedlist *exec) { if (exec->event.cmd == CRON_JUMP) { #ifdef DEBUG_CRON debug_printf("cron: match (JUMP %p)\n", &(exec->event.handler)); #endif #ifndef DEBUG_CRON_DRYRUN exec->event.handler(&(exec->event.extradata)); #endif } else if (exec->event.cmd == CRON_ECMD) { // ECMD PARSER #ifdef DEBUG_CRON debug_printf("cron: match (%s)\n", (char *) &(exec->event.ecmddata)); #endif #ifndef DEBUG_CRON_DRYRUN char output[ECMD_INPUTBUF_LENGTH]; #ifdef DEBUG_CRON int16_t l = #endif ecmd_parse_command((char *) &(exec->event.ecmddata), output, sizeof(output) - 1); #ifdef DEBUG_CRON if (is_ECMD_AGAIN(l)) l = ECMD_AGAIN(l); if (is_ECMD_FINAL(l)) { output[l] = 0; debug_printf("cron output %s\n", output); } else { debug_printf("cron output error %d\n", l); } #endif #endif } /* Execute job endless if repeat value is equal to zero otherwise * decrement the value and check if is equal to zero. * If that is the case, it is time to kick out this cronjob. */ if (exec->event.repeat > 0 && !(--exec->event.repeat)) cron_jobrm(exec); }
int16_t parse_cmd_help(char *cmd, char *output, uint16_t len) { (void) len; /* trick: use bytes on cmd as "connection specific static variables" */ if (cmd[0] != 23) { /* indicator flag: real invocation: 0 */ cmd[0] = 23; /* continuing call: 23 */ cmd[1] = 0; /* counter for output lines */ } char *text = (char *)pgm_read_word(&ecmd_cmds[(uint8_t) cmd[1] ++].name); len = strlen_P (text); memcpy_P (output, text, len); text = (char *) pgm_read_word(&ecmd_cmds[(uint8_t) cmd[1]].name); return text ? ECMD_AGAIN(len) : ECMD_FINAL(len); }
static void irc_handle_ecmd (void) { int16_t len = ecmd_parse_command(STATE->inbuf, STATE->outbuf, ECMD_OUTPUTBUF_LENGTH - 1); if ((STATE->reparse = is_ECMD_AGAIN(len)) != 0) { /* convert ECMD_AGAIN back to ECMD_FINAL */ len = ECMD_AGAIN(len); } if (is_ECMD_ERR(len)) strcpy_P(STATE->outbuf, PSTR("parse error")); else STATE->outbuf[len] = 0; return; }
/** * Get all named pins in a list (separator is the newline character). * Warning: this funtion return only that much entries that fit into * the output buffer. * */ int16_t parse_cmd_pin_list(char *cmd, char *output, uint16_t len) { uint16_t help_len = 0; const char *text; /* trick: use bytes on cmd as "connection specific static variables" */ if (cmd[0] != 23) { /* indicator flag: real invocation: 0 */ cmd[0] = 23; /* continuing call: 23 */ cmd[1] = 0; /* counter for output lines */ } while (1) { /* get named-pin from array */ text = (const char *)pgm_read_word(&portio_pincfg[ (uint8_t)cmd[1]++ ].name); /* leave loop if end of array is reached */ if (text == NULL) break; uint8_t lineLength = strlen_P (text); /* leave loop if output buffer is too small */ if (help_len+lineLength+1>len) { // if we get called again, we have to get this entry again, too. (uint8_t)cmd[1]--; break; } memcpy_P (output, text, lineLength); output += lineLength; /* add newline character */ *output = '\n'; ++output; help_len += lineLength+1; } /* Remove last newline character if end of array is reached */ if (text == NULL && help_len) { --help_len; return ECMD_FINAL(help_len); } else { return ECMD_AGAIN(help_len); } }
int16_t parse_cmd_sd_dir(char *cmd, char *output, uint16_t len) { if (vfs_sd_rootnode == 0) return ECMD_FINAL(snprintf_P(output, len, PSTR("SD/MMC backend not available."))); if (cmd[0] != ECMD_STATE_MAGIC) { fat_reset_dir(vfs_sd_rootnode); cmd[0] = ECMD_STATE_MAGIC; } struct fat_dir_entry_struct dir_entry; if (!fat_read_dir(vfs_sd_rootnode, &dir_entry)) return ECMD_FINAL_OK; return ECMD_AGAIN(snprintf_P(output, len, PSTR("%32s%c %ld"), dir_entry.long_name, dir_entry.attributes & FAT_ATTRIB_DIR ? '/' : ' ', dir_entry.file_size)); }
int16_t parse_cmd_onewire_list(char *cmd, char *output, uint16_t len) { #ifdef ONEWIRE_DS2502_SUPPORT int8_t list_type; while (*cmd == ' ') cmd++; switch (*cmd) { case 't': list_type = OW_LIST_TYPE_TEMP_SENSOR; break; case 'e': list_type = OW_LIST_TYPE_EEPROM; break; case '\0': list_type = OW_LIST_TYPE_ALL; break; default: return ECMD_ERR_PARSE_ERROR; } cmd++; /* for static bytes */ #endif /* trick: use bytes on cmd as "connection specific static variables" */ if (cmd[0] != ECMD_STATE_MAGIC) /* indicator flag: real invocation: 0 */ { cmd[0] = ECMD_STATE_MAGIC; /* continuing call: 23 */ cmd[1] = 0; /* counter for sensors in list */ } uint8_t i = cmd[1]; /* This is a special case: the while loop below printed a sensor which was * last in the list, so we still need to send an 'OK' after the sensor id */ if (i >= OW_SENSORS_COUNT) return ECMD_FINAL_OK; int16_t ret = 0; do { if (ow_sensors[i].ow_rom_code.raw != 0) { #ifdef ONEWIRE_DS2502_SUPPORT if (list_type == OW_LIST_TYPE_ALL || (list_type == OW_LIST_TYPE_TEMP_SENSOR && ow_temp_sensor(&ow_sensors[i].ow_rom_code)) || (list_type == OW_LIST_TYPE_EEPROM && ow_eeprom(&ow_sensors[i].ow_rom_code))) { #endif #ifdef ONEWIRE_NAMING_SUPPORT const char *name = ""; if (ow_sensors[i].named) name = ow_sensors[i].name; #endif #ifdef ONEWIRE_ECMD_LIST_VALUES_SUPPORT char temperature[7]; itoa_fixedpoint(ow_sensors[i].temp.val, ow_sensors[i].temp.twodigits + 1, temperature, sizeof(temperature)); #endif ret = snprintf_P(output, len, PSTR("%02x%02x%02x%02x%02x%02x%02x%02x" #ifdef ONEWIRE_NAMING_SUPPORT "\t%s" #endif #ifdef ONEWIRE_ECMD_LIST_VALUES_SUPPORT "\t%s" #endif #ifdef ONEWIRE_ECMD_LIST_POWER_SUPPORT "\t%d" #endif ), ow_sensors[i].ow_rom_code.bytewise[0], ow_sensors[i].ow_rom_code.bytewise[1], ow_sensors[i].ow_rom_code.bytewise[2], ow_sensors[i].ow_rom_code.bytewise[3], ow_sensors[i].ow_rom_code.bytewise[4], ow_sensors[i].ow_rom_code.bytewise[5], ow_sensors[i].ow_rom_code.bytewise[6], ow_sensors[i].ow_rom_code.bytewise[7] #ifdef ONEWIRE_NAMING_SUPPORT , name #endif #ifdef ONEWIRE_ECMD_LIST_VALUES_SUPPORT , temperature #endif #ifdef ONEWIRE_ECMD_LIST_POWER_SUPPORT , ow_sensors[i].power #endif ); #ifdef ONEWIRE_DS2502_SUPPORT } #endif } i++; } while (ret == 0 && i < OW_SENSORS_COUNT); /* The while loop exited either because a sensor has been found or because * there is no sensor left, let's check for that */ if (ret == 0) { /* => i has reached OW_SENSORS_COUNT */ return ECMD_FINAL_OK; } /* else, ret is != 0 which means a sensor has been found and this functions * has to be called again to prevent a buffer overflow. save i to cmd[1] */ cmd[1] = i; return ECMD_AGAIN(ret); }
int16_t parse_cmd_onewire_list(char *cmd, char *output, uint16_t len) { uint8_t firstonbus = 0; int16_t ret; if (ow_global.lock == 0) { firstonbus = 1; #if ONEWIRE_BUSCOUNT > 1 ow_global.bus = 0; #endif OW_DEBUG_LIST("called onewire list for the first time\n"); #ifdef ONEWIRE_DS2502_SUPPORT /* parse optional parameters */ while (*cmd == ' ') cmd++; switch (*cmd) { case 't': ow_global.list_type = OW_LIST_TYPE_TEMP_SENSOR; break; case 'e': ow_global.list_type = OW_LIST_TYPE_EEPROM; break; case '\0': ow_global.list_type = OW_LIST_TYPE_ALL; break; default: return ECMD_ERR_PARSE_ERROR; } #endif } else { OW_DEBUG_LIST("called onewire list again\n"); firstonbus = 0; } #if defined ONEWIRE_DS2502_SUPPORT || ONEWIRE_BUSCOUNT > 1 list_next:; #endif #if ONEWIRE_BUSCOUNT > 1 ret = ow_search_rom((uint8_t) (1 << (ow_global.bus + ONEWIRE_STARTPIN)), firstonbus); #else ret = ow_search_rom(ONEWIRE_BUSMASK, firstonbus); #endif /* make sure only one conversion happens at a time */ ow_global.lock = 1; if (ret == 1) { #ifdef ONEWIRE_DS2502_SUPPORT if (ow_global.list_type == OW_LIST_TYPE_ALL || (ow_global.list_type == OW_LIST_TYPE_TEMP_SENSOR && ow_temp_sensor(&ow_global.current_rom)) || (ow_global.list_type == OW_LIST_TYPE_EEPROM && ow_eeprom(&ow_global.current_rom))) { /* only print device rom address if it matches the selected list type */ #endif OW_DEBUG_LIST("discovered device " #if ONEWIRE_BUSCOUNT > 1 "%02x %02x %02x %02x %02x %02x %02x %02x on bus %d\n", #else "%02x %02x %02x %02x %02x %02x %02x %02x\n", #endif ow_global.current_rom.bytewise[0], ow_global.current_rom.bytewise[1], ow_global.current_rom.bytewise[2], ow_global.current_rom.bytewise[3], ow_global.current_rom.bytewise[4], ow_global.current_rom.bytewise[5], ow_global.current_rom.bytewise[6], ow_global.current_rom.bytewise[7] #if ONEWIRE_BUSCOUNT > 1 , ow_global.bus); #else ); #endif #ifdef ONEWIRE_NAMING_SUPPORT char *name = ""; ow_sensor_t *sensor = ow_find_sensor(&ow_global.current_rom); if (sensor != NULL && sensor->named) { name = sensor->name; } #endif ret = snprintf_P(output, len, PSTR("%02x%02x%02x%02x%02x%02x%02x%02x" #ifdef ONEWIRE_NAMING_SUPPORT "\t%s" #endif ), ow_global.current_rom.bytewise[0], ow_global.current_rom.bytewise[1], ow_global.current_rom.bytewise[2], ow_global.current_rom.bytewise[3], ow_global.current_rom.bytewise[4], ow_global.current_rom.bytewise[5], ow_global.current_rom.bytewise[6], ow_global.current_rom.bytewise[7] #ifdef ONEWIRE_NAMING_SUPPORT , name #endif ); OW_DEBUG_LIST("generated %d bytes\n", ret); /* set return value that the parser has to be called again */ if (ret > 0) ret = ECMD_AGAIN(ret); OW_DEBUG_LIST("returning %d\n", ret); return ECMD_FINAL(ret); #ifdef ONEWIRE_DS2502_SUPPORT }
void ecmd_net_main(void) { struct ecmd_connection_state_t *state = &uip_conn->appstate.ecmd; if (!uip_poll()) { #ifdef DEBUG_ECMD_NET debug_printf("ecmd_net_main()\n"); #endif } if(uip_connected()) { #ifdef DEBUG_ECMD_NET debug_printf("new connection\n"); #endif state->in_len = 0; state->out_len = 0; state->parse_again = 0; state->parse_again = 0; state->close_requested = 0; #ifdef ECMD_PAM_SUPPORT state->pam_state = PAM_UNKOWN; #endif memset(state->inbuf, 0, ECMD_INPUTBUF_LENGTH); } #ifdef ECMD_PAM_SUPPORT if (state->pam_state == PAM_DENIED) { state->out_len = sprintf_P(state->outbuf, PSTR("authentification failed\n")); state->close_requested = 1; } #endif if(uip_acked() #ifdef ECMD_PAM_SUPPORT || (state->pam_state == PAM_SUCCESS && state->in_len) #endif ) { state->out_len = 0; if (state->parse_again) { #ifdef DEBUG_ECMD_NET debug_printf("transmission done, calling parser again\n"); #endif /* if the first character is ! close the connection after the last * byte is sent */ uint8_t skip = 0; if (state->inbuf[0] == '!') { skip = 1; state->close_requested = 1; } /* parse command and write output to state->outbuf, reserving at least * one byte for the terminating \n */ int l = ecmd_parse_command(state->inbuf + skip, state->outbuf, ECMD_OUTPUTBUF_LENGTH-1); /* check if the parse has to be called again */ if (is_ECMD_AGAIN(l)) { state->parse_again = 1; l = ECMD_AGAIN(l); } else { state->parse_again = 0; /* We have to clear the input buffer */ state->in_len = 0; } if (l > 0) { state->outbuf[l++] = '\n'; state->out_len = l; } } } if(uip_newdata()) { newdata(); } if(uip_rexmit() || uip_newdata() || uip_acked() || uip_connected() || uip_poll()) { if (state->out_len > 0) { #ifdef DEBUG_ECMD_NET debug_printf("sending %d bytes\n", state->out_len); #endif uip_send(state->outbuf, state->out_len); } else if (state->close_requested) uip_close(); } }
void newdata(void) { struct ecmd_connection_state_t *state = &uip_conn->appstate.ecmd; uint16_t diff = ECMD_INPUTBUF_LENGTH - state->in_len; if (diff > 0) { int cplen; if (uip_datalen() <= diff) cplen = uip_datalen(); else cplen = diff; memcpy(state->inbuf + state->in_len, uip_appdata, cplen); state->in_len += cplen; #ifdef DEBUG_ECMD_NET debug_printf("copied %d bytes\n", cplen); #endif } else { #ifdef DEBUG_ECMD_NET debug_printf("buffer full\n"); #endif } char *lf = memchr(state->inbuf, '\n', state->in_len); if (lf != NULL || memchr(uip_appdata, '\n', uip_datalen()) != NULL) { #ifdef DEBUG_ECMD_NET debug_printf("calling parser\n"); #endif if (lf) *lf = '\0'; else state->inbuf[ECMD_INPUTBUF_LENGTH-1] = '\0'; /* kill \r */ int l; for (l = 0; l < ECMD_INPUTBUF_LENGTH; l++) if (state->inbuf[l] == '\r') state->inbuf[l] = '\0'; /* if the first character is ! close the connection after the last * byte is sent */ uint8_t skip = 0; if (state->inbuf[0] == '!') { skip = 1; state->close_requested = 1; } #ifdef ECMD_PAM_SUPPORT if (state->pam_state == PAM_UNKOWN) { if (strncmp_P(state->inbuf + skip, PSTR("auth "), 5) != 0) { /* No authentification request */ auth_required: state->out_len = sprintf_P(state->outbuf, PSTR("authentification required\n")); memset(state->inbuf, 0, ECMD_INPUTBUF_LENGTH); state->in_len = 0; return; } else { char *user = state->inbuf + skip + 5; /* "auth " */ char *pass = strchr(user + 1,' '); if (! pass) goto auth_required; *pass = 0; do { pass++; } while (*pass == ' '); char *p = strchr(pass, ' '); if (p) *p = 0; /* Do the Pam request, the pam request will cache username and * passwort if its necessary. */ pam_auth(user, pass, &state->pam_state); if (p && p[1] != 0) { /* There ist something after the PAM request */ memmove(state->inbuf, p+1, strlen(p+1) + 1); skip = 0; state->in_len = strlen(p+1); if (state->pam_state == PAM_PENDING) state->parse_again = 1; } else { state->in_len = 0; return; } } } if (state->pam_state == PAM_PENDING || state->pam_state == PAM_DENIED) return; /* Pam Subsystem promisses to change this state */ #endif /* parse command and write output to state->outbuf, reserving at least * one byte for the terminating \n */ l = ecmd_parse_command(state->inbuf + skip, state->outbuf, ECMD_OUTPUTBUF_LENGTH-1); #ifdef DEBUG_ECMD_NET debug_printf("parser returned %d\n", l); #endif /* check if the parse has to be called again */ if (is_ECMD_AGAIN(l)) { #ifdef DEBUG_ECMD_NET debug_printf("parser needs to be called again\n"); #endif state->parse_again = 1; l = ECMD_AGAIN(l); } #ifdef DEBUG_ECMD_NET debug_printf("parser really returned %d\n", l); #endif if (l > 0) { if (state->outbuf[l] != ECMD_NO_NEWLINE) state->outbuf[l++] = '\n'; state->out_len = l; } if (!state->parse_again) { #ifdef DEBUG_ECMD_NET debug_printf("clearing buffer\n"); #endif memset(state->inbuf, 0, ECMD_INPUTBUF_LENGTH); state->in_len = 0; } } }