Files
sics/secopprot.c

86 lines
2.2 KiB
C

#include <errno.h>
#include <tcl.h>
#include <json-c/json.h>
#include "ascon.h"
#include "ascon.i"
#include "script.h"
/*
* protocol for SECoP
*
* Markus Zolliker June 2017
*/
/*----------------------------------------------------------------------------*/
int SecopProtHandler(Ascon *a) {
int ret;
char *result;
char *space;
char *json;
Tcl_Obj *tcllist[3], *tclobj;
int l;
struct json_object *jobj;
switch (a->state) {
case AsconWriting:
/* do not skip garbage (might be a message!) */
l = GetDynStringLength(a->wrBuffer) - a->wrPos;
ret = AsconWriteChars(a->fd, GetCharArray(a->wrBuffer) + a->wrPos, l);
if (ret < 0) {
AsconError(a, "ASC4", errno); /* sets state to AsconFailed */
} else {
a->wrPos += ret;
if (a->wrPos >= GetDynStringLength(a->wrBuffer)) {
a->state = AsconWriteDone;
}
}
return 1;
case AsconWriteStart:
if (GetDynStringLength(a->wrBuffer) == 0) {
/* do not send empty message */
a->state = AsconWriteDone;
return 1;
}
break;
}
ret = AsconStdHandler(a);
switch (a->state) {
case AsconReading:
if (ret) {
if (a->timeout < 1) {
/* extend timeout to 1 sec during a message */
a->start = DoubleTime() + 1 - a->timeout;
}
}
break;
case AsconReadDone:
result = GetCharArray(a->rdBuffer);
space = strchr(result, ' ');
if (space) {
json = strchr(space+1, ' ');
if (json) {
json++;
jobj = json_tokener_parse(json);
if (jobj) {
tcllist[0] = Tcl_NewStringObj(result, space - result);
tcllist[1] = Tcl_NewStringObj(space + 1, json - space - 2);
tcllist[2] = json2tcl(jobj);
tclobj = Tcl_NewListObj(3, tcllist);
DynStringCopy(a->rdBuffer, Tcl_GetString(tclobj));
json_object_put(jobj); /* free jobj */
}
}
}
}
return ret;
}
/*----------------------------------------------------------------------------*/
void AddSecopProtocol() {
static AsconProtocol secopprot;
secopprot.name = "SECoP";
secopprot.handler = SecopProtHandler;
secopprot.init = AsconStdInit;
AsconInsertProtocol(&secopprot);
}