Example #1
0
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));
    }
}
Example #2
0
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
  }
}
Example #3
0
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();

}
Example #4
0
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;
}
Example #5
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;
}
Example #6
0
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));
}
Example #7
0
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;
}
Example #8
0
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));
	}
}
Example #9
0
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));
  }
}
Example #10
0
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);
}
Example #11
0
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 */
}
Example #12
0
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*/
}
Example #13
0
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;
}
Example #14
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));
}
Example #15
0
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;
}
Example #16
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);
}
Example #17
0
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);
}
Example #18
0
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);
}
Example #19
0
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;
}
Example #20
0
/**
 * 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);
	}
}
Example #21
0
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));
}
Example #22
0
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);
}
Example #23
0
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
    }
Example #24
0
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();
    }
}
Example #25
0
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;
        }
    }
}