86 lines
2.2 KiB
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);
|
|
}
|