Browse code

Merge 64f336d0ed2dca161beadf2892f83849874bba43 into 57ee97f52dd90c86743b6fd6dd682285ef994e80

mojtabaesfandiari authored on 09/09/2020 13:45:23 • GitHub committed on 09/09/2020 13:45:23
Showing 96 changed files
... ...
@@ -236,6 +236,31 @@ int received_via_test( struct sip_msg *msg )
236 236
 	return rcvd;
237 237
 }
238 238
 
239
+int received_in_via( struct sip_msg *msg ){
240
+	struct hdr_field *p;
241
+	struct via_body *pp = NULL;
242
+	int rcvd;
243
+
244
+	if(!msg->eoh
245
+	   && (parse_headers(msg, HDR_EOH_F, 0) == -1 || !msg->eoh)) {
246
+		ERR("bad msg while parsing to EOH \n");
247
+		return -1;
248
+	}
249
+
250
+	p = msg->h_via1;
251
+	while (p->type == HDR_VIA_T){
252
+
253
+		pp = p->parsed;
254
+//		LM_INFO("Step-1\n");
255
+//		LM_INFO("Via:<%.*s>\n", pp->host.len, pp->host.s);
256
+		rcvd = (check_via_address(&msg->rcv.src_ip, &pp->host, pp->port, received_dns)!=0);
257
+		if (!rcvd)		//the match is found. return.
258
+			return 1;
259
+		p = p->next;
260
+	}
261
+	return 0;
262
+}
263
+
239 264
 static char * warning_builder( struct sip_msg *msg, unsigned int *returned_len)
240 265
 {
241 266
 	static char buf[MAX_WARNING_LEN];
... ...
@@ -134,6 +134,9 @@ int received_test( struct sip_msg *msg );
134 134
 /* check if IP address in Via != source IP address of signaling */
135 135
 int received_via_test( struct sip_msg *msg );
136 136
 
137
+/* check if IP address:Port in rcv is exist in Via IP address of signaling */
138
+int received_in_via( struct sip_msg *msg );
139
+
137 140
 /* builds a char* buffer from message headers without body
138 141
  * first line is excluded in case of skip_first_line=1
139 142
  */
140 143
new file mode 100644
... ...
@@ -0,0 +1,153 @@
1
+/*
2
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
3
+ * From ASN.1 module "HI1NotificationOperations"
4
+ * 	found in "HI1NotificationOperations.asn"
5
+ */
6
+
7
+#include "Alarm-Indicator.h"
8
+
9
+static int
10
+memb_domainID_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
11
+			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
12
+	
13
+	if(!sptr) {
14
+		ASN__CTFAIL(app_key, td, sptr,
15
+			"%s: value not given (%s:%d)",
16
+			td->name, __FILE__, __LINE__);
17
+		return -1;
18
+	}
19
+	
20
+	
21
+	if(1 /* No applicable constraints whatsoever */) {
22
+		/* Nothing is here. See below */
23
+	}
24
+	
25
+	return td->check_constraints(td, sptr, ctfailcb, app_key);
26
+}
27
+
28
+static int
29
+memb_alarm_information_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
30
+			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
31
+	const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
32
+	size_t size;
33
+	
34
+	if(!sptr) {
35
+		ASN__CTFAIL(app_key, td, sptr,
36
+			"%s: value not given (%s:%d)",
37
+			td->name, __FILE__, __LINE__);
38
+		return -1;
39
+	}
40
+	
41
+	size = st->size;
42
+	
43
+	if((size >= 1 && size <= 256)) {
44
+		/* Constraint check succeeded */
45
+		return 0;
46
+	} else {
47
+		ASN__CTFAIL(app_key, td, sptr,
48
+			"%s: constraint failed (%s:%d)",
49
+			td->name, __FILE__, __LINE__);
50
+		return -1;
51
+	}
52
+}
53
+
54
+static asn_TYPE_member_t asn_MBR_Alarm_Indicator_1[] = {
55
+	{ ATF_POINTER, 2, offsetof(struct Alarm_Indicator, domainID),
56
+		(ASN_TAG_CLASS_CONTEXT | (0 << 2)),
57
+		-1,	/* IMPLICIT tag at current level */
58
+		&asn_DEF_OBJECT_IDENTIFIER,
59
+		memb_domainID_constraint_1,
60
+		0,	/* PER is not compiled, use -gen-PER */
61
+		0,
62
+		"domainID"
63
+		},
64
+	{ ATF_POINTER, 1, offsetof(struct Alarm_Indicator, communicationIdentifier),
65
+		(ASN_TAG_CLASS_CONTEXT | (1 << 2)),
66
+		-1,	/* IMPLICIT tag at current level */
67
+		&asn_DEF_CommunicationIdentifier,
68
+		0,	/* Defer constraints checking to the member type */
69
+		0,	/* PER is not compiled, use -gen-PER */
70
+		0,
71
+		"communicationIdentifier"
72
+		},
73
+	{ ATF_NOFLAGS, 0, offsetof(struct Alarm_Indicator, timeStamp),
74
+		(ASN_TAG_CLASS_CONTEXT | (2 << 2)),
75
+		+1,	/* EXPLICIT tag at current level */
76
+		&asn_DEF_TimeStamp,
77
+		0,	/* Defer constraints checking to the member type */
78
+		0,	/* PER is not compiled, use -gen-PER */
79
+		0,
80
+		"timeStamp"
81
+		},
82
+	{ ATF_NOFLAGS, 0, offsetof(struct Alarm_Indicator, alarm_information),
83
+		(ASN_TAG_CLASS_CONTEXT | (3 << 2)),
84
+		-1,	/* IMPLICIT tag at current level */
85
+		&asn_DEF_OCTET_STRING,
86
+		memb_alarm_information_constraint_1,
87
+		0,	/* PER is not compiled, use -gen-PER */
88
+		0,
89
+		"alarm-information"
90
+		},
91
+	{ ATF_POINTER, 2, offsetof(struct Alarm_Indicator, lawfulInterceptionIdentifier),
92
+		(ASN_TAG_CLASS_CONTEXT | (4 << 2)),
93
+		-1,	/* IMPLICIT tag at current level */
94
+		&asn_DEF_LawfulInterceptionIdentifier,
95
+		0,	/* Defer constraints checking to the member type */
96
+		0,	/* PER is not compiled, use -gen-PER */
97
+		0,
98
+		"lawfulInterceptionIdentifier"
99
+		},
100
+	{ ATF_POINTER, 1, offsetof(struct Alarm_Indicator, national_HI1_ASN1parameters),
101
+		(ASN_TAG_CLASS_CONTEXT | (5 << 2)),
102
+		-1,	/* IMPLICIT tag at current level */
103
+		&asn_DEF_National_HI1_ASN1parameters,
104
+		0,	/* Defer constraints checking to the member type */
105
+		0,	/* PER is not compiled, use -gen-PER */
106
+		0,
107
+		"national-HI1-ASN1parameters"
108
+		},
109
+};
110
+static const ber_tlv_tag_t asn_DEF_Alarm_Indicator_tags_1[] = {
111
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
112
+};
113
+static const asn_TYPE_tag2member_t asn_MAP_Alarm_Indicator_tag2el_1[] = {
114
+    { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* domainID */
115
+    { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* communicationIdentifier */
116
+    { (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 }, /* timeStamp */
117
+    { (ASN_TAG_CLASS_CONTEXT | (3 << 2)), 3, 0, 0 }, /* alarm-information */
118
+    { (ASN_TAG_CLASS_CONTEXT | (4 << 2)), 4, 0, 0 }, /* lawfulInterceptionIdentifier */
119
+    { (ASN_TAG_CLASS_CONTEXT | (5 << 2)), 5, 0, 0 } /* national-HI1-ASN1parameters */
120
+};
121
+static asn_SEQUENCE_specifics_t asn_SPC_Alarm_Indicator_specs_1 = {
122
+	sizeof(struct Alarm_Indicator),
123
+	offsetof(struct Alarm_Indicator, _asn_ctx),
124
+	asn_MAP_Alarm_Indicator_tag2el_1,
125
+	6,	/* Count of tags in the map */
126
+	0, 0, 0,	/* Optional elements (not needed) */
127
+	3,	/* Start extensions */
128
+	7	/* Stop extensions */
129
+};
130
+asn_TYPE_descriptor_t asn_DEF_Alarm_Indicator = {
131
+	"Alarm-Indicator",
132
+	"Alarm-Indicator",
133
+	SEQUENCE_free,
134
+	SEQUENCE_print,
135
+	SEQUENCE_constraint,
136
+	SEQUENCE_decode_ber,
137
+	SEQUENCE_encode_der,
138
+	SEQUENCE_decode_xer,
139
+	SEQUENCE_encode_xer,
140
+	0, 0,	/* No PER support, use "-gen-PER" to enable */
141
+	0,	/* Use generic outmost tag fetcher */
142
+	asn_DEF_Alarm_Indicator_tags_1,
143
+	sizeof(asn_DEF_Alarm_Indicator_tags_1)
144
+		/sizeof(asn_DEF_Alarm_Indicator_tags_1[0]), /* 1 */
145
+	asn_DEF_Alarm_Indicator_tags_1,	/* Same as above */
146
+	sizeof(asn_DEF_Alarm_Indicator_tags_1)
147
+		/sizeof(asn_DEF_Alarm_Indicator_tags_1[0]), /* 1 */
148
+	0,	/* No PER visible constraints */
149
+	asn_MBR_Alarm_Indicator_1,
150
+	6,	/* Elements count */
151
+	&asn_SPC_Alarm_Indicator_specs_1	/* Additional specs */
152
+};
153
+
0 154
new file mode 100644
... ...
@@ -0,0 +1,57 @@
1
+/*
2
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
3
+ * From ASN.1 module "HI1NotificationOperations"
4
+ * 	found in "HI1NotificationOperations.asn"
5
+ */
6
+
7
+#ifndef	_Alarm_Indicator_H_
8
+#define	_Alarm_Indicator_H_
9
+
10
+
11
+#include "asn_application.h"
12
+
13
+/* Including external dependencies */
14
+#include "OBJECT_IDENTIFIER.h"
15
+#include "TimeStamp.h"
16
+#include "OCTET_STRING.h"
17
+#include "LawfulInterceptionIdentifier.h"
18
+#include "constr_SEQUENCE.h"
19
+
20
+#ifdef __cplusplus
21
+extern "C" {
22
+#endif
23
+
24
+/* Forward declarations */
25
+struct CommunicationIdentifier;
26
+struct National_HI1_ASN1parameters;
27
+
28
+/* Alarm-Indicator */
29
+typedef struct Alarm_Indicator {
30
+	OBJECT_IDENTIFIER_t	*domainID	/* OPTIONAL */;
31
+	struct CommunicationIdentifier	*communicationIdentifier	/* OPTIONAL */;
32
+	TimeStamp_t	 timeStamp;
33
+	OCTET_STRING_t	 alarm_information;
34
+	/*
35
+	 * This type is extensible,
36
+	 * possible extensions are below.
37
+	 */
38
+	LawfulInterceptionIdentifier_t	*lawfulInterceptionIdentifier	/* OPTIONAL */;
39
+	struct National_HI1_ASN1parameters	*national_HI1_ASN1parameters	/* OPTIONAL */;
40
+	
41
+	/* Context for parsing across buffer boundaries */
42
+	asn_struct_ctx_t _asn_ctx;
43
+} Alarm_Indicator_t;
44
+
45
+/* Implementation */
46
+extern asn_TYPE_descriptor_t asn_DEF_Alarm_Indicator;
47
+
48
+#ifdef __cplusplus
49
+}
50
+#endif
51
+
52
+/* Referred external types */
53
+#include "CommunicationIdentifier.h"
54
+#include "National-HI1-ASN1parameters.h"
55
+
56
+#endif	/* _Alarm_Indicator_H_ */
57
+#include "asn_internal.h"
0 58
new file mode 100644
... ...
@@ -0,0 +1,189 @@
1
+/*-
2
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
3
+ * Redistribution and modifications are permitted subject to BSD license.
4
+ */
5
+#include "asn_internal.h"
6
+#include "BIT_STRING.h"
7
+#include "asn_internal.h"
8
+
9
+/*
10
+ * BIT STRING basic type description.
11
+ */
12
+static const ber_tlv_tag_t asn_DEF_BIT_STRING_tags[] = {
13
+	(ASN_TAG_CLASS_UNIVERSAL | (3 << 2))
14
+};
15
+static asn_OCTET_STRING_specifics_t asn_DEF_BIT_STRING_specs = {
16
+	sizeof(BIT_STRING_t),
17
+	offsetof(BIT_STRING_t, _asn_ctx),
18
+	ASN_OSUBV_BIT
19
+};
20
+asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {
21
+	"BIT STRING",
22
+	"BIT_STRING",
23
+	OCTET_STRING_free,         /* Implemented in terms of OCTET STRING */
24
+	BIT_STRING_print,
25
+	BIT_STRING_constraint,
26
+	OCTET_STRING_decode_ber,   /* Implemented in terms of OCTET STRING */
27
+	OCTET_STRING_encode_der,   /* Implemented in terms of OCTET STRING */
28
+	OCTET_STRING_decode_xer_binary,
29
+	BIT_STRING_encode_xer,
30
+	OCTET_STRING_decode_uper,	/* Unaligned PER decoder */
31
+	OCTET_STRING_encode_uper,	/* Unaligned PER encoder */
32
+	0, /* Use generic outmost tag fetcher */
33
+	asn_DEF_BIT_STRING_tags,
34
+	sizeof(asn_DEF_BIT_STRING_tags)
35
+	  / sizeof(asn_DEF_BIT_STRING_tags[0]),
36
+	asn_DEF_BIT_STRING_tags,	/* Same as above */
37
+	sizeof(asn_DEF_BIT_STRING_tags)
38
+	  / sizeof(asn_DEF_BIT_STRING_tags[0]),
39
+	0,	/* No PER visible constraints */
40
+	0, 0,	/* No members */
41
+	&asn_DEF_BIT_STRING_specs
42
+};
43
+
44
+/*
45
+ * BIT STRING generic constraint.
46
+ */
47
+int
48
+BIT_STRING_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
49
+		asn_app_constraint_failed_f *ctfailcb, void *app_key) {
50
+	const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
51
+
52
+	if(st && st->buf) {
53
+		if((st->size == 0 && st->bits_unused)
54
+		|| st->bits_unused < 0 || st->bits_unused > 7) {
55
+			ASN__CTFAIL(app_key, td, sptr,
56
+				"%s: invalid padding byte (%s:%d)",
57
+				td->name, __FILE__, __LINE__);
58
+			return -1;
59
+		}
60
+	} else {
61
+		ASN__CTFAIL(app_key, td, sptr,
62
+			"%s: value not given (%s:%d)",
63
+			td->name, __FILE__, __LINE__);
64
+		return -1;
65
+	}
66
+
67
+	return 0;
68
+}
69
+
70
+static char *_bit_pattern[16] = {
71
+	"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
72
+	"1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
73
+};
74
+
75
+asn_enc_rval_t
76
+BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
77
+	int ilevel, enum xer_encoder_flags_e flags,
78
+		asn_app_consume_bytes_f *cb, void *app_key) {
79
+	asn_enc_rval_t er;
80
+	char scratch[128];
81
+	char *p = scratch;
82
+	char *scend = scratch + (sizeof(scratch) - 10);
83
+	const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
84
+	int xcan = (flags & XER_F_CANONICAL);
85
+	uint8_t *buf;
86
+	uint8_t *end;
87
+
88
+	if(!st || !st->buf)
89
+		ASN__ENCODE_FAILED;
90
+
91
+	er.encoded = 0;
92
+
93
+	buf = st->buf;
94
+	end = buf + st->size - 1;	/* Last byte is special */
95
+
96
+	/*
97
+	 * Binary dump
98
+	 */
99
+	for(; buf < end; buf++) {
100
+		int v = *buf;
101
+		int nline = xcan?0:(((buf - st->buf) % 8) == 0);
102
+		if(p >= scend || nline) {
103
+			er.encoded += p - scratch;
104
+			ASN__CALLBACK(scratch, p - scratch);
105
+			p = scratch;
106
+			if(nline) ASN__TEXT_INDENT(1, ilevel);
107
+		}
108
+		memcpy(p + 0, _bit_pattern[v >> 4], 4);
109
+		memcpy(p + 4, _bit_pattern[v & 0x0f], 4);
110
+		p += 8;
111
+	}
112
+
113
+	if(!xcan && ((buf - st->buf) % 8) == 0)
114
+		ASN__TEXT_INDENT(1, ilevel);
115
+	er.encoded += p - scratch;
116
+	ASN__CALLBACK(scratch, p - scratch);
117
+	p = scratch;
118
+
119
+	if(buf == end) {
120
+		int v = *buf;
121
+		int ubits = st->bits_unused;
122
+		int i;
123
+		for(i = 7; i >= ubits; i--)
124
+			*p++ = (v & (1 << i)) ? 0x31 : 0x30;
125
+		er.encoded += p - scratch;
126
+		ASN__CALLBACK(scratch, p - scratch);
127
+	}
128
+
129
+	if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);
130
+
131
+	ASN__ENCODED_OK(er);
132
+cb_failed:
133
+	ASN__ENCODE_FAILED;
134
+}
135
+
136
+
137
+/*
138
+ * BIT STRING specific contents printer.
139
+ */
140
+int
141
+BIT_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
142
+		asn_app_consume_bytes_f *cb, void *app_key) {
143
+	const char * const h2c = "0123456789ABCDEF";
144
+	char scratch[64];
145
+	const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
146
+	uint8_t *buf;
147
+	uint8_t *end;
148
+	char *p = scratch;
149
+
150
+	(void)td;	/* Unused argument */
151
+
152
+	if(!st || !st->buf)
153
+		return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
154
+
155
+	ilevel++;
156
+	buf = st->buf;
157
+	end = buf + st->size;
158
+
159
+	/*
160
+	 * Hexadecimal dump.
161
+	 */
162
+	for(; buf < end; buf++) {
163
+		if((buf - st->buf) % 16 == 0 && (st->size > 16)
164
+				&& buf != st->buf) {
165
+			_i_INDENT(1);
166
+			/* Dump the string */
167
+			if(cb(scratch, p - scratch, app_key) < 0) return -1;
168
+			p = scratch;
169
+		}
170
+		*p++ = h2c[*buf >> 4];
171
+		*p++ = h2c[*buf & 0x0F];
172
+		*p++ = 0x20;
173
+	}
174
+
175
+	if(p > scratch) {
176
+		p--;	/* Eat the tailing space */
177
+
178
+		if((st->size > 16)) {
179
+			_i_INDENT(1);
180
+		}
181
+
182
+		/* Dump the incomplete 16-bytes row */
183
+		if(cb(scratch, p - scratch, app_key) < 0)
184
+			return -1;
185
+	}
186
+
187
+	return 0;
188
+}
189
+
0 190
new file mode 100644
... ...
@@ -0,0 +1,33 @@
1
+/*-
2
+ * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
3
+ * Redistribution and modifications are permitted subject to BSD license.
4
+ */
5
+#ifndef	_BIT_STRING_H_
6
+#define	_BIT_STRING_H_
7
+
8
+#include "OCTET_STRING.h"	/* Some help from OCTET STRING */
9
+
10
+#ifdef __cplusplus
11
+extern "C" {
12
+#endif
13
+
14
+typedef struct BIT_STRING_s {
15
+	uint8_t *buf;	/* BIT STRING body */
16
+	int size;	/* Size of the above buffer */
17
+
18
+	int bits_unused;/* Unused trailing bits in the last octet (0..7) */
19
+
20
+	asn_struct_ctx_t _asn_ctx;	/* Parsing across buffer boundaries */
21
+} BIT_STRING_t;
22
+
23
+extern asn_TYPE_descriptor_t asn_DEF_BIT_STRING;
24
+
25
+asn_struct_print_f BIT_STRING_print;	/* Human-readable output */
26
+asn_constr_check_f BIT_STRING_constraint;
27
+xer_type_encoder_f BIT_STRING_encode_xer;
28
+
29
+#ifdef __cplusplus
30
+}
31
+#endif
32
+
33
+#endif	/* _BIT_STRING_H_ */
0 34
new file mode 100644
... ...
@@ -0,0 +1,92 @@
1
+cmake_minimum_required(VERSION 3.9)
2
+project(hi1ops_v4)
3
+
4
+set(CMAKE_CXX_STANDARD 11)
5
+
6
+add_executable(hi1ops_v4
7
+        Alarm-Indicator.c
8
+        Alarm-Indicator.h
9
+        asn_application.h
10
+        asn_codecs.h
11
+        asn_codecs_prim.c
12
+        asn_codecs_prim.h
13
+        asn_internal.h
14
+        asn_system.h
15
+        ber_decoder.c
16
+        ber_decoder.h
17
+        ber_tlv_length.c
18
+        ber_tlv_length.h
19
+        ber_tlv_tag.c
20
+        ber_tlv_tag.h
21
+        BIT_STRING.c
22
+        BIT_STRING.h
23
+        Code.c
24
+        Code.h
25
+        CommunicationIdentifier.c
26
+        CommunicationIdentifier.h
27
+        constr_CHOICE.c
28
+        constr_CHOICE.h
29
+        constr_SEQUENCE.c
30
+        constr_SEQUENCE.h
31
+        constr_TYPE.c
32
+        constr_TYPE.h
33
+        constraints.c
34
+        constraints.h
35
+        der_encoder.c
36
+        der_encoder.h
37
+        GeneralizedTime.c
38
+        GeneralizedTime.h
39
+        HI1-Operation.c
40
+        HI1-Operation.h
41
+        hi1ops.c
42
+        hi1ops.h
43
+        IA5String.c
44
+        IA5String.h
45
+        INTEGER.c
46
+        INTEGER.h
47
+        IP-value.c
48
+        IP-value.h
49
+        IPAddress.c
50
+        IPAddress.h
51
+        LawfulInterceptionIdentifier.c
52
+        LawfulInterceptionIdentifier.h
53
+        LocalTimeStamp.c
54
+        LocalTimeStamp.h
55
+        National-HI1-ASN1parameters.c
56
+        National-HI1-ASN1parameters.h
57
+        NativeEnumerated.c
58
+        NativeEnumerated.h
59
+        NativeInteger.c
60
+        NativeInteger.h
61
+        Network-Element-Identifier.c
62
+        Network-Element-Identifier.h
63
+        Network-Identifier.c
64
+        Network-Identifier.h
65
+        Notification.c
66
+        Notification.h
67
+        OBJECT_IDENTIFIER.c
68
+        OBJECT_IDENTIFIER.h
69
+        OCTET_STRING.c
70
+        OCTET_STRING.h
71
+        per_decoder.c
72
+        per_decoder.h
73
+        per_encoder.c
74
+        per_encoder.h
75
+        per_opentype.c
76
+        per_opentype.h
77
+        per_support.c
78
+        per_support.h
79
+        PrintableString.c
80
+        PrintableString.h
81
+        Priority.c
82
+        Priority.h
83
+        TimeStamp.c
84
+        TimeStamp.h
85
+        UTCTime.c
86
+        UTCTime.h
87
+        xer_decoder.c
88
+        xer_decoder.h
89
+        xer_encoder.c
90
+        xer_encoder.h
91
+        xer_support.c
92
+        xer_support.h)
0 93
new file mode 100644
... ...
@@ -0,0 +1,64 @@
1
+/*
2
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
3
+ * From ASN.1 module "Remote-Operations-Information-Objects"
4
+ * 	found in "Remote-Operations-Information-Objects.asn"
5
+ */
6
+
7
+#include "Code.h"
8
+
9
+static asn_TYPE_member_t asn_MBR_Code_1[] = {
10
+	{ ATF_NOFLAGS, 0, offsetof(struct Code, choice.local),
11
+		(ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
12
+		0,
13
+		&asn_DEF_NativeInteger,
14
+		0,	/* Defer constraints checking to the member type */
15
+		0,	/* PER is not compiled, use -gen-PER */
16
+		0,
17
+		"local"
18
+		},
19
+	{ ATF_NOFLAGS, 0, offsetof(struct Code, choice.global),
20
+		(ASN_TAG_CLASS_UNIVERSAL | (6 << 2)),
21
+		0,
22
+		&asn_DEF_OBJECT_IDENTIFIER,
23
+		0,	/* Defer constraints checking to the member type */
24
+		0,	/* PER is not compiled, use -gen-PER */
25
+		0,
26
+		"global"
27
+		},
28
+};
29
+static const asn_TYPE_tag2member_t asn_MAP_Code_tag2el_1[] = {
30
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* local */
31
+    { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 1, 0, 0 } /* global */
32
+};
33
+static asn_CHOICE_specifics_t asn_SPC_Code_specs_1 = {
34
+	sizeof(struct Code),
35
+	offsetof(struct Code, _asn_ctx),
36
+	offsetof(struct Code, present),
37
+	sizeof(((struct Code *)0)->present),
38
+	asn_MAP_Code_tag2el_1,
39
+	2,	/* Count of tags in the map */
40
+	0,
41
+	-1	/* Extensions start */
42
+};
43
+asn_TYPE_descriptor_t asn_DEF_Code = {
44
+	"Code",
45
+	"Code",
46
+	CHOICE_free,
47
+	CHOICE_print,
48
+	CHOICE_constraint,
49
+	CHOICE_decode_ber,
50
+	CHOICE_encode_der,
51
+	CHOICE_decode_xer,
52
+	CHOICE_encode_xer,
53
+	0, 0,	/* No PER support, use "-gen-PER" to enable */
54
+	CHOICE_outmost_tag,
55
+	0,	/* No effective tags (pointer) */
56
+	0,	/* No effective tags (count) */
57
+	0,	/* No tags (pointer) */
58
+	0,	/* No tags (count) */
59
+	0,	/* No PER visible constraints */
60
+	asn_MBR_Code_1,
61
+	2,	/* Elements count */
62
+	&asn_SPC_Code_specs_1	/* Additional specs */
63
+};
64
+
0 65
new file mode 100644
... ...
@@ -0,0 +1,49 @@
1
+/*
2
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
3
+ * From ASN.1 module "Remote-Operations-Information-Objects"
4
+ * 	found in "Remote-Operations-Information-Objects.asn"
5
+ */
6
+
7
+#ifndef	_Code_H_
8
+#define	_Code_H_
9
+
10
+
11
+#include "asn_application.h"
12
+
13
+/* Including external dependencies */
14
+#include "NativeInteger.h"
15
+#include "OBJECT_IDENTIFIER.h"
16
+#include "constr_CHOICE.h"
17
+
18
+#ifdef __cplusplus
19
+extern "C" {
20
+#endif
21
+
22
+/* Dependencies */
23
+typedef enum Code_PR {
24
+	Code_PR_NOTHING,	/* No components present */
25
+	Code_PR_local,
26
+	Code_PR_global
27
+} Code_PR;
28
+
29
+/* Code */
30
+typedef struct Code {
31
+	Code_PR present;
32
+	union Code_u {
33
+		long	 local;
34
+		OBJECT_IDENTIFIER_t	 global;
35
+	} choice;
36
+	
37
+	/* Context for parsing across buffer boundaries */
38
+	asn_struct_ctx_t _asn_ctx;
39
+} Code_t;
40
+
41
+/* Implementation */
42
+extern asn_TYPE_descriptor_t asn_DEF_Code;
43
+
44
+#ifdef __cplusplus
45
+}
46
+#endif
47
+
48
+#endif	/* _Code_H_ */
49
+#include "asn_internal.h"
0 50
new file mode 100644
... ...
@@ -0,0 +1,94 @@
1
+/*
2
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
3
+ * From ASN.1 module "HI2Operations"
4
+ * 	found in "HI2Operations.asn"
5
+ */
6
+
7
+#include "CommunicationIdentifier.h"
8
+
9
+static int
10
+memb_communication_Identity_Number_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
11
+			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
12
+	const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
13
+	size_t size;
14
+	
15
+	if(!sptr) {
16
+		ASN__CTFAIL(app_key, td, sptr,
17
+			"%s: value not given (%s:%d)",
18
+			td->name, __FILE__, __LINE__);
19
+		return -1;
20
+	}
21
+	
22
+	size = st->size;
23
+	
24
+	if((size >= 1 && size <= 8)) {
25
+		/* Constraint check succeeded */
26
+		return 0;
27
+	} else {
28
+		ASN__CTFAIL(app_key, td, sptr,
29
+			"%s: constraint failed (%s:%d)",
30
+			td->name, __FILE__, __LINE__);
31
+		return -1;
32
+	}
33
+}
34
+
35
+static asn_TYPE_member_t asn_MBR_CommunicationIdentifier_1[] = {
36
+	{ ATF_POINTER, 1, offsetof(struct CommunicationIdentifier, communication_Identity_Number),
37
+		(ASN_TAG_CLASS_CONTEXT | (0 << 2)),
38
+		-1,	/* IMPLICIT tag at current level */
39
+		&asn_DEF_OCTET_STRING,
40
+		memb_communication_Identity_Number_constraint_1,
41
+		0,	/* PER is not compiled, use -gen-PER */
42
+		0,
43
+		"communication-Identity-Number"
44
+		},
45
+	{ ATF_NOFLAGS, 0, offsetof(struct CommunicationIdentifier, network_Identifier),
46
+		(ASN_TAG_CLASS_CONTEXT | (1 << 2)),
47
+		-1,	/* IMPLICIT tag at current level */
48
+		&asn_DEF_Network_Identifier,
49
+		0,	/* Defer constraints checking to the member type */
50
+		0,	/* PER is not compiled, use -gen-PER */
51
+		0,
52
+		"network-Identifier"
53
+		},
54
+};
55
+static const ber_tlv_tag_t asn_DEF_CommunicationIdentifier_tags_1[] = {
56
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
57
+};
58
+static const asn_TYPE_tag2member_t asn_MAP_CommunicationIdentifier_tag2el_1[] = {
59
+    { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* communication-Identity-Number */
60
+    { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 } /* network-Identifier */
61
+};
62
+static asn_SEQUENCE_specifics_t asn_SPC_CommunicationIdentifier_specs_1 = {
63
+	sizeof(struct CommunicationIdentifier),
64
+	offsetof(struct CommunicationIdentifier, _asn_ctx),
65
+	asn_MAP_CommunicationIdentifier_tag2el_1,
66
+	2,	/* Count of tags in the map */
67
+	0, 0, 0,	/* Optional elements (not needed) */
68
+	1,	/* Start extensions */
69
+	3	/* Stop extensions */
70
+};
71
+asn_TYPE_descriptor_t asn_DEF_CommunicationIdentifier = {
72
+	"CommunicationIdentifier",
73
+	"CommunicationIdentifier",
74
+	SEQUENCE_free,
75
+	SEQUENCE_print,
76
+	SEQUENCE_constraint,
77
+	SEQUENCE_decode_ber,
78
+	SEQUENCE_encode_der,
79
+	SEQUENCE_decode_xer,
80
+	SEQUENCE_encode_xer,
81
+	0, 0,	/* No PER support, use "-gen-PER" to enable */
82
+	0,	/* Use generic outmost tag fetcher */
83
+	asn_DEF_CommunicationIdentifier_tags_1,
84
+	sizeof(asn_DEF_CommunicationIdentifier_tags_1)
85
+		/sizeof(asn_DEF_CommunicationIdentifier_tags_1[0]), /* 1 */
86
+	asn_DEF_CommunicationIdentifier_tags_1,	/* Same as above */
87
+	sizeof(asn_DEF_CommunicationIdentifier_tags_1)
88
+		/sizeof(asn_DEF_CommunicationIdentifier_tags_1[0]), /* 1 */
89
+	0,	/* No PER visible constraints */
90
+	asn_MBR_CommunicationIdentifier_1,
91
+	2,	/* Elements count */
92
+	&asn_SPC_CommunicationIdentifier_specs_1	/* Additional specs */
93
+};
94
+
0 95
new file mode 100644
... ...
@@ -0,0 +1,43 @@
1
+/*
2
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
3
+ * From ASN.1 module "HI2Operations"
4
+ * 	found in "HI2Operations.asn"
5
+ */
6
+
7
+#ifndef	_CommunicationIdentifier_H_
8
+#define	_CommunicationIdentifier_H_
9
+
10
+
11
+#include "asn_application.h"
12
+
13
+/* Including external dependencies */
14
+#include "OCTET_STRING.h"
15
+#include "Network-Identifier.h"
16
+#include "constr_SEQUENCE.h"
17
+
18
+#ifdef __cplusplus
19
+extern "C" {
20
+#endif
21
+
22
+/* CommunicationIdentifier */
23
+typedef struct CommunicationIdentifier {
24
+	OCTET_STRING_t	*communication_Identity_Number	/* OPTIONAL */;
25
+	Network_Identifier_t	 network_Identifier;
26
+	/*
27
+	 * This type is extensible,
28
+	 * possible extensions are below.
29
+	 */
30
+	
31
+	/* Context for parsing across buffer boundaries */
32
+	asn_struct_ctx_t _asn_ctx;
33
+} CommunicationIdentifier_t;
34
+
35
+/* Implementation */
36
+extern asn_TYPE_descriptor_t asn_DEF_CommunicationIdentifier;
37
+
38
+#ifdef __cplusplus
39
+}
40
+#endif
41
+
42
+#endif	/* _CommunicationIdentifier_H_ */
43
+#include "asn_internal.h"
0 44
new file mode 100644
... ...
@@ -0,0 +1,706 @@
1
+/*-
2
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
3
+ * Redistribution and modifications are permitted subject to BSD license.
4
+ */
5
+#define	_POSIX_PTHREAD_SEMANTICS	/* for Sun */
6
+#define	_REENTRANT			/* for Sun */
7
+#define _BSD_SOURCE     /* for timegm(3) */
8
+#include "asn_internal.h"
9
+#include "GeneralizedTime.h"
10
+
11
+#ifdef	__CYGWIN__
12
+#include "/usr/include/time.h"
13
+#else
14
+#include "time.h"
15
+#endif	/* __CYGWIN__ */
16
+
17
+#include "stdio.h"
18
+#include "errno.h"
19
+
20
+#if	defined(_WIN32)
21
+#pragma message( "PLEASE STOP AND READ!")
22
+#pragma message( "  localtime_r is implemented via localtime(), which may be not thread-safe.")
23
+#pragma message( "  gmtime_r is implemented via gmtime(), which may be not thread-safe.")
24
+#pragma message( "  ")
25
+#pragma message( "  You must fix the code by inserting appropriate locking")
26
+#pragma message( "  if you want to use asn_GT2time() or asn_UT2time().")
27
+#pragma message( "PLEASE STOP AND READ!")
28
+
29
+static struct tm *localtime_r(const time_t *tloc, struct tm *result) {
30
+	struct tm *tm;
31
+	if((tm = localtime(tloc)))
32
+		return memcpy(result, tm, sizeof(struct tm));
33
+	return 0;
34
+}
35
+
36
+static struct tm *gmtime_r(const time_t *tloc, struct tm *result) {
37
+	struct tm *tm;
38
+	if((tm = gmtime(tloc)))
39
+		return memcpy(result, tm, sizeof(struct tm));
40
+	return 0;
41
+}
42
+
43
+#define	tzset()	_tzset()
44
+#define	putenv(c)	_putenv(c)
45
+#define	_EMULATE_TIMEGM
46
+
47
+#endif	/* _WIN32 */
48
+
49
+#if	defined(sun) || defined(_sun_) || defined(__solaris__)
50
+#define	_EMULATE_TIMEGM
51
+#endif
52
+
53
+/*
54
+ * Where to look for offset from GMT, Phase I.
55
+ * Several platforms are known.
56
+ */
57
+#if defined(__FreeBSD__)				\
58
+	|| (defined(__GNUC__) && defined(__APPLE_CC__))	\
59
+	|| (defined __GLIBC__ && __GLIBC__ >= 2)
60
+#undef	HAVE_TM_GMTOFF
61
+#define	HAVE_TM_GMTOFF
62
+#endif	/* BSDs and newer glibc */
63
+
64
+/*
65
+ * Where to look for offset from GMT, Phase II.
66
+ */
67
+#ifdef	HAVE_TM_GMTOFF
68
+#define	GMTOFF(tm)	((tm).tm_gmtoff)
69
+#else	/* HAVE_TM_GMTOFF */
70
+#define	GMTOFF(tm)	(-timezone)
71
+#endif	/* HAVE_TM_GMTOFF */
72
+
73
+#if	defined(_WIN32)
74
+#pragma message( "PLEASE STOP AND READ!")
75
+#pragma message( "  timegm() is implemented via getenv(\"TZ\")/setenv(\"TZ\"), which may be not thread-safe.")
76
+#pragma message( "  ")
77
+#pragma message( "  You must fix the code by inserting appropriate locking")
78
+#pragma message( "  if you want to use asn_GT2time() or asn_UT2time().")
79
+#pragma message( "PLEASE STOP AND READ!")
80
+#else
81
+#if	(defined(_EMULATE_TIMEGM) || !defined(HAVE_TM_GMTOFF))
82
+#warning "PLEASE STOP AND READ!"
83
+#warning "  timegm() is implemented via getenv(\"TZ\")/setenv(\"TZ\"), which may be not thread-safe."
84
+#warning "  "
85
+#warning "  You must fix the code by inserting appropriate locking"
86
+#warning "  if you want to use asn_GT2time() or asn_UT2time()."
87
+#warning "PLEASE STOP AND READ!"
88
+#endif	/* _EMULATE_TIMEGM */
89
+#endif
90
+
91
+/*
92
+ * Override our GMTOFF decision for other known platforms.
93
+ */
94
+#ifdef __CYGWIN__
95
+#undef	GMTOFF
96
+static long GMTOFF(struct tm a){
97
+	struct tm *lt;
98
+	time_t local_time, gmt_time;
99
+	long zone;
100
+
101
+	tzset();
102
+	gmt_time = time (NULL);
103
+
104
+	lt = gmtime(&gmt_time);
105
+
106
+	local_time = mktime(lt);
107
+	return (gmt_time - local_time);
108
+}
109
+#define	_EMULATE_TIMEGM
110
+
111
+#endif	/* __CYGWIN__ */
112
+
113
+#define	ATZVARS do {							\
114
+	char tzoldbuf[64];						\
115
+	char *tzold
116
+#define	ATZSAVETZ do {							\
117
+	tzold = getenv("TZ");						\
118
+	if(tzold) {							\
119
+		size_t tzlen = strlen(tzold);				\
120
+		if(tzlen < sizeof(tzoldbuf)) {				\
121
+			tzold = memcpy(tzoldbuf, tzold, tzlen + 1);	\
122
+		} else {						\
123
+			char *dupptr = tzold;				\
124
+			tzold = MALLOC(tzlen + 1);			\
125
+			if(tzold) memcpy(tzold, dupptr, tzlen + 1);	\
126
+		}							\
127
+		setenv("TZ", "UTC", 1);					\
128
+	}								\
129
+	tzset();							\
130
+} while(0)
131
+#define	ATZOLDTZ do {							\
132
+	if (tzold) {							\
133
+		setenv("TZ", tzold, 1);					\
134
+		*tzoldbuf = 0;						\
135
+		if(tzold != tzoldbuf)					\
136
+			FREEMEM(tzold);					\
137
+	} else {							\
138
+		unsetenv("TZ");						\
139
+	}								\
140
+	tzset();							\
141
+} while(0); } while(0);
142
+
143
+#ifndef HAVE_TIMEGM
144
+#ifdef	_EMULATE_TIMEGM
145
+static time_t timegm(struct tm *tm) {
146
+	time_t tloc;
147
+	ATZVARS;
148
+	ATZSAVETZ;
149
+	tloc = mktime(tm);
150
+	ATZOLDTZ;
151
+	return tloc;
152
+}
153
+#endif	/* _EMULATE_TIMEGM */
154
+#endif
155
+
156
+
157
+#ifndef	ASN___INTERNAL_TEST_MODE
158
+
159
+/*
160
+ * GeneralizedTime basic type description.
161
+ */
162
+static const ber_tlv_tag_t asn_DEF_GeneralizedTime_tags[] = {
163
+	(ASN_TAG_CLASS_UNIVERSAL | (24 << 2)),	/* [UNIVERSAL 24] IMPLICIT ...*/
164
+	(ASN_TAG_CLASS_UNIVERSAL | (26 << 2)),  /* [UNIVERSAL 26] IMPLICIT ...*/
165
+	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))    /* ... OCTET STRING */
166
+};
167
+static asn_per_constraints_t asn_DEF_GeneralizedTime_constraints = {
168
+	{ APC_CONSTRAINED, 7, 7, 0x20, 0x7e },  /* Value */
169
+	{ APC_SEMI_CONSTRAINED, -1, -1, 0, 0 }, /* Size */
170
+	0, 0
171
+};
172
+asn_TYPE_descriptor_t asn_DEF_GeneralizedTime = {
173
+	"GeneralizedTime",
174
+	"GeneralizedTime",
175
+	OCTET_STRING_free,
176
+	GeneralizedTime_print,
177
+	GeneralizedTime_constraint, /* Check validity of time */
178
+	OCTET_STRING_decode_ber,    /* Implemented in terms of OCTET STRING */
179
+	GeneralizedTime_encode_der,
180
+	OCTET_STRING_decode_xer_utf8,
181
+	GeneralizedTime_encode_xer,
182
+	OCTET_STRING_decode_uper,
183
+	OCTET_STRING_encode_uper,
184
+	0, /* Use generic outmost tag fetcher */
185
+	asn_DEF_GeneralizedTime_tags,
186
+	sizeof(asn_DEF_GeneralizedTime_tags)
187
+	  / sizeof(asn_DEF_GeneralizedTime_tags[0]) - 2,
188
+	asn_DEF_GeneralizedTime_tags,
189
+	sizeof(asn_DEF_GeneralizedTime_tags)
190
+	  / sizeof(asn_DEF_GeneralizedTime_tags[0]),
191
+	&asn_DEF_GeneralizedTime_constraints,
192
+	0, 0,	/* No members */
193
+	0	/* No specifics */
194
+};
195
+
196
+#endif	/* ASN___INTERNAL_TEST_MODE */
197
+
198
+/*
199
+ * Check that the time looks like the time.
200
+ */
201
+int
202
+GeneralizedTime_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
203
+		asn_app_constraint_failed_f *ctfailcb, void *app_key) {
204
+	const GeneralizedTime_t *st = (const GeneralizedTime_t *)sptr;
205
+	time_t tloc;
206
+
207
+	errno = EPERM;			/* Just an unlikely error code */
208
+	tloc = asn_GT2time(st, 0, 0);
209
+	if(tloc == -1 && errno != EPERM) {
210
+		ASN__CTFAIL(app_key, td, sptr,
211
+			"%s: Invalid time format: %s (%s:%d)",
212
+			td->name, strerror(errno), __FILE__, __LINE__);
213
+		return -1;
214
+	}
215
+
216
+	return 0;
217
+}
218
+
219
+asn_enc_rval_t
220
+GeneralizedTime_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
221
+	int tag_mode, ber_tlv_tag_t tag,
222
+	asn_app_consume_bytes_f *cb, void *app_key) {
223
+	GeneralizedTime_t *st = (GeneralizedTime_t *)sptr;
224
+	asn_enc_rval_t erval;
225
+	int fv, fd;	/* seconds fraction value and number of digits */
226
+	struct tm tm;
227
+	time_t tloc;
228
+
229
+	/*
230
+	 * Encode as a canonical DER.
231
+	 */
232
+	errno = EPERM;
233
+	tloc = asn_GT2time_frac(st, &fv, &fd, &tm, 1);	/* Recognize time */
234
+	if(tloc == -1 && errno != EPERM)
235
+		/* Failed to recognize time. Fail completely. */
236
+		ASN__ENCODE_FAILED;
237
+
238
+	st = asn_time2GT_frac(0, &tm, fv, fd, 1); /* Save time canonically */
239
+	if(!st) ASN__ENCODE_FAILED;	/* Memory allocation failure. */
240
+
241
+	erval = OCTET_STRING_encode_der(td, st, tag_mode, tag, cb, app_key);
242
+
243
+	FREEMEM(st->buf);
244
+	FREEMEM(st);
245
+
246
+	return erval;
247
+}
248
+
249
+#ifndef	ASN___INTERNAL_TEST_MODE
250
+
251
+asn_enc_rval_t
252
+GeneralizedTime_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
253
+	int ilevel, enum xer_encoder_flags_e flags,
254
+		asn_app_consume_bytes_f *cb, void *app_key) {
255
+
256
+	if(flags & XER_F_CANONICAL) {
257
+		GeneralizedTime_t *gt;
258
+		asn_enc_rval_t rv;
259
+		int fv, fd;		/* fractional parts */
260
+		struct tm tm;
261
+
262
+		errno = EPERM;
263
+		if(asn_GT2time_frac((GeneralizedTime_t *)sptr,
264
+					&fv, &fd, &tm, 1) == -1
265
+				&& errno != EPERM)
266
+			ASN__ENCODE_FAILED;
267
+
268
+		gt = asn_time2GT_frac(0, &tm, fv, fd, 1);
269
+		if(!gt) ASN__ENCODE_FAILED;
270
+	
271
+		rv = OCTET_STRING_encode_xer_utf8(td, sptr, ilevel, flags,
272
+			cb, app_key);
273
+		ASN_STRUCT_FREE(asn_DEF_GeneralizedTime, gt);
274
+		return rv;
275
+	} else {
276
+		return OCTET_STRING_encode_xer_utf8(td, sptr, ilevel, flags,
277
+			cb, app_key);
278
+	}
279
+}
280
+
281
+#endif	/* ASN___INTERNAL_TEST_MODE */
282
+
283
+int
284
+GeneralizedTime_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
285
+	asn_app_consume_bytes_f *cb, void *app_key) {
286
+	const GeneralizedTime_t *st = (const GeneralizedTime_t *)sptr;
287
+
288
+	(void)td;	/* Unused argument */
289
+	(void)ilevel;	/* Unused argument */
290
+
291
+	if(st && st->buf) {
292
+		char buf[32];
293
+		struct tm tm;
294
+		int ret;
295
+
296
+		errno = EPERM;
297
+		if(asn_GT2time(st, &tm, 1) == -1 && errno != EPERM)
298
+			return (cb("<bad-value>", 11, app_key) < 0) ? -1 : 0;
299
+
300
+		ret = snprintf(buf, sizeof(buf),
301
+			"%04d-%02d-%02d %02d:%02d:%02d (GMT)",
302
+			tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
303
+			tm.tm_hour, tm.tm_min, tm.tm_sec);
304
+		assert(ret > 0 && ret < (int)sizeof(buf));
305
+		return (cb(buf, ret, app_key) < 0) ? -1 : 0;
306
+	} else {
307
+		return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
308
+	}
309
+}
310
+
311
+time_t
312
+asn_GT2time(const GeneralizedTime_t *st, struct tm *ret_tm, int as_gmt) {
313
+	return asn_GT2time_frac(st, 0, 0, ret_tm, as_gmt);
314
+}
315
+
316
+time_t
317
+asn_GT2time_prec(const GeneralizedTime_t *st, int *frac_value, int frac_digits, struct tm *ret_tm, int as_gmt) {
318
+	time_t tloc;
319
+	int fv, fd = 0;
320
+
321
+	if(frac_value)
322
+		tloc = asn_GT2time_frac(st, &fv, &fd, ret_tm, as_gmt);
323
+	else
324
+		return asn_GT2time_frac(st, 0, 0, ret_tm, as_gmt);
325
+	if(fd == 0 || frac_digits <= 0) {
326
+		*frac_value = 0;
327
+	} else {
328
+		while(fd > frac_digits)
329
+			fv /= 10, fd--;
330
+		while(fd < frac_digits) {
331
+			if(fv < INT_MAX / 10) {
332
+				fv *= 10;
333
+				fd++;
334
+			} else {
335
+				/* Too long precision request */
336
+				fv = 0;
337
+				break;
338
+			}
339
+		}
340
+
341
+		*frac_value = fv;
342
+	}
343
+
344
+	return tloc;
345
+}
346
+
347
+time_t
348
+asn_GT2time_frac(const GeneralizedTime_t *st, int *frac_value, int *frac_digits, struct tm *ret_tm, int as_gmt) {
349
+	struct tm tm_s;
350
+	uint8_t *buf;
351
+	uint8_t *end;
352
+	int gmtoff_h = 0;
353
+	int gmtoff_m = 0;
354
+	int gmtoff = 0;	/* h + m */
355
+	int offset_specified = 0;
356
+	int fvalue = 0;
357
+	int fdigits = 0;
358
+	time_t tloc;
359
+
360
+	if(!st || !st->buf) {
361
+		errno = EINVAL;
362
+		return -1;
363
+	} else {
364
+		buf = st->buf;
365
+		end = buf + st->size;
366
+	}
367
+
368
+	if(st->size < 10) {
369
+		errno = EINVAL;
370
+		return -1;
371
+	}
372
+
373
+	/*
374
+	 * Decode first 10 bytes: "AAAAMMJJhh"
375
+	 */
376
+	memset(&tm_s, 0, sizeof(tm_s));
377
+#undef	B2F
378
+#undef	B2T
379
+#define	B2F(var)	do {					\
380
+		unsigned ch = *buf;				\
381
+		if(ch < 0x30 || ch > 0x39) {			\
382
+			errno = EINVAL;				\
383
+			return -1;				\
384
+		} else {					\
385
+			var = var * 10 + (ch - 0x30);		\
386
+			buf++;					\
387
+		}						\
388
+	} while(0)
389
+#define	B2T(var)	B2F(tm_s.var)
390
+
391
+	B2T(tm_year);	/* 1: A */
392
+	B2T(tm_year);	/* 2: A */
393
+	B2T(tm_year);	/* 3: A */
394
+	B2T(tm_year);	/* 4: A */
395
+	B2T(tm_mon);	/* 5: M */
396
+	B2T(tm_mon);	/* 6: M */
397
+	B2T(tm_mday);	/* 7: J */
398
+	B2T(tm_mday);	/* 8: J */
399
+	B2T(tm_hour);	/* 9: h */
400
+	B2T(tm_hour);	/* 0: h */
401
+
402
+	if(buf == end) goto local_finish;
403
+
404
+	/*
405
+	 * Parse [mm[ss[(.|,)ffff]]]
406
+	 *        ^^
407
+	 */
408
+	switch(*buf) {
409
+	case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
410
+	case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
411
+		tm_s.tm_min = (*buf++) - 0x30;
412
+		if(buf == end) { errno = EINVAL; return -1; }
413
+		B2T(tm_min);
414
+		break;
415
+	case 0x2B: case 0x2D:	/* +, - */
416
+		goto offset;
417
+	case 0x5A:		/* Z */
418
+		goto utc_finish;
419
+	default:
420
+		errno = EINVAL;
421
+		return -1;
422
+	}
423
+
424
+	if(buf == end) goto local_finish;
425
+
426
+	/*
427
+	 * Parse [mm[ss[(.|,)ffff]]]
428
+	 *           ^^
429
+	 */
430
+	switch(*buf) {
431
+	case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
432
+	case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
433
+		tm_s.tm_sec = (*buf++) - 0x30;
434
+		if(buf == end) { errno = EINVAL; return -1; }
435
+		B2T(tm_sec);
436
+		break;
437
+	case 0x2B: case 0x2D:	/* +, - */
438
+		goto offset;
439
+	case 0x5A:		/* Z */
440
+		goto utc_finish;
441
+	default:
442
+		errno = EINVAL;
443
+		return -1;
444
+	}
445
+
446
+	if(buf == end) goto local_finish;
447
+
448
+	/*
449
+	 * Parse [mm[ss[(.|,)ffff]]]
450
+	 *               ^ ^
451
+	 */
452
+	switch(*buf) {
453
+	case 0x2C: case 0x2E: /* (.|,) */
454
+		/*
455
+		 * Process fractions of seconds.
456
+		 */
457
+		for(buf++; buf < end; buf++) {
458
+			int v = *buf;
459
+			/* GCC 4.x is being too smart without volatile */
460
+			switch(v) {
461
+			case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
462
+			case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
463
+				if(fvalue < INT_MAX/10) {
464
+					fvalue = fvalue * 10 + (v - 0x30);
465
+					fdigits++;
466
+				} else {
467
+					/* Not enough precision, ignore */
468
+				}
469
+				continue;
470
+			default:
471
+				break;
472
+			}
473
+			break;
474
+		}
475
+	}
476
+
477
+	if(buf == end) goto local_finish;
478
+
479
+	switch(*buf) {
480
+	case 0x2B: case 0x2D:	/* +, - */
481
+		goto offset;
482
+	case 0x5A:		/* Z */
483
+		goto utc_finish;
484
+	default:
485
+		errno = EINVAL;
486
+		return -1;
487
+	}
488
+
489
+
490
+offset:
491
+
492
+	if(end - buf < 3) {
493
+		errno = EINVAL;
494
+		return -1;
495
+	}
496
+	buf++;
497
+	B2F(gmtoff_h);
498
+	B2F(gmtoff_h);
499
+	if(buf[-3] == 0x2D)	/* Negative */
500
+		gmtoff = -1;
501
+	else
502
+		gmtoff = 1;
503
+
504
+	if((end - buf) == 2) {
505
+		B2F(gmtoff_m);
506
+		B2F(gmtoff_m);
507
+	} else if(end != buf) {
508
+		errno = EINVAL;
509
+		return -1;
510
+	}
511
+
512
+	gmtoff = gmtoff * (3600 * gmtoff_h + 60 * gmtoff_m);
513
+
514
+	/* Fall through */
515
+utc_finish:
516
+
517
+	offset_specified = 1;
518
+
519
+	/* Fall through */
520
+local_finish:
521
+
522
+	/*
523
+	 * Validation.
524
+	 */
525
+	if((tm_s.tm_mon > 12 || tm_s.tm_mon < 1)
526
+	|| (tm_s.tm_mday > 31 || tm_s.tm_mday < 1)
527
+	|| (tm_s.tm_hour > 23)
528
+	|| (tm_s.tm_sec > 60)
529
+	) {
530
+		errno = EINVAL;
531
+		return -1;
532
+	}
533
+
534
+	/* Canonicalize */
535
+	tm_s.tm_mon -= 1;	/* 0 - 11 */
536
+	tm_s.tm_year -= 1900;
537
+	tm_s.tm_isdst = -1;
538
+
539
+	tm_s.tm_sec -= gmtoff;
540
+
541
+	/*** AT THIS POINT tm_s is either GMT or local (unknown) ****/
542
+
543
+	if(offset_specified) {
544
+		tloc = timegm(&tm_s);
545
+	} else {
546
+		/*
547
+		 * Without an offset (or "Z"),
548
+		 * we can only guess that it is a local zone.
549
+		 * Interpret it in this fashion.
550
+		 */
551
+		tloc = mktime(&tm_s);
552
+	}
553
+	if(tloc == -1) {
554
+		errno = EINVAL;
555
+		return -1;
556
+	}
557
+
558
+	if(ret_tm) {
559
+		if(as_gmt) {
560
+			if(offset_specified) {
561
+				*ret_tm = tm_s;
562
+			} else {