/*
 * charbychar.c
 *
 *  This is a variation of the standard AsonHandler which implements
 *  a char by char mode while sending. This means, that the protocol
 *  handler waits for the echoed character from the device before sending
 *  the next character.
 *
 *  Created on: Apr 1, 2010
 *      Author: koennecke
 */
#include <errno.h>
#include <ascon.h>
#include <ascon.i>

/*-----------------------------------------------------------
 * I am abusing the echo field as a flag if we are reading
 * an echo char or not
-----------------------------------------------------------*/
static int CharByCharHandler(Ascon *a)
{
	int ret;
	char chr;

	switch(a->state){
	case AsconWriting:
		if(a->wrPos < GetDynStringLength(a->wrBuffer)){
			ret = AsconWriteChars(a->fd,GetCharArray(a->wrBuffer)+a->wrPos,1);
		    if (ret < 0) {
		      AsconError(a, "ASC4", errno); /* sets state to AsconFailed */
		      return 0;
		    } else {
		      a->wrPos++;
		      a->private = (void *)1;
		      a->state = AsconReading;
		      a->start = DoubleTime();
		    }
		    break;
		} else {
			a->private = NULL;
			a->state = AsconWriteDone;
		}
		break;
	case AsconReading:
		/**
		 * Here I rely on the fact that the base
		 * handler, in AsconReadStart, clears the
		 * rdBuffer of amassed echo characters.
		 */
		ret = AsconStdHandler(a);
		if(ret == 1){
			if(a->private != NULL){
				a->state = AsconWriting;
			}
		}
		return ret;
		break;
	default:
		return AsconStdHandler(a);
	}
	return 1;
}
/*------------------------------------------------------------------------*/
void AddCharByCharProtocoll()
{
  AsconProtocol *prot = NULL;

  prot = calloc(sizeof(AsconProtocol), 1);
  prot->name = strdup("charbychar");
  prot->init = AsconStdInit;
  prot->handler = CharByCharHandler;
  AsconInsertProtocol(prot);
}
