blob: 58b4583ac2a71a5166d310f2d9da2ec473d73060 [file] [log] [blame]
Harald Welte92c45f32010-06-12 18:59:38 +02001/*-
Harald Welteec0e2172010-07-20 00:03:44 +02002 * Copyright (c) 2003, 2004, 2005, 2007 Lev Walkin <vlm@lionet.info>.
Harald Welte92c45f32010-06-12 18:59:38 +02003 * All rights reserved.
4 * Redistribution and modifications are permitted subject to BSD license.
5 */
6/*
7 * Declarations internally useful for the ASN.1 support code.
8 */
9#ifndef _ASN_INTERNAL_H_
10#define _ASN_INTERNAL_H_
11
12#include "asn_application.h" /* Application-visible API */
13
14#ifndef __NO_ASSERT_H__ /* Include assert.h only for internal use. */
15#include <assert.h> /* for assert() macro */
16#endif
17
Harald Weltea68b3a32011-10-14 20:35:00 +020018#include <osmocom/core/talloc.h>
Harald Weltefa034002010-07-18 23:15:24 +020019
Harald Welte92c45f32010-06-12 18:59:38 +020020#ifdef __cplusplus
21extern "C" {
22#endif
23
24/* Environment version might be used to avoid running with the old library */
Harald Welte41b85d52015-08-31 08:56:53 +020025#define ASN1C_ENVIRONMENT_VERSION 924 /* Compile-time version */
Harald Welte92c45f32010-06-12 18:59:38 +020026int get_asn1c_environment_version(void); /* Run-time version */
27
Harald Weltefa034002010-07-18 23:15:24 +020028extern void *talloc_asn1_ctx;
29
Harald Welte6264d3d2010-07-18 23:30:11 +020030#define CALLOC(nmemb, size) talloc_zero_size(talloc_asn1_ctx, (nmemb) * (size))
Harald Weltefa034002010-07-18 23:15:24 +020031#define MALLOC(size) talloc_size(talloc_asn1_ctx, size)
32#define REALLOC(oldptr, size) talloc_realloc_size(talloc_asn1_ctx, oldptr, size)
33#define FREEMEM(ptr) talloc_free(ptr)
Harald Welte92c45f32010-06-12 18:59:38 +020034
Harald Welte41b85d52015-08-31 08:56:53 +020035#define asn_debug_indent 0
36#define ASN_DEBUG_INDENT_ADD(i) do{}while(0)
37
Harald Welte92c45f32010-06-12 18:59:38 +020038/*
39 * A macro for debugging the ASN.1 internals.
40 * You may enable or override it.
41 */
42#ifndef ASN_DEBUG /* If debugging code is not defined elsewhere... */
43#if EMIT_ASN_DEBUG == 1 /* And it was asked to emit this code... */
44#ifdef __GNUC__
Harald Welteec0e2172010-07-20 00:03:44 +020045#ifdef ASN_THREAD_SAFE
Harald Welte41b85d52015-08-31 08:56:53 +020046/* Thread safety requires sacrifice in output indentation:
47 * Retain empty definition of ASN_DEBUG_INDENT_ADD. */
Harald Welteec0e2172010-07-20 00:03:44 +020048#else /* !ASN_THREAD_SAFE */
Harald Welte41b85d52015-08-31 08:56:53 +020049#undef ASN_DEBUG_INDENT_ADD
50#undef asn_debug_indent
Harald Welteec0e2172010-07-20 00:03:44 +020051int asn_debug_indent;
Harald Welte41b85d52015-08-31 08:56:53 +020052#define ASN_DEBUG_INDENT_ADD(i) do { asn_debug_indent += i; } while(0)
Harald Welteec0e2172010-07-20 00:03:44 +020053#endif /* ASN_THREAD_SAFE */
Harald Welte41b85d52015-08-31 08:56:53 +020054extern int asn_debug; /* Allow option on execution */
55#define ASN_DEBUG(fmt, args...) \
56if (asn_debug) { \
57 do { \
Harald Welteec0e2172010-07-20 00:03:44 +020058 int adi = asn_debug_indent; \
59 while(adi--) fprintf(stderr, " "); \
60 fprintf(stderr, fmt, ##args); \
61 fprintf(stderr, " (%s:%d)\n", \
62 __FILE__, __LINE__); \
Harald Welte41b85d52015-08-31 08:56:53 +020063 } while(0); \
64}
Harald Welte92c45f32010-06-12 18:59:38 +020065#else /* !__GNUC__ */
66void ASN_DEBUG_f(const char *fmt, ...);
67#define ASN_DEBUG ASN_DEBUG_f
68#endif /* __GNUC__ */
69#else /* EMIT_ASN_DEBUG != 1 */
70static inline void ASN_DEBUG(const char *fmt, ...) { (void)fmt; }
71#endif /* EMIT_ASN_DEBUG */
72#endif /* ASN_DEBUG */
73
74/*
75 * Invoke the application-supplied callback and fail, if something is wrong.
76 */
77#define __ASN_E_cbc(buf, size) (cb((buf), (size), app_key) < 0)
78#define _ASN_E_CALLBACK(foo) do { \
79 if(foo) goto cb_failed; \
80 } while(0)
81#define _ASN_CALLBACK(buf, size) \
82 _ASN_E_CALLBACK(__ASN_E_cbc(buf, size))
83#define _ASN_CALLBACK2(buf1, size1, buf2, size2) \
84 _ASN_E_CALLBACK(__ASN_E_cbc(buf1, size1) || __ASN_E_cbc(buf2, size2))
85#define _ASN_CALLBACK3(buf1, size1, buf2, size2, buf3, size3) \
86 _ASN_E_CALLBACK(__ASN_E_cbc(buf1, size1) \
87 || __ASN_E_cbc(buf2, size2) \
88 || __ASN_E_cbc(buf3, size3))
89
90#define _i_ASN_TEXT_INDENT(nl, level) do { \
91 int __level = (level); \
92 int __nl = ((nl) != 0); \
93 int __i; \
94 if(__nl) _ASN_CALLBACK("\n", 1); \
Harald Welteec0e2172010-07-20 00:03:44 +020095 if(__level < 0) __level = 0; \
Harald Welte92c45f32010-06-12 18:59:38 +020096 for(__i = 0; __i < __level; __i++) \
97 _ASN_CALLBACK(" ", 4); \
98 er.encoded += __nl + 4 * __level; \
99} while(0)
100
101#define _i_INDENT(nl) do { \
102 int __i; \
103 if((nl) && cb("\n", 1, app_key) < 0) return -1; \
104 for(__i = 0; __i < ilevel; __i++) \
105 if(cb(" ", 4, app_key) < 0) return -1; \
106} while(0)
107
108/*
109 * Check stack against overflow, if limit is set.
110 */
111#define _ASN_DEFAULT_STACK_MAX (30000)
112static inline int
113_ASN_STACK_OVERFLOW_CHECK(asn_codec_ctx_t *ctx) {
114 if(ctx && ctx->max_stack_size) {
115
116 /* ctx MUST be allocated on the stack */
117 ptrdiff_t usedstack = ((char *)ctx - (char *)&ctx);
118 if(usedstack > 0) usedstack = -usedstack; /* grows up! */
119
120 /* double negative required to avoid int wrap-around */
121 if(usedstack < -(ptrdiff_t)ctx->max_stack_size) {
122 ASN_DEBUG("Stack limit %ld reached",
123 (long)ctx->max_stack_size);
124 return -1;
125 }
126 }
127 return 0;
128}
129
130#ifdef __cplusplus
131}
132#endif
133
134#endif /* _ASN_INTERNAL_H_ */