예제 #1
0
uint8_t pdu_parser(uint8_t *pdu) 
{
    uint8_t i = 3;
    uint8_t ret_val = 1;
    int16_t write_len = 0;
    uint16_t reply_len = 0;

    SMS_DEBUG("pdu_parser called: %d\n", pdu[i]);
    if (pdu[i++] == '+') {
        SMS_DEBUG("pdu_parser called: %d\n", pdu[i]);
        if (!strncmp((char *) pdu + i, "CMGL", 4)) {    
            SMS_DEBUG("messages will be received\r\n");
            uint8_t smsc_len, sender_len;
            if (reply_len == 0) {
                while (pdu[++i] != '\n');
                i ++;
                /* get length of smsc number */
                sscanf((char *) pdu + i, "%02hhX", &smsc_len);
                /* we ignore some flags "0000" */
                i += (smsc_len * 2) + 4;
                /* get data length */
                sscanf((char *) pdu + i, "%02hhX", &sender_len);
                /* get number of message sender */
                strncpy(nummer, (char *) pdu + i, sender_len + 5);
                nummer[sender_len + 5] = '\0';
                i = i + sender_len + 5 + 18;
                read_sms((uint8_t *) pdu + i);
            }
            
            SMS_DEBUG("ecmd: %s\n", text);
            do {
                if (reply_len < (int16_t)sizeof(write_buffer)) {
                    write_len = ecmd_parse_command((char *) text, 
                                              write_buffer + reply_len, 
                                              sizeof(write_buffer) - reply_len - 1);
                    SMS_DEBUG("ret_len ecmd parser: %d\r\n", write_len);
                    if (is_ECMD_AGAIN(write_len)) {
                        reply_len += -(10 + write_len);
                        *(write_buffer + reply_len) = ' ';
                        reply_len++;
                    } 
                    else if (write_len > 0) {
                        SMS_DEBUG("finished: \"%s\"\n", write_buffer);
                        ret_val = 0;
                        reply_len += write_len;
                        break;
                    }
                    SMS_DEBUG("%s\n", write_buffer);
                }
                else {
                    break;
                }
            } while (write_len <= 0);
           
            write_buffer[reply_len] = '\0';
            sms_send((uint8_t *) nummer, (uint8_t *) write_buffer, NULL, 1);
        }
    }
    return ret_val;
}
예제 #2
0
파일: ecmd_lufa.c 프로젝트: sankeq/ethersex
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();

}
예제 #3
0
파일: jabber.c 프로젝트: AnDann/ethersex
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;
}
예제 #4
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;
}
예제 #5
0
파일: ecmd_usb.c 프로젝트: muccc/matemat
uint8_t 
ecmd_usb_setup(uint8_t  data[8]) 
{
  usbRequest_t *rq = (void *)data;
  if (rq->wValue.word == 1) { /* Write */ 
    recv_count = 0;
  } else { /* Read */
    uint8_t len = ecmd_parse_command(recv_buffer, send_buffer, ECMD_USB_BUFFER_LEN);
    if (len > 0) 
      recv_buffer[len] = 0;
    send_count = 0;
  }
  return USB_NO_MSG;
}
예제 #6
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*/
}
예제 #7
0
static void
jabber_parse_ecmd (char *message)
{
    int16_t len = ecmd_parse_command(message, STATE->outbuf,
				     ECMD_OUTPUTBUF_LENGTH - 1);
    if (len <= -10) {
	JABDEBUG ("jabber_ecmd doesn't support multiple reply lines (yet)\n");
	len = -len - 10;
   }

   if (len < 0)
	strcpy_P (STATE->outbuf, PSTR ("parse error"));
   else
	STATE->outbuf[len] = 0;
}
예제 #8
0
int16_t parse_ecmd_twi_slave (void)
{
	TWIDEBUG("parse_ecmd_twi_slave\n");
	twi_get_rx_data(cmd_rx_buffer);
	ecmd_len = ecmd_parse_command(cmd_rx_buffer, cmd_tx_buffer, sizeof(cmd_tx_buffer));
	twi_set_tx_data(cmd_tx_buffer);		

	/*dont know how to return multiple lines in tx_buffer*/
	//if (is_ECMD_AGAIN(ecmd_len)) {
	  /* convert ECMD_AGAIN back to ECMD_FINAL */
	//ecmd_len = ECMD_AGAIN(ecmd_len);
	//}
	//else if (is_ECMD_ERR(ecmd_len))
	  // return;
	return ECMD_FINAL_OK;
}
예제 #9
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);
}
예제 #10
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;
}
예제 #11
0
int16_t
parse_cmd_call(char *cmd, char *output, uint16_t len)
{
  char filename[10];
  char line[ECMD_INPUTBUF_LENGTH];
  uint8_t lsize = 0;
  uint8_t run = 0;
  vfs_size_t filesize;

  sscanf_P(cmd, PSTR("%s"), &filename); // should check for ".es" extention!
  current_script.handle = vfs_open(filename);

  if (current_script.handle == NULL)
  {
    SCRIPTDEBUG("%s not found\n", filename);
    return ECMD_FINAL(1);
  }

  filesize = vfs_size(current_script.handle);

  SCRIPTDEBUG("start %s from %i bytes\n", filename, filesize);
  current_script.linenumber = 0;
  current_script.filepointer = 0;

  // open file as long it is open, we have not reached max lines and 
  // not the end of the file as we know it
  while ((current_script.handle != NULL) &&
         (run++ < ECMD_SCRIPT_MAXLINES) &&
         (filesize > current_script.filepointer))
  {

    lsize = readline(line);
    SCRIPTDEBUG("(linenr:%i, pos:%i, bufsize:%i)\n",
                current_script.linenumber, current_script.filepointer, lsize);
    SCRIPTDEBUG("exec: %s\n", line);
    if (lsize != 0)
    {
      ecmd_parse_command(line, output, len);
    }
  }
  SCRIPTDEBUG("end\n");

  parse_cmd_exit(cmd, output, len);

  return ECMD_FINAL_OK;
}
예제 #12
0
파일: irc.c 프로젝트: HansBaechle/ethersex
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;
}
예제 #13
0
파일: ecmd_net.c 프로젝트: muccc/matemat
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, 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;
        }


        /* 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 (l <= -10) {
#ifdef DEBUG_ECMD_NET
            debug_printf("parser needs to be called again\n");
#endif

            state->parse_again = 1;
            l = -l - 10;
        }

#ifdef DEBUG_ECMD_NET
        debug_printf("parser really returned %d\n", l);
#endif

        if (l > 0) {
            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;
        }
    }
}
예제 #14
0
파일: ecmd_net.c 프로젝트: muccc/matemat
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->close_requested = 0;
        memset(state->inbuf, 0, ECMD_INPUTBUF_LENGTH);
    }

    if(uip_acked()) {
        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 (l <= -10) {
                state->parse_again = 1;
                l = -l - 10;
            } else
                state->parse_again = 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();
    }
}
예제 #15
0
int16_t
parse_cmd_if(char *cmd, char *output, uint16_t len)
{
  char cmpcmd[ECMD_SCRIPT_COMPARATOR_LENGTH];
  char comparator[3];
  char konst[ECMD_SCRIPT_COMPARATOR_LENGTH];
//  char cmd[]= "if ( whm != 00:01 ) then exit";
  uint8_t success = 0;          // default false

  sscanf_P(cmd, PSTR("( %s %s %s ) then "), &cmpcmd, &comparator, &konst);
  char *ecmd = strstr_P(cmd, PSTR("then"));
  if (ecmd == NULL)
  {
    SCRIPTDEBUG("cmd not found\n");
    return ECMD_FINAL(1);
  }
  ecmd += 5;

  SCRIPTDEBUG("ecmd: %s\n", ecmd);
  SCRIPTDEBUG("cmpcmd: %s\n", cmpcmd);
  SCRIPTDEBUG("comparator: %s\n", comparator);
  SCRIPTDEBUG("konst: %s\n", konst);

  // if cmpcmd starts with % it is a variable
  if (cmpcmd[0] == '%')
  {
    uint8_t varpos = cmpcmd[1] - '0';
    // get variable and set it to output
    strcpy(output, vars[varpos].value);
  }
  else
  {                             // if not, it is a command
    // execute cmp! and check output
    if (!ecmd_parse_command(cmpcmd, output, len))
    {
      SCRIPTDEBUG("compare wrong\n");
      return ECMD_FINAL(1);
    }
  }
  SCRIPTDEBUG("cmp '%s' %s '%s'\n", output, comparator, konst);

  // check comparator  
  if (strcmp(comparator, STR_EQUALS) == 0)
  {
    SCRIPTDEBUG("try " STR_EQUALS "\n");
    success = (strcmp(output, konst) == 0);
  }
  else if (strcmp(comparator, STR_NOTEQUALS) == 0)
  {
    SCRIPTDEBUG("try " STR_NOTEQUALS "\n");
    success = (strcmp(output, konst) != 0);
  }
  else
  {
    uint16_t outputvalue = atoi(output);
    uint16_t konstvalue = atoi(konst);
//    debug_printf("cmp atoi: %i %s %i\n", outputvalue, comparator, konstvalue);
    if (strcmp(comparator, OK) == 0)
    {
      SCRIPTDEBUG("try " OK "\n");
      success = outputvalue;
    }
    else if (strcmp(comparator, NOT) == 0)
    {
      SCRIPTDEBUG("try " NOT "\n");
      success = (outputvalue != 0);
    }
    else if (strcmp(comparator, EQUALS) == 0)
    {
      SCRIPTDEBUG("try " EQUALS "\n");
      success = (outputvalue == konstvalue);
    }
    else if (strcmp(comparator, NOTEQUALS) == 0)
    {
      SCRIPTDEBUG("try " NOTEQUALS "\n");
      success = (outputvalue != konstvalue);
    }
    else if (strcmp(comparator, GREATER) == 0)
    {
      SCRIPTDEBUG("try " GREATER "\n");
      success = (outputvalue > konstvalue);
    }
    else if (strcmp(comparator, LOWER) == 0)
    {
      SCRIPTDEBUG("try " LOWER "\n");
      success = (outputvalue < konstvalue);
    }
    else if (strcmp(comparator, GREATEREQUALS) == 0)
    {
      SCRIPTDEBUG("try " GREATEREQUALS "\n");
      success = (outputvalue >= konstvalue);
    }
    else if (strcmp(comparator, LOWEREQUALS) == 0)
    {
      SCRIPTDEBUG("try " LOWEREQUALS "\n");
      success = (outputvalue <= konstvalue);
    }
    else
    {
//      debug_printf("unknown comparator: %s\n", comparator);
      return ECMD_FINAL(3);
    }
  }
  // if compare ok, execute command after then
  if (success)
  {
    SCRIPTDEBUG("OK, do: %s\n", ecmd);
    if (ecmd_parse_command(ecmd, output, len))
    {
      SCRIPTDEBUG("done: %s\n", output);
      return ECMD_FINAL(snprintf_P(output, len, PSTR("%s"), output));
    }
    return ECMD_FINAL(2);
  }
  SCRIPTDEBUG("success was: %i\n", success);
  return ECMD_FINAL(1);
}
예제 #16
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();
    }
}
예제 #17
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;
        }
    }
}