Preparing support for acknowledgements

This commit is contained in:
Pierre Pronchery 2014-03-22 23:40:28 +09:00
parent 362d266383
commit 32593c6e25
6 changed files with 175 additions and 18 deletions

View File

@ -49,6 +49,7 @@ dist:
$(PACKAGE)-$(VERSION)/src/common.c \ $(PACKAGE)-$(VERSION)/src/common.c \
$(PACKAGE)-$(VERSION)/src/Makefile \ $(PACKAGE)-$(VERSION)/src/Makefile \
$(PACKAGE)-$(VERSION)/src/appinterface.h \ $(PACKAGE)-$(VERSION)/src/appinterface.h \
$(PACKAGE)-$(VERSION)/src/appmessage.h \
$(PACKAGE)-$(VERSION)/src/apptransport.h \ $(PACKAGE)-$(VERSION)/src/apptransport.h \
$(PACKAGE)-$(VERSION)/src/common.h \ $(PACKAGE)-$(VERSION)/src/common.h \
$(PACKAGE)-$(VERSION)/src/project.conf \ $(PACKAGE)-$(VERSION)/src/project.conf \

View File

@ -28,10 +28,14 @@
/* types */ /* types */
typedef enum _AppMessageType typedef enum _AppMessageType
{ {
AMT_CALL = 0 AMT_CALL = 0,
AMT_ACKNOWLEDGEMENT
} AppMessageType; } AppMessageType;
# define AMT_CALLBACK AMT_CALL # define AMT_CALLBACK AMT_CALL
typedef uint32_t AppMessageID;
/* calls */
typedef enum _AppMessageCallDirection typedef enum _AppMessageCallDirection
{ {
AMCD_IN = 0, AMCD_IN = 0,
@ -52,10 +56,14 @@ typedef struct _AppMessageCallArgument
/* functions */ /* functions */
/* calls */
AppMessage * appmessage_new_call(String const * method, AppMessage * appmessage_new_call(String const * method,
AppMessageCallArgument * args, size_t args_cnt); AppMessageCallArgument * args, size_t args_cnt);
AppMessage * appmessage_new_callv(String const * method, ...); AppMessage * appmessage_new_callv(String const * method, ...);
AppMessage * appmessage_new_callv_variables(String const * method, ...); AppMessage * appmessage_new_callv_variables(String const * method, ...);
/* acknowledgement */
AppMessage * appmessage_new_acknowledgement(AppMessageID id);
/* generic */
AppMessage * appmessage_new_deserialize(Buffer * buffer); AppMessage * appmessage_new_deserialize(Buffer * buffer);
void appmessage_delete(AppMessage * appmessage); void appmessage_delete(AppMessage * appmessage);

View File

@ -39,7 +39,7 @@ appclient.o: appclient.c appinterface.h ../include/App/appclient.h common.h
appinterface.o: appinterface.c ../include/App/appserver.h ../config.h appinterface.o: appinterface.c ../include/App/appserver.h ../config.h
$(CC) $(libApp_CFLAGS) -c appinterface.c $(CC) $(libApp_CFLAGS) -c appinterface.c
appmessage.o: appmessage.c appmessage.o: appmessage.c ../include/App/appmessage.h appmessage.h
$(CC) $(libApp_CFLAGS) -c appmessage.c $(CC) $(libApp_CFLAGS) -c appmessage.c
appserver.o: appserver.c appinterface.h ../include/App/appserver.h ../config.h appserver.o: appserver.c appinterface.h ../include/App/appserver.h ../config.h

View File

@ -22,7 +22,7 @@
# include <stdio.h> # include <stdio.h>
#endif #endif
#include <System.h> #include <System.h>
#include "App/appmessage.h" #include "appmessage.h"
/* AppMessage */ /* AppMessage */
@ -31,6 +31,7 @@
struct _AppMessage struct _AppMessage
{ {
AppMessageType type; AppMessageType type;
AppMessageID id;
union union
{ {
@ -46,6 +47,22 @@ struct _AppMessage
/* public */ /* public */
/* functions */ /* functions */
/* appmessage_new_acknowledgement */
AppMessage * appmessage_new_acknowledgement(AppMessageID id)
{
AppMessage * message;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, method);
#endif
if((message = object_new(sizeof(*message))) == NULL)
return NULL;
message->type = AMT_ACKNOWLEDGEMENT;
message->id = id;
return message;
}
/* appmessage_new_call */ /* appmessage_new_call */
AppMessage * appmessage_new_call(char const * method, AppMessage * appmessage_new_call(char const * method,
AppMessageCallArgument * args, size_t args_cnt) AppMessageCallArgument * args, size_t args_cnt)
@ -59,6 +76,7 @@ AppMessage * appmessage_new_call(char const * method,
if((message = object_new(sizeof(*message))) == NULL) if((message = object_new(sizeof(*message))) == NULL)
return NULL; return NULL;
message->type = AMT_CALL; message->type = AMT_CALL;
message->id = 0;
message->t.call.method = string_new(method); message->t.call.method = string_new(method);
message->t.call.args = malloc(sizeof(*args) * args_cnt); message->t.call.args = malloc(sizeof(*args) * args_cnt);
message->t.call.args_cnt = args_cnt; message->t.call.args_cnt = args_cnt;
@ -90,6 +108,7 @@ AppMessage * appmessage_new_callv(char const * method, ...)
if((message = object_new(sizeof(*message))) == NULL) if((message = object_new(sizeof(*message))) == NULL)
return NULL; return NULL;
message->type = AMT_CALL; message->type = AMT_CALL;
message->id = 0;
message->t.call.method = string_new(method); message->t.call.method = string_new(method);
message->t.call.args = NULL; message->t.call.args = NULL;
message->t.call.args_cnt = 0; message->t.call.args_cnt = 0;
@ -138,6 +157,7 @@ AppMessage * appmessage_new_callv_variables(char const * method, ...)
if((message = object_new(sizeof(*message))) == NULL) if((message = object_new(sizeof(*message))) == NULL)
return NULL; return NULL;
message->type = AMT_CALL; message->type = AMT_CALL;
message->id = 0;
message->t.call.method = string_new(method); message->t.call.method = string_new(method);
message->t.call.args = NULL; message->t.call.args = NULL;
message->t.call.args_cnt = 0; message->t.call.args_cnt = 0;
@ -171,8 +191,12 @@ AppMessage * appmessage_new_callv_variables(char const * method, ...)
/* appmessage_new_deserialize */ /* appmessage_new_deserialize */
static AppMessage * _new_deserialize_acknowledgement(AppMessage * message,
char const * data, const size_t size, size_t pos);
static AppMessage * _new_deserialize_call(AppMessage * message, static AppMessage * _new_deserialize_call(AppMessage * message,
char const * data, size_t size, size_t pos); char const * data, const size_t size, size_t pos);
static AppMessage * _new_deserialize_id(AppMessage * message, char const * data,
const size_t size, size_t * pos);
AppMessage * appmessage_new_deserialize(Buffer * buffer) AppMessage * appmessage_new_deserialize(Buffer * buffer)
{ {
@ -203,6 +227,9 @@ AppMessage * appmessage_new_deserialize(Buffer * buffer)
variable_delete(v); variable_delete(v);
switch((message->type = u8)) switch((message->type = u8))
{ {
case AMT_ACKNOWLEDGEMENT:
return _new_deserialize_acknowledgement(message, data,
size, pos);
case AMT_CALL: case AMT_CALL:
return _new_deserialize_call(message, data, size, pos); return _new_deserialize_call(message, data, size, pos);
default: default:
@ -213,8 +240,17 @@ AppMessage * appmessage_new_deserialize(Buffer * buffer)
} }
} }
static AppMessage * _new_deserialize_acknowledgement(AppMessage * message,
char const * data, const size_t size, size_t pos)
{
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
return _new_deserialize_id(message, data, size, &pos);
}
static AppMessage * _new_deserialize_call(AppMessage * message, static AppMessage * _new_deserialize_call(AppMessage * message,
char const * data, size_t size, size_t pos) char const * data, const size_t size, size_t pos)
{ {
size_t s; size_t s;
Variable * v; Variable * v;
@ -224,6 +260,8 @@ static AppMessage * _new_deserialize_call(AppMessage * message,
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__); fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif #endif
if(_new_deserialize_id(message, data, size, &pos) == NULL)
return NULL;
message->t.call.method = NULL; message->t.call.method = NULL;
message->t.call.args = NULL; message->t.call.args = NULL;
message->t.call.args_cnt = 0; message->t.call.args_cnt = 0;
@ -231,12 +269,12 @@ static AppMessage * _new_deserialize_call(AppMessage * message,
if((v = variable_new_deserialize_type(VT_STRING, &s, &data[pos])) if((v = variable_new_deserialize_type(VT_STRING, &s, &data[pos]))
== NULL) == NULL)
{ {
error_set_code(1, "%s%u", "Unknown method "); error_set_code(1, "%s", "Could not obtain the AppMessage call"
" method");
appmessage_delete(message); appmessage_delete(message);
return NULL; return NULL;
} }
pos += s; pos += s;
size -= s;
/* XXX may fail */ /* XXX may fail */
variable_get_as(v, VT_STRING, &message->t.call.method); variable_get_as(v, VT_STRING, &message->t.call.method);
variable_delete(v); variable_delete(v);
@ -257,7 +295,7 @@ static AppMessage * _new_deserialize_call(AppMessage * message,
return NULL; return NULL;
} }
message->t.call.args = p; message->t.call.args = p;
s = size; s = size - pos;
if((v = variable_new_deserialize(&s, &data[pos])) == NULL) if((v = variable_new_deserialize(&s, &data[pos])) == NULL)
{ {
appmessage_delete(message); appmessage_delete(message);
@ -268,7 +306,6 @@ static AppMessage * _new_deserialize_call(AppMessage * message,
variable_get_type(v)); variable_get_type(v));
#endif #endif
pos += s; pos += s;
size -= s;
message->t.call.args[i].direction = AMCD_IN; /* XXX */ message->t.call.args[i].direction = AMCD_IN; /* XXX */
message->t.call.args[i].arg = v; message->t.call.args[i].arg = v;
message->t.call.args_cnt = i + 1; message->t.call.args_cnt = i + 1;
@ -276,6 +313,34 @@ static AppMessage * _new_deserialize_call(AppMessage * message,
return message; return message;
} }
static AppMessage * _new_deserialize_id(AppMessage * message, char const * data,
const size_t size, size_t * pos)
{
int ret = 0;
size_t s = size;
Variable * v;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
if((v = variable_new_deserialize_type(VT_UINT32, &s, &data[*pos]))
== NULL)
{
error_set_code(1, "%s", "Could not obtain the AppMessage ID");
appmessage_delete(message);
return NULL;
}
ret = variable_get_as(v, VT_UINT32, &message->id);
variable_delete(v);
if(ret != 0)
{
appmessage_delete(message);
return NULL;
}
*pos += s;
return message;
}
/* appmessage_delete */ /* appmessage_delete */
static void _delete_call(AppMessage * message); static void _delete_call(AppMessage * message);
@ -284,6 +349,8 @@ void appmessage_delete(AppMessage * message)
{ {
switch(message->type) switch(message->type)
{ {
case AMT_ACKNOWLEDGEMENT:
break;
case AMT_CALL: case AMT_CALL:
_delete_call(message); _delete_call(message);
break; break;
@ -298,6 +365,13 @@ static void _delete_call(AppMessage * message)
/* accessors */ /* accessors */
/* appmessage_get_id */
AppMessageID appmessage_get_id(AppMessage * message)
{
return message->id;
}
/* appmessage_get_method */ /* appmessage_get_method */
String const * appmessage_get_method(AppMessage * message) String const * appmessage_get_method(AppMessage * message)
{ {
@ -314,30 +388,36 @@ AppMessageType appmessage_get_type(AppMessage * message)
} }
/* appmessage_set_id */
void appmessage_set_id(AppMessage * message, AppMessageID id)
{
message->id = id;
}
/* useful */ /* useful */
/* appmessage_serialize */ /* appmessage_serialize */
static int _serialize_acknowledgement(AppMessage * message, Buffer * buffer,
Buffer * b);
static int _serialize_append(Buffer * buffer, Buffer * b); static int _serialize_append(Buffer * buffer, Buffer * b);
static int _serialize_call(AppMessage * message, Buffer * buffer, Buffer * b); static int _serialize_call(AppMessage * message, Buffer * buffer, Buffer * b);
static int _serialize_id(AppMessage * message, Buffer * buffer, Buffer * b);
static int _serialize_type(AppMessage * message, Buffer * buffer, Buffer * b);
int appmessage_serialize(AppMessage * message, Buffer * buffer) int appmessage_serialize(AppMessage * message, Buffer * buffer)
{ {
int ret;
Variable * v;
Buffer * b; Buffer * b;
if((b = buffer_new(0, NULL)) == NULL) if((b = buffer_new(0, NULL)) == NULL)
return -1; return -1;
/* reset the output buffer */ /* reset the output buffer */
buffer_set_size(buffer, 0); buffer_set_size(buffer, 0);
if((v = variable_new(VT_UINT8, &message->type)) == NULL) if(_serialize_type(message, buffer, b) != 0)
return -1; return -1;
ret = (variable_serialize(v, b, 0) == 0
&& _serialize_append(buffer, b) == 0) ? 0 : -1;
variable_delete(v);
if(ret != 0)
return ret;
switch(message->type) switch(message->type)
{ {
case AMT_ACKNOWLEDGEMENT:
return _serialize_acknowledgement(message, buffer, b);
case AMT_CALL: case AMT_CALL:
return _serialize_call(message, buffer, b); return _serialize_call(message, buffer, b);
default: default:
@ -347,6 +427,12 @@ int appmessage_serialize(AppMessage * message, Buffer * buffer)
} }
} }
static int _serialize_acknowledgement(AppMessage * message, Buffer * buffer,
Buffer * b)
{
return _serialize_id(message, buffer, b);
}
static int _serialize_append(Buffer * buffer, Buffer * b) static int _serialize_append(Buffer * buffer, Buffer * b)
{ {
return buffer_set_data(buffer, buffer_get_size(buffer), return buffer_set_data(buffer, buffer_get_size(buffer),
@ -359,6 +445,8 @@ static int _serialize_call(AppMessage * message, Buffer * buffer, Buffer * b)
Variable * v; Variable * v;
size_t i; size_t i;
if(_serialize_id(message, buffer, b) != 0)
return -1;
if((v = variable_new(VT_STRING, message->t.call.method)) == NULL) if((v = variable_new(VT_STRING, message->t.call.method)) == NULL)
return -1; return -1;
ret = (variable_serialize(v, b, 0) == 0 ret = (variable_serialize(v, b, 0) == 0
@ -377,3 +465,29 @@ static int _serialize_call(AppMessage * message, Buffer * buffer, Buffer * b)
buffer_delete(b); buffer_delete(b);
return (i == message->t.call.args_cnt) ? 0 : -1; return (i == message->t.call.args_cnt) ? 0 : -1;
} }
static int _serialize_id(AppMessage * message, Buffer * buffer, Buffer * b)
{
int ret;
Variable * v;
if((v = variable_new(VT_UINT32, &message->id)) == NULL)
return -1;
ret = (variable_serialize(v, b, 0) == 0
&& _serialize_append(buffer, b) == 0) ? 0 : -1;
variable_delete(v);
return ret;
}
static int _serialize_type(AppMessage * message, Buffer * buffer, Buffer * b)
{
int ret;
Variable * v;
if((v = variable_new(VT_UINT8, &message->type)) == NULL)
return -1;
ret = (variable_serialize(v, b, 0) == 0
&& _serialize_append(buffer, b) == 0) ? 0 : -1;
variable_delete(v);
return ret;
}

31
src/appmessage.h Normal file
View File

@ -0,0 +1,31 @@
/* $Id$ */
/* Copyright (c) 2014 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS System libApp */
/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef LIBAPP_SRC_APPMESSAGE_H
# define LIBAPP_SRC_APPMESSAGE_H
# include <stdint.h>
# include "App/appmessage.h"
/* AppMessage */
/* functions */
/* accessors */
AppMessageID appmessage_get_id(AppMessage * message);
void appmessage_set_id(AppMessage * message, AppMessageID id);
#endif /* !LIBAPP_SRC_APPMESSAGE_H */

View File

@ -5,7 +5,7 @@ cflags_force=-W -fPIC `pkg-config --cflags libSystem`
cflags=-Wall -g -O2 -pedantic cflags=-Wall -g -O2 -pedantic
ldflags_force=`pkg-config --libs libSystem` ldflags_force=`pkg-config --libs libSystem`
ldflags= ldflags=
dist=Makefile,appinterface.h,apptransport.h,common.h dist=Makefile,appinterface.h,appmessage.h,apptransport.h,common.h
[libApp] [libApp]
type=library type=library
@ -19,6 +19,9 @@ depends=appinterface.h,../include/App/appclient.h,common.h
[appinterface.c] [appinterface.c]
depends=../include/App/appserver.h,../config.h depends=../include/App/appserver.h,../config.h
[appmessage.c]
depends=../include/App/appmessage.h,appmessage.h
[apptransport.c] [apptransport.c]
depends=../include/App/appmessage.h,../config.h depends=../include/App/appmessage.h,../config.h