initial commit
basic functionalities are in, though some parts are missing
This commit is contained in:
parent
d105cd39b1
commit
8bde857aee
49 changed files with 2821 additions and 0 deletions
50
sml/Makefile
Normal file
50
sml/Makefile
Normal file
|
@ -0,0 +1,50 @@
|
|||
CFLAGS+=-I./include/ -fPIC -g -Wall
|
||||
|
||||
LIB_DIR=./lib
|
||||
OBJ_LIB=$(LIB_DIR)/libsml.o
|
||||
DYN_LIB=$(LIB_DIR)/libsml.so
|
||||
ST_LIB=$(LIB_DIR)/libsml.a
|
||||
|
||||
OBJS = \
|
||||
src/sml.o \
|
||||
src/sml_attention_response.o \
|
||||
src/sml_transport.o \
|
||||
src/sml_octet_string.o \
|
||||
src/sml_shared.o \
|
||||
src/sml_number.o \
|
||||
src/sml_message.o \
|
||||
src/sml_time.o \
|
||||
src/sml_list.o \
|
||||
src/sml_status.o \
|
||||
src/sml_value.o \
|
||||
src/sml_tree.o \
|
||||
src/sml_boolean.o \
|
||||
src/sml_crc16.o \
|
||||
src/sml_open_request.o \
|
||||
src/sml_open_response.o \
|
||||
src/sml_get_list_request.o \
|
||||
src/sml_get_list_response.o \
|
||||
src/sml_close_request.o \
|
||||
src/sml_close_response.o \
|
||||
src/sml_set_proc_parameter_request.o \
|
||||
src/sml_get_proc_parameter_request.o \
|
||||
src/sml_get_profile_pack_request.o \
|
||||
src/sml_get_profile_pack_response.o \
|
||||
|
||||
|
||||
libsml: $(DYN_LIB) $(ST_LIB) $(OBJ_LIB)
|
||||
|
||||
$(DYN_LIB): $(OBJS)
|
||||
$(LD) -shared -o $@ $^
|
||||
|
||||
$(OBJ_LIB): $(OBJS)
|
||||
$(LD) -r -o $@ $^
|
||||
|
||||
$(ST_LIB): $(OBJS)
|
||||
$(AR) -rs $@ $^
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -f src/*.o
|
||||
@rm -f $(LIB_DIR)/*.so $(LIB_DIR)/*.a $(LIB_DIR)/*.o
|
||||
|
34
sml/include/sml/sml.h
Normal file
34
sml/include/sml/sml.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#ifndef _SML_H
|
||||
#define _SML_H
|
||||
|
||||
#include "sml_message.h"
|
||||
#include "sml_shared.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
sml_message **messages;
|
||||
short messages_len;
|
||||
sml_buffer *buf;
|
||||
} sml_file;
|
||||
|
||||
// Parses a SML file.
|
||||
sml_file *sml_file_parse(unsigned char *buffer, size_t buffer_len);
|
||||
sml_file *sml_file_init();
|
||||
void sml_file_add_message(sml_file *file, sml_message *message);
|
||||
void sml_file_write(sml_file *file);
|
||||
void sml_file_free(sml_file *file);
|
||||
void sml_file_print(sml_file *file);
|
||||
|
||||
void mc_sml_hexdump(unsigned char *buffer, size_t buffer_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
31
sml/include/sml/sml_attention_response.h
Normal file
31
sml/include/sml/sml_attention_response.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
|
||||
#ifndef _SML_ATTENTION_RESPONSE_H
|
||||
#define _SML_ATTENTION_RESPONSE_H
|
||||
|
||||
#include "sml_shared.h"
|
||||
#include "sml_octet_string.h"
|
||||
#include "sml_tree.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
octet_string *server_id;
|
||||
octet_string *attention_number;
|
||||
octet_string *attention_message; // optional
|
||||
sml_tree *attention_details; // optional
|
||||
} sml_attention_response;
|
||||
|
||||
sml_attention_response *sml_attention_response_parse(sml_buffer *buf);
|
||||
|
||||
void sml_attention_response_free(sml_attention_response *msg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
23
sml/include/sml/sml_boolean.h
Normal file
23
sml/include/sml/sml_boolean.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef _SML_BOOLEAN_H
|
||||
#define _SML_BOOLEAN_H
|
||||
|
||||
#define SML_BOOLEAN_TRUE 0xFF
|
||||
#define SML_BOOLEAN_FALSE 0x00
|
||||
|
||||
#include "sml_shared.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef u8 sml_boolean;
|
||||
|
||||
sml_boolean sml_boolean_parse(sml_buffer *buf);
|
||||
void sml_boolean_write(sml_boolean boolean, sml_buffer *buf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
28
sml/include/sml/sml_close_request.h
Normal file
28
sml/include/sml/sml_close_request.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef _SML_CLOSE_REQUEST_H
|
||||
#define _SML_CLOSE_REQUEST_H
|
||||
|
||||
#include "sml_shared.h"
|
||||
#include "sml_octet_string.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
sml_signature *global_signature; // optional
|
||||
} sml_close_request;
|
||||
|
||||
sml_close_request *sml_close_request_init();
|
||||
|
||||
void sml_close_request_write(sml_close_request *msg, sml_buffer *buf);
|
||||
|
||||
sml_close_request * sml_close_request_parse(sml_buffer *buf);
|
||||
|
||||
void sml_close_request_free(sml_close_request *msg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
23
sml/include/sml/sml_close_response.h
Normal file
23
sml/include/sml/sml_close_response.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
|
||||
#ifndef _SML_CLOSE_RESPONSE_H
|
||||
#define _SML_CLOSE_RESPONSE_H
|
||||
|
||||
#include "sml_close_request.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef sml_close_request sml_close_response;
|
||||
|
||||
sml_close_response *sml_close_response_parse(sml_buffer *buf);
|
||||
|
||||
void sml_close_response_free(sml_close_response *msg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
22
sml/include/sml/sml_crc16.h
Normal file
22
sml/include/sml/sml_crc16.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#ifndef SML_CRC16_H_
|
||||
#define SML_CRC16_H_
|
||||
|
||||
#include "sml_shared.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// CRC16 FSC implementation based on DIN 62056-46
|
||||
u16 sml_crc16_calculate(unsigned char *cp, int len) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* SML_CRC16_H_ */
|
||||
|
||||
|
||||
|
39
sml/include/sml/sml_get_list_request.h
Normal file
39
sml/include/sml/sml_get_list_request.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
#ifndef _SML_GET_LIST_REQUEST_H
|
||||
#define _SML_GET_LIST_REQUEST_H
|
||||
|
||||
#include "sml_shared.h"
|
||||
#include "sml_octet_string.h"
|
||||
#include "sml_time.h"
|
||||
#include "sml_list.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
octet_string *client_id;
|
||||
octet_string *server_id; // optional
|
||||
octet_string *username; // optional
|
||||
octet_string *password; // optional
|
||||
octet_string *list_name; // optional
|
||||
|
||||
|
||||
} sml_get_list_request;
|
||||
|
||||
|
||||
|
||||
sml_get_list_request *sml_get_list_request_parse(sml_buffer *buf);
|
||||
|
||||
sml_get_list_request* sml_get_list_request_init();
|
||||
|
||||
void sml_get_list_request_write(sml_get_list_request *msg, sml_buffer *buf);
|
||||
|
||||
void sml_get_list_request_free(sml_get_list_request *msg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
33
sml/include/sml/sml_get_list_response.h
Normal file
33
sml/include/sml/sml_get_list_response.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
#ifndef _SML_GET_LIST_RESPONSE_H
|
||||
#define _SML_GET_LIST_RESPONSE_H
|
||||
|
||||
#include "sml_shared.h"
|
||||
#include "sml_octet_string.h"
|
||||
#include "sml_time.h"
|
||||
#include "sml_list.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
octet_string *client_id; // optional
|
||||
octet_string *server_id;
|
||||
octet_string *list_name; // optional
|
||||
sml_time *act_sensor_time; // optional
|
||||
sml_list *val_list;
|
||||
sml_signature *list_signature; // optional
|
||||
sml_time *act_gateway_time; // optional
|
||||
} sml_get_list_response;
|
||||
|
||||
sml_get_list_response *sml_get_list_response_parse(sml_buffer *buf);
|
||||
|
||||
void sml_get_list_response_free(sml_get_list_response *msg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
32
sml/include/sml/sml_get_proc_parameter_request.h
Normal file
32
sml/include/sml/sml_get_proc_parameter_request.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
#ifndef _SML_GET_PROC_PARAMETER_REQUEST_H
|
||||
#define _SML_GET_PROC_PARAMETER_REQUEST_H
|
||||
|
||||
#include "sml_shared.h"
|
||||
#include "sml_octet_string.h"
|
||||
#include "sml_tree.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
octet_string *server_id; // optional
|
||||
octet_string *username; // optional
|
||||
octet_string *password; // optional
|
||||
sml_tree_path *parameter_tree_path;
|
||||
sml_tree *parameter_tree;
|
||||
} sml_get_proc_parameter_request;
|
||||
|
||||
sml_get_proc_parameter_request *sml_get_proc_parameter_request_init();
|
||||
|
||||
void sml_get_proc_parameter_request_write(sml_get_proc_parameter_request *msg, sml_buffer *buf);
|
||||
|
||||
void sml_get_proc_parameter_request_free(sml_get_proc_parameter_request *msg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
42
sml/include/sml/sml_get_profile_pack_request.h
Normal file
42
sml/include/sml/sml_get_profile_pack_request.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
#ifndef _SML_GET_PROFILE_PACK_REQUEST_H
|
||||
#define _SML_GET_PROFILE_PACK_REQUEST_H
|
||||
|
||||
#include "sml_shared.h"
|
||||
#include "sml_octet_string.h"
|
||||
#include "sml_time.h"
|
||||
#include "sml_list.h"
|
||||
#include "sml_tree.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
octet_string *server_id; // optional
|
||||
octet_string *username; // optional
|
||||
octet_string *password; // optional
|
||||
sml_boolean with_rawdata; // optional
|
||||
sml_time *begin_time; // optional
|
||||
sml_time *end_time; // optional
|
||||
sml_tree_path *parameter_tree_path;
|
||||
// sml_object_list * object_list; // optional sml_object_list not implemented yet
|
||||
sml_tree *das_details; // optional
|
||||
} sml_get_profile_pack_request;
|
||||
|
||||
|
||||
sml_get_profile_pack_request *sml_get_profile_pack_request_parse(sml_buffer *buf);
|
||||
|
||||
sml_get_profile_pack_request *sml_get_profile_pack_request_init();
|
||||
|
||||
void sml_get_profile_pack_request_write(sml_get_profile_pack_request *msg, sml_buffer *buf);
|
||||
|
||||
void sml_get_profile_pack_request_free(sml_get_profile_pack_request *msg);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
36
sml/include/sml/sml_get_profile_pack_response.h
Normal file
36
sml/include/sml/sml_get_profile_pack_response.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
#ifndef _SML_GET_PROFILE_PACK_RESPONSE_H
|
||||
#define _SML_GET_PROFILE_PACK_RESPONSE_H
|
||||
|
||||
#include "sml_shared.h"
|
||||
#include "sml_octet_string.h"
|
||||
#include "sml_time.h"
|
||||
#include "sml_list.h"
|
||||
#include "sml_tree.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
octet_string *server_id;
|
||||
sml_time *act_time; // specified by germans (current time was meant) ;)
|
||||
u32 *reg_period;
|
||||
sml_tree_path *parameter_tree_path;
|
||||
sml_list *list_of_sml_prof_obj_header_entry;
|
||||
sml_list *list_of_sml_prof_obj_period_entry;
|
||||
octet_string *rawdata; // optional
|
||||
sml_signature *profile_signature; // optional
|
||||
|
||||
} sml_get_profile_pack_response;
|
||||
|
||||
sml_get_profile_pack_response *sml_get_profile_pack_response_parse(sml_buffer *buf);
|
||||
|
||||
void sml_get_profile_pack_response_free(sml_get_profile_pack_response *msg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
43
sml/include/sml/sml_list.h
Normal file
43
sml/include/sml/sml_list.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
|
||||
|
||||
#ifndef _SML_LIST_H
|
||||
#define _SML_LIST_H
|
||||
|
||||
#include "sml_time.h"
|
||||
#include "sml_octet_string.h"
|
||||
#include "sml_number.h"
|
||||
#include "sml_status.h"
|
||||
#include "sml_value.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct sml_list_entry {
|
||||
octet_string *obj_name;
|
||||
sml_status *status; // optional
|
||||
sml_time *val_time; // optional
|
||||
sml_unit unit; // optional
|
||||
i8 scaler; // optional
|
||||
sml_value *value;
|
||||
sml_signature *value_signature; // optional
|
||||
|
||||
// list specific
|
||||
struct sml_list_entry *next;
|
||||
} sml_list;
|
||||
|
||||
sml_list *sml_list_init();
|
||||
|
||||
void sml_list_write(sml_list *list, sml_buffer *buf);
|
||||
|
||||
sml_list *sml_list_parse(sml_buffer *buf);
|
||||
|
||||
void sml_list_free(sml_list *list);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
70
sml/include/sml/sml_message.h
Normal file
70
sml/include/sml/sml_message.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
|
||||
#ifndef _SML_MESSAGE_H
|
||||
#define _SML_MESSAGE_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "sml_octet_string.h"
|
||||
#include "sml_time.h"
|
||||
#include "sml_list.h"
|
||||
#include "sml_tree.h"
|
||||
|
||||
#include "sml_open_request.h"
|
||||
#include "sml_open_response.h"
|
||||
#include "sml_get_list_response.h"
|
||||
#include "sml_close_request.h"
|
||||
#include "sml_close_response.h"
|
||||
#include "sml_set_proc_parameter_request.h"
|
||||
|
||||
#define SML_MESSAGE_OPEN_REQUEST 0x00000100
|
||||
#define SML_MESSAGE_OPEN_RESPONSE 0x00000101
|
||||
#define SML_MESSAGE_CLOSE_REQUEST 0x00000200
|
||||
#define SML_MESSAGE_CLOSE_RESPONSE 0x00000201
|
||||
#define SML_MESSAGE_GET_PROFILE_PACK_REQUEST 0x00000300
|
||||
#define SML_MESSAGE_GET_PROFILE_PACK_RESPONSE 0x00000301
|
||||
#define SML_MESSAGE_GET_PROFILE_LIST_REQUEST 0x00000400
|
||||
#define SML_MESSAGE_GET_PROFILE_LIST_RESPONSE 0x00000401
|
||||
#define SML_MESSAGE_GET_PROC_PARAMETER_REQUEST 0x00000500
|
||||
#define SML_MESSAGE_GET_PROC_PARAMETER_RESPONSE 0x00000501
|
||||
#define SML_MESSAGE_SET_PROC_PARAMETER_REQUEST 0x00000600
|
||||
#define SML_MESSAGE_SET_PROC_PARAMETER_RESPONSE 0x00000601
|
||||
#define SML_MESSAGE_GET_LIST_REQUEST 0x00000700
|
||||
#define SML_MESSAGE_GET_LIST_RESPONSE 0x00000701
|
||||
#define SML_MESSAGE_ATTENTION_RESPONSE 0x0000FF01
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
u16 tag;
|
||||
void *data;
|
||||
} sml_message_body;
|
||||
|
||||
typedef struct {
|
||||
octet_string *transaction_id;
|
||||
u8 group_id;
|
||||
u8 abort_on_error;
|
||||
sml_message_body *message_body;
|
||||
u16 crc;
|
||||
/* end of message */
|
||||
} sml_message;
|
||||
|
||||
// SML MESSAGE
|
||||
sml_message *sml_message_parse(sml_buffer *buf);
|
||||
sml_message *sml_message_init(); // Sets a transaction id.
|
||||
void sml_message_free(sml_message *msg);
|
||||
void sml_message_write(sml_message *msg, sml_buffer *buf);
|
||||
|
||||
// SML_MESSAGE_BODY
|
||||
sml_message_body *sml_message_body_parse(sml_buffer *buf);
|
||||
sml_message_body *sml_message_body_init(u16 tag, void *data);
|
||||
void sml_message_body_free(sml_message_body *message_body);
|
||||
void sml_message_body_write(sml_message_body *message_body, sml_buffer *buf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
35
sml/include/sml/sml_number.h
Normal file
35
sml/include/sml/sml_number.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
|
||||
#ifndef _SML_NUMBER_H
|
||||
#define _SML_NUMBER_H
|
||||
|
||||
#include "sml_shared.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// Parses a number. Identified by type (SML_TYPE_INTEGER or SML_TYPE_UNSIGNED)
|
||||
// and maximal number of bytes (SML_TYPE_NUMBER_8, SML_TYPE_NUMBER_16,
|
||||
// SML_TYPE_NUMBER_32, SML_TYPE_NUMBER_64)
|
||||
u64 mc_sml_parse_number(sml_buffer *buf, unsigned char type, int max_size);
|
||||
|
||||
#define mc_sml_parse_u8(buf) (u8) mc_sml_parse_number(buf, SML_TYPE_UNSIGNED, SML_TYPE_NUMBER_8)
|
||||
#define mc_sml_parse_u16(buf) (u16) mc_sml_parse_number(buf, SML_TYPE_UNSIGNED, SML_TYPE_NUMBER_16)
|
||||
#define mc_sml_parse_u32(buf) (u32) mc_sml_parse_number(buf, SML_TYPE_UNSIGNED, SML_TYPE_NUMBER_32)
|
||||
#define mc_sml_parse_u64(buf) (u64) mc_sml_parse_number(buf, SML_TYPE_UNSIGNED, SML_TYPE_NUMBER_64)
|
||||
#define mc_sml_parse_i8(buf) (i8) mc_sml_parse_number(buf, SML_TYPE_INTEGER, SML_TYPE_NUMBER_8)
|
||||
#define mc_sml_parse_i16(buf) (i16) mc_sml_parse_number(buf, SML_TYPE_INTEGER, SML_TYPE_NUMBER_16)
|
||||
#define mc_sml_parse_i32(buf) (i32) mc_sml_parse_number(buf, SML_TYPE_INTEGER, SML_TYPE_NUMBER_32)
|
||||
#define mc_sml_parse_i64(buf) (i64) mc_sml_parse_number(buf, SML_TYPE_INTEGER, SML_TYPE_NUMBER_64)
|
||||
|
||||
void sml_number_write(unsigned char type, int size, u64 value, sml_buffer *buf);
|
||||
|
||||
typedef u8 sml_unit;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
41
sml/include/sml/sml_octet_string.h
Normal file
41
sml/include/sml/sml_octet_string.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
#ifndef _SML_OCTET_STRING_H
|
||||
#define _SML_OCTET_STRING_H
|
||||
|
||||
#include <string.h>
|
||||
#include "sml_shared.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned char *str;
|
||||
int len;
|
||||
} octet_string;
|
||||
|
||||
// sml signature
|
||||
typedef octet_string sml_signature;
|
||||
|
||||
octet_string *sml_octet_string_init(unsigned char *str, int length);
|
||||
|
||||
octet_string *sml_octet_string_init_from_hex(char *str);
|
||||
|
||||
void sml_octet_string_free(octet_string *str);
|
||||
|
||||
// Parses a octet string, updates the buffer accordingly, memory must be free'd elsewhere.
|
||||
octet_string *sml_octet_string_parse(sml_buffer *buf);
|
||||
|
||||
void sml_octet_string_write(octet_string *str, sml_buffer *buf);
|
||||
|
||||
int sml_octet_string_cmp_with_hex(octet_string *str, char *hex);
|
||||
|
||||
octet_string *sml_octet_string_generate_uuid();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
40
sml/include/sml/sml_open_request.h
Normal file
40
sml/include/sml/sml_open_request.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
#ifndef _SML_OPEN_REQUEST_H
|
||||
#define _SML_OPEN_REQUEST_H
|
||||
|
||||
#include "sml_shared.h"
|
||||
#include "sml_octet_string.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
octet_string *codepage; // optional
|
||||
octet_string *client_id;
|
||||
octet_string *req_file_id;
|
||||
octet_string *server_id; // optional
|
||||
octet_string *username; // optional
|
||||
octet_string *password; // optional
|
||||
u8 sml_version; // optional
|
||||
} sml_open_request;
|
||||
|
||||
//sml_open_request *sml_open_request_init();
|
||||
|
||||
//sml_open_request *sml_open_request_init(char* client_id,char* req_file_id, char* server_id);
|
||||
|
||||
sml_open_request *sml_open_request_init();
|
||||
|
||||
void sml_open_request_write(sml_open_request *msg, sml_buffer *buf);
|
||||
|
||||
sml_open_request *sml_open_request_parse(sml_buffer *buf);
|
||||
|
||||
void sml_open_request_free(sml_open_request *msg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
32
sml/include/sml/sml_open_response.h
Normal file
32
sml/include/sml/sml_open_response.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
|
||||
#ifndef _SML_OPEN_RESPONSE_H
|
||||
#define _SML_OPEN_RESPONSE_H
|
||||
|
||||
#include "sml_shared.h"
|
||||
#include "sml_octet_string.h"
|
||||
#include "sml_time.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
octet_string *codepage; // optional
|
||||
octet_string *client_id; // optional
|
||||
octet_string *req_file_id;
|
||||
octet_string *server_id;
|
||||
sml_time *ref_time; // optional
|
||||
u8 sml_version; // optional
|
||||
} sml_open_response;
|
||||
|
||||
sml_open_response *sml_open_response_parse(sml_buffer *buf);
|
||||
|
||||
void sml_open_response_free(sml_open_response *msg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
32
sml/include/sml/sml_set_proc_parameter_request.h
Normal file
32
sml/include/sml/sml_set_proc_parameter_request.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
#ifndef _SML_SET_PROC_PARAMETER_REQUEST_H
|
||||
#define _SML_SET_PROC_PARAMETER_REQUEST_H
|
||||
|
||||
#include "sml_shared.h"
|
||||
#include "sml_octet_string.h"
|
||||
#include "sml_tree.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
octet_string *server_id; // optional
|
||||
octet_string *username; // optional
|
||||
octet_string *password; // optional
|
||||
sml_tree_path *parameter_tree_path;
|
||||
sml_tree *parameter_tree;
|
||||
} sml_set_proc_parameter_request;
|
||||
|
||||
sml_set_proc_parameter_request *sml_set_proc_parameter_request_init();
|
||||
|
||||
void sml_set_proc_parameter_request_write(sml_set_proc_parameter_request *msg, sml_buffer *buf);
|
||||
|
||||
void sml_set_proc_parameter_request_free(sml_set_proc_parameter_request *msg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
101
sml/include/sml/sml_shared.h
Normal file
101
sml/include/sml/sml_shared.h
Normal file
|
@ -0,0 +1,101 @@
|
|||
#ifndef _SML_SHARED_H
|
||||
#define _SML_SHARED_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
typedef int8_t i8;
|
||||
typedef int16_t i16;
|
||||
typedef int32_t i32;
|
||||
typedef int64_t i64;
|
||||
|
||||
#define SML_ANOTHER_TL 0x80
|
||||
#define SML_TYPE_FIELD 0x70
|
||||
#define SML_LENGTH_FIELD 0xF
|
||||
#define SML_OPTIONAL_SKIPPED 0x1
|
||||
#define SML_MESSAGE_END 0x0
|
||||
|
||||
#define SML_TYPE_OCTET_STRING 0
|
||||
#define SML_TYPE_LIST 112
|
||||
#define SML_TYPE_BOOLEAN 64
|
||||
#define SML_TYPE_INTEGER 80
|
||||
#define SML_TYPE_UNSIGNED 96
|
||||
|
||||
#define SML_TYPE_NUMBER_8 sizeof(u8)
|
||||
#define SML_TYPE_NUMBER_16 sizeof(u16)
|
||||
#define SML_TYPE_NUMBER_32 sizeof(u32)
|
||||
#define SML_TYPE_NUMBER_64 sizeof(u64)
|
||||
|
||||
|
||||
// This sml_buffer is used in two different use-cases.
|
||||
//
|
||||
// Parsing: the raw data is in the buffer field,
|
||||
// the buffer_len is the number of raw bytes received,
|
||||
// the cursor points to the current position during parsing
|
||||
//
|
||||
// Writing: At the beginning the buffer field is malloced and zeroed with
|
||||
// a default length, this default length is stored in buffer_len
|
||||
// (i.e. the maximum bytes one can write to this buffer)
|
||||
// cursor points to the position, where on can write during the
|
||||
// writing process. If a file is completely written to the buffer,
|
||||
// cursor is the number of bytes written to the buffer.
|
||||
typedef struct {
|
||||
unsigned char *buffer;
|
||||
size_t buffer_len;
|
||||
int cursor;
|
||||
int error;
|
||||
char *error_msg;
|
||||
} sml_buffer;
|
||||
|
||||
sml_buffer *sml_buffer_init(size_t length);
|
||||
|
||||
void sml_buffer_free(sml_buffer *buf);
|
||||
|
||||
// Returns the length of the following data structure. Sets the cursor position to
|
||||
// the value field.
|
||||
int mc_sml_get_length(sml_buffer *buf);
|
||||
|
||||
void mc_sml_set_type_and_length(sml_buffer *buf, unsigned int type, unsigned int l);
|
||||
|
||||
// Checks if a error is occured.
|
||||
int mc_sml_buf_has_errors(sml_buffer *buf);
|
||||
|
||||
|
||||
// Returns the type field of the current byte.
|
||||
int mc_sml_buf_get_current_type(sml_buffer *buf);
|
||||
|
||||
// Returns the current byte.
|
||||
unsigned char mc_sml_buf_get_current_byte(sml_buffer *buf);
|
||||
|
||||
|
||||
// Returns a pointer to the current buffer position.
|
||||
unsigned char *mc_sml_buf_get_current_buf(sml_buffer *buf);
|
||||
|
||||
void mc_sml_optional_write(sml_buffer *buf);
|
||||
|
||||
// Sets the number of bytes read (moves the cursor forward)
|
||||
void mc_sml_buf_update_read_bytes(sml_buffer *buf, int bytes);
|
||||
|
||||
// Checks if the next field is a skipped optional field, updates the buffer accordingly
|
||||
int mc_sml_is_optional_skipped(sml_buffer *buf);
|
||||
#define SML_SKIP_OPTIONAL (mc_sml_is_optional_skipped(buf)) ? 0 :
|
||||
|
||||
void hexdump(unsigned char *buffer, size_t buffer_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
26
sml/include/sml/sml_status.h
Normal file
26
sml/include/sml/sml_status.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef _SML_STATUS_H
|
||||
#define _SML_STATUS_H
|
||||
|
||||
#include "sml_number.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef union {
|
||||
u8 status8;
|
||||
u16 status16;
|
||||
u32 status32;
|
||||
u64 status64;
|
||||
} sml_status;
|
||||
|
||||
sml_status *sml_status_parse(sml_buffer *buf);
|
||||
|
||||
void sml_status_free(sml_status *status);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
25
sml/include/sml/sml_time.h
Normal file
25
sml/include/sml/sml_time.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
#ifndef _SML_TIME_H
|
||||
#define _SML_TIME_H
|
||||
|
||||
#include "sml_shared.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
u8 tag;
|
||||
u32 data;
|
||||
} sml_time;
|
||||
|
||||
// Parses a time, updates the buffer accordingly, memory must be free'd elsewhere.
|
||||
sml_time *sml_time_parse(sml_buffer *buf);
|
||||
void sml_time_write(sml_time *time, sml_buffer *buf);
|
||||
void sml_time_free(sml_time *time);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
19
sml/include/sml/sml_transport.h
Normal file
19
sml/include/sml/sml_transport.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef _SML_TRANSPORT_H
|
||||
#define _SML_TRANSPORT_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
//void (*mc_sml_transport_receiver_fun)(unsigned char *buffer, size_t buffer_len) = 0;
|
||||
|
||||
void mc_sml_transport_listen(int fd, void (*mc_sml_transport_receiver)(unsigned char *buffer, size_t buffer_len));
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
64
sml/include/sml/sml_tree.h
Normal file
64
sml/include/sml/sml_tree.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
#ifndef _SML_TREE_H
|
||||
#define _SML_TREE_H
|
||||
|
||||
#include "sml_shared.h"
|
||||
#include "sml_octet_string.h"
|
||||
#include "sml_value.h"
|
||||
#include "sml_time.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define SML_PROC_PAR_VALUE_TAG_VALUE 0x01
|
||||
#define SML_PROC_PAR_VALUE_TAG_PERIOD_ENTRY 0x02
|
||||
#define SML_PROC_PAR_VALUE_TAG_TUPEL_ENTRY 0x03
|
||||
#define SML_PROC_PAR_VALUE_TAG_TIME 0x04
|
||||
|
||||
|
||||
// TODO
|
||||
typedef struct {
|
||||
u8 tag;
|
||||
union {
|
||||
sml_value *value;
|
||||
// sml_period_entry
|
||||
// sml_tupel_entry
|
||||
sml_time *time;
|
||||
} data;
|
||||
} sml_proc_par_value;
|
||||
|
||||
typedef struct {
|
||||
octet_string **path_entries;
|
||||
int path_entries_len;
|
||||
} sml_tree_path;
|
||||
|
||||
typedef struct s_tree{
|
||||
octet_string *parameter_name;
|
||||
sml_proc_par_value *parameter_value; // optional
|
||||
struct s_tree **child_list; // optional
|
||||
int child_list_len;
|
||||
} sml_tree;
|
||||
|
||||
// SML_TREE_PATH
|
||||
sml_tree_path *sml_tree_path_init();
|
||||
void sml_tree_path_add_path_entry(sml_tree_path *tree_path, octet_string *entry);
|
||||
void sml_tree_path_write(sml_tree_path *tree_path, sml_buffer *buf);
|
||||
void sml_tree_path_free(sml_tree_path *tree_path);
|
||||
|
||||
// SML_TREE
|
||||
sml_tree *sml_tree_init(octet_string *parameter_name);
|
||||
void sml_tree_write(sml_tree *tree, sml_buffer *buf);
|
||||
sml_tree *sml_tree_parse(sml_buffer *buf);
|
||||
void sml_tree_free(sml_tree *tree);
|
||||
|
||||
// SML_PROC_PAR_VALUE
|
||||
sml_proc_par_value *sml_proc_par_value_init(u8 tag, void *data);
|
||||
void sml_proc_par_value_write(sml_proc_par_value *value, sml_buffer *buf);
|
||||
void sml_proc_par_value_free(sml_proc_par_value *value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
39
sml/include/sml/sml_value.h
Normal file
39
sml/include/sml/sml_value.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
#ifndef _SML_VALUE_H
|
||||
#define _SML_VALUE_H
|
||||
|
||||
#include "sml_shared.h"
|
||||
#include "sml_octet_string.h"
|
||||
#include "sml_number.h"
|
||||
#include "sml_boolean.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
u8 type;
|
||||
union {
|
||||
sml_boolean boolean;
|
||||
octet_string *bytes; // can has zero length
|
||||
i8 int8;
|
||||
i16 int16;
|
||||
i32 int32;
|
||||
i64 int64;
|
||||
u8 uint8;
|
||||
u16 uint16;
|
||||
u32 uint32;
|
||||
u64 uint64;
|
||||
} data;
|
||||
} sml_value;
|
||||
|
||||
sml_value *sml_value_parse(sml_buffer *buf);
|
||||
void sml_value_write(sml_value *value, sml_buffer *buf);
|
||||
sml_value *sml_value_init();
|
||||
void sml_value_free(sml_value *value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
133
sml/src/sml.c
Normal file
133
sml/src/sml.c
Normal file
|
@ -0,0 +1,133 @@
|
|||
|
||||
#include <sml/sml.h>
|
||||
#include <sml/sml_shared.h>
|
||||
#include <sml/sml_message.h>
|
||||
#include <sml/sml_number.h>
|
||||
#include <sml/sml_time.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
// EDL meter must provide at least 250 bytes as a receive buffer
|
||||
#define SML_FILE_BUFFER_LENGTH 512
|
||||
|
||||
/*
|
||||
void mc_sml_hexdump_rest(sml_buffer *buf) {
|
||||
int i;
|
||||
unsigned char *rest = mc_sml_buf_get_current_buf(buf);
|
||||
for (i = 0; i < buf->buffer_len - buf->cursor; i++) {
|
||||
printf("%02X ", (unsigned char) rest[i]);
|
||||
if ((i + 1) % 8 == 0) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
*/
|
||||
|
||||
void mc_sml_hexdump(unsigned char *buffer, size_t buffer_len) {
|
||||
printf("SML dump (%zu bytes)\n", buffer_len);
|
||||
hexdump(buffer, buffer_len);
|
||||
}
|
||||
|
||||
sml_file *sml_file_parse(unsigned char *buffer, size_t buffer_len) {
|
||||
|
||||
//buffer += 8;
|
||||
//buffer_len -= 16;
|
||||
sml_file *file = (sml_file*) malloc(sizeof(sml_file));
|
||||
memset(file, 0, sizeof(sml_file));
|
||||
|
||||
sml_buffer *buf = sml_buffer_init(buffer_len);
|
||||
memcpy(buf->buffer, buffer, buffer_len);
|
||||
file->buf = buf;
|
||||
|
||||
sml_message *msg;
|
||||
|
||||
// parsing all messages
|
||||
for (; buf->cursor < buf->buffer_len;) {
|
||||
|
||||
if(mc_sml_buf_get_current_byte(buf) == SML_MESSAGE_END) {
|
||||
// reading trailing zeroed bytes
|
||||
mc_sml_buf_update_read_bytes(buf, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
msg = sml_message_parse(buf);
|
||||
|
||||
if (mc_sml_buf_has_errors(buf)) {
|
||||
printf("warning: could not read the whole file\n");
|
||||
break;
|
||||
}
|
||||
|
||||
sml_file_add_message(file, msg);
|
||||
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
sml_file *sml_file_init() {
|
||||
sml_file *file = (sml_file*) malloc(sizeof(sml_file));
|
||||
memset(file, 0, sizeof(sml_file));
|
||||
|
||||
sml_buffer *buf = sml_buffer_init(SML_FILE_BUFFER_LENGTH);
|
||||
file->buf = buf;
|
||||
return file;
|
||||
}
|
||||
|
||||
void sml_file_add_message(sml_file *file, sml_message *message) {
|
||||
file->messages_len++;
|
||||
file->messages = (sml_message **) realloc(file->messages, sizeof(sml_message *) * file->messages_len);
|
||||
file->messages[file->messages_len - 1] = message;
|
||||
}
|
||||
|
||||
void sml_file_write(sml_file *file) {
|
||||
|
||||
int i;
|
||||
if (file->messages && file->messages_len > 0) {
|
||||
for (i = 0; i < file->messages_len; i++) {
|
||||
sml_message_write(file->messages[i], file->buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sml_file_free(sml_file *file) {
|
||||
if (file) {
|
||||
|
||||
if (file->messages) {
|
||||
int i;
|
||||
for (i = 0; i < file->messages_len; i++) {
|
||||
sml_message_free(file->messages[i]);
|
||||
}
|
||||
free(file->messages);
|
||||
}
|
||||
|
||||
if (file->buf) {
|
||||
sml_buffer_free(file->buf);
|
||||
}
|
||||
|
||||
free(file);
|
||||
}
|
||||
}
|
||||
|
||||
void sml_file_print(sml_file *file) {
|
||||
int i;
|
||||
printf("SML file (%d SML messages, %d bytes)\n", file->messages_len, file->buf->cursor);
|
||||
for (i = 0; i < file->messages_len; i++) {
|
||||
printf("SML message %4.X\n", file->messages[i]->message_body->tag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
47
sml/src/sml_attention_response.c
Normal file
47
sml/src/sml_attention_response.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
|
||||
#include <sml/sml_attention_response.h>
|
||||
#include <sml/sml_tree.h>
|
||||
|
||||
sml_attention_response *sml_attention_response_parse(sml_buffer *buf){
|
||||
sml_attention_response *msg = (sml_attention_response *) malloc(sizeof(sml_attention_response));
|
||||
memset(msg, 0, sizeof(sml_attention_response));
|
||||
|
||||
if (mc_sml_buf_get_current_type(buf) != SML_TYPE_LIST) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (mc_sml_get_length(buf) != 4) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
msg->server_id = sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->attention_number = sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->attention_message = SML_SKIP_OPTIONAL sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->attention_details = SML_SKIP_OPTIONAL sml_tree_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
return msg;
|
||||
|
||||
error:
|
||||
free(msg);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void sml_attention_response_free(sml_attention_response *msg){
|
||||
if (msg) {
|
||||
sml_octet_string_free(msg->server_id);
|
||||
sml_octet_string_free(msg->attention_number);
|
||||
sml_octet_string_free(msg->attention_message);
|
||||
sml_tree_free(msg->attention_details);
|
||||
free(msg);
|
||||
}
|
||||
}
|
22
sml/src/sml_boolean.c
Normal file
22
sml/src/sml_boolean.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
#include <sml/sml_boolean.h>
|
||||
#include <stdio.h>
|
||||
|
||||
sml_boolean sml_boolean_parse(sml_buffer *buf) {
|
||||
printf("NYI: %s\n", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sml_boolean_write(sml_boolean boolean, sml_buffer *buf) {
|
||||
mc_sml_set_type_and_length(buf, SML_TYPE_BOOLEAN, 1);
|
||||
if (boolean == SML_BOOLEAN_FALSE) {
|
||||
buf->buffer[buf->cursor] = SML_BOOLEAN_FALSE;
|
||||
}
|
||||
else {
|
||||
buf->buffer[buf->cursor] = SML_BOOLEAN_TRUE;
|
||||
}
|
||||
buf->cursor++;
|
||||
}
|
||||
|
||||
|
||||
|
52
sml/src/sml_close_request.c
Normal file
52
sml/src/sml_close_request.c
Normal file
|
@ -0,0 +1,52 @@
|
|||
|
||||
#include <sml/sml_close_request.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
sml_close_request *sml_close_request_init() {
|
||||
sml_close_request *close_request = (sml_close_request *) malloc(sizeof(sml_close_request));
|
||||
memset(close_request, 0, sizeof(sml_close_request));
|
||||
return close_request;
|
||||
}
|
||||
|
||||
void sml_close_request_write(sml_close_request *msg, sml_buffer *buf) {
|
||||
mc_sml_set_type_and_length(buf, SML_TYPE_LIST, 1);
|
||||
|
||||
if (msg->global_signature != NULL){
|
||||
sml_octet_string_write(msg->global_signature,buf);
|
||||
} else mc_sml_optional_write(buf);
|
||||
}
|
||||
|
||||
sml_close_request * sml_close_request_parse(sml_buffer *buf) {
|
||||
sml_close_request *msg = (sml_close_request *) malloc(sizeof(sml_close_request));
|
||||
memset(msg, 0, sizeof(sml_close_request));
|
||||
|
||||
if (mc_sml_buf_get_current_type(buf) != SML_TYPE_LIST) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (mc_sml_get_length(buf) != 1) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
msg->global_signature = SML_SKIP_OPTIONAL sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
return msg;
|
||||
|
||||
error:
|
||||
free(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sml_close_request_free(sml_close_request *msg) {
|
||||
if (msg) {
|
||||
sml_octet_string_free(msg->global_signature);
|
||||
free(msg);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
36
sml/src/sml_close_response.c
Normal file
36
sml/src/sml_close_response.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
|
||||
#include <sml/sml_close_response.h>
|
||||
#include <stdio.h>
|
||||
|
||||
sml_close_response *sml_close_response_parse(sml_buffer *buf) {
|
||||
|
||||
sml_close_response *msg = (sml_close_response *) malloc(sizeof(sml_close_response));
|
||||
memset(msg, 0, sizeof(sml_close_response));
|
||||
|
||||
if (mc_sml_buf_get_current_type(buf) != SML_TYPE_LIST) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (mc_sml_get_length(buf) != 1) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
msg->global_signature = SML_SKIP_OPTIONAL sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
return msg;
|
||||
|
||||
error:
|
||||
free(msg);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void sml_close_response_free(sml_close_response *msg) {
|
||||
if (msg) {
|
||||
sml_octet_string_free(msg->global_signature);
|
||||
free(msg);
|
||||
}
|
||||
}
|
39
sml/src/sml_crc16.c
Normal file
39
sml/src/sml_crc16.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
|
||||
#include <sml/sml_crc16.h>
|
||||
|
||||
#define PPPINITFCS16 0xffff // initial FCS value
|
||||
|
||||
// table taken from DIN EN 62056-46
|
||||
static u16 fcstab [256] = { 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48,
|
||||
0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c,
|
||||
0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210,
|
||||
0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
|
||||
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef,
|
||||
0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 0xce4c, 0xdfc5,
|
||||
0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3,
|
||||
0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 0x728f, 0x4014, 0x519d,
|
||||
0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 0x7387,
|
||||
0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862,
|
||||
0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52,
|
||||
0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
|
||||
0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e,
|
||||
0xf2a7, 0xc03c, 0xd1b5, 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402,
|
||||
0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5,
|
||||
0x4d7c, 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df,
|
||||
0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5,
|
||||
0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3,
|
||||
0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d,
|
||||
0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
|
||||
};
|
||||
|
||||
u16 sml_crc16_calculate(unsigned char *cp, int len) {
|
||||
u16 fcs = PPPINITFCS16;
|
||||
while (len--) {
|
||||
fcs = (fcs >> 8) ^ fcstab[(fcs ^ *cp++) & 0xff];
|
||||
}
|
||||
fcs ^= 0xffff;
|
||||
fcs = ((fcs & 0xff) << 8) | ((fcs & 0xff00) >> 8);
|
||||
return fcs;
|
||||
}
|
||||
|
||||
|
88
sml/src/sml_get_list_request.c
Normal file
88
sml/src/sml_get_list_request.c
Normal file
|
@ -0,0 +1,88 @@
|
|||
|
||||
#include <sml/sml_get_list_request.h>
|
||||
#include <stdio.h>
|
||||
|
||||
sml_get_list_request* sml_get_list_request_init(){
|
||||
sml_get_list_request *msg = (sml_get_list_request *) malloc(sizeof(sml_get_list_request));
|
||||
memset(msg, 0, sizeof(sml_get_list_request));
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
void sml_get_list_request_write(sml_get_list_request *msg, sml_buffer *buf) {
|
||||
mc_sml_set_type_and_length(buf, SML_TYPE_LIST, 5);
|
||||
|
||||
sml_octet_string_write(msg->client_id, buf);
|
||||
|
||||
// optional server_id
|
||||
if (msg->server_id != NULL){
|
||||
sml_octet_string_write(msg->server_id, buf);
|
||||
} else mc_sml_optional_write(buf);
|
||||
|
||||
// optional username
|
||||
if (msg->username != NULL){
|
||||
sml_octet_string_write(msg->username, buf);
|
||||
} else mc_sml_optional_write(buf);
|
||||
|
||||
// optional password
|
||||
if (msg->password != NULL){
|
||||
sml_octet_string_write(msg->password, buf);
|
||||
} else mc_sml_optional_write(buf);
|
||||
|
||||
// optional list_name
|
||||
if (msg->list_name != NULL){
|
||||
sml_octet_string_write(msg->list_name,buf);
|
||||
} else mc_sml_optional_write(buf);
|
||||
|
||||
}
|
||||
|
||||
|
||||
sml_get_list_request *sml_get_list_request_parse(sml_buffer *buf) {
|
||||
|
||||
sml_get_list_request *msg = (sml_get_list_request *) malloc(sizeof(sml_get_list_request));
|
||||
memset(msg, 0, sizeof(sml_get_list_request));
|
||||
|
||||
if (mc_sml_buf_get_current_type(buf) != SML_TYPE_LIST) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (mc_sml_get_length(buf) != 5) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
msg->client_id = SML_SKIP_OPTIONAL sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->server_id = sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->username = SML_SKIP_OPTIONAL sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->password = SML_SKIP_OPTIONAL sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->list_name = SML_SKIP_OPTIONAL sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
return msg;
|
||||
|
||||
error:
|
||||
free(msg);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void sml_get_list_request_free(sml_get_list_request *msg) {
|
||||
if (msg) {
|
||||
sml_octet_string_free(msg->client_id);
|
||||
sml_octet_string_free(msg->server_id);
|
||||
sml_octet_string_free(msg->list_name);
|
||||
sml_octet_string_free(msg->username);
|
||||
sml_octet_string_free(msg->password);
|
||||
free(msg);
|
||||
}
|
||||
}
|
61
sml/src/sml_get_list_response.c
Normal file
61
sml/src/sml_get_list_response.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
|
||||
#include <sml/sml_get_list_response.h>
|
||||
|
||||
|
||||
sml_get_list_response *sml_get_list_response_parse(sml_buffer *buf) {
|
||||
|
||||
|
||||
sml_get_list_response *msg = (sml_get_list_response *) malloc(sizeof(sml_get_list_response));
|
||||
memset(msg, 0, sizeof(sml_get_list_response));
|
||||
|
||||
if (mc_sml_buf_get_current_type(buf) != SML_TYPE_LIST) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (mc_sml_get_length(buf) != 7) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
msg->client_id = SML_SKIP_OPTIONAL sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->server_id = sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->list_name = SML_SKIP_OPTIONAL sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->act_sensor_time = SML_SKIP_OPTIONAL sml_time_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->val_list = sml_list_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->list_signature = SML_SKIP_OPTIONAL sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->act_gateway_time = SML_SKIP_OPTIONAL sml_time_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
return msg;
|
||||
|
||||
error:
|
||||
free(msg);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void sml_get_list_response_free(sml_get_list_response *msg) {
|
||||
if (msg) {
|
||||
sml_octet_string_free(msg->client_id);
|
||||
sml_octet_string_free(msg->server_id);
|
||||
sml_octet_string_free(msg->list_name);
|
||||
sml_time_free(msg->act_sensor_time);
|
||||
sml_list_free(msg->val_list);
|
||||
sml_octet_string_free(msg->list_signature);
|
||||
sml_time_free(msg->act_gateway_time);
|
||||
free(msg);
|
||||
}
|
||||
}
|
45
sml/src/sml_get_proc_parameter_request.c
Normal file
45
sml/src/sml_get_proc_parameter_request.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
|
||||
|
||||
#include <sml/sml_get_proc_parameter_request.h>
|
||||
#include <sml/sml_tree.h>
|
||||
#include <stdio.h>
|
||||
|
||||
sml_get_proc_parameter_request *sml_get_proc_parameter_request_init() {
|
||||
sml_get_proc_parameter_request *msg = (sml_get_proc_parameter_request *) malloc(sizeof (sml_get_proc_parameter_request));
|
||||
memset(msg, 0, sizeof(sml_get_proc_parameter_request));
|
||||
return msg;
|
||||
}
|
||||
|
||||
void sml_get_proc_parameter_request_write(sml_get_proc_parameter_request *msg, sml_buffer *buf) {
|
||||
mc_sml_set_type_and_length(buf, SML_TYPE_LIST, 5);
|
||||
|
||||
// optional server_id
|
||||
if (msg->server_id != NULL){
|
||||
sml_octet_string_write(msg->server_id, buf);
|
||||
} else mc_sml_optional_write(buf);
|
||||
|
||||
// optional username
|
||||
if (msg->username != NULL) {
|
||||
sml_octet_string_write(msg->username, buf);
|
||||
} else mc_sml_optional_write(buf);
|
||||
|
||||
// optional password
|
||||
if (msg->password != NULL){
|
||||
sml_octet_string_write(msg->password, buf);
|
||||
} else mc_sml_optional_write(buf);
|
||||
|
||||
sml_tree_path_write(msg->parameter_tree_path, buf);
|
||||
|
||||
sml_tree_write(msg->parameter_tree, buf);
|
||||
}
|
||||
|
||||
void sml_get_proc_parameter_request_free(sml_get_proc_parameter_request *msg) {
|
||||
if (msg){
|
||||
sml_octet_string_free(msg->server_id);
|
||||
sml_octet_string_free(msg->username);
|
||||
sml_octet_string_free(msg->password);
|
||||
sml_tree_path_free(msg->parameter_tree_path);
|
||||
sml_tree_free(msg->parameter_tree);
|
||||
free(msg);
|
||||
}
|
||||
}
|
106
sml/src/sml_get_profile_pack_request.c
Normal file
106
sml/src/sml_get_profile_pack_request.c
Normal file
|
@ -0,0 +1,106 @@
|
|||
|
||||
#include <sml/sml_get_profile_pack_request.h>
|
||||
#include <sml/sml_tree.h>
|
||||
#include <sml/sml_boolean.h>
|
||||
#include <sml/sml_time.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
|
||||
sml_get_profile_pack_request *sml_get_profile_pack_request_init(){
|
||||
sml_get_profile_pack_request *msg = (sml_get_profile_pack_request *) malloc(sizeof(sml_get_profile_pack_request));
|
||||
memset(msg, 0, sizeof(sml_get_profile_pack_request));
|
||||
msg->parameter_tree_path = sml_tree_path_init();
|
||||
return msg;
|
||||
}
|
||||
|
||||
void sml_get_profile_pack_request_write(sml_get_profile_pack_request *msg, sml_buffer *buf) {
|
||||
mc_sml_set_type_and_length(buf, SML_TYPE_LIST, 9);
|
||||
|
||||
// server_id
|
||||
if (msg->server_id != NULL) {
|
||||
sml_octet_string_write(msg->server_id,buf);
|
||||
} else mc_sml_optional_write(buf);
|
||||
|
||||
// username
|
||||
if (msg->username != NULL) {
|
||||
sml_octet_string_write(msg->username,buf);
|
||||
} else mc_sml_optional_write(buf);
|
||||
|
||||
// password
|
||||
if (msg->password != NULL) {
|
||||
sml_octet_string_write(msg->password,buf);
|
||||
} else mc_sml_optional_write(buf);
|
||||
|
||||
// with_rawdata
|
||||
if (msg->with_rawdata != NULL) {
|
||||
printf("TODO: %s - comparision is not valid", __FUNCTION__);
|
||||
sml_boolean_write(msg->with_rawdata,buf);
|
||||
} else mc_sml_optional_write(buf); // with_rawdata
|
||||
|
||||
// begin_time
|
||||
if (msg->begin_time != NULL){
|
||||
sml_time_write(msg->begin_time, buf);
|
||||
} else mc_sml_optional_write(buf); // begin_time
|
||||
mc_sml_optional_write(buf); // end_time
|
||||
|
||||
// parameter_tree_path is not optional
|
||||
sml_tree_path_write(msg->parameter_tree_path, buf);
|
||||
|
||||
mc_sml_optional_write(buf); // object_list
|
||||
mc_sml_optional_write(buf); // das_details
|
||||
printf("request_write");
|
||||
}
|
||||
|
||||
|
||||
sml_get_profile_pack_request *sml_get_profile_pack_request_parse(sml_buffer *buf) {
|
||||
|
||||
sml_get_profile_pack_request *msg = (sml_get_profile_pack_request *) malloc(sizeof(sml_get_profile_pack_request));
|
||||
memset(msg, 0, sizeof(sml_get_profile_pack_request));
|
||||
|
||||
if (mc_sml_buf_get_current_type(buf) != SML_TYPE_LIST) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (mc_sml_get_length(buf) != 9) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
printf("TODO:sml_get_profile_pack_request_parse -> not implemented yet");
|
||||
|
||||
/* msg->client_id = SML_SKIP_OPTIONAL sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->server_id = sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->list_name = SML_SKIP_OPTIONAL sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
*/
|
||||
/*msg->act_sensor_time = SML_SKIP_OPTIONAL sml_time_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->val_list = sml_list_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->list_signature = SML_SKIP_OPTIONAL sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->act_gateway_time = SML_SKIP_OPTIONAL sml_time_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
*/
|
||||
return msg;
|
||||
|
||||
error:
|
||||
free(msg);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void sml_get_profile_pack_request_free(sml_get_profile_pack_request *msg){
|
||||
printf("NYI: %s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
|
18
sml/src/sml_get_profile_pack_response.c
Normal file
18
sml/src/sml_get_profile_pack_response.c
Normal file
|
@ -0,0 +1,18 @@
|
|||
|
||||
#include <sml/sml_get_profile_pack_response.h>
|
||||
#include <sml/sml_shared.h>
|
||||
#include <sml/sml_octet_string.h>
|
||||
#include <sml/sml_time.h>
|
||||
#include <sml/sml_list.h>
|
||||
#include <sml/sml_tree.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
sml_get_profile_pack_response *sml_get_profile_pack_response_parse(sml_buffer *buf){
|
||||
printf("NYI: %s\n", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sml_get_profile_pack_response_free(sml_get_profile_pack_response *msg){
|
||||
printf("NYI: %s\n", __FUNCTION__);
|
||||
}
|
114
sml/src/sml_list.c
Normal file
114
sml/src/sml_list.c
Normal file
|
@ -0,0 +1,114 @@
|
|||
|
||||
#include <sml/sml_list.h>
|
||||
#include <sml/sml_shared.h>
|
||||
#include <sml/sml_time.h>
|
||||
#include <sml/sml_octet_string.h>
|
||||
#include <sml/sml_status.h>
|
||||
#include <sml/sml_value.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
|
||||
|
||||
sml_list *sml_list_init(){
|
||||
sml_list *s = (sml_list *)malloc(sizeof(sml_list));
|
||||
memset(s, 0, sizeof(sml_list));
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
sml_list *sml_list_parse(sml_buffer *buf) {
|
||||
int elems, i;
|
||||
if (mc_sml_buf_get_current_type(buf) != SML_TYPE_LIST) {
|
||||
buf->error = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
elems = mc_sml_get_length(buf);
|
||||
sml_list *start = 0;
|
||||
sml_list *cur = 0;
|
||||
sml_list *tmp;
|
||||
|
||||
for (i = 0; i < elems; i++) {
|
||||
|
||||
if (mc_sml_buf_get_current_type(buf) != SML_TYPE_LIST) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (mc_sml_get_length(buf) != 7) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
tmp = (sml_list *) malloc(sizeof(sml_list));
|
||||
if (i == 0) {
|
||||
start = tmp;
|
||||
cur = tmp;
|
||||
}
|
||||
else {
|
||||
cur->next = tmp;
|
||||
cur = tmp;
|
||||
}
|
||||
|
||||
cur->obj_name = sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
cur->status = SML_SKIP_OPTIONAL sml_status_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
cur->val_time = SML_SKIP_OPTIONAL sml_time_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
cur->unit = SML_SKIP_OPTIONAL mc_sml_parse_u8(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
cur->scaler = SML_SKIP_OPTIONAL mc_sml_parse_i8(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
cur->value = SML_SKIP_OPTIONAL sml_value_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
cur->value_signature = SML_SKIP_OPTIONAL sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
cur->next = 0;
|
||||
}
|
||||
return start;
|
||||
|
||||
error:
|
||||
buf->error = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sml_list_write(sml_list *list, sml_buffer *buf){
|
||||
mc_sml_set_type_and_length(buf, SML_TYPE_LIST, 1);
|
||||
mc_sml_optional_write(buf);
|
||||
//
|
||||
}
|
||||
|
||||
void sml_list_entry_free(sml_list *list) {
|
||||
if (list) {
|
||||
sml_octet_string_free(list->obj_name);
|
||||
sml_status_free(list->status);
|
||||
sml_time_free(list->val_time);
|
||||
sml_value_free(list->value);
|
||||
sml_octet_string_free(list->value_signature);
|
||||
free(list);
|
||||
}
|
||||
}
|
||||
|
||||
void sml_list_free(sml_list *list) {
|
||||
if (list) {
|
||||
sml_list *f = list;
|
||||
sml_list *n = list->next;
|
||||
|
||||
while(f) {
|
||||
sml_list_entry_free(f);
|
||||
f = n;
|
||||
if (f) {
|
||||
n = f->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
221
sml/src/sml_message.c
Normal file
221
sml/src/sml_message.c
Normal file
|
@ -0,0 +1,221 @@
|
|||
|
||||
#include <sml/sml_message.h>
|
||||
#include <sml/sml_number.h>
|
||||
#include <sml/sml_octet_string.h>
|
||||
#include <sml/sml_shared.h>
|
||||
#include <sml/sml_list.h>
|
||||
#include <sml/sml_time.h>
|
||||
#include <sml/sml_crc16.h>
|
||||
#include <sml/sml_get_proc_parameter_request.h>
|
||||
#include <sml/sml_set_proc_parameter_request.h>
|
||||
#include <sml/sml_get_profile_pack_request.h>
|
||||
#include <sml/sml_get_list_request.h>
|
||||
#include <sml/sml_get_list_response.h>
|
||||
#include <sml/sml_attention_response.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define SML_MESSAGE_TRANSACTION_MAGIC_NUMBER 0x6F4D654E
|
||||
|
||||
// SML MESSAGE
|
||||
|
||||
sml_message *sml_message_parse(sml_buffer *buf) {
|
||||
sml_message *msg = (sml_message *) malloc(sizeof(sml_message));
|
||||
memset(msg, 0, sizeof(sml_message));
|
||||
|
||||
if (mc_sml_buf_get_current_type(buf) != SML_TYPE_LIST) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (mc_sml_get_length(buf) != 6) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
msg->transaction_id = sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->group_id = mc_sml_parse_u8(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->abort_on_error = mc_sml_parse_u8(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->message_body = sml_message_body_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->crc = mc_sml_parse_u16(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
if (mc_sml_buf_get_current_byte(buf) == SML_MESSAGE_END) {
|
||||
mc_sml_buf_update_read_bytes(buf, 1);
|
||||
}
|
||||
return msg;
|
||||
|
||||
error:
|
||||
// TODO: free encapsulated stuff
|
||||
free(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sml_message *sml_message_init() {
|
||||
sml_message *msg = (sml_message *) malloc(sizeof(sml_message));
|
||||
memset(msg, 0, sizeof(sml_message));
|
||||
|
||||
int id = ((unsigned int) getpid()) | SML_MESSAGE_TRANSACTION_MAGIC_NUMBER;
|
||||
msg->transaction_id = sml_octet_string_init((unsigned char *)&id, sizeof(int));
|
||||
|
||||
return msg;
|
||||
}
|
||||
void sml_message_free(sml_message *msg) {
|
||||
if (msg) {
|
||||
if (msg->transaction_id)
|
||||
sml_octet_string_free(msg->transaction_id);
|
||||
if (msg->message_body)
|
||||
sml_message_body_free(msg->message_body);
|
||||
free(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void sml_message_write(sml_message *msg, sml_buffer *buf) {
|
||||
int msg_start = buf->cursor;
|
||||
mc_sml_set_type_and_length(buf, SML_TYPE_LIST, 6);
|
||||
sml_octet_string_write(msg->transaction_id, buf);
|
||||
sml_number_write(SML_TYPE_UNSIGNED, SML_TYPE_NUMBER_8, (u64) msg->group_id, buf);
|
||||
sml_number_write(SML_TYPE_UNSIGNED, SML_TYPE_NUMBER_8, (u64) msg->abort_on_error, buf);
|
||||
sml_message_body_write(msg->message_body, buf);
|
||||
|
||||
msg->crc = sml_crc16_calculate(&(buf->buffer[msg_start]), buf->cursor - msg_start);
|
||||
|
||||
sml_number_write(SML_TYPE_UNSIGNED, SML_TYPE_NUMBER_16, (u64) msg->crc, buf);
|
||||
|
||||
// end of message
|
||||
buf->buffer[buf->cursor] = 0x0;
|
||||
buf->cursor++;
|
||||
}
|
||||
|
||||
// SML MESSAGE BODY
|
||||
|
||||
sml_message_body *sml_message_body_parse(sml_buffer *buf) {
|
||||
sml_message_body *msg_body = (sml_message_body *) malloc(sizeof(sml_message_body));
|
||||
memset(msg_body, 0, sizeof(sml_message_body));
|
||||
|
||||
if (mc_sml_buf_get_current_type(buf) != SML_TYPE_LIST) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (mc_sml_get_length(buf) != 2) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
msg_body->tag = mc_sml_parse_u16(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
switch (msg_body->tag) {
|
||||
case SML_MESSAGE_OPEN_REQUEST:
|
||||
msg_body->data = sml_open_request_parse(buf);
|
||||
break;
|
||||
case SML_MESSAGE_OPEN_RESPONSE:
|
||||
msg_body->data = sml_open_response_parse(buf);
|
||||
break;
|
||||
case SML_MESSAGE_CLOSE_REQUEST:
|
||||
msg_body->data = sml_close_request_parse(buf);
|
||||
break;
|
||||
case SML_MESSAGE_CLOSE_RESPONSE:
|
||||
msg_body->data = sml_close_response_parse(buf);
|
||||
break;
|
||||
case SML_MESSAGE_GET_LIST_RESPONSE:
|
||||
msg_body->data = sml_get_list_response_parse(buf);
|
||||
break;
|
||||
case SML_MESSAGE_GET_LIST_REQUEST:
|
||||
msg_body->data = sml_get_list_request_parse(buf);
|
||||
break;
|
||||
case SML_MESSAGE_ATTENTION_RESPONSE:
|
||||
msg_body->data = sml_attention_response_parse(buf);
|
||||
break;
|
||||
default:
|
||||
printf("error: message type %04X not yet implemented\n", msg_body->tag);
|
||||
break;
|
||||
}
|
||||
|
||||
return msg_body;
|
||||
|
||||
error:
|
||||
free(msg_body);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sml_message_body *sml_message_body_init(u16 tag, void *data) {
|
||||
sml_message_body *message_body = (sml_message_body *) malloc(sizeof(sml_message_body));
|
||||
memset(message_body, 0, sizeof(sml_message_body));
|
||||
message_body->tag = tag;
|
||||
message_body->data = data;
|
||||
return message_body;
|
||||
}
|
||||
|
||||
void sml_message_body_write(sml_message_body *message_body, sml_buffer *buf) {
|
||||
mc_sml_set_type_and_length(buf, SML_TYPE_LIST, 2);
|
||||
sml_number_write(SML_TYPE_UNSIGNED, SML_TYPE_NUMBER_16, (u64) message_body->tag, buf);
|
||||
|
||||
switch (message_body->tag) {
|
||||
case SML_MESSAGE_OPEN_REQUEST:
|
||||
sml_open_request_write((sml_open_request *) message_body->data, buf);
|
||||
break;
|
||||
case SML_MESSAGE_CLOSE_REQUEST:
|
||||
sml_close_request_write((sml_close_request *) message_body->data, buf);
|
||||
break;
|
||||
case SML_MESSAGE_SET_PROC_PARAMETER_REQUEST:
|
||||
sml_set_proc_parameter_request_write((sml_set_proc_parameter_request *) message_body->data, buf);
|
||||
break;
|
||||
case SML_MESSAGE_GET_PROC_PARAMETER_REQUEST:
|
||||
sml_get_proc_parameter_request_write((sml_get_proc_parameter_request *) message_body->data, buf);
|
||||
break;
|
||||
case SML_MESSAGE_GET_LIST_REQUEST:
|
||||
sml_get_list_request_write((sml_get_list_request *)message_body->data, buf);
|
||||
break;
|
||||
case SML_MESSAGE_GET_PROFILE_PACK_REQUEST:
|
||||
sml_get_profile_pack_request_write((sml_get_profile_pack_request *)message_body->data, buf);
|
||||
break;
|
||||
default:
|
||||
printf("error: message type %04X not yet implemented\n", message_body->tag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void sml_message_body_free(sml_message_body *message_body) {
|
||||
if (message_body) {
|
||||
switch (message_body->tag) {
|
||||
case SML_MESSAGE_OPEN_REQUEST:
|
||||
sml_open_request_free((sml_open_request *) message_body->data);
|
||||
break;
|
||||
case SML_MESSAGE_OPEN_RESPONSE:
|
||||
sml_open_response_free((sml_open_response *) message_body->data);
|
||||
break;
|
||||
case SML_MESSAGE_CLOSE_REQUEST:
|
||||
sml_close_request_free((sml_close_request *) message_body->data);
|
||||
break;
|
||||
case SML_MESSAGE_CLOSE_RESPONSE:
|
||||
sml_close_response_free((sml_close_response *) message_body->data);
|
||||
break;
|
||||
case SML_MESSAGE_SET_PROC_PARAMETER_REQUEST:
|
||||
sml_set_proc_parameter_request_free((sml_set_proc_parameter_request *) message_body->data);
|
||||
break;
|
||||
case SML_MESSAGE_GET_LIST_REQUEST:
|
||||
sml_get_list_request_free((sml_get_list_request *) message_body->data);
|
||||
break;
|
||||
case SML_MESSAGE_GET_LIST_RESPONSE:
|
||||
sml_get_list_response_free((sml_get_list_response *) message_body->data);
|
||||
break;
|
||||
default:
|
||||
printf("NYI: %s for message type %04X\n", __FUNCTION__, message_body->tag);
|
||||
break;
|
||||
}
|
||||
|
||||
free(message_body);
|
||||
}
|
||||
}
|
||||
|
43
sml/src/sml_number.c
Normal file
43
sml/src/sml_number.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
|
||||
#include <sml/sml_number.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
u64 mc_sml_parse_number(sml_buffer *buf, unsigned char type, int max_size) {
|
||||
|
||||
int l, i;
|
||||
u64 n = 0;
|
||||
if (mc_sml_buf_get_current_type(buf) != type) {
|
||||
buf->error = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
l = mc_sml_get_length(buf);
|
||||
if (l < 0 || l > max_size) {
|
||||
buf->error = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: this doesn't work for integers (leading 1's)
|
||||
// mathias runge: -> fixed bug in sml_value_parse for SML_TYPE_INTEGER -> see comment in sml_value.cpp
|
||||
// maybe this one is fixed too?
|
||||
for (i = 0; i < l; i++) {
|
||||
n <<= 8;
|
||||
n |= mc_sml_buf_get_current_byte(buf);
|
||||
mc_sml_buf_update_read_bytes(buf, 1);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
void sml_number_write(unsigned char type, int size, u64 value, sml_buffer *buf) {
|
||||
mc_sml_set_type_and_length(buf, type, size);
|
||||
int i;
|
||||
u64 mask = 0xFF;
|
||||
mask <<= (8 * (size - 1));
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
buf->buffer[buf->cursor + i] = (unsigned char) ((mask & value) >> (8 * (size - i - 1)));
|
||||
mask >>= 8;
|
||||
}
|
||||
buf->cursor += size;
|
||||
}
|
113
sml/src/sml_octet_string.c
Normal file
113
sml/src/sml_octet_string.c
Normal file
|
@ -0,0 +1,113 @@
|
|||
|
||||
#include <sml/sml_octet_string.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef SML_WITH_UUID_LIB
|
||||
#include <uuid/uuid.h>
|
||||
#endif
|
||||
|
||||
octet_string *sml_octet_string_init(unsigned char *str, int length) {
|
||||
octet_string *s = (octet_string *)malloc(sizeof(octet_string));
|
||||
memset(s, 0, sizeof(octet_string));
|
||||
if (length > 0) {
|
||||
s->str = (unsigned char *)malloc(length);
|
||||
memcpy(s->str, str, length);
|
||||
s->len = length;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
uint8_t ctoi(uint8_t c){
|
||||
uint8_t ret = 0;
|
||||
|
||||
if((c >= '0') && (c <= '9')){
|
||||
ret = c - '0';
|
||||
} else if((c >= 'a') && (c <= 'f')){
|
||||
ret = c - 'a' + 10;
|
||||
} else if((c >= 'A') && (c <= 'F')){
|
||||
ret = c - 'A' + 10;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
inline uint8_t c2toi(uint8_t c1, uint8_t c2){
|
||||
return ctoi(c1) << 4 | ctoi(c2);
|
||||
}
|
||||
|
||||
inline uint8_t c2ptoi(char* c){
|
||||
return ctoi((uint8_t)c[0]) << 4 | ctoi((uint8_t)c[1]);
|
||||
}
|
||||
|
||||
octet_string *sml_octet_string_init_from_hex(char *str) {
|
||||
int i, len = strlen(str);
|
||||
if (len % 2 != 0) {
|
||||
return 0;
|
||||
}
|
||||
unsigned char bytes[len / 2];
|
||||
for (i = 0; i < (len / 2); i++) {
|
||||
bytes[i] = c2ptoi(&(str[i * 2]));
|
||||
}
|
||||
return sml_octet_string_init(bytes, len / 2);
|
||||
}
|
||||
|
||||
void sml_octet_string_free(octet_string *str) {
|
||||
if (str) {
|
||||
if (str->str) {
|
||||
free(str->str);
|
||||
}
|
||||
free(str);
|
||||
}
|
||||
}
|
||||
|
||||
octet_string *sml_octet_string_parse(sml_buffer *buf) {
|
||||
int l;
|
||||
if (mc_sml_buf_get_current_type(buf) != SML_TYPE_OCTET_STRING) {
|
||||
buf->error = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
l = mc_sml_get_length(buf);
|
||||
if (l < 0) {
|
||||
buf->error = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
octet_string *str = sml_octet_string_init(mc_sml_buf_get_current_buf(buf), l);
|
||||
mc_sml_buf_update_read_bytes(buf, l);
|
||||
return str;
|
||||
}
|
||||
|
||||
void sml_octet_string_write(octet_string *str, sml_buffer *buf) {
|
||||
mc_sml_set_type_and_length(buf, SML_TYPE_OCTET_STRING, (unsigned int) str->len);
|
||||
memcpy(mc_sml_buf_get_current_buf(buf), str->str, str->len);
|
||||
buf->cursor += str->len;
|
||||
}
|
||||
|
||||
octet_string *sml_octet_string_generate_uuid() {
|
||||
#ifdef SML_WITH_UUID_LIB
|
||||
uuid_t uuid;
|
||||
uuid_generate(uuid);
|
||||
return sml_octet_string_init(uuid, 16);
|
||||
#else
|
||||
printf("TODO %s\n", __FUNCTION__);
|
||||
return sml_octet_string_init((unsigned char*)"RANDOM", 6);
|
||||
#endif
|
||||
}
|
||||
|
||||
int sml_octet_string_cmp_with_hex(octet_string *str, char *hex) {
|
||||
octet_string *hstr = sml_octet_string_init_from_hex(hex);
|
||||
if (str->len != hstr->len) {
|
||||
sml_octet_string_free(hstr);
|
||||
return -1;
|
||||
}
|
||||
int result = memcmp(str->str, hstr->str, str->len);
|
||||
sml_octet_string_free(hstr);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
105
sml/src/sml_open_request.c
Normal file
105
sml/src/sml_open_request.c
Normal file
|
@ -0,0 +1,105 @@
|
|||
|
||||
#include <sml/sml_open_request.h>
|
||||
|
||||
#include <sml/sml_number.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
sml_open_request *sml_open_request_init(){
|
||||
sml_open_request *open_request = (sml_open_request *) malloc(sizeof(sml_open_request));
|
||||
memset(open_request, 0, sizeof(sml_open_request));
|
||||
return open_request;
|
||||
}
|
||||
|
||||
/*
|
||||
sml_open_request *sml_open_request_init(char* client_id,char* req_file_id, char* server_id){
|
||||
sml_open_request *open_request = (sml_open_request *) malloc(sizeof(sml_open_request));
|
||||
memset(open_request, 0, sizeof(sml_open_request));
|
||||
|
||||
// printf("TODO: %s\n", __FUNCTION__);
|
||||
open_request->client_id = sml_octet_string_init((unsigned char *)client_id,strlen(client_id));
|
||||
open_request->req_file_id = sml_octet_string_init((unsigned char *)req_file_id,strlen(req_file_id));
|
||||
open_request->server_id = sml_octet_string_init((unsigned char *)server_id, strlen(server_id));
|
||||
return open_request;
|
||||
}
|
||||
|
||||
sml_open_request *sml_open_request_init() {
|
||||
// sml_open_request *open_request = (sml_open_request *) malloc(sizeof(sml_open_request));
|
||||
//memset(open_request, 0, sizeof(sml_open_request));
|
||||
|
||||
// printf("TODO: %s\n", __FUNCTION__);
|
||||
//open_request->username = sml_octet_string_init((unsigned char *)"kunde",5);
|
||||
//open_request->username = sml_octet_string_init((unsigned char *)"kunde",5);
|
||||
//open_request->client_id = sml_octet_string_init((unsigned char *)"SEDICMA", 7);
|
||||
//open_request->req_file_id = sml_octet_string_init((unsigned char *)"01", 2);
|
||||
char server_id[] ={0x06, 0x45, 0x4d, 0x48, 0x01, 0x02, 0x71, 0x53, 0x3b, 0xcd};
|
||||
//open_request->server_id = sml_octet_string_init(server_id, 10);
|
||||
return sml_open_request_init("SEDICMA", "02", server_id);
|
||||
}
|
||||
*/
|
||||
void sml_open_request_write(sml_open_request *msg, sml_buffer *buf) {
|
||||
mc_sml_set_type_and_length(buf, SML_TYPE_LIST, 7);
|
||||
|
||||
mc_sml_optional_write(buf);
|
||||
sml_octet_string_write(msg->client_id, buf);
|
||||
sml_octet_string_write(msg->req_file_id, buf);
|
||||
sml_octet_string_write(msg->server_id, buf);
|
||||
sml_octet_string_write(msg->username,buf);
|
||||
sml_octet_string_write(msg->password,buf);
|
||||
mc_sml_optional_write(buf);
|
||||
|
||||
}
|
||||
|
||||
sml_open_request *sml_open_request_parse(sml_buffer *buf) {
|
||||
sml_open_request *msg = (sml_open_request *) malloc(sizeof(sml_open_request));
|
||||
memset(msg, 0, sizeof(sml_open_request));
|
||||
|
||||
if (mc_sml_buf_get_current_type(buf) != SML_TYPE_LIST) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (mc_sml_get_length(buf) != 7) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
msg->codepage = SML_SKIP_OPTIONAL sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->client_id = sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->req_file_id = sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->server_id = SML_SKIP_OPTIONAL sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->username = SML_SKIP_OPTIONAL sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->password = SML_SKIP_OPTIONAL sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->sml_version = SML_SKIP_OPTIONAL mc_sml_parse_u8(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
return msg;
|
||||
|
||||
error:
|
||||
free(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sml_open_request_free(sml_open_request *msg) {
|
||||
free(msg->client_id);
|
||||
free(msg->password);
|
||||
free(msg->req_file_id);
|
||||
free(msg->server_id);
|
||||
free(msg->username);
|
||||
free(msg);
|
||||
// printf("NYI: %s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
|
53
sml/src/sml_open_response.c
Normal file
53
sml/src/sml_open_response.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
|
||||
#include <sml/sml_open_response.h>
|
||||
|
||||
#include <sml/sml_number.h>
|
||||
|
||||
sml_open_response *sml_open_response_parse(sml_buffer *buf) {
|
||||
sml_open_response *msg = (sml_open_response *) malloc(sizeof(sml_open_response));
|
||||
memset(msg, 0, sizeof(sml_open_response));
|
||||
|
||||
if (mc_sml_buf_get_current_type(buf) != SML_TYPE_LIST) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (mc_sml_get_length(buf) != 6) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
msg->codepage = SML_SKIP_OPTIONAL sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->client_id = SML_SKIP_OPTIONAL sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->req_file_id = sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->server_id = sml_octet_string_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->ref_time = SML_SKIP_OPTIONAL sml_time_parse(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
msg->sml_version = SML_SKIP_OPTIONAL mc_sml_parse_u8(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
return msg;
|
||||
error:
|
||||
free(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sml_open_response_free(sml_open_response *msg) {
|
||||
if (msg) {
|
||||
sml_octet_string_free(msg->codepage);
|
||||
sml_octet_string_free(msg->client_id);
|
||||
sml_octet_string_free(msg->req_file_id);
|
||||
sml_octet_string_free(msg->server_id);
|
||||
sml_time_free(msg->ref_time);
|
||||
free(msg);
|
||||
}
|
||||
}
|
26
sml/src/sml_set_proc_parameter_request.c
Normal file
26
sml/src/sml_set_proc_parameter_request.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
|
||||
#include <sml/sml_set_proc_parameter_request.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
sml_set_proc_parameter_request *sml_set_proc_parameter_request_init() {
|
||||
sml_set_proc_parameter_request *msg = (sml_set_proc_parameter_request *) malloc(sizeof (sml_set_proc_parameter_request));
|
||||
memset(msg, 0, sizeof(sml_set_proc_parameter_request));
|
||||
return msg;
|
||||
}
|
||||
|
||||
void sml_set_proc_parameter_request_write(sml_set_proc_parameter_request *msg, sml_buffer *buf) {
|
||||
mc_sml_set_type_and_length(buf, SML_TYPE_LIST, 5);
|
||||
mc_sml_optional_write(buf);
|
||||
mc_sml_optional_write(buf);
|
||||
mc_sml_optional_write(buf);
|
||||
sml_tree_path_write(msg->parameter_tree_path, buf);
|
||||
sml_tree_write(msg->parameter_tree, buf);
|
||||
}
|
||||
|
||||
void sml_set_proc_parameter_request_free(sml_set_proc_parameter_request *msg) {
|
||||
printf("NYI: %s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
|
123
sml/src/sml_shared.c
Normal file
123
sml/src/sml_shared.c
Normal file
|
@ -0,0 +1,123 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <sml/sml_shared.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int mc_sml_get_length(sml_buffer *buf) {
|
||||
int length = 0;
|
||||
unsigned char byte = mc_sml_buf_get_current_byte(buf);
|
||||
int list = ((byte & SML_TYPE_FIELD) == SML_TYPE_LIST) ? 0 : -1;
|
||||
|
||||
for (;buf->cursor < buf->buffer_len;) {
|
||||
byte = mc_sml_buf_get_current_byte(buf);
|
||||
length <<= 4;
|
||||
length |= (byte & SML_LENGTH_FIELD);
|
||||
|
||||
if ((byte & SML_ANOTHER_TL) != SML_ANOTHER_TL) {
|
||||
break;
|
||||
}
|
||||
mc_sml_buf_update_read_bytes(buf, 1);
|
||||
if(list) {
|
||||
list += -1;
|
||||
}
|
||||
}
|
||||
mc_sml_buf_update_read_bytes(buf, 1);
|
||||
return length + list;
|
||||
}
|
||||
|
||||
void mc_sml_set_type_and_length(sml_buffer *buf, unsigned int type, unsigned int l) {
|
||||
// set the type
|
||||
buf->buffer[buf->cursor] |= type;
|
||||
|
||||
if (type != SML_TYPE_LIST) {
|
||||
l++;
|
||||
}
|
||||
|
||||
if (l > SML_LENGTH_FIELD) {
|
||||
// how much shifts are necessary
|
||||
int mask_pos = (sizeof(unsigned int) * 2) - 1;
|
||||
|
||||
// the 4 most significant bits of l
|
||||
unsigned int mask = 0xF0 << (8 * (sizeof(unsigned int) - 1));
|
||||
|
||||
// select the 4 most significant bits with a bit set
|
||||
while (!(mask & l)) {
|
||||
mask >>= 4;
|
||||
mask_pos--;
|
||||
}
|
||||
|
||||
// copy the bits to the buffer
|
||||
while (mask > SML_LENGTH_FIELD) {
|
||||
buf->buffer[buf->cursor] |= SML_ANOTHER_TL;
|
||||
buf->buffer[buf->cursor] |= ((mask & l) >> (4 * mask_pos));
|
||||
mask >>= 4;
|
||||
mask_pos--;
|
||||
buf->cursor++;
|
||||
}
|
||||
}
|
||||
buf->buffer[buf->cursor] |= (l & SML_LENGTH_FIELD);
|
||||
buf->cursor++;
|
||||
}
|
||||
|
||||
int mc_sml_buf_has_errors(sml_buffer *buf) {
|
||||
return buf->error != 0;
|
||||
}
|
||||
|
||||
int mc_sml_buf_get_current_type(sml_buffer *buf) {
|
||||
return (buf->buffer[buf->cursor] & SML_TYPE_FIELD);
|
||||
}
|
||||
|
||||
unsigned char mc_sml_buf_get_current_byte(sml_buffer *buf) {
|
||||
return buf->buffer[buf->cursor];
|
||||
}
|
||||
|
||||
unsigned char *mc_sml_buf_get_current_buf(sml_buffer *buf) {
|
||||
return &(buf->buffer[buf->cursor]);
|
||||
}
|
||||
|
||||
void mc_sml_buf_update_read_bytes(sml_buffer *buf, int bytes) {
|
||||
buf->cursor += bytes;
|
||||
}
|
||||
|
||||
sml_buffer *sml_buffer_init(size_t length) {
|
||||
sml_buffer *buf = (sml_buffer *) malloc(sizeof(sml_buffer));
|
||||
memset(buf, 0, sizeof(sml_buffer));
|
||||
buf->buffer = (unsigned char *) malloc(length);
|
||||
buf->buffer_len = length;
|
||||
memset(buf->buffer, 0, buf->buffer_len);
|
||||
return buf;
|
||||
}
|
||||
|
||||
void mc_sml_optional_write(sml_buffer *buf) {
|
||||
buf->buffer[buf->cursor] = SML_OPTIONAL_SKIPPED;
|
||||
buf->cursor++;
|
||||
}
|
||||
|
||||
void sml_buffer_free(sml_buffer *buf) {
|
||||
if (buf) {
|
||||
if (buf->buffer)
|
||||
free(buf->buffer);
|
||||
if (buf->error_msg)
|
||||
free(buf->error_msg);
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
int mc_sml_is_optional_skipped(sml_buffer *buf) {
|
||||
if (mc_sml_buf_get_current_byte(buf) == SML_OPTIONAL_SKIPPED) {
|
||||
mc_sml_buf_update_read_bytes(buf, 1);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hexdump(unsigned char *buffer, size_t buffer_len) {
|
||||
int i;
|
||||
for (i = 0; i < buffer_len; i++) {
|
||||
printf("%02X ", (unsigned char) buffer[i]);
|
||||
if ((i + 1) % 8 == 0) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
50
sml/src/sml_status.c
Normal file
50
sml/src/sml_status.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
|
||||
#include <sml/sml_status.h>
|
||||
#include <sml/sml_shared.h>
|
||||
|
||||
sml_status *sml_status_parse(sml_buffer *buf) {
|
||||
int type = mc_sml_buf_get_current_type(buf);
|
||||
unsigned char byte = mc_sml_buf_get_current_byte(buf);
|
||||
|
||||
sml_status *state = (sml_status *) malloc(sizeof(sml_status));
|
||||
switch (type) {
|
||||
case SML_TYPE_UNSIGNED:
|
||||
switch (byte & SML_LENGTH_FIELD) {
|
||||
case SML_TYPE_NUMBER_8:
|
||||
state->status8 = mc_sml_parse_u8(buf);
|
||||
break;
|
||||
case SML_TYPE_NUMBER_16:
|
||||
state->status16 = mc_sml_parse_u16(buf);
|
||||
break;
|
||||
case SML_TYPE_NUMBER_16 + 1:
|
||||
case SML_TYPE_NUMBER_32:
|
||||
state->status32 = mc_sml_parse_u32(buf);
|
||||
break;
|
||||
case SML_TYPE_NUMBER_32 + 1:
|
||||
case SML_TYPE_NUMBER_32 + 2:
|
||||
case SML_TYPE_NUMBER_32 + 3:
|
||||
case SML_TYPE_NUMBER_64:
|
||||
state->status64 = mc_sml_parse_u64(buf);
|
||||
break;
|
||||
default:
|
||||
buf->error = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
buf->error = 1;
|
||||
break;
|
||||
}
|
||||
if (mc_sml_buf_has_errors(buf)) {
|
||||
free(state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void sml_status_free(sml_status *status) {
|
||||
if (status) {
|
||||
free(status);
|
||||
}
|
||||
}
|
42
sml/src/sml_time.c
Normal file
42
sml/src/sml_time.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
|
||||
#include <sml/sml_time.h>
|
||||
#include <sml/sml_shared.h>
|
||||
#include <sml/sml_number.h>
|
||||
#include <stdio.h>
|
||||
|
||||
sml_time *sml_time_parse(sml_buffer *buf) {
|
||||
sml_time *tme = (sml_time *) malloc(sizeof(sml_time));
|
||||
|
||||
if (mc_sml_buf_get_current_type(buf) != SML_TYPE_LIST) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (mc_sml_get_length(buf) != 2) {
|
||||
buf->error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
tme->tag = mc_sml_parse_u8(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
tme->data = mc_sml_parse_u32(buf);
|
||||
if (mc_sml_buf_has_errors(buf)) goto error;
|
||||
|
||||
return tme;
|
||||
|
||||
error:
|
||||
free(tme);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sml_time_write(sml_time *time, sml_buffer *buf){
|
||||
printf("NYI: %s (writing optional flag instead)\n", __FUNCTION__);
|
||||
mc_sml_optional_write(buf);
|
||||
}
|
||||
|
||||
void sml_time_free(sml_time *time) {
|
||||
if (time) {
|
||||
free(time);
|
||||
}
|
||||
}
|
101
sml/src/sml_transport.c
Normal file
101
sml/src/sml_transport.c
Normal file
|
@ -0,0 +1,101 @@
|
|||
|
||||
#include <sml/sml_transport.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define MC_SML_BUFFER_LEN 8096
|
||||
|
||||
// Invokes on every incoming SML message the given method. The buffer is freed afterwards.
|
||||
void mc_sml_transport_listen(int fd, void (*mc_sml_transport_receiver)(unsigned char *buffer, size_t buffer_len)) {
|
||||
|
||||
fd_set readfds;
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(fd, &readfds);
|
||||
|
||||
unsigned char byte;
|
||||
unsigned char buf[MC_SML_BUFFER_LEN];
|
||||
int esc = 0, start = 0, i, end = 0, r;
|
||||
|
||||
for (i = 0; i < MC_SML_BUFFER_LEN;) {
|
||||
select(fd + 1, &readfds, 0, 0, 0);
|
||||
if (FD_ISSET(fd, &readfds)) {
|
||||
|
||||
if (!i) { // read until escaped start sequence;
|
||||
r = read(fd, &byte, 1);
|
||||
if (r <= 0) continue;
|
||||
|
||||
if (esc == 4) {
|
||||
if (byte == 0x01) {
|
||||
buf[esc + start++] = byte;
|
||||
if (start == 4) {
|
||||
i = esc + start;
|
||||
esc = 0;
|
||||
start = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// no start sequence
|
||||
esc = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (byte == 0x1b) {
|
||||
buf[esc++] = byte;
|
||||
}
|
||||
else {
|
||||
// no escape sequence
|
||||
esc = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // read the message
|
||||
r = read(fd, (void *)(&(buf[i])), 1);
|
||||
if (r <= 0) continue;
|
||||
|
||||
if (esc == 4) {
|
||||
if (end) {
|
||||
end++;
|
||||
if (end == 5) {
|
||||
char *sml_file = (char *) malloc(i);
|
||||
memcpy(sml_file, &(buf[0]), i);
|
||||
// without the SML transport stuff
|
||||
mc_sml_transport_receiver((unsigned char *)(sml_file ), i);
|
||||
free(sml_file);
|
||||
i = -1;
|
||||
esc = 0;
|
||||
end = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (buf[i] == 0x1a) {
|
||||
end++;
|
||||
}
|
||||
else {
|
||||
// dont read other escaped sequences yet
|
||||
printf("error: unrecognized sequence");
|
||||
esc = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (buf[i] == 0x1b) {
|
||||
esc++;
|
||||
}
|
||||
else {
|
||||
esc = 0;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("error: no end sequence found, buffer full.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
115
sml/src/sml_tree.c
Normal file
115
sml/src/sml_tree.c
Normal file
|
@ -0,0 +1,115 @@
|
|||
|
||||
#include <sml/sml_tree.h>
|
||||
#include <sml/sml_value.h>
|
||||
#include <stdio.h>
|
||||
|
||||
sml_tree_path *sml_tree_path_init() {
|
||||
sml_tree_path *tree_path = (sml_tree_path *) malloc(sizeof(sml_tree_path));
|
||||
memset(tree_path, 0, sizeof(sml_tree_path));
|
||||
return tree_path;
|
||||
}
|
||||
|
||||
void sml_tree_path_add_path_entry(sml_tree_path *tree_path, octet_string *entry) {
|
||||
tree_path->path_entries_len++;
|
||||
tree_path->path_entries = (octet_string **) realloc(tree_path->path_entries, sizeof(octet_string *) * tree_path->path_entries_len);
|
||||
tree_path->path_entries[tree_path->path_entries_len - 1] = entry;
|
||||
}
|
||||
|
||||
void sml_tree_path_write(sml_tree_path *tree_path, sml_buffer *buf) {
|
||||
int i;
|
||||
if (tree_path->path_entries && tree_path->path_entries_len > 0) {
|
||||
mc_sml_set_type_and_length(buf, SML_TYPE_LIST, tree_path->path_entries_len);
|
||||
for (i = 0; i < tree_path->path_entries_len; i++) {
|
||||
sml_octet_string_write(tree_path->path_entries[i], buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sml_tree_path_free(sml_tree_path *tree_path){
|
||||
printf("NYI: %s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
sml_tree *sml_tree_init(octet_string *parameter_name) {
|
||||
sml_tree *tree = (sml_tree *) malloc(sizeof(sml_tree));
|
||||
memset(tree, 0, sizeof(sml_tree));
|
||||
tree->parameter_name = parameter_name;
|
||||
return tree;
|
||||
}
|
||||
|
||||
sml_tree *sml_tree_parse(sml_buffer *buf){
|
||||
printf("ERROR : NYI sml_tree_parse() not implemented yet");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sml_tree_free(sml_tree *tree){
|
||||
printf("ERROR : NYI sml_tree_free() not implemented yet");
|
||||
}
|
||||
|
||||
void sml_tree_write(sml_tree *tree, sml_buffer *buf) {
|
||||
mc_sml_set_type_and_length(buf, SML_TYPE_LIST, 3);
|
||||
sml_octet_string_write(tree->parameter_name, buf);
|
||||
// TODO
|
||||
sml_proc_par_value_write(tree->parameter_value, buf);
|
||||
//mc_sml_optional_write(buf);
|
||||
mc_sml_optional_write(buf);
|
||||
}
|
||||
|
||||
sml_proc_par_value *sml_proc_par_value_init(u8 tag, void *data) {
|
||||
|
||||
sml_proc_par_value *value = (sml_proc_par_value *) malloc(sizeof(sml_proc_par_value));
|
||||
memset(value, 0, sizeof(sml_proc_par_value));
|
||||
value->tag = tag;
|
||||
|
||||
switch (tag) {
|
||||
case SML_PROC_PAR_VALUE_TAG_VALUE:
|
||||
value->data.value = (sml_value*)data;
|
||||
break;
|
||||
case SML_PROC_PAR_VALUE_TAG_PERIOD_ENTRY:
|
||||
printf("TODO: %s\n", __FUNCTION__);
|
||||
break;
|
||||
case SML_PROC_PAR_VALUE_TAG_TUPEL_ENTRY:
|
||||
printf("TODO: %s\n", __FUNCTION__);
|
||||
break;
|
||||
case SML_PROC_PAR_VALUE_TAG_TIME:
|
||||
printf("TODO: %s\n", __FUNCTION__);
|
||||
break;
|
||||
default:
|
||||
if (value) {
|
||||
free(value);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void sml_proc_par_value_write(sml_proc_par_value *value, sml_buffer *buf) {
|
||||
mc_sml_set_type_and_length(buf, SML_TYPE_LIST, 2);
|
||||
sml_number_write(SML_TYPE_UNSIGNED, SML_TYPE_NUMBER_8, (u64) value->tag, buf);
|
||||
|
||||
switch (value->tag) {
|
||||
case SML_PROC_PAR_VALUE_TAG_VALUE:
|
||||
sml_value_write(value->data.value, buf);
|
||||
break;
|
||||
case SML_PROC_PAR_VALUE_TAG_PERIOD_ENTRY:
|
||||
printf("TODO: %s\n", __FUNCTION__);
|
||||
break;
|
||||
case SML_PROC_PAR_VALUE_TAG_TUPEL_ENTRY:
|
||||
printf("TODO: %s\n", __FUNCTION__);
|
||||
break;
|
||||
case SML_PROC_PAR_VALUE_TAG_TIME:
|
||||
printf("TODO: %s\n", __FUNCTION__);
|
||||
break;
|
||||
default:
|
||||
if (value) {
|
||||
free(value);
|
||||
}
|
||||
buf->error = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sml_proc_par_value_free(sml_proc_par_value *value){
|
||||
printf("NYI: %s\n", __FUNCTION__);
|
||||
}
|
108
sml/src/sml_value.c
Normal file
108
sml/src/sml_value.c
Normal file
|
@ -0,0 +1,108 @@
|
|||
|
||||
#include <sml/sml_value.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
sml_value *sml_value_parse(sml_buffer *buf) {
|
||||
int type = mc_sml_buf_get_current_type(buf);
|
||||
unsigned char byte = mc_sml_buf_get_current_byte(buf);
|
||||
|
||||
sml_value *value = (sml_value *) malloc(sizeof(sml_value));
|
||||
value->type = type;
|
||||
|
||||
switch (type) {
|
||||
case SML_TYPE_OCTET_STRING:
|
||||
value->data.bytes = sml_octet_string_parse(buf);
|
||||
break;
|
||||
case SML_TYPE_UNSIGNED:
|
||||
switch (byte & SML_LENGTH_FIELD) {
|
||||
case SML_TYPE_NUMBER_8:
|
||||
value->data.uint8 = mc_sml_parse_u8(buf);
|
||||
value->type |= SML_TYPE_NUMBER_8;
|
||||
break;
|
||||
case SML_TYPE_NUMBER_16:
|
||||
value->data.uint16 = mc_sml_parse_u16(buf);
|
||||
value->type |= SML_TYPE_NUMBER_16;
|
||||
break;
|
||||
case SML_TYPE_NUMBER_16 + 1:
|
||||
case SML_TYPE_NUMBER_32:
|
||||
value->data.uint32 = mc_sml_parse_u32(buf);
|
||||
value->type |= SML_TYPE_NUMBER_32;
|
||||
break;
|
||||
case SML_TYPE_NUMBER_32 + 1:
|
||||
case SML_TYPE_NUMBER_32 + 2:
|
||||
case SML_TYPE_NUMBER_32 + 3:
|
||||
case SML_TYPE_NUMBER_64:
|
||||
value->data.uint64 = mc_sml_parse_u64(buf);
|
||||
value->type |= SML_TYPE_NUMBER_64;
|
||||
break;
|
||||
default:
|
||||
buf->error = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case SML_TYPE_INTEGER:
|
||||
//switch (byte & SML_LENGTH_FIELD) {
|
||||
// Integer 59 00 00 00 00 00 01 20 09 could'nt be evaluated cause (byte & SML_LENGTH_FIELD)=9
|
||||
// but 8 is maximum :( -> now it's working
|
||||
// TODO: check if same problem exists for other SML_TYPEs too
|
||||
switch ((byte & SML_LENGTH_FIELD)-1) {
|
||||
case SML_TYPE_NUMBER_8:
|
||||
value->data.int8 = mc_sml_parse_i8(buf);
|
||||
value->type |= SML_TYPE_NUMBER_8;
|
||||
break;
|
||||
case SML_TYPE_NUMBER_16:
|
||||
value->data.int16 = mc_sml_parse_i16(buf);
|
||||
value->type |= SML_TYPE_NUMBER_16;
|
||||
break;
|
||||
case SML_TYPE_NUMBER_16 + 1:
|
||||
case SML_TYPE_NUMBER_32:
|
||||
value->data.int32 = mc_sml_parse_i32(buf);
|
||||
value->type |= SML_TYPE_NUMBER_32;
|
||||
break;
|
||||
case SML_TYPE_NUMBER_32 + 1:
|
||||
case SML_TYPE_NUMBER_32 + 2:
|
||||
case SML_TYPE_NUMBER_32 + 3:
|
||||
case SML_TYPE_NUMBER_64:
|
||||
value->data.int64 = mc_sml_parse_i64(buf);
|
||||
value->type |= SML_TYPE_NUMBER_64;
|
||||
break;
|
||||
default:
|
||||
buf->error = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
buf->error = 1;
|
||||
break;
|
||||
}
|
||||
if (mc_sml_buf_has_errors(buf)) {
|
||||
free(value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void sml_value_write(sml_value *value, sml_buffer *buf) {
|
||||
if (value->type == SML_TYPE_BOOLEAN) {
|
||||
sml_boolean_write(value->data.boolean, buf);
|
||||
}
|
||||
}
|
||||
|
||||
sml_value *sml_value_init() {
|
||||
sml_value *value = (sml_value *) malloc(sizeof(sml_value));
|
||||
memset(value, 0, sizeof(value));
|
||||
return value;
|
||||
}
|
||||
|
||||
void sml_value_free(sml_value *value) {
|
||||
if (value) {
|
||||
if (value->type == SML_TYPE_OCTET_STRING) {
|
||||
sml_octet_string_free(value->data.bytes);
|
||||
}
|
||||
free(value);
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Reference in a new issue