/** * This is a protocol implementation for the new SICS asynchronous I/O * infrastructure and the Juelich chopper system as used at MARS. * * The Juelich chopper control program likes checksums to come with * messages and uses $ as both send and reply terminators. * * copyright: see file COPYRIGHT * * Mark Koennecke, June 2008 */ #include #include #include #include static int calculateJulCheckSum(char *realCommand) { int i, checkSum = 0; for (i = 1; i < strlen(realCommand); i++) { checkSum += (int) realCommand[i]; } return checkSum; } /*---------------------------------------------------------------------------*/ int JulchoHandler(Ascon * a) { char *data = NULL; int checkSum, ret; char checkBuffer[30], chr; switch (a->state) { case AsconWriteStart: data = GetCharArray(a->wrBuffer); checkSum = calculateJulCheckSum(data); snprintf(checkBuffer, 30, "{%d}$", checkSum); DynStringConcat(a->wrBuffer, checkBuffer); 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) { a->start = DoubleTime(); if (chr == '$') { DynStringConcatChar(a->rdBuffer, '\0'); a->state = AsconReadDone; break; } else { if (DynStringConcatChar(a->rdBuffer, chr) == 0) { AsconError(a, "DynStringConcatChar failed:", ENOMEM); break; } } } 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; } /*-------------------------------------------------------------------------*/ void AddJulChoProtocoll() { AsconProtocol *prot = NULL; prot = calloc(sizeof(AsconProtocol), 1); prot->name = strdup("julcho"); prot->init = AsconStdInit; prot->handler = JulchoHandler; AsconInsertProtocol(prot); }