Exemple #1
0
/*
 * Send character c down the UART Tx, wait until tx holding register
 * is empty.
 */
int uart_putchar(char c, FILE *stream)
{
    int rc = 0;

    UCSRB &= ~_BV(TXCIE);
    if (txCount <= txBuffSize)
    {
        *(unsigned char *) txBuffIn = c;
        txBuffIn++;
        if (txBuffIn >= txBuff + txBuffSize)
        {
            txBuffIn = txBuff;
        }
        txCount++;
        HIGH_WATER(maxTx, txCount);
        txStart();
    } else
    {
        uart_toe++;
        rc = -1;
    }
    UCSRB |= _BV(TXCIE);

    return rc;
}
int ElectronSerialPipe::put(const void* buffer, int length, bool blocking)
{
    int count = length;
    const char* ptr = (const char*)buffer;
    if (count)
    {
        do
        {
            int written = _pipeTx.put(ptr, count, false);
            if (written) {
                ptr += written;
                count -= written;
                txStart();
            }
            else if (!blocking)
                break;
            /* nothing / just wait */;
        }
        while (count);
    }
    return (length - count);
}
/******************************************
 *
 * Process the state machine, send a frame if we need to.  Returns >0 if
 * there is a frame to be send.
 *
 ******************************************/
int statemachine_run(struct interface_data *thisint, char *inframe, 
		     int insize, char *outframe, int *outsize)
{
  int retVal = XENONE;

  //printf("%s:\n", __FUNCTION__);

  if ((!thisint) || (!outframe) || (!outsize))
    {
      debug_printf(DEBUG_NORMAL, "Invalid data passed in to statemachine_run()!\n");
      return XEMALLOC;
    }

  if (thisint->statemachine == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Statemachine is not set up correctly in statemachine_run()!\n");
      return XEMALLOC;
    }

  if (thisint->statemachine->tick == TRUE)
    {
      // The clock ticked -- Update all of the needed counters.
      dec_if_nz(&thisint->statemachine->authWhile);
      dec_if_nz(&thisint->statemachine->heldWhile);
      dec_if_nz(&thisint->statemachine->startWhen);
      thisint->statemachine->tick = FALSE;
#ifdef RTL_WPA_CLIENT
     if (thisint->statemachine->curState != AUTHENTICATED) {
      int old_level = debug_getlevel();
      debug_setlevel(8, 0);
#endif
      debug_printf(DEBUG_EVERYTHING, "Clock tick! authWhile=%d heldWhile=%d "
		   "startWhen=%d curState=",
		   thisint->statemachine->authWhile,
		   thisint->statemachine->heldWhile,
		   thisint->statemachine->startWhen,
		   thisint->statemachine->curState);
      
      switch (thisint->statemachine->curState)
	{
	case DISCONNECTED:
	  debug_printf_nl(DEBUG_EVERYTHING, "DISCONNECTED\n");
	  break;
	case LOGOFF:
	  debug_printf_nl(DEBUG_EVERYTHING, "LOGOFF\n");
	  break;
	case ACQUIRED:
	  debug_printf_nl(DEBUG_EVERYTHING, "ACQUIRED\n");
	  break;
	case AUTHENTICATING:
	  debug_printf_nl(DEBUG_EVERYTHING, "AUTHENTICATING\n");
	  break;
	case AUTHENTICATED:
	  debug_printf_nl(DEBUG_EVERYTHING, "AUTHENTICATED\n");
	  break;
	case CONNECTING:
	  debug_printf_nl(DEBUG_EVERYTHING, "CONNECTING\n");
	  break;
	case HELD:
	  debug_printf_nl(DEBUG_EVERYTHING, "HELD\n");
	  break;
	default:
	  debug_printf_nl(DEBUG_EVERYTHING, "UNKNOWN!\n");
	  break;
	}
#ifdef RTL_WPA_CLIENT
      debug_setlevel(old_level, 0);
     }
#endif
    }

  thisint->statemachine->portEnabled = get_if_state(thisint);

  // Our state machine is in initalize mode, so set things up.  (THIS ONE
  // MUST COME LAST, before the switch!)
  if ((thisint->statemachine->initialize == TRUE) || 
      (thisint->statemachine->portEnabled == FALSE))
    {
      debug_printf(DEBUG_STATE, "(global) -> DISCONNECTED\n");
      thisint->statemachine->curState = DISCONNECTED;
      thisint->statemachine->initialize = FALSE;
      if (thisint->isWireless == TRUE) cardif_reset_keys(thisint);
    }
  else if (thisint->statemachine->eapFail &&
	   !(thisint->statemachine->initialize || 
	     !thisint->statemachine->portEnabled) &&
	   !thisint->statemachine->userLogoff &&
	   !thisint->statemachine->logoffSent)
    {
      debug_printf(DEBUG_STATE, "(global) -> HELD\n");
      thisint->statemachine->lastState = thisint->statemachine->curState;
      thisint->statemachine->curState = HELD;
      if (thisint->isWireless == TRUE) cardif_reset_keys(thisint);
    }
  else if (thisint->statemachine->userLogoff &&
	   !thisint->statemachine->logoffSent &&
	   !(thisint->statemachine->initialize || 
	     !thisint->statemachine->portEnabled))
    {
      debug_printf(DEBUG_STATE, "(global) -> LOGOFF\n");
      thisint->statemachine->lastState = thisint->statemachine->curState;
      thisint->statemachine->curState = LOGOFF;
      if (thisint->isWireless == TRUE) cardif_reset_keys(thisint);
    }
  else if (thisint->statemachine->eapSuccess &&
	   !(thisint->statemachine->initialize || 
	     !thisint->statemachine->portEnabled) &&
	   !thisint->statemachine->userLogoff &&
	   !thisint->statemachine->logoffSent)
    {
      debug_printf(DEBUG_STATE, "(global) -> AUTHENTICATED\n");
      thisint->statemachine->lastState = thisint->statemachine->curState;
      thisint->statemachine->curState = AUTHENTICATED;
    }

  switch (thisint->statemachine->curState)
    {
    case DISCONNECTED:
      debug_printf(DEBUG_STATE, "Processing DISCONNECTED state.\n");
      thisint->statemachine->eapSuccess = FALSE;
      thisint->statemachine->eapFail = FALSE;
      thisint->statemachine->startCount = 0;
      thisint->statemachine->logoffSent = FALSE;
      thisint->statemachine->previousId = 256;
      thisint->statemachine->suppStatus = UNAUTHORIZED;
      thisint->statemachine->lastState = DISCONNECTED;

      // Automatically change to connected state.
      thisint->statemachine->curState = CONNECTING;
      debug_printf(DEBUG_STATE, "DISCONNECTED -> CONNECTING\n");
      break;

    case LOGOFF:
      if (((thisint->statemachine->userLogoff == TRUE) &&
	   (thisint->statemachine->logoffSent == FALSE)) &&
	  !((thisint->statemachine->initialize == TRUE) ||
	    (thisint->statemachine->portEnabled == FALSE)))
	{
	  debug_printf(DEBUG_STATE, "Processing LOGOFF state.\n");
	  txLogoff(outframe, outsize);
	  thisint->statemachine->logoffSent = TRUE;
	  thisint->statemachine->suppStatus = UNAUTHORIZED;
	  retVal = XDATA;    // We have some data to return.
	}
      if (thisint->statemachine->userLogoff != 1)
	{
	  // If we aren't stuck in logoff state, switch to disconnected.
	  thisint->statemachine->lastState = LOGOFF;
	  thisint->statemachine->curState = DISCONNECTED;
	  debug_printf(DEBUG_STATE, "LOGOFF -> DISCONNECTED\n");
	}
      thisint->statemachine->lastState = LOGOFF;
      break;

    case HELD:
      if ((thisint->statemachine->eapFail == TRUE) && 
	  !((thisint->statemachine->initialize == TRUE) || 
	    (thisint->statemachine->portEnabled == FALSE)) &&
	  (thisint->statemachine->userLogoff == FALSE) &&
	  (thisint->statemachine->logoffSent == FALSE))
	{
	  debug_printf(DEBUG_STATE, "Processing HELD state.\n");
	  thisint->statemachine->heldWhile = thisint->statemachine->heldPeriod;
	  thisint->statemachine->eapFail = FALSE;
	  thisint->statemachine->suppStatus = UNAUTHORIZED;
	}
      if (thisint->statemachine->heldWhile == 0)
	{
	  thisint->statemachine->lastState = HELD;
	  thisint->statemachine->curState = DISCONNECTED;
	  debug_printf(DEBUG_STATE, "HELD -> DISCONNECTED\n");
	}
      if (thisint->statemachine->reqId == TRUE)
	{
	  thisint->statemachine->lastState = HELD;
	  thisint->statemachine->curState = ACQUIRED;
	  debug_printf(DEBUG_STATE, "HELD -> ACQUIRED\n");
	}
      thisint->statemachine->lastState = HELD;
      break;

    case AUTHENTICATED:
      if ((thisint->statemachine->eapSuccess == TRUE) &&
	  !((thisint->statemachine->initialize == TRUE) ||
	    (thisint->statemachine->portEnabled == FALSE)))
	{
	  thisint->statemachine->eapSuccess = FALSE;
	  thisint->statemachine->eapFail = FALSE;
	  thisint->statemachine->suppStatus = AUTHORIZED;


	}
      if (thisint->statemachine->reqId == TRUE)
	{
	  thisint->statemachine->lastState = AUTHENTICATED;
	  thisint->statemachine->curState = ACQUIRED;
	  debug_printf(DEBUG_STATE, "AUTHENTICATED -> ACQUIRED\n");
	}
      thisint->statemachine->lastState = AUTHENTICATED;
      break;

    case ACQUIRED:
      if (thisint->statemachine->reqId)
	{
	  debug_printf(DEBUG_STATE, "Processing ACQUIRED state.\n");
	  debug_printf(DEBUG_NORMAL, "Connection established, authenticating...\n");
	  thisint->statemachine->authWhile = thisint->statemachine->authPeriod;
	  thisint->statemachine->startCount = 0;
	  thisint->statemachine->reqId = FALSE;
	  thisint->statemachine->reqAuth = FALSE;
	  txRspId(thisint, outframe, outsize);
	  thisint->statemachine->previousId = thisint->statemachine->receivedId;
	  retVal = XDATA;
	}
      if (thisint->statemachine->reqAuth == TRUE)
	{
	  thisint->statemachine->lastState = ACQUIRED;
	  thisint->statemachine->curState = AUTHENTICATING;
	  debug_printf(DEBUG_STATE, "ACQUIRED -> AUTHENTICATING)\n");
	  // Below is a hack.  We should find a better way to handle this!
	  retVal=statemachine_run(thisint, inframe, insize, outframe, outsize);
	}
      thisint->statemachine->lastState = ACQUIRED;
      break;

    case AUTHENTICATING:
      if (thisint->statemachine->reqAuth == TRUE)
	{
	  debug_printf(DEBUG_STATE, "Processing AUTHENTICATING state.\n");
	  thisint->statemachine->authWhile = thisint->statemachine->authPeriod;
	  thisint->statemachine->reqAuth = FALSE;
	  txRspAuth(thisint, inframe, insize, outframe, outsize);
	  
	  if (inframe != NULL)
	    thisint->statemachine->previousId = thisint->statemachine->receivedId;
	  if (*outsize != 0) 
	    {
	      retVal = XDATA;
	    }
	} else {
	  // Even though reqAuth != when we are in this state, we want to
	  // call txRspAuth in order to allow EAP types to request 
	  // interactive data.
	  txRspAuth(thisint, inframe, insize, outframe, outsize);
	  if (*outsize != 0)
	    {
	      retVal = XDATA;
	    }
	}
      if (thisint->statemachine->authWhile == 0)
	{
	  thisint->statemachine->lastState = AUTHENTICATING;
	  thisint->statemachine->curState = CONNECTING;
	  debug_printf(DEBUG_STATE, "AUTHENTICATING -> CONNECTING\n");
	}
      if (thisint->statemachine->reqId == TRUE)
	{
	  thisint->statemachine->lastState = AUTHENTICATING;
	  thisint->statemachine->curState = ACQUIRED;
	  debug_printf(DEBUG_STATE, "AUTHENTICATING -> ACQUIRED\n");
	}
      thisint->statemachine->lastState = AUTHENTICATING;
      break;

    case CONNECTING:
      if ((thisint->statemachine->startWhen==0) && 
	  (thisint->statemachine->startCount < thisint->statemachine->maxStart))
	{
	  debug_printf(DEBUG_STATE, "Processing CONNECTING state.\n");
	  thisint->statemachine->startWhen = thisint->statemachine->startPeriod;
	  thisint->statemachine->startCount++;
	  thisint->statemachine->reqId = FALSE;
	  txStart(outframe, outsize);
	  retVal = XDATA;
	}
      if (thisint->statemachine->reqId == TRUE)
	{
	  thisint->statemachine->lastState = CONNECTING;
	  thisint->statemachine->curState = ACQUIRED;
	  debug_printf(DEBUG_STATE, "CONNECTING -> ACQUIRED\n");
	}
#ifndef RTL_WPA_CLIENT  
      if ((thisint->statemachine->startWhen == 0) && 
	  (thisint->statemachine->startCount >= thisint->statemachine->maxStart))
	{
	  debug_printf(DEBUG_NORMAL, "Defaulting to AUTHENTICATED state!\n");

	  thisint->statemachine->lastState = CONNECTING;
	  thisint->statemachine->curState = AUTHENTICATED;
	  debug_printf(DEBUG_STATE, "CONNECTING -> AUTHENTICATED\n");
	}
#endif /* RTL_WPA_CLIENT */	
      thisint->statemachine->lastState = CONNECTING;
      break;
    }

  return retVal;
}
int ElectronSerialPipe::putc(int c)
{
    c = _pipeTx.putc(c);
    txStart();
    return c;
}