/** * This is an asynchronous protocol driver for the protocol of * the Phytron MCC-2 motor controller. * The send format is: * DATA * the reply format is: * NACK | ACK |& REPLY * * copyright: see file COPYRIGHT * * Mark Koennecke, June 2009 */ #include #include #include #include #define STX '\2' #define ETX '\3' #define NACK '\5' #define ACK '\6' /*---------------------------------------------------------------------------*/ static int PhytronHandler(Ascon * a) { char *data = NULL; int ret, l; char chr; switch (a->state) { case AsconWriteStart: DynStringInsert(a->wrBuffer,"\2",0); DynStringConcatChar(a->wrBuffer,ETX); a->state = AsconWriting; a->wrPos = 0; break; case AsconReading: ret = AsconReadChar(a->fd, &chr); if (ret < 0) { /* EINTR means we must retry */ if (errno != EINTR && errno != EAGAIN) { AsconError(a, "AsconReadChar failed:", errno); } return 1; } else if (ret > 0) { if(chr == STX){ DynStringClear(a->rdBuffer); } else if (chr == ACK){ DynStringConcat(a->rdBuffer,"ACK"); } else if(chr == NACK){ DynStringConcat(a->rdBuffer,"NACK"); } else if(chr == ETX){ a->state = AsconReadDone; } else { DynStringConcatChar(a->rdBuffer,chr); } } else if (ret == 0) { if (a->timeout > 0) { if (DoubleTime() - a->start > a->timeout) { AsconError(a, "read timeout", 0); a->state = AsconTimeout; } } return 0; } break; default: return AsconStdHandler(a); } return 1; } /*------------------------------------------------------------------------*/ static int PhytronInit(Ascon * a, SConnection * con, int argc, char *argv[]) { a->fd = -1; a->state = AsconConnectStart; a->reconnectInterval = 10; a->hostport = strdup(argv[1]); if (argc > 2) { a->timeout = atof(argv[2]); } else { a->timeout = 2.0; /* sec */ } a->killPrivate = free; return 1; } /*------------------------------------------------------------------------*/ void AddPhytronProtocoll() { AsconProtocol *prot = NULL; prot = calloc(sizeof(AsconProtocol), 1); prot->name = strdup("phytron"); prot->init = PhytronInit; prot->handler = PhytronHandler; AsconInsertProtocol(prot); }