#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Typedefs that CORE needs. */
typedef char c_int8_t;
typedef unsigned char c_uint8_t;
typedef @short_value@ c_int16_t;
typedef unsigned @short_value@ c_uint16_t;
typedef @int_value@ c_int32_t;
typedef unsigned @int_value@ c_uint32_t;
typedef @long_value@ c_int64_t;
typedef unsigned @long_value@ c_uint64_t;
#if SIZEOF_VOIDP == 8
typedef c_uint64_t c_uintptr_t;
typedef c_int64_t c_intptr_t;
#else
typedef c_uint32_t c_uintptr_t;
typedef c_int32_t c_intptr_t;
#endif
/* Mechanisms to properly type numeric literals */
@int64_literal@
@uint64_literal@
@int64_t_fmt@
@uint64_t_fmt@
@uint64_t_hex_fmt@
@pid_t_fmt@
#ifdef INT16_MIN
#define C_INT16_MIN INT16_MIN
#else
#define C_INT16_MIN (-0x7fff - 1)
#endif
#ifdef INT16_MAX
#define C_INT16_MAX INT16_MAX
#else
#define C_INT16_MAX (0x7fff)
#endif
#ifdef UINT16_MAX
#define C_UINT16_MAX UINT16_MAX
#else
#define C_UINT16_MAX (0xffff)
#endif
#ifdef INT32_MIN
#define C_INT32_MIN INT32_MIN
#else
#define C_INT32_MIN (-0x7fffffff - 1)
#endif
#ifdef INT32_MAX
#define C_INT32_MAX INT32_MAX
#else
#define C_INT32_MAX 0x7fffffff
#endif
#ifdef UINT32_MAX
#define C_UINT32_MAX UINT32_MAX
#else
#define C_UINT32_MAX (0xffffffffU)
#endif
#ifdef INT64_MIN
#define C_INT64_MIN INT64_MIN
#else
#define C_INT64_MIN (C_INT64_C(-0x7fffffffffffffff) - 1)
#endif
#ifdef INT64_MAX
#define C_INT64_MAX INT64_MAX
#else
#define C_INT64_MAX C_INT64_C(0x7fffffffffffffff)
#endif
#ifdef UINT64_MAX
#define C_UINT64_MAX UINT64_MAX
#else
#define C_UINT64_MAX C_UINT64_C(0xffffffffffffffff)
#endif
/* Definitions that CORE programs need to work properly. */
/**
* Thread callbacks from CORE functions must be declared with THREAD_FUNC,
* so that they follow the platform's calling convention.
*
*
* void* THREAD_FUNC my_thread_entry_fn(thread_id id, void *data);
*
*
*/
#define THREAD_FUNC
/**
* The public CORE functions are declared with CORE_DECLARE(), so they may
* use the most appropriate calling convention. Public CORE functions with
* variable arguments must use CORE_DECLARE_NONSTD().
*
* @remark Both the declaration and implementations must use the same macro.
*
*
* CORE_DECLARE(rettype) core_func(args)
*
* @see CORE_DECLARE_NONSTD @see CORE_DECLARE_DATA
* @remark Note that when CORE compiles the library itself, it passes the
* symbol -DCORE_DECLARE_EXPORT to the compiler on some platforms (e.g. Win32)
* to export public symbols from the dynamic library build.\n
* The user must define the CORE_DECLARE_STATIC when compiling to target
* the static CORE library on some platforms (e.g. Win32.) The public symbols
* are neither exported nor imported when CORE_DECLARE_STATIC is defined.\n
* By default, compiling an application and including the CORE public
* headers, without defining CORE_DECLARE_STATIC, will prepare the code to be
* linked to the dynamic library.
*/
#define CORE_DECLARE(type) type
/**
* The public CORE functions using variable arguments are declared with
* CORE_DECLARE_NONSTD(), as they must follow the C language calling convention.
* @see CORE_DECLARE @see CORE_DECLARE_DATA
* @remark Both the declaration and implementations must use the same macro.
*
*
* CORE_DECLARE_NONSTD(rettype) core_func(args, ...);
*
*
*/
#define CORE_DECLARE_NONSTD(type) type
/**
* The public CORE variables are declared with CORE_DECLARE_DATA.
* This assures the appropriate indirection is invoked at compile time.
* @see CORE_DECLARE @see CORE_DECLARE_NONSTD
* @remark Note that the declaration and implementations use different forms,
* but both must include the macro.
*
*
*
* extern CORE_DECLARE_DATA type core_variable;\n
* CORE_DECLARE_DATA type core_variable = value;
*
*
*/
#define CORE_DECLARE_DATA
#if defined(PATH_MAX)
#define C_PATH_MAX PATH_MAX
#elif defined(_POSIX_PATH_MAX)
#define C_PATH_MAX _POSIX_PATH_MAX
#else
#error no decision has been made on C_PATH_MAX for your platform
#endif
/** @} */
/* Definitions that only Win32 programs need to compile properly. */
#if WORDS_BIGENDIAN
#define ED2(x1, x2) x1 x2
#define ED3(x1, x2, x3) x1 x2 x3
#define ED4(x1, x2, x3, x4) x1 x2 x3 x4
#define ED5(x1, x2, x3, x4, x5) x1 x2 x3 x4 x5
#define ED6(x1, x2, x3, x4, x5, x6) x1 x2 x3 x4 x5 x6
#define ED7(x1, x2, x3, x4, x5, x6, x7) x1 x2 x3 x4 x5 x6 x7
#define ED8(x1, x2, x3, x4, x5, x6, x7, x8) x1 x2 x3 x4 x5 x6 x7 x8
#else
#define ED2(x1, x2) x2 x1
#define ED3(x1, x2, x3) x3 x2 x1
#define ED4(x1, x2, x3, x4) x4 x3 x2 x1
#define ED5(x1, x2, x3, x4, x5) x5 x4 x3 x2 x1
#define ED6(x1, x2, x3, x4, x5, x6) x6 x5 x4 x3 x2 x1
#define ED7(x1, x2, x3, x4, x5, x6, x7) x7 x6 x5 x4 x3 x2 x1
#define ED8(x1, x2, x3, x4, x5, x6, x7, x8) x8 x7 x6 x5 x4 x3 x2 x1
#endif
/** FALSE */
#ifndef FALSE
#define FALSE 0
#endif
/** TRUE */
#ifndef TRUE
#define TRUE (!FALSE)
#endif
/* CORE_ALIGN() is only to be used to align on a power of 2 boundary */
#define CORE_ALIGN(size, boundary) \
(((size) + ((boundary) - 1)) & ~((boundary) - 1))
/** Default alignment */
#define CORE_ALIGN_DEFAULT(size) CORE_ALIGN(size, 4)
#ifdef __cplusplus
}
#endif
#endif /* CORE_H */
nextepc-0.3.10/lib/core/include/core_aes.h 0000664 0000000 0000000 00000002614 13335533574 0020331 0 ustar 00root root 0000000 0000000 #ifndef _CORE_AES_H__
#define _CORE_AES_H__
#include "core.h"
#include "core_errno.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define AES_BLOCK_SIZE 16
#define MAX_KEY_BITS 256
#define KEYLENGTH(keybits) ((keybits)/8)
#define RKLENGTH(keybits) ((keybits)/8+28)
#define NROUNDS(keybits) ((keybits)/32+6)
CORE_DECLARE(int) aes_setup_enc(c_uint32_t *rk, const c_uint8_t *key,
int keybits);
CORE_DECLARE(int) aes_setup_dec(c_uint32_t *rk, const c_uint8_t *key,
int keybits);
CORE_DECLARE(void) aes_encrypt(const c_uint32_t *rk, int nrounds,
const c_uint8_t plaintext[16], c_uint8_t ciphertext[16]);
CORE_DECLARE(void) aes_decrypt(const c_uint32_t *rk, int nrounds,
const c_uint8_t ciphertext[16], c_uint8_t plaintext[16]);
CORE_DECLARE(status_t) aes_cbc_encrypt(const c_uint8_t *key,
const c_uint32_t keybits, c_uint8_t *ivec,
const c_uint8_t *in, const c_uint32_t inlen,
c_uint8_t *out, c_uint32_t *outlen);
CORE_DECLARE(status_t) aes_cbc_decrypt(const c_uint8_t *key,
const c_uint32_t keybits, c_uint8_t *ivec,
const c_uint8_t *in, const c_uint32_t inlen,
c_uint8_t *out, c_uint32_t *outlen);
CORE_DECLARE(status_t) aes_ctr128_encrypt(const c_uint8_t *key,
c_uint8_t *ivec, const c_uint8_t *in, const c_uint32_t inlen,
c_uint8_t *out);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
nextepc-0.3.10/lib/core/include/core_aes_cmac.h 0000664 0000000 0000000 00000001436 13335533574 0021315 0 ustar 00root root 0000000 0000000 #ifndef _CORE_AES_CMAC_H
#define _CORE_AES_CMAC_H
#include "core_aes.h"
#define AES_CMAC_DIGEST_LEN 16
#ifdef __cplusplus
extern "C" {
#endif
/**
* Caculate CMAC value
*
* @param cmac
* @param key
* @param msg
* @param len
*
* @return CORE_OK
* CORE_ERROR
*/
CORE_DECLARE(status_t) aes_cmac_calculate(c_uint8_t *cmac, const c_uint8_t *key,
const c_uint8_t *msg, const c_uint32_t len);
/**
* Verify CMAC value
*
* @param cmac
* @param key
* @param msg
* @param len
*
* @return CORE_OK
* CORE_ERROR
* ERR_INVALID_CMAC
*/
#define ERR_INVALID_CMAC -2
CORE_DECLARE(status_t) aes_cmac_verify(c_uint8_t *cmac, const c_uint8_t *key,
const c_uint8_t *msg, const c_uint32_t len);
#ifdef __cplusplus
}
#endif
#endif /* ! _CORE_AES_CMAC_H */
nextepc-0.3.10/lib/core/include/core_atomic.h 0000664 0000000 0000000 00000006277 13335533574 0021046 0 ustar 00root root 0000000 0000000 #ifndef __CORE_ATOMIC_H__
#define __CORE_ATOMIC_H__
#include "core.h"
#include "core_errno.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* this function is required on some platforms to initialize the
* atomic operation's internal structures
* @param p pool
* @return APR_SUCCESS on successful completion
* @remark Programs do NOT need to call this directly. APR will call this
* automatically from apr_initialize.
* @internal
*/
CORE_DECLARE(status_t) atomic_init();
CORE_DECLARE(status_t) atomic_final();
/*
* Atomic operations on 32-bit values
* Note: Each of these functions internally implements a memory barrier
* on platforms that require it
*/
/**
* atomically read an c_uint32_t from memory
* @param mem the pointer
*/
CORE_DECLARE(c_uint32_t) atomic_read32(volatile c_uint32_t *mem);
/**
* atomically set an c_uint32_t in memory
* @param mem pointer to the object
* @param val value that the object will assume
*/
CORE_DECLARE(void) atomic_set32(volatile c_uint32_t *mem, c_uint32_t val);
/**
* atomically add 'val' to an c_uint32_t
* @param mem pointer to the object
* @param val amount to add
* @return old value pointed to by mem
*/
CORE_DECLARE(c_uint32_t) atomic_add32(volatile c_uint32_t *mem, c_uint32_t val);
/**
* atomically subtract 'val' from an c_uint32_t
* @param mem pointer to the object
* @param val amount to subtract
*/
CORE_DECLARE(void) atomic_sub32(volatile c_uint32_t *mem, c_uint32_t val);
/**
* atomically increment an c_uint32_t by 1
* @param mem pointer to the object
* @return old value pointed to by mem
*/
CORE_DECLARE(c_uint32_t) atomic_inc32(volatile c_uint32_t *mem);
/**
* atomically decrement an c_uint32_t by 1
* @param mem pointer to the atomic value
* @return zero if the value becomes zero on decrement, otherwise non-zero
*/
CORE_DECLARE(int) atomic_dec32(volatile c_uint32_t *mem);
/**
* compare an c_uint32_t's value with 'cmp'.
* If they are the same swap the value with 'with'
* @param mem pointer to the value
* @param with what to swap it with
* @param cmp the value to compare it to
* @return the old value of *mem
*/
CORE_DECLARE(c_uint32_t) atomic_cas32(volatile c_uint32_t *mem, c_uint32_t with,
c_uint32_t cmp);
/**
* exchange an c_uint32_t's value with 'val'.
* @param mem pointer to the value
* @param val what to swap it with
* @return the old value of *mem
*/
CORE_DECLARE(c_uint32_t) atomic_xchg32(volatile c_uint32_t *mem,
c_uint32_t val);
/**
* compare the pointer's value with cmp.
* If they are the same swap the value with 'with'
* @param mem pointer to the pointer
* @param with what to swap it with
* @param cmp the value to compare it to
* @return the old value of the pointer
*/
CORE_DECLARE(void*) atomic_casptr(void *volatile *mem, void *with,
const void *cmp);
/**
* exchange a pair of pointer values
* @param mem pointer to the pointer
* @param with what to swap it with
* @return the old value of the pointer
*/
CORE_DECLARE(void*) atomic_xchgptr(void *volatile *mem, void *with);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* !__CORE_ATOMIC_H__ */
nextepc-0.3.10/lib/core/include/core_cond.h 0000664 0000000 0000000 00000010061 13335533574 0020477 0 ustar 00root root 0000000 0000000 #ifndef __CORE_COND_H__
#define __CORE_COND_H__
/**
* @file cond.h
* @brief CORE Condition Variable Routines
*/
#include "core.h"
#include "core_errno.h"
#include "core_time.h"
#include "core_mutex.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup cond Condition Variable Routines
* @ingroup CORE
* @{
*/
/** Opaque structure for thread condition variables */
typedef c_uintptr_t cond_id;
/**
* Initialize Conditional Pool
*/
CORE_DECLARE(status_t) cond_init(void);
/**
* Finalize Conditional Pool
*/
CORE_DECLARE(status_t) cond_final(void);
/**
* Note: destroying a condition variable (or likewise, destroying or
* clearing the pool from which a condition variable was allocated) if
* any threads are blocked waiting on it gives undefined results.
*/
/**
* Create and initialize a condition variable that can be used to signal
* and schedule threads in a single process.
* @param id the memory address where the newly created condition variable
* will be stored.
*/
CORE_DECLARE(status_t) cond_create(cond_id *id);
/**
* Put the active calling thread to sleep until signaled to wake up. Each
* condition variable must be associated with a mutex, and that mutex must
* be locked before calling this function, or the behavior will be
* undefined. As the calling thread is put to sleep, the given mutex
* will be simultaneously released; and as this thread wakes up the lock
* is again simultaneously acquired.
* @param id the condition variable on which to block.
* @param mid the mutex that must be locked upon entering this function,
* is released while the thread is asleep, and is again acquired before
* returning from this function.
* @remark Spurious wakeups may occur. Before and after every call to wait on
* a condition variable, the caller should test whether the condition is already
* met.
*/
CORE_DECLARE(status_t) cond_wait(cond_id id, mutex_id mid);
/**
* Put the active calling thread to sleep until signaled to wake up or
* the timeout is reached. Each condition variable must be associated
* with a mutex, and that mutex must be locked before calling this
* function, or the behavior will be undefined. As the calling thread
* is put to sleep, the given mutex will be simultaneously released;
* and as this thread wakes up the lock is again simultaneously acquired.
* @param id the condition variable on which to block.
* @param mid the mutex that must be locked upon entering this function,
* is released while the thread is asleep, and is again acquired before
* returning from this function.
* @param timeout The amount of time in microseconds to wait. This is
* a maximum, not a minimum. If the condition is signaled, we
* will wake up before this time, otherwise the error CORE_TIMEUP
* is returned.
*/
CORE_DECLARE(status_t) cond_timedwait(
cond_id id, mutex_id mid, c_time_t timeout);
/**
* Signals a single thread, if one exists, that is blocking on the given
* condition variable. That thread is then scheduled to wake up and acquire
* the associated mutex. Although it is not required, if predictable scheduling
* is desired, that mutex must be locked while calling this function.
* @param id the condition variable on which to produce the signal.
* @remark If no threads are waiting on the condition variable, nothing happens.
*/
CORE_DECLARE(status_t) cond_signal(cond_id id);
/**
* Signals all threads blocking on the given condition variable.
* Each thread that was signaled is then scheduled to wake up and acquire
* the associated mutex. This will happen in a serialized manner.
* @param id the condition variable on which to produce the broadcast.
* @remark If no threads are waiting on the condition variable, nothing happens.
*/
CORE_DECLARE(status_t) cond_broadcast(cond_id id);
/**
* Destroy the condition variable and free the associated memory.
* @param id the condition variable to destroy.
*/
CORE_DECLARE(status_t) cond_delete(cond_id id);
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ! __CORE_COND_H__ */
nextepc-0.3.10/lib/core/include/core_debug.h 0000664 0000000 0000000 00000013072 13335533574 0020647 0 ustar 00root root 0000000 0000000 #ifndef __CORE_DEBUG_H__
#define __CORE_DEBUG_H__
#include "core.h"
#include "core_time.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#ifdef TRACE_MODULE
int TRACE_MODULE;
#endif
extern int g_trace_mask;
#define trace_level_set(__level) (TRACE_MODULE = __level);
#define D_MSG_TYPE_NONE 0
#define D_MSG_TYPE_RAW 1
#define D_MSG_TYPE_TRACE 2
#define D_MSG_TYPE_LOG 3
#define D_MSG_TYPE_ASSERT 4
#define D_MSG_TO_CONSOLE 0x00000001
#define D_MSG_TO_STDOUT 0x00000002
#define D_MSG_TO_SYSLOG 0x00000004
#define D_MSG_TO_NETWORK 0x00000008
#define D_MSG_TO_FILE 0x00000010
#define D_MSG_TO_ALL (D_MSG_TO_CONSOLE | D_MSG_TO_STDOUT | \
D_MSG_TO_SYSLOG | D_MSG_TO_NETWORK | \
D_MSG_TO_FILE )
#define D_LOG_LEVEL_NONE 0
#define D_LOG_LEVEL_FATAL 1
#define D_LOG_LEVEL_ERROR 2
#define D_LOG_LEVEL_WARN 3
#define D_LOG_LEVEL_INFO 4
#define D_LOG_LEVEL_FULL D_LOG_LEVEL_INFO
CORE_DECLARE(int) d_msg(int tp, int lv, c_time_t t, char *fn, int ln,
char *fmt, ...);
/**
* Use for printing message. This always print out the message.
*/
#define d_print(fmt, ...) \
d_msg(D_MSG_TYPE_RAW, 0, 0, NULL, 0, fmt, ## __VA_ARGS__)
#define __MAX_HEX_BUF 128
/**
* Use for printing binary buffer as printable hex string. This always
* print out the message.
*/
#define d_print_hex(__buf, __buflen) do { \
int __i = 0, __l, __off = 0; \
char __hex[__MAX_HEX_BUF*2+__MAX_HEX_BUF/4+__MAX_HEX_BUF/32+4], *__p; \
d_print("%d bytes hex:\r\n", __buflen); \
while (__off < (__buflen)) { \
__p = __hex; __p[0] = 0; \
__l = ((__buflen) - __off) > __MAX_HEX_BUF ? \
__MAX_HEX_BUF : (__buflen) - __off; \
for (__i = 0; __i < __l; __i++) { \
__p += sprintf(__p, "%02x", ((char*)(__buf))[__off+__i] & 0xff); \
if ((__i & 0x1f) == 31) \
__p += sprintf(__p, "\r\n"); \
else if ((__i & 0x3) == 3) \
__p += sprintf(__p, " "); \
} \
__off += __l; \
d_print(__hex); \
} \
if (__i & 0x1f) d_print("\r\n"); \
} while (0)
/**
* Use for trace.
* Trace message shall be shown only if trace level is set equal or higher
* than __level.
*/
#define d_trace(__level, fmt, ...) \
(!g_trace_mask || TRACE_MODULE < __level ? 0 : \
d_msg(D_MSG_TYPE_TRACE, 0, time_now(), NULL, 0, fmt, ## __VA_ARGS__))
#define d_trace2(__level, fmt, ...) \
(!g_trace_mask || TRACE_MODULE < __level ? 0 : \
d_msg(D_MSG_TYPE_RAW, 0, 0, NULL, 0, fmt, ## __VA_ARGS__))
/**
* Use for trace binary buffer as printable hex string .
* Trace message shall be shown only if trace level is set equal or higher
* than __level.
*/
#define d_trace_hex(__level, __buf, __buflen) do { \
if (g_trace_mask && TRACE_MODULE >= __level) \
d_print_hex(__buf, __buflen); \
} while (0)
/**
* Informative log.
* If log level is larger than 4,
* this message is logged with informative format.
*/
#define d_info(fmt, ...) \
d_msg(D_MSG_TYPE_LOG, D_LOG_LEVEL_INFO, time_now(), \
__FILE__, __LINE__, fmt, ## __VA_ARGS__)
/**
* Informative log.
* If log level is larger than 3,
* this message is logged with warning format.
*/
#define d_warn(fmt, ...) \
d_msg(D_MSG_TYPE_LOG, D_LOG_LEVEL_WARN, time_now(), \
__FILE__, __LINE__, fmt, ## __VA_ARGS__)
/**
* Error log.
* If log level is larger than 2,
* this message is logged with error format.
*/
#define d_error(fmt, ...) \
d_msg(D_MSG_TYPE_LOG, D_LOG_LEVEL_ERROR, time_now(), \
__FILE__, __LINE__, fmt, ## __VA_ARGS__)
/**
* Fatal error log.
* If log level is larger than 1,
* this message is logged with fatal error format.
*/
#define d_fatal(fmt, ...) \
d_msg(D_MSG_TYPE_LOG, D_LOG_LEVEL_FATAL, time_now(), \
__FILE__, __LINE__, fmt, ## __VA_ARGS__)
/**
* Assertion
* this message is logged with assertion format.
*/
#define d_assert(cond, expr, fmt, ...) \
if (!(cond)) { \
d_msg(D_MSG_TYPE_ASSERT, 0, time_now(), __FILE__, __LINE__, \
"!("#cond"). "fmt, ## __VA_ARGS__); \
expr; \
}
status_t d_msg_console_init(int console_fd);
void d_msg_console_final();
void d_msg_syslog_init(const char *name);
void d_msg_syslog_final();
status_t d_msg_network_init(const char *name);
void d_msg_network_final();
status_t d_msg_network_start(const char *file);
void d_msg_network_stop();
void d_msg_network_final();
status_t d_msg_file_init(const char *file);
void d_msg_file_final();
void d_msg_to(int to, int on_off);
int d_msg_get_to();
/**
* Turn on log partially.
* level 4: d_fatal, d_error, d_warn, d_info
* level 3: d_fatal, d_error, d_warn
* level 2: d_fatal, d_error
* level 1: d_fatal
* level 0: none
*/
void d_log_set_level(int to, int level);
int d_log_get_level(int to);
/**
* Turn on log fully.
* All of d_info, d_warn, d_error and d_fatal will be shown.
* Equivalent to log_level(4).
*/
void d_log_full(int to);
/**
* Turn off log fully.
* All log will not be shown.
* Equivalent to log_level(0).
*/
void d_log_off(int to);
/**
* Turn on trace mask globally.
*/
void d_trace_global_on();
/**
* Turn off trace mask globally.
* Any trace of any module will not be shown although some trace module is
* turned on.
*/
void d_trace_global_off();
/**
* Turn on trace of specifed module with level. */
void d_trace_level(int *mod_name, int level);
/**
* Turn off trace of specifed module.
* Equivalent to trace_level(0).
*/
void d_trace_off(int *mod_name);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ! __CORE_DEBUG_H__ */
nextepc-0.3.10/lib/core/include/core_errno.h 0000664 0000000 0000000 00000145430 13335533574 0020712 0 ustar 00root root 0000000 0000000 /* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CORE_ERRNO_H__
#define __CORE_ERRNO_H__
/**
* @file core_errno.h
* @brief CORE Error Codes
*/
#include "core.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup core_errno Error Codes
* @ingroup CORE
* @{
*/
/**
* Type for specifying an error or status code.
*/
typedef int status_t;
/**
* Return a human readable string describing the specified error.
* @param statcode The error code the get a string for.
* @param buf A buffer to hold the error string.
* @param bufsize Size of the buffer to hold the string.
*/
CORE_DECLARE(char *) core_strerror(status_t statcode, char *buf,
size_t bufsize);
#if defined(DOXYGEN)
/**
* @def FROM_OS_ERROR(os_err_type syserr)
* Fold a platform specific error into an STATUS_T code.
* @return STATUS_T
* @param e The platform os error code.
* @warning macro implementation; the syserr argument may be evaluated
* multiple times.
*/
#define FROM_OS_ERROR(e) (e == 0 ? CORE_OK : e + OS_START_SYSERR)
/**
* @def TO_OS_ERROR(STATUS_T statcode)
* @return os_err_type
* Fold an STATUS_T code back to the native platform defined error.
* @param e The STATUS_T folded platform os error code.
* @warning macro implementation; the statcode argument may be evaluated
* multiple times. If the statcode was not created by get_os_error
* or FROM_OS_ERROR, the results are undefined.
*/
#define TO_OS_ERROR(e) (e == 0 ? CORE_OK : e - OS_START_SYSERR)
/** @def get_os_error()
* @return STATUS_T the last platform error, folded into STATUS_T, on most platforms
* @remark This retrieves errno, or calls a GetLastError() style function, and
* folds it with FROM_OS_ERROR. Some platforms (such as OS2) have no
* such mechanism, so this call may be unsupported. Do NOT use this
* call for socket errors from socket, send, recv etc!
*/
/** @def set_os_error(e)
* Reset the last platform error, unfolded from an STATUS_T, on some platforms
* @param e The OS error folded in a prior call to FROM_OS_ERROR()
* @warning This is a macro implementation; the statcode argument may be evaluated
* multiple times. If the statcode was not created by get_os_error
* or FROM_OS_ERROR, the results are undefined. This macro sets
* errno, or calls a SetLastError() style function, unfolding statcode
* with TO_OS_ERROR. Some platforms (such as OS2) have no such
* mechanism, so this call may be unsupported.
*/
/** @def get_netos_error()
* Return the last socket error, folded into STATUS_T, on all platforms
* @remark This retrieves errno or calls a GetLastSocketError() style function,
* and folds it with FROM_OS_ERROR.
*/
/** @def set_netos_error(e)
* Reset the last socket error, unfolded from an STATUS_T
* @param e The socket error folded in a prior call to FROM_OS_ERROR()
* @warning This is a macro implementation; the statcode argument may be evaluated
* multiple times. If the statcode was not created by get_os_error
* or FROM_OS_ERROR, the results are undefined. This macro sets
* errno, or calls a WSASetLastError() style function, unfolding
* socketcode with TO_OS_ERROR.
*/
#endif /* defined(DOXYGEN) */
/**
* OS_START_ERROR is where the CORE specific error values start.
*/
#define OS_START_ERROR 20000
/**
* OS_ERRSPACE_SIZE is the maximum number of errors you can fit
* into one of the error/status ranges below -- except for
* OS_START_USERERR, which see.
*/
#define OS_ERRSPACE_SIZE 50000
/**
* UTIL_ERRSPACE_SIZE is the size of the space that is reserved for
* use within core-util. This space is reserved above that used by CORE
* internally.
* @note This number MUST be smaller than OS_ERRSPACE_SIZE by a
* large enough amount that CORE has sufficient room for it's
* codes.
*/
#define UTIL_ERRSPACE_SIZE 20000
/**
* OS_START_STATUS is where the CORE specific status codes start.
*/
#define OS_START_STATUS (OS_START_ERROR + OS_ERRSPACE_SIZE)
/**
* UTIL_START_STATUS is where CORE-Util starts defining it's
* status codes.
*/
#define UTIL_START_STATUS (OS_START_STATUS + \
(OS_ERRSPACE_SIZE - UTIL_ERRSPACE_SIZE))
/**
* OS_START_USERERR are reserved for applications that use CORE that
* layer their own error codes along with CORE's. Note that the
* error immediately following this one is set ten times farther
* away than usual, so that users of core have a lot of room in
* which to declare custom error codes.
*
* In general applications should try and create unique error codes. To try
* and assist in finding suitable ranges of numbers to use, the following
* ranges are known to be used by the listed applications. If your
* application defines error codes please advise the range of numbers it
* uses to dev@core.apache.org for inclusion in this list.
*
* Ranges shown are in relation to OS_START_USERERR
*
* Subversion - Defined ranges, of less than 100, at intervals of 5000
* starting at an offset of 5000, e.g.
* +5000 to 5100, +10000 to 10100
*/
#define OS_START_USERERR (OS_START_STATUS + OS_ERRSPACE_SIZE)
/**
* OS_START_USEERR is obsolete, defined for compatibility only.
* Use OS_START_USERERR instead.
*/
#define OS_START_USEERR OS_START_USERERR
/**
* OS_START_CANONERR is where CORE versions of errno values are defined
* on systems which don't have the corresponding errno.
*/
#define OS_START_CANONERR (OS_START_USERERR \
+ (OS_ERRSPACE_SIZE * 10))
/**
* OS_START_EAIERR folds EAI_ error codes from getaddrinfo() into
* STATUS_T values.
*/
#define OS_START_EAIERR (OS_START_CANONERR + OS_ERRSPACE_SIZE)
/**
* OS_START_SYSERR folds platform-specific system error values into
* STATUS_T values.
*/
#define OS_START_SYSERR (OS_START_EAIERR + OS_ERRSPACE_SIZE)
/**
* @defgroup CORE_ERROR_map CORE Error Space
*
* The following attempts to show the relation of the various constants
* used for mapping CORE Status codes.
*
* 0
*
* 20,000 OS_START_ERROR
*
* + OS_ERRSPACE_SIZE (50,000)
*
* 70,000 OS_START_STATUS
*
* + OS_ERRSPACE_SIZE - UTIL_ERRSPACE_SIZE (30,000)
*
* 100,000 UTIL_START_STATUS
*
* + UTIL_ERRSPACE_SIZE (20,000)
*
* 120,000 OS_START_USERERR
*
* + 10 x OS_ERRSPACE_SIZE (50,000 * 10)
*
* 620,000 OS_START_CANONERR
*
* + OS_ERRSPACE_SIZE (50,000)
*
* 670,000 OS_START_EAIERR
*
* + OS_ERRSPACE_SIZE (50,000)
*
* 720,000 OS_START_SYSERR
*
*
*/
/** no error. */
#define CORE_OK 0
#define CORE_ERROR -1
/**
* @defgroup CORE_Error CORE Error Values
*
* CORE ERROR VALUES
* CORE_ENOSTAT CORE was unable to perform a stat on the file
* CORE_ENOPOOL CORE was not provided a pool with which to allocate memory
* CORE_EBADDATE CORE was given an invalid date
* CORE_EINVALSOCK CORE was given an invalid socket
* CORE_ENOPROC CORE was not given a process structure
* CORE_ENOTIME CORE was not given a time structure
* CORE_ENODIR CORE was not given a directory structure
* CORE_ENOLOCK CORE was not given a lock structure
* CORE_ENOPOLL CORE was not given a poll structure
* CORE_ENOSOCKET CORE was not given a socket
* CORE_ENOTHREAD CORE was not given a thread structure
* CORE_ENOTHDKEY CORE was not given a thread key structure
* CORE_ENOSHMAVAIL There is no more shared memory available
* CORE_EDSOOPEN CORE was unable to open the dso object. For more
* information call dso_error().
* CORE_EGENERAL General failure (specific information not available)
* CORE_EBADIP The specified IP address is invalid
* CORE_EBADMASK The specified netmask is invalid
* CORE_ESYMNOTFOUND Could not find the requested symbol
* CORE_ENOTENOUGHENTROPY Not enough entropy to continue
*
*
*
* CORE STATUS VALUES
* CORE_INCHILD Program is currently executing in the child
* CORE_INPARENT Program is currently executing in the parent
* CORE_DETACH The thread is detached
* CORE_NOTDETACH The thread is not detached
* CORE_CHILD_DONE The child has finished executing
* CORE_CHILD_NOTDONE The child has not finished executing
* CORE_TIMEUP The operation did not finish before the timeout
* CORE_INCOMPLETE The operation was incomplete although some processing
* was performed and the results are partially valid
* CORE_BADCH Getopt found an option not in the option string
* CORE_BADARG Getopt found an option that is missing an argument
* and an argument was specified in the option string
* CORE_EOF CORE has encountered the end of the file
* CORE_NOTFOUND CORE was unable to find the socket in the poll structure
* CORE_ANONYMOUS CORE is using anonymous shared memory
* CORE_FILEBASED CORE is using a file name as the key to the shared memory
* CORE_KEYBASED CORE is using a shared key as the key to the shared memory
* CORE_EINIT Ininitalizer value. If no option has been found, but
* the status variable requires a value, this should be used
* CORE_ENOTIMPL The CORE function has not been implemented on this
* platform, either because nobody has gotten to it yet,
* or the function is impossible on this platform.
* CORE_EMISMATCH Two passwords do not match.
* CORE_EABSOLUTE The given path was absolute.
* CORE_ERELATIVE The given path was relative.
* CORE_EINCOMPLETE The given path was neither relative nor absolute.
* CORE_EABOVEROOT The given path was above the root path.
* CORE_EBUSY The given lock was busy.
* CORE_EPROC_UNKNOWN The given process wasn't recognized by CORE
*
* @{
*/
/** @see STATUS_IS_ENOSTAT */
#define CORE_ENOSTAT (OS_START_ERROR + 1)
/** @see STATUS_IS_ENOPOOL */
#define CORE_ENOPOOL (OS_START_ERROR + 2)
/* empty slot: +3 */
/** @see STATUS_IS_EBADDATE */
#define CORE_EBADDATE (OS_START_ERROR + 4)
/** @see STATUS_IS_EINVALSOCK */
#define CORE_EINVALSOCK (OS_START_ERROR + 5)
/** @see STATUS_IS_ENOPROC */
#define CORE_ENOPROC (OS_START_ERROR + 6)
/** @see STATUS_IS_ENOTIME */
#define CORE_ENOTIME (OS_START_ERROR + 7)
/** @see STATUS_IS_ENODIR */
#define CORE_ENODIR (OS_START_ERROR + 8)
/** @see STATUS_IS_ENOLOCK */
#define CORE_ENOLOCK (OS_START_ERROR + 9)
/** @see STATUS_IS_ENOPOLL */
#define CORE_ENOPOLL (OS_START_ERROR + 10)
/** @see STATUS_IS_ENOSOCKET */
#define CORE_ENOSOCKET (OS_START_ERROR + 11)
/** @see STATUS_IS_ENOTHREAD */
#define CORE_ENOTHREAD (OS_START_ERROR + 12)
/** @see STATUS_IS_ENOTHDKEY */
#define CORE_ENOTHDKEY (OS_START_ERROR + 13)
/** @see STATUS_IS_EGENERAL */
#define CORE_EGENERAL (OS_START_ERROR + 14)
/** @see STATUS_IS_ENOSHMAVAIL */
#define CORE_ENOSHMAVAIL (OS_START_ERROR + 15)
/** @see STATUS_IS_EBADIP */
#define CORE_EBADIP (OS_START_ERROR + 16)
/** @see STATUS_IS_EBADMASK */
#define CORE_EBADMASK (OS_START_ERROR + 17)
/* empty slot: +18 */
/** @see STATUS_IS_EDSOPEN */
#define CORE_EDSOOPEN (OS_START_ERROR + 19)
/** @see STATUS_IS_EABSOLUTE */
#define CORE_EABSOLUTE (OS_START_ERROR + 20)
/** @see STATUS_IS_ERELATIVE */
#define CORE_ERELATIVE (OS_START_ERROR + 21)
/** @see STATUS_IS_EINCOMPLETE */
#define CORE_EINCOMPLETE (OS_START_ERROR + 22)
/** @see STATUS_IS_EABOVEROOT */
#define CORE_EABOVEROOT (OS_START_ERROR + 23)
/** @see STATUS_IS_EBADPATH */
#define CORE_EBADPATH (OS_START_ERROR + 24)
/** @see STATUS_IS_EPATHWILD */
#define CORE_EPATHWILD (OS_START_ERROR + 25)
/** @see STATUS_IS_ESYMNOTFOUND */
#define CORE_ESYMNOTFOUND (OS_START_ERROR + 26)
/** @see STATUS_IS_EPROC_UNKNOWN */
#define CORE_EPROC_UNKNOWN (OS_START_ERROR + 27)
/** @see STATUS_IS_ENOTENOUGHENTROPY */
#define CORE_ENOTENOUGHENTROPY (OS_START_ERROR + 28)
/** @} */
/**
* @defgroup STATUS_IS Status Value Tests
* @warning For any particular error condition, more than one of these tests
* may match. This is because platform-specific error codes may not
* always match the semantics of the POSIX codes these tests (and the
* corresponding CORE error codes) are named after. A notable example
* are the STATUS_IS_ENOENT and STATUS_IS_ENOTDIR tests on
* Win32 platforms. The programmer should always be aware of this and
* adjust the order of the tests accordingly.
* @{
*/
/**
* CORE was unable to perform a stat on the file
* @warning always use this test, as platform-specific variances may meet this
* more than one error code
*/
#define STATUS_IS_ENOSTAT(s) ((s) == CORE_ENOSTAT)
/**
* CORE was not provided a pool with which to allocate memory
* @warning always use this test, as platform-specific variances may meet this
* more than one error code
*/
#define STATUS_IS_ENOPOOL(s) ((s) == CORE_ENOPOOL)
/** CORE was given an invalid date */
#define STATUS_IS_EBADDATE(s) ((s) == CORE_EBADDATE)
/** CORE was given an invalid socket */
#define STATUS_IS_EINVALSOCK(s) ((s) == CORE_EINVALSOCK)
/** CORE was not given a process structure */
#define STATUS_IS_ENOPROC(s) ((s) == CORE_ENOPROC)
/** CORE was not given a time structure */
#define STATUS_IS_ENOTIME(s) ((s) == CORE_ENOTIME)
/** CORE was not given a directory structure */
#define STATUS_IS_ENODIR(s) ((s) == CORE_ENODIR)
/** CORE was not given a lock structure */
#define STATUS_IS_ENOLOCK(s) ((s) == CORE_ENOLOCK)
/** CORE was not given a poll structure */
#define STATUS_IS_ENOPOLL(s) ((s) == CORE_ENOPOLL)
/** CORE was not given a socket */
#define STATUS_IS_ENOSOCKET(s) ((s) == CORE_ENOSOCKET)
/** CORE was not given a thread structure */
#define STATUS_IS_ENOTHREAD(s) ((s) == CORE_ENOTHREAD)
/** CORE was not given a thread key structure */
#define STATUS_IS_ENOTHDKEY(s) ((s) == CORE_ENOTHDKEY)
/** Generic Error which can not be put into another spot */
#define STATUS_IS_EGENERAL(s) ((s) == CORE_EGENERAL)
/** There is no more shared memory available */
#define STATUS_IS_ENOSHMAVAIL(s) ((s) == CORE_ENOSHMAVAIL)
/** The specified IP address is invalid */
#define STATUS_IS_EBADIP(s) ((s) == CORE_EBADIP)
/** The specified netmask is invalid */
#define STATUS_IS_EBADMASK(s) ((s) == CORE_EBADMASK)
/* empty slot: +18 */
/**
* CORE was unable to open the dso object.
* For more information call dso_error().
*/
#if defined(WIN32)
#define STATUS_IS_EDSOOPEN(s) ((s) == CORE_EDSOOPEN \
|| TO_OS_ERROR(s) == ERROR_MOD_NOT_FOUND)
#else
#define STATUS_IS_EDSOOPEN(s) ((s) == CORE_EDSOOPEN)
#endif
/** The given path was absolute. */
#define STATUS_IS_EABSOLUTE(s) ((s) == CORE_EABSOLUTE)
/** The given path was relative. */
#define STATUS_IS_ERELATIVE(s) ((s) == CORE_ERELATIVE)
/** The given path was neither relative nor absolute. */
#define STATUS_IS_EINCOMPLETE(s) ((s) == CORE_EINCOMPLETE)
/** The given path was above the root path. */
#define STATUS_IS_EABOVEROOT(s) ((s) == CORE_EABOVEROOT)
/** The given path was bad. */
#define STATUS_IS_EBADPATH(s) ((s) == CORE_EBADPATH)
/** The given path contained wildcards. */
#define STATUS_IS_EPATHWILD(s) ((s) == CORE_EPATHWILD)
/** Could not find the requested symbol.
* For more information call dso_error().
*/
#if defined(WIN32)
#define STATUS_IS_ESYMNOTFOUND(s) ((s) == CORE_ESYMNOTFOUND \
|| TO_OS_ERROR(s) == ERROR_PROC_NOT_FOUND)
#else
#define STATUS_IS_ESYMNOTFOUND(s) ((s) == CORE_ESYMNOTFOUND)
#endif
/** The given process was not recognized by CORE. */
#define STATUS_IS_EPROC_UNKNOWN(s) ((s) == CORE_EPROC_UNKNOWN)
/** CORE could not gather enough entropy to continue. */
#define STATUS_IS_ENOTENOUGHENTROPY(s) ((s) == CORE_ENOTENOUGHENTROPY)
/** @} */
/**
* @addtogroup CORE_Error
* @{
*/
/** @see STATUS_IS_INCHILD */
#define CORE_INCHILD (OS_START_STATUS + 1)
/** @see STATUS_IS_INPARENT */
#define CORE_INPARENT (OS_START_STATUS + 2)
/** @see STATUS_IS_DETACH */
#define CORE_DETACH (OS_START_STATUS + 3)
/** @see STATUS_IS_NOTDETACH */
#define CORE_NOTDETACH (OS_START_STATUS + 4)
/** @see STATUS_IS_CHILD_DONE */
#define CORE_CHILD_DONE (OS_START_STATUS + 5)
/** @see STATUS_IS_CHILD_NOTDONE */
#define CORE_CHILD_NOTDONE (OS_START_STATUS + 6)
/** @see STATUS_IS_TIMEUP */
#define CORE_TIMEUP (OS_START_STATUS + 7)
/** @see STATUS_IS_INCOMPLETE */
#define CORE_INCOMPLETE (OS_START_STATUS + 8)
/* empty slot: +9 */
/* empty slot: +10 */
/* empty slot: +11 */
/** @see STATUS_IS_BADCH */
#define CORE_BADCH (OS_START_STATUS + 12)
/** @see STATUS_IS_BADARG */
#define CORE_BADARG (OS_START_STATUS + 13)
/** @see STATUS_IS_EOF */
#define CORE_EOF (OS_START_STATUS + 14)
/** @see STATUS_IS_NOTFOUND */
#define CORE_NOTFOUND (OS_START_STATUS + 15)
/* empty slot: +16 */
/* empty slot: +17 */
/* empty slot: +18 */
/** @see STATUS_IS_ANONYMOUS */
#define CORE_ANONYMOUS (OS_START_STATUS + 19)
/** @see STATUS_IS_FILEBASED */
#define CORE_FILEBASED (OS_START_STATUS + 20)
/** @see STATUS_IS_KEYBASED */
#define CORE_KEYBASED (OS_START_STATUS + 21)
/** @see STATUS_IS_EINIT */
#define CORE_EINIT (OS_START_STATUS + 22)
/** @see STATUS_IS_ENOTIMPL */
#define CORE_ENOTIMPL (OS_START_STATUS + 23)
/** @see STATUS_IS_EMISMATCH */
#define CORE_EMISMATCH (OS_START_STATUS + 24)
/** @see STATUS_IS_EBUSY */
#define CORE_EBUSY (OS_START_STATUS + 25)
/** @} */
/**
* @addtogroup STATUS_IS
* @{
*/
/**
* Program is currently executing in the child
* @warning
* always use this test, as platform-specific variances may meet this
* more than one error code */
#define STATUS_IS_INCHILD(s) ((s) == CORE_INCHILD)
/**
* Program is currently executing in the parent
* @warning
* always use this test, as platform-specific variances may meet this
* more than one error code
*/
#define STATUS_IS_INPARENT(s) ((s) == CORE_INPARENT)
/**
* The thread is detached
* @warning
* always use this test, as platform-specific variances may meet this
* more than one error code
*/
#define STATUS_IS_DETACH(s) ((s) == CORE_DETACH)
/**
* The thread is not detached
* @warning
* always use this test, as platform-specific variances may meet this
* more than one error code
*/
#define STATUS_IS_NOTDETACH(s) ((s) == CORE_NOTDETACH)
/**
* The child has finished executing
* @warning
* always use this test, as platform-specific variances may meet this
* more than one error code
*/
#define STATUS_IS_CHILD_DONE(s) ((s) == CORE_CHILD_DONE)
/**
* The child has not finished executing
* @warning
* always use this test, as platform-specific variances may meet this
* more than one error code
*/
#define STATUS_IS_CHILD_NOTDONE(s) ((s) == CORE_CHILD_NOTDONE)
/**
* The operation did not finish before the timeout
* @warning
* always use this test, as platform-specific variances may meet this
* more than one error code
*/
#define STATUS_IS_TIMEUP(s) ((s) == CORE_TIMEUP)
/**
* The operation was incomplete although some processing was performed
* and the results are partially valid.
* @warning
* always use this test, as platform-specific variances may meet this
* more than one error code
*/
#define STATUS_IS_INCOMPLETE(s) ((s) == CORE_INCOMPLETE)
/* empty slot: +9 */
/* empty slot: +10 */
/* empty slot: +11 */
/**
* Getopt found an option not in the option string
* @warning
* always use this test, as platform-specific variances may meet this
* more than one error code
*/
#define STATUS_IS_BADCH(s) ((s) == CORE_BADCH)
/**
* Getopt found an option not in the option string and an argument was
* specified in the option string
* @warning
* always use this test, as platform-specific variances may meet this
* more than one error code
*/
#define STATUS_IS_BADARG(s) ((s) == CORE_BADARG)
/**
* CORE has encountered the end of the file
* @warning
* always use this test, as platform-specific variances may meet this
* more than one error code
*/
#define STATUS_IS_EOF(s) ((s) == CORE_EOF)
/**
* CORE was unable to find the socket in the poll structure
* @warning
* always use this test, as platform-specific variances may meet this
* more than one error code
*/
#define STATUS_IS_NOTFOUND(s) ((s) == CORE_NOTFOUND)
/* empty slot: +16 */
/* empty slot: +17 */
/* empty slot: +18 */
/**
* CORE is using anonymous shared memory
* @warning
* always use this test, as platform-specific variances may meet this
* more than one error code
*/
#define STATUS_IS_ANONYMOUS(s) ((s) == CORE_ANONYMOUS)
/**
* CORE is using a file name as the key to the shared memory
* @warning
* always use this test, as platform-specific variances may meet this
* more than one error code
*/
#define STATUS_IS_FILEBASED(s) ((s) == CORE_FILEBASED)
/**
* CORE is using a shared key as the key to the shared memory
* @warning
* always use this test, as platform-specific variances may meet this
* more than one error code
*/
#define STATUS_IS_KEYBASED(s) ((s) == CORE_KEYBASED)
/**
* Ininitalizer value. If no option has been found, but
* the status variable requires a value, this should be used
* @warning
* always use this test, as platform-specific variances may meet this
* more than one error code
*/
#define STATUS_IS_EINIT(s) ((s) == CORE_EINIT)
/**
* The CORE function has not been implemented on this
* platform, either because nobody has gotten to it yet,
* or the function is impossible on this platform.
* @warning
* always use this test, as platform-specific variances may meet this
* more than one error code
*/
#define STATUS_IS_ENOTIMPL(s) ((s) == CORE_ENOTIMPL)
/**
* Two passwords do not match.
* @warning
* always use this test, as platform-specific variances may meet this
* more than one error code
*/
#define STATUS_IS_EMISMATCH(s) ((s) == CORE_EMISMATCH)
/**
* The given lock was busy
* @warning always use this test, as platform-specific variances may meet this
* more than one error code
*/
#define STATUS_IS_EBUSY(s) ((s) == CORE_EBUSY)
/** @} */
/**
* @addtogroup CORE_Error CORE Error Values
* @{
*/
/* CORE CANONICAL ERROR VALUES */
/** @see STATUS_IS_EACCES */
#ifdef EACCES
#define CORE_EACCES EACCES
#else
#define CORE_EACCES (OS_START_CANONERR + 1)
#endif
/** @see STATUS_IS_EEXIST */
#ifdef EEXIST
#define CORE_EEXIST EEXIST
#else
#define CORE_EEXIST (OS_START_CANONERR + 2)
#endif
/** @see STATUS_IS_ENAMETOOLONG */
#ifdef ENAMETOOLONG
#define CORE_ENAMETOOLONG ENAMETOOLONG
#else
#define CORE_ENAMETOOLONG (OS_START_CANONERR + 3)
#endif
/** @see STATUS_IS_ENOENT */
#ifdef ENOENT
#define CORE_ENOENT ENOENT
#else
#define CORE_ENOENT (OS_START_CANONERR + 4)
#endif
/** @see STATUS_IS_ENOTDIR */
#ifdef ENOTDIR
#define CORE_ENOTDIR ENOTDIR
#else
#define CORE_ENOTDIR (OS_START_CANONERR + 5)
#endif
/** @see STATUS_IS_ENOSPC */
#ifdef ENOSPC
#define CORE_ENOSPC ENOSPC
#else
#define CORE_ENOSPC (OS_START_CANONERR + 6)
#endif
/** @see STATUS_IS_ENOMEM */
#ifdef ENOMEM
#define CORE_ENOMEM ENOMEM
#else
#define CORE_ENOMEM (OS_START_CANONERR + 7)
#endif
/** @see STATUS_IS_EMFILE */
#ifdef EMFILE
#define CORE_EMFILE EMFILE
#else
#define CORE_EMFILE (OS_START_CANONERR + 8)
#endif
/** @see STATUS_IS_ENFILE */
#ifdef ENFILE
#define CORE_ENFILE ENFILE
#else
#define CORE_ENFILE (OS_START_CANONERR + 9)
#endif
/** @see STATUS_IS_EBADF */
#ifdef EBADF
#define CORE_EBADF EBADF
#else
#define CORE_EBADF (OS_START_CANONERR + 10)
#endif
/** @see STATUS_IS_EINVAL */
#ifdef EINVAL
#define CORE_EINVAL EINVAL
#else
#define CORE_EINVAL (OS_START_CANONERR + 11)
#endif
/** @see STATUS_IS_ESPIPE */
#ifdef ESPIPE
#define CORE_ESPIPE ESPIPE
#else
#define CORE_ESPIPE (OS_START_CANONERR + 12)
#endif
/**
* @see STATUS_IS_EAGAIN
* @warning use STATUS_IS_EAGAIN instead of just testing this value
*/
#ifdef EAGAIN
#define CORE_EAGAIN EAGAIN
#elif defined(EWOULDBLOCK)
#define CORE_EAGAIN EWOULDBLOCK
#else
#define CORE_EAGAIN (OS_START_CANONERR + 13)
#endif
/** @see STATUS_IS_EINTR */
#ifdef EINTR
#define CORE_EINTR EINTR
#else
#define CORE_EINTR (OS_START_CANONERR + 14)
#endif
/** @see STATUS_IS_ENOTSOCK */
#ifdef ENOTSOCK
#define CORE_ENOTSOCK ENOTSOCK
#else
#define CORE_ENOTSOCK (OS_START_CANONERR + 15)
#endif
/** @see STATUS_IS_ECONNREFUSED */
#ifdef ECONNREFUSED
#define CORE_ECONNREFUSED ECONNREFUSED
#else
#define CORE_ECONNREFUSED (OS_START_CANONERR + 16)
#endif
/** @see STATUS_IS_EINPROGRESS */
#ifdef EINPROGRESS
#define CORE_EINPROGRESS EINPROGRESS
#else
#define CORE_EINPROGRESS (OS_START_CANONERR + 17)
#endif
/**
* @see STATUS_IS_ECONNABORTED
* @warning use STATUS_IS_ECONNABORTED instead of just testing this value
*/
#ifdef ECONNABORTED
#define CORE_ECONNABORTED ECONNABORTED
#else
#define CORE_ECONNABORTED (OS_START_CANONERR + 18)
#endif
/** @see STATUS_IS_ECONNRESET */
#ifdef ECONNRESET
#define CORE_ECONNRESET ECONNRESET
#else
#define CORE_ECONNRESET (OS_START_CANONERR + 19)
#endif
/** @see STATUS_IS_ETIMEDOUT
* @deprecated */
#ifdef ETIMEDOUT
#define CORE_ETIMEDOUT ETIMEDOUT
#else
#define CORE_ETIMEDOUT (OS_START_CANONERR + 20)
#endif
/** @see STATUS_IS_EHOSTUNREACH */
#ifdef EHOSTUNREACH
#define CORE_EHOSTUNREACH EHOSTUNREACH
#else
#define CORE_EHOSTUNREACH (OS_START_CANONERR + 21)
#endif
/** @see STATUS_IS_ENETUNREACH */
#ifdef ENETUNREACH
#define CORE_ENETUNREACH ENETUNREACH
#else
#define CORE_ENETUNREACH (OS_START_CANONERR + 22)
#endif
/** @see STATUS_IS_EFTYPE */
#ifdef EFTYPE
#define CORE_EFTYPE EFTYPE
#else
#define CORE_EFTYPE (OS_START_CANONERR + 23)
#endif
/** @see STATUS_IS_EPIPE */
#ifdef EPIPE
#define CORE_EPIPE EPIPE
#else
#define CORE_EPIPE (OS_START_CANONERR + 24)
#endif
/** @see STATUS_IS_EXDEV */
#ifdef EXDEV
#define CORE_EXDEV EXDEV
#else
#define CORE_EXDEV (OS_START_CANONERR + 25)
#endif
/** @see STATUS_IS_ENOTEMPTY */
#ifdef ENOTEMPTY
#define CORE_ENOTEMPTY ENOTEMPTY
#else
#define CORE_ENOTEMPTY (OS_START_CANONERR + 26)
#endif
/** @see STATUS_IS_EAFNOSUPPORT */
#ifdef EAFNOSUPPORT
#define CORE_EAFNOSUPPORT EAFNOSUPPORT
#else
#define CORE_EAFNOSUPPORT (OS_START_CANONERR + 27)
#endif
/** @} */
#if defined(OS2) && !defined(DOXYGEN)
#define FROM_OS_ERROR(e) (e == 0 ? CORE_OK : e + OS_START_SYSERR)
#define TO_OS_ERROR(e) (e == 0 ? CORE_OK : e - OS_START_SYSERR)
#define INCL_DOSERRORS
#define INCL_DOS
/* Leave these undefined.
* OS2 doesn't rely on the errno concept.
* The API calls always return a result codes which
* should be filtered through FROM_OS_ERROR().
*
* #define get_os_error() (FROM_OS_ERROR(GetLastError()))
* #define set_os_error(e) (SetLastError(TO_OS_ERROR(e)))
*/
/* A special case, only socket calls require this;
*/
#define get_netos_error() (FROM_OS_ERROR(errno))
#define set_netos_error(e) (errno = TO_OS_ERROR(e))
/* And this needs to be greped away for good:
*/
#define OS2_STATUS(e) (FROM_OS_ERROR(e))
/* These can't sit in a private header, so in spite of the extra size,
* they need to be made available here.
*/
#define SOCBASEERR 10000
#define SOCEPERM (SOCBASEERR+1) /* Not owner */
#define SOCESRCH (SOCBASEERR+3) /* No such process */
#define SOCEINTR (SOCBASEERR+4) /* Interrupted system call */
#define SOCENXIO (SOCBASEERR+6) /* No such device or address */
#define SOCEBADF (SOCBASEERR+9) /* Bad file number */
#define SOCEACCES (SOCBASEERR+13) /* Permission denied */
#define SOCEFAULT (SOCBASEERR+14) /* Bad address */
#define SOCEINVAL (SOCBASEERR+22) /* Invalid argument */
#define SOCEMFILE (SOCBASEERR+24) /* Too many open files */
#define SOCEPIPE (SOCBASEERR+32) /* Broken pipe */
#define SOCEOS2ERR (SOCBASEERR+100) /* OS/2 Error */
#define SOCEWOULDBLOCK (SOCBASEERR+35) /* Operation would block */
#define SOCEINPROGRESS (SOCBASEERR+36) /* Operation now in progress */
#define SOCEALREADY (SOCBASEERR+37) /* Operation already in progress */
#define SOCENOTSOCK (SOCBASEERR+38) /* Socket operation on non-socket */
#define SOCEDESTADDRREQ (SOCBASEERR+39) /* Destination address required */
#define SOCEMSGSIZE (SOCBASEERR+40) /* Message too long */
#define SOCEPROTOTYPE (SOCBASEERR+41) /* Protocol wrong type for socket */
#define SOCENOPROTOOPT (SOCBASEERR+42) /* Protocol not available */
#define SOCEPROTONOSUPPORT (SOCBASEERR+43) /* Protocol not supported */
#define SOCESOCKTNOSUPPORT (SOCBASEERR+44) /* Socket type not supported */
#define SOCEOPNOTSUPP (SOCBASEERR+45) /* Operation not supported on socket */
#define SOCEPFNOSUPPORT (SOCBASEERR+46) /* Protocol family not supported */
#define SOCEAFNOSUPPORT (SOCBASEERR+47) /* Address family not supported by protocol family */
#define SOCEADDRINUSE (SOCBASEERR+48) /* Address already in use */
#define SOCEADDRNOTAVAIL (SOCBASEERR+49) /* Can't assign requested address */
#define SOCENETDOWN (SOCBASEERR+50) /* Network is down */
#define SOCENETUNREACH (SOCBASEERR+51) /* Network is unreachable */
#define SOCENETRESET (SOCBASEERR+52) /* Network dropped connection on reset */
#define SOCECONNABORTED (SOCBASEERR+53) /* Software caused connection abort */
#define SOCECONNRESET (SOCBASEERR+54) /* Connection reset by peer */
#define SOCENOBUFS (SOCBASEERR+55) /* No buffer space available */
#define SOCEISCONN (SOCBASEERR+56) /* Socket is already connected */
#define SOCENOTCONN (SOCBASEERR+57) /* Socket is not connected */
#define SOCESHUTDOWN (SOCBASEERR+58) /* Can't send after socket shutdown */
#define SOCETOOMANYREFS (SOCBASEERR+59) /* Too many references: can't splice */
#define SOCETIMEDOUT (SOCBASEERR+60) /* Connection timed out */
#define SOCECONNREFUSED (SOCBASEERR+61) /* Connection refused */
#define SOCELOOP (SOCBASEERR+62) /* Too many levels of symbolic links */
#define SOCENAMETOOLONG (SOCBASEERR+63) /* File name too long */
#define SOCEHOSTDOWN (SOCBASEERR+64) /* Host is down */
#define SOCEHOSTUNREACH (SOCBASEERR+65) /* No route to host */
#define SOCENOTEMPTY (SOCBASEERR+66) /* Directory not empty */
/* CORE CANONICAL ERROR TESTS */
#define STATUS_IS_EACCES(s) ((s) == CORE_EACCES \
|| (s) == OS_START_SYSERR + ERROR_ACCESS_DENIED \
|| (s) == OS_START_SYSERR + ERROR_SHARING_VIOLATION)
#define STATUS_IS_EEXIST(s) ((s) == CORE_EEXIST \
|| (s) == OS_START_SYSERR + ERROR_OPEN_FAILED \
|| (s) == OS_START_SYSERR + ERROR_FILE_EXISTS \
|| (s) == OS_START_SYSERR + ERROR_ALREADY_EXISTS \
|| (s) == OS_START_SYSERR + ERROR_ACCESS_DENIED)
#define STATUS_IS_ENAMETOOLONG(s) ((s) == CORE_ENAMETOOLONG \
|| (s) == OS_START_SYSERR + ERROR_FILENAME_EXCED_RANGE \
|| (s) == OS_START_SYSERR + SOCENAMETOOLONG)
#define STATUS_IS_ENOENT(s) ((s) == CORE_ENOENT \
|| (s) == OS_START_SYSERR + ERROR_FILE_NOT_FOUND \
|| (s) == OS_START_SYSERR + ERROR_PATH_NOT_FOUND \
|| (s) == OS_START_SYSERR + ERROR_NO_MORE_FILES \
|| (s) == OS_START_SYSERR + ERROR_OPEN_FAILED)
#define STATUS_IS_ENOTDIR(s) ((s) == CORE_ENOTDIR)
#define STATUS_IS_ENOSPC(s) ((s) == CORE_ENOSPC \
|| (s) == OS_START_SYSERR + ERROR_DISK_FULL)
#define STATUS_IS_ENOMEM(s) ((s) == CORE_ENOMEM)
#define STATUS_IS_EMFILE(s) ((s) == CORE_EMFILE \
|| (s) == OS_START_SYSERR + ERROR_TOO_MANY_OPEN_FILES)
#define STATUS_IS_ENFILE(s) ((s) == CORE_ENFILE)
#define STATUS_IS_EBADF(s) ((s) == CORE_EBADF \
|| (s) == OS_START_SYSERR + ERROR_INVALID_HANDLE)
#define STATUS_IS_EINVAL(s) ((s) == CORE_EINVAL \
|| (s) == OS_START_SYSERR + ERROR_INVALID_PARAMETER \
|| (s) == OS_START_SYSERR + ERROR_INVALID_FUNCTION)
#define STATUS_IS_ESPIPE(s) ((s) == CORE_ESPIPE \
|| (s) == OS_START_SYSERR + ERROR_NEGATIVE_SEEK)
#define STATUS_IS_EAGAIN(s) ((s) == CORE_EAGAIN \
|| (s) == OS_START_SYSERR + ERROR_NO_DATA \
|| (s) == OS_START_SYSERR + SOCEWOULDBLOCK \
|| (s) == OS_START_SYSERR + ERROR_LOCK_VIOLATION)
#define STATUS_IS_EINTR(s) ((s) == CORE_EINTR \
|| (s) == OS_START_SYSERR + SOCEINTR)
#define STATUS_IS_ENOTSOCK(s) ((s) == CORE_ENOTSOCK \
|| (s) == OS_START_SYSERR + SOCENOTSOCK)
#define STATUS_IS_ECONNREFUSED(s) ((s) == CORE_ECONNREFUSED \
|| (s) == OS_START_SYSERR + SOCECONNREFUSED)
#define STATUS_IS_EINPROGRESS(s) ((s) == CORE_EINPROGRESS \
|| (s) == OS_START_SYSERR + SOCEINPROGRESS)
#define STATUS_IS_ECONNABORTED(s) ((s) == CORE_ECONNABORTED \
|| (s) == OS_START_SYSERR + SOCECONNABORTED)
#define STATUS_IS_ECONNRESET(s) ((s) == CORE_ECONNRESET \
|| (s) == OS_START_SYSERR + SOCECONNRESET)
/* XXX deprecated */
#define STATUS_IS_ETIMEDOUT(s) ((s) == CORE_ETIMEDOUT \
|| (s) == OS_START_SYSERR + SOCETIMEDOUT)
#undef STATUS_IS_TIMEUP
#define STATUS_IS_TIMEUP(s) ((s) == CORE_TIMEUP \
|| (s) == OS_START_SYSERR + SOCETIMEDOUT)
#define STATUS_IS_EHOSTUNREACH(s) ((s) == CORE_EHOSTUNREACH \
|| (s) == OS_START_SYSERR + SOCEHOSTUNREACH)
#define STATUS_IS_ENETUNREACH(s) ((s) == CORE_ENETUNREACH \
|| (s) == OS_START_SYSERR + SOCENETUNREACH)
#define STATUS_IS_EFTYPE(s) ((s) == CORE_EFTYPE)
#define STATUS_IS_EPIPE(s) ((s) == CORE_EPIPE \
|| (s) == OS_START_SYSERR + ERROR_BROKEN_PIPE \
|| (s) == OS_START_SYSERR + SOCEPIPE)
#define STATUS_IS_EXDEV(s) ((s) == CORE_EXDEV \
|| (s) == OS_START_SYSERR + ERROR_NOT_SAME_DEVICE)
#define STATUS_IS_ENOTEMPTY(s) ((s) == CORE_ENOTEMPTY \
|| (s) == OS_START_SYSERR + ERROR_DIR_NOT_EMPTY \
|| (s) == OS_START_SYSERR + ERROR_ACCESS_DENIED)
#define STATUS_IS_EAFNOSUPPORT(s) ((s) == CORE_AFNOSUPPORT \
|| (s) == OS_START_SYSERR + SOCEAFNOSUPPORT)
/*
Sorry, too tired to wrap this up for OS2... feel free to
fit the following into their best matches.
{ ERROR_NO_SIGNAL_SENT, ESRCH },
{ SOCEALREADY, EALREADY },
{ SOCEDESTADDRREQ, EDESTADDRREQ },
{ SOCEMSGSIZE, EMSGSIZE },
{ SOCEPROTOTYPE, EPROTOTYPE },
{ SOCENOPROTOOPT, ENOPROTOOPT },
{ SOCEPROTONOSUPPORT, EPROTONOSUPPORT },
{ SOCESOCKTNOSUPPORT, ESOCKTNOSUPPORT },
{ SOCEOPNOTSUPP, EOPNOTSUPP },
{ SOCEPFNOSUPPORT, EPFNOSUPPORT },
{ SOCEADDRINUSE, EADDRINUSE },
{ SOCEADDRNOTAVAIL, EADDRNOTAVAIL },
{ SOCENETDOWN, ENETDOWN },
{ SOCENETRESET, ENETRESET },
{ SOCENOBUFS, ENOBUFS },
{ SOCEISCONN, EISCONN },
{ SOCENOTCONN, ENOTCONN },
{ SOCESHUTDOWN, ESHUTDOWN },
{ SOCETOOMANYREFS, ETOOMANYREFS },
{ SOCELOOP, ELOOP },
{ SOCEHOSTDOWN, EHOSTDOWN },
{ SOCENOTEMPTY, ENOTEMPTY },
{ SOCEPIPE, EPIPE }
*/
#elif defined(WIN32) && !defined(DOXYGEN) /* !defined(OS2) */
#define FROM_OS_ERROR(e) (e == 0 ? CORE_OK : e + OS_START_SYSERR)
#define TO_OS_ERROR(e) (e == 0 ? CORE_OK : e - OS_START_SYSERR)
#define get_os_error() (FROM_OS_ERROR(GetLastError()))
#define set_os_error(e) (SetLastError(TO_OS_ERROR(e)))
/* A special case, only socket calls require this:
*/
#define get_netos_error() (FROM_OS_ERROR(WSAGetLastError()))
#define set_netos_error(e) (WSASetLastError(TO_OS_ERROR(e)))
/* CORE CANONICAL ERROR TESTS */
#define STATUS_IS_EACCES(s) ((s) == CORE_EACCES \
|| (s) == OS_START_SYSERR + ERROR_ACCESS_DENIED \
|| (s) == OS_START_SYSERR + ERROR_CANNOT_MAKE \
|| (s) == OS_START_SYSERR + ERROR_CURRENT_DIRECTORY \
|| (s) == OS_START_SYSERR + ERROR_DRIVE_LOCKED \
|| (s) == OS_START_SYSERR + ERROR_FAIL_I24 \
|| (s) == OS_START_SYSERR + ERROR_LOCK_VIOLATION \
|| (s) == OS_START_SYSERR + ERROR_LOCK_FAILED \
|| (s) == OS_START_SYSERR + ERROR_NOT_LOCKED \
|| (s) == OS_START_SYSERR + ERROR_NETWORK_ACCESS_DENIED \
|| (s) == OS_START_SYSERR + ERROR_SHARING_VIOLATION)
#define STATUS_IS_EEXIST(s) ((s) == CORE_EEXIST \
|| (s) == OS_START_SYSERR + ERROR_FILE_EXISTS \
|| (s) == OS_START_SYSERR + ERROR_ALREADY_EXISTS)
#define STATUS_IS_ENAMETOOLONG(s) ((s) == CORE_ENAMETOOLONG \
|| (s) == OS_START_SYSERR + ERROR_FILENAME_EXCED_RANGE \
|| (s) == OS_START_SYSERR + WSAENAMETOOLONG)
#define STATUS_IS_ENOENT(s) ((s) == CORE_ENOENT \
|| (s) == OS_START_SYSERR + ERROR_FILE_NOT_FOUND \
|| (s) == OS_START_SYSERR + ERROR_PATH_NOT_FOUND \
|| (s) == OS_START_SYSERR + ERROR_OPEN_FAILED \
|| (s) == OS_START_SYSERR + ERROR_NO_MORE_FILES)
#define STATUS_IS_ENOTDIR(s) ((s) == CORE_ENOTDIR \
|| (s) == OS_START_SYSERR + ERROR_PATH_NOT_FOUND \
|| (s) == OS_START_SYSERR + ERROR_BAD_NETPATH \
|| (s) == OS_START_SYSERR + ERROR_BAD_NET_NAME \
|| (s) == OS_START_SYSERR + ERROR_BAD_PATHNAME \
|| (s) == OS_START_SYSERR + ERROR_INVALID_DRIVE)
#define STATUS_IS_ENOSPC(s) ((s) == CORE_ENOSPC \
|| (s) == OS_START_SYSERR + ERROR_DISK_FULL)
#define STATUS_IS_ENOMEM(s) ((s) == CORE_ENOMEM \
|| (s) == OS_START_SYSERR + ERROR_ARENA_TRASHED \
|| (s) == OS_START_SYSERR + ERROR_NOT_ENOUGH_MEMORY \
|| (s) == OS_START_SYSERR + ERROR_INVALID_BLOCK \
|| (s) == OS_START_SYSERR + ERROR_NOT_ENOUGH_QUOTA \
|| (s) == OS_START_SYSERR + ERROR_OUTOFMEMORY)
#define STATUS_IS_EMFILE(s) ((s) == CORE_EMFILE \
|| (s) == OS_START_SYSERR + ERROR_TOO_MANY_OPEN_FILES)
#define STATUS_IS_ENFILE(s) ((s) == CORE_ENFILE)
#define STATUS_IS_EBADF(s) ((s) == CORE_EBADF \
|| (s) == OS_START_SYSERR + ERROR_INVALID_HANDLE \
|| (s) == OS_START_SYSERR + ERROR_INVALID_TARGET_HANDLE)
#define STATUS_IS_EINVAL(s) ((s) == CORE_EINVAL \
|| (s) == OS_START_SYSERR + ERROR_INVALID_ACCESS \
|| (s) == OS_START_SYSERR + ERROR_INVALID_DATA \
|| (s) == OS_START_SYSERR + ERROR_INVALID_FUNCTION \
|| (s) == OS_START_SYSERR + ERROR_INVALID_HANDLE \
|| (s) == OS_START_SYSERR + ERROR_INVALID_PARAMETER \
|| (s) == OS_START_SYSERR + ERROR_NEGATIVE_SEEK)
#define STATUS_IS_ESPIPE(s) ((s) == CORE_ESPIPE \
|| (s) == OS_START_SYSERR + ERROR_SEEK_ON_DEVICE \
|| (s) == OS_START_SYSERR + ERROR_NEGATIVE_SEEK)
#define STATUS_IS_EAGAIN(s) ((s) == CORE_EAGAIN \
|| (s) == OS_START_SYSERR + ERROR_NO_DATA \
|| (s) == OS_START_SYSERR + ERROR_NO_PROC_SLOTS \
|| (s) == OS_START_SYSERR + ERROR_NESTING_NOT_ALLOWED \
|| (s) == OS_START_SYSERR + ERROR_MAX_THRDS_REACHED \
|| (s) == OS_START_SYSERR + ERROR_LOCK_VIOLATION \
|| (s) == OS_START_SYSERR + WSAEWOULDBLOCK)
#define STATUS_IS_EINTR(s) ((s) == CORE_EINTR \
|| (s) == OS_START_SYSERR + WSAEINTR)
#define STATUS_IS_ENOTSOCK(s) ((s) == CORE_ENOTSOCK \
|| (s) == OS_START_SYSERR + WSAENOTSOCK)
#define STATUS_IS_ECONNREFUSED(s) ((s) == CORE_ECONNREFUSED \
|| (s) == OS_START_SYSERR + WSAECONNREFUSED)
#define STATUS_IS_EINPROGRESS(s) ((s) == CORE_EINPROGRESS \
|| (s) == OS_START_SYSERR + WSAEINPROGRESS)
#define STATUS_IS_ECONNABORTED(s) ((s) == CORE_ECONNABORTED \
|| (s) == OS_START_SYSERR + WSAECONNABORTED)
#define STATUS_IS_ECONNRESET(s) ((s) == CORE_ECONNRESET \
|| (s) == OS_START_SYSERR + ERROR_NETNAME_DELETED \
|| (s) == OS_START_SYSERR + WSAECONNRESET)
/* XXX deprecated */
#define STATUS_IS_ETIMEDOUT(s) ((s) == CORE_ETIMEDOUT \
|| (s) == OS_START_SYSERR + WSAETIMEDOUT \
|| (s) == OS_START_SYSERR + WAIT_TIMEOUT)
#undef STATUS_IS_TIMEUP
#define STATUS_IS_TIMEUP(s) ((s) == CORE_TIMEUP \
|| (s) == OS_START_SYSERR + WSAETIMEDOUT \
|| (s) == OS_START_SYSERR + WAIT_TIMEOUT)
#define STATUS_IS_EHOSTUNREACH(s) ((s) == CORE_EHOSTUNREACH \
|| (s) == OS_START_SYSERR + WSAEHOSTUNREACH)
#define STATUS_IS_ENETUNREACH(s) ((s) == CORE_ENETUNREACH \
|| (s) == OS_START_SYSERR + WSAENETUNREACH)
#define STATUS_IS_EFTYPE(s) ((s) == CORE_EFTYPE \
|| (s) == OS_START_SYSERR + ERROR_EXE_MACHINE_TYPE_MISMATCH \
|| (s) == OS_START_SYSERR + ERROR_INVALID_DLL \
|| (s) == OS_START_SYSERR + ERROR_INVALID_MODULETYPE \
|| (s) == OS_START_SYSERR + ERROR_BAD_EXE_FORMAT \
|| (s) == OS_START_SYSERR + ERROR_INVALID_EXE_SIGNATURE \
|| (s) == OS_START_SYSERR + ERROR_FILE_CORRUPT \
|| (s) == OS_START_SYSERR + ERROR_BAD_FORMAT)
#define STATUS_IS_EPIPE(s) ((s) == CORE_EPIPE \
|| (s) == OS_START_SYSERR + ERROR_BROKEN_PIPE)
#define STATUS_IS_EXDEV(s) ((s) == CORE_EXDEV \
|| (s) == OS_START_SYSERR + ERROR_NOT_SAME_DEVICE)
#define STATUS_IS_ENOTEMPTY(s) ((s) == CORE_ENOTEMPTY \
|| (s) == OS_START_SYSERR + ERROR_DIR_NOT_EMPTY)
#define STATUS_IS_EAFNOSUPPORT(s) ((s) == CORE_EAFNOSUPPORT \
|| (s) == OS_START_SYSERR + WSAEAFNOSUPPORT)
#elif defined(NETWARE) && defined(USE_WINSOCK) && !defined(DOXYGEN) /* !defined(OS2) && !defined(WIN32) */
#define FROM_OS_ERROR(e) (e == 0 ? CORE_OK : e + OS_START_SYSERR)
#define TO_OS_ERROR(e) (e == 0 ? CORE_OK : e - OS_START_SYSERR)
#define get_os_error() (errno)
#define set_os_error(e) (errno = (e))
/* A special case, only socket calls require this: */
#define get_netos_error() (FROM_OS_ERROR(WSAGetLastError()))
#define set_netos_error(e) (WSASetLastError(TO_OS_ERROR(e)))
/* CORE CANONICAL ERROR TESTS */
#define STATUS_IS_EACCES(s) ((s) == CORE_EACCES)
#define STATUS_IS_EEXIST(s) ((s) == CORE_EEXIST)
#define STATUS_IS_ENAMETOOLONG(s) ((s) == CORE_ENAMETOOLONG)
#define STATUS_IS_ENOENT(s) ((s) == CORE_ENOENT)
#define STATUS_IS_ENOTDIR(s) ((s) == CORE_ENOTDIR)
#define STATUS_IS_ENOSPC(s) ((s) == CORE_ENOSPC)
#define STATUS_IS_ENOMEM(s) ((s) == CORE_ENOMEM)
#define STATUS_IS_EMFILE(s) ((s) == CORE_EMFILE)
#define STATUS_IS_ENFILE(s) ((s) == CORE_ENFILE)
#define STATUS_IS_EBADF(s) ((s) == CORE_EBADF)
#define STATUS_IS_EINVAL(s) ((s) == CORE_EINVAL)
#define STATUS_IS_ESPIPE(s) ((s) == CORE_ESPIPE)
#define STATUS_IS_EAGAIN(s) ((s) == CORE_EAGAIN \
|| (s) == EWOULDBLOCK \
|| (s) == OS_START_SYSERR + WSAEWOULDBLOCK)
#define STATUS_IS_EINTR(s) ((s) == CORE_EINTR \
|| (s) == OS_START_SYSERR + WSAEINTR)
#define STATUS_IS_ENOTSOCK(s) ((s) == CORE_ENOTSOCK \
|| (s) == OS_START_SYSERR + WSAENOTSOCK)
#define STATUS_IS_ECONNREFUSED(s) ((s) == CORE_ECONNREFUSED \
|| (s) == OS_START_SYSERR + WSAECONNREFUSED)
#define STATUS_IS_EINPROGRESS(s) ((s) == CORE_EINPROGRESS \
|| (s) == OS_START_SYSERR + WSAEINPROGRESS)
#define STATUS_IS_ECONNABORTED(s) ((s) == CORE_ECONNABORTED \
|| (s) == OS_START_SYSERR + WSAECONNABORTED)
#define STATUS_IS_ECONNRESET(s) ((s) == CORE_ECONNRESET \
|| (s) == OS_START_SYSERR + WSAECONNRESET)
/* XXX deprecated */
#define STATUS_IS_ETIMEDOUT(s) ((s) == CORE_ETIMEDOUT \
|| (s) == OS_START_SYSERR + WSAETIMEDOUT \
|| (s) == OS_START_SYSERR + WAIT_TIMEOUT)
#undef STATUS_IS_TIMEUP
#define STATUS_IS_TIMEUP(s) ((s) == CORE_TIMEUP \
|| (s) == OS_START_SYSERR + WSAETIMEDOUT \
|| (s) == OS_START_SYSERR + WAIT_TIMEOUT)
#define STATUS_IS_EHOSTUNREACH(s) ((s) == CORE_EHOSTUNREACH \
|| (s) == OS_START_SYSERR + WSAEHOSTUNREACH)
#define STATUS_IS_ENETUNREACH(s) ((s) == CORE_ENETUNREACH \
|| (s) == OS_START_SYSERR + WSAENETUNREACH)
#define STATUS_IS_ENETDOWN(s) ((s) == OS_START_SYSERR + WSAENETDOWN)
#define STATUS_IS_EFTYPE(s) ((s) == CORE_EFTYPE)
#define STATUS_IS_EPIPE(s) ((s) == CORE_EPIPE)
#define STATUS_IS_EXDEV(s) ((s) == CORE_EXDEV)
#define STATUS_IS_ENOTEMPTY(s) ((s) == CORE_ENOTEMPTY)
#define STATUS_IS_EAFNOSUPPORT(s) ((s) == CORE_EAFNOSUPPORT \
|| (s) == OS_START_SYSERR + WSAEAFNOSUPPORT)
#else /* !defined(NETWARE) && !defined(OS2) && !defined(WIN32) */
/*
* os error codes are clib error codes
*/
#define FROM_OS_ERROR(e) (e)
#define TO_OS_ERROR(e) (e)
#define get_os_error() (errno)
#define set_os_error(e) (errno = (e))
/* A special case, only socket calls require this:
*/
#define get_netos_error() (errno)
#define set_netos_error(e) (errno = (e))
/**
* @addtogroup STATUS_IS
* @{
*/
/** permission denied */
#define STATUS_IS_EACCES(s) ((s) == CORE_EACCES)
/** file exists */
#define STATUS_IS_EEXIST(s) ((s) == CORE_EEXIST)
/** path name is too long */
#define STATUS_IS_ENAMETOOLONG(s) ((s) == CORE_ENAMETOOLONG)
/**
* no such file or directory
* @remark
* EMVSCATLG can be returned by the automounter on z/OS for
* paths which do not exist.
*/
#ifdef EMVSCATLG
#define STATUS_IS_ENOENT(s) ((s) == CORE_ENOENT \
|| (s) == EMVSCATLG)
#else
#define STATUS_IS_ENOENT(s) ((s) == CORE_ENOENT)
#endif
/** not a directory */
#define STATUS_IS_ENOTDIR(s) ((s) == CORE_ENOTDIR)
/** no space left on device */
#ifdef EDQUOT
#define STATUS_IS_ENOSPC(s) ((s) == CORE_ENOSPC \
|| (s) == EDQUOT)
#else
#define STATUS_IS_ENOSPC(s) ((s) == CORE_ENOSPC)
#endif
/** not enough memory */
#define STATUS_IS_ENOMEM(s) ((s) == CORE_ENOMEM)
/** too many open files */
#define STATUS_IS_EMFILE(s) ((s) == CORE_EMFILE)
/** file table overflow */
#define STATUS_IS_ENFILE(s) ((s) == CORE_ENFILE)
/** bad file # */
#define STATUS_IS_EBADF(s) ((s) == CORE_EBADF)
/** invalid argument */
#define STATUS_IS_EINVAL(s) ((s) == CORE_EINVAL)
/** illegal seek */
#define STATUS_IS_ESPIPE(s) ((s) == CORE_ESPIPE)
/** operation would block */
#if !defined(EWOULDBLOCK) || !defined(EAGAIN)
#define STATUS_IS_EAGAIN(s) ((s) == CORE_EAGAIN)
#elif (EWOULDBLOCK == EAGAIN)
#define STATUS_IS_EAGAIN(s) ((s) == CORE_EAGAIN)
#else
#define STATUS_IS_EAGAIN(s) ((s) == CORE_EAGAIN \
|| (s) == EWOULDBLOCK)
#endif
/** interrupted system call */
#define STATUS_IS_EINTR(s) ((s) == CORE_EINTR)
/** socket operation on a non-socket */
#define STATUS_IS_ENOTSOCK(s) ((s) == CORE_ENOTSOCK)
/** Connection Refused */
#define STATUS_IS_ECONNREFUSED(s) ((s) == CORE_ECONNREFUSED)
/** operation now in progress */
#define STATUS_IS_EINPROGRESS(s) ((s) == CORE_EINPROGRESS)
/**
* Software caused connection abort
* @remark
* EPROTO on certain older kernels really means ECONNABORTED, so we need to
* ignore it for them. See discussion in new-httpd archives nh.9701 & nh.9603
*
* There is potentially a bug in Solaris 2.x x<6, and other boxes that
* implement tcp sockets in userland (i.e. on top of STREAMS). On these
* systems, EPROTO can actually result in a fatal loop. See PR#981 for
* example. It's hard to handle both uses of EPROTO.
*/
#ifdef EPROTO
#define STATUS_IS_ECONNABORTED(s) ((s) == CORE_ECONNABORTED \
|| (s) == EPROTO)
#else
#define STATUS_IS_ECONNABORTED(s) ((s) == CORE_ECONNABORTED)
#endif
/** Connection Reset by peer */
#define STATUS_IS_ECONNRESET(s) ((s) == CORE_ECONNRESET)
/** Operation timed out
* @deprecated */
#define STATUS_IS_ETIMEDOUT(s) ((s) == CORE_ETIMEDOUT)
/** no route to host */
#define STATUS_IS_EHOSTUNREACH(s) ((s) == CORE_EHOSTUNREACH)
/** network is unreachable */
#define STATUS_IS_ENETUNREACH(s) ((s) == CORE_ENETUNREACH)
/** inappropiate file type or format */
#define STATUS_IS_EFTYPE(s) ((s) == CORE_EFTYPE)
/** broken pipe */
#define STATUS_IS_EPIPE(s) ((s) == CORE_EPIPE)
/** cross device link */
#define STATUS_IS_EXDEV(s) ((s) == CORE_EXDEV)
/** Directory Not Empty */
#define STATUS_IS_ENOTEMPTY(s) ((s) == CORE_ENOTEMPTY || \
(s) == CORE_EEXIST)
/** Address Family not supported */
#define STATUS_IS_EAFNOSUPPORT(s) ((s) == CORE_EAFNOSUPPORT)
/** @} */
#endif /* !defined(NETWARE) && !defined(OS2) && !defined(WIN32) */
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ! __CORE_ERRNO_H__ */
nextepc-0.3.10/lib/core/include/core_event.h 0000664 0000000 0000000 00000007271 13335533574 0020706 0 ustar 00root root 0000000 0000000 #ifndef __EVENT_H__
#define __EVENT_H__
#include "core_msgq.h"
#include "core_timer.h"
#include "core_fsm.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define EVENT_SIZE sizeof(event_t)
#define event_set(__ptr_e, __evnt) ((__ptr_e)->event = (__evnt))
#define event_get(__ptr_e) ((__ptr_e)->event)
#define event_set_param1(__ptr_e, __param) \
((__ptr_e)->param1 = (c_uintptr_t)(__param))
#define event_set_param2(__ptr_e, __param) \
((__ptr_e)->param2 = (c_uintptr_t)(__param))
#define event_set_param3(__ptr_e, __param) \
((__ptr_e)->param3 = (c_uintptr_t)(__param))
#define event_set_param4(__ptr_e, __param) \
((__ptr_e)->param4 = (c_uintptr_t)(__param))
#define event_set_param5(__ptr_e, __param) \
((__ptr_e)->param5 = (c_uintptr_t)(__param))
#define event_set_param6(__ptr_e, __param) \
((__ptr_e)->param6 = (c_uintptr_t)(__param))
#define event_set_param7(__ptr_e, __param) \
((__ptr_e)->param7 = (c_uintptr_t)(__param))
#define event_set_param8(__ptr_e, __param) \
((__ptr_e)->param8 = (c_uintptr_t)(__param))
#define event_get_param1(__ptr_e) ((__ptr_e)->param1)
#define event_get_param2(__ptr_e) ((__ptr_e)->param2)
#define event_get_param3(__ptr_e) ((__ptr_e)->param3)
#define event_get_param4(__ptr_e) ((__ptr_e)->param4)
#define event_get_param5(__ptr_e) ((__ptr_e)->param5)
#define event_get_param6(__ptr_e) ((__ptr_e)->param6)
#define event_get_param7(__ptr_e) ((__ptr_e)->param7)
#define event_get_param8(__ptr_e) ((__ptr_e)->param8)
#define timer_create(__tm_service, __ptr_e, __duration) \
event_timer_create((__tm_service), TIMER_TYPE_ONE_SHOT, \
(__duration), (__ptr_e))
#define periodic_timer_create(__tm_service, __ptr_e, __duration) \
event_timer_create((__tm_service), TIMER_TYPE_PERIODIC, \
(__duration), (__ptr_e))
#define timer_set_param1(__ptr_e, __param) tm_set_param2(__ptr_e, __param);
#define timer_set_param2(__ptr_e, __param) tm_set_param3(__ptr_e, __param);
#define timer_set_param3(__ptr_e, __param) tm_set_param4(__ptr_e, __param);
#define timer_set_param4(__ptr_e, __param) tm_set_param5(__ptr_e, __param);
#define timer_set_param5(__ptr_e, __param) tm_set_param6(__ptr_e, __param);
typedef struct {
fsm_event_t event;
c_uintptr_t param1;
c_uintptr_t param2;
c_uintptr_t param3;
c_uintptr_t param4;
c_uintptr_t param5;
c_uintptr_t param6;
c_uintptr_t param7;
c_uintptr_t param8;
} event_t;
extern char *EVT_NAME_UNKNOWN;
/**
* Create event message queue
*
* @return event queue or 0
*/
CORE_DECLARE(msgq_id) event_create(int opt);
/**
* Delete event message queue
*
* @return CORE_OK or CORE_ERROR
*/
CORE_DECLARE(status_t) event_delete(msgq_id queue_id);
/**
* Send a event to event queue
*
* @return If success, return CORE_OK
* If queue is full, return CORE_EAGAIN
* If else, return CORE_ERROR
*/
CORE_DECLARE(status_t) event_send(msgq_id queue_id, event_t *e);
/**
* Receive a event from event queue
*
* @return If success, return CORE_OK
* If queue is empty, return CORE_EAGAIN
* If else, return CORE_ERROR.
*/
CORE_DECLARE(status_t) event_recv(msgq_id queue_id, event_t *e);
/**
* Receive a event from event queue with timeout
*
* @return If success, return CORE_OK
* If timout occurs, return CORE_TIMEUP.
* If queue is empty, return CORE_EAGAIN
* If else, return CORE_ERROR.
*/
CORE_DECLARE(status_t) event_timedrecv(
msgq_id queue_id, event_t *e, c_time_t timeout);
/**
* Create a timer
*/
CORE_DECLARE(tm_block_id) event_timer_create(tm_service_t *tm_service,
tm_type_e type, c_uint32_t duration, c_uintptr_t event);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __EVENT_H__ */
nextepc-0.3.10/lib/core/include/core_file.h 0000664 0000000 0000000 00000056247 13335533574 0020513 0 ustar 00root root 0000000 0000000 #ifndef __CORE_FILE_H__
#define __CORE_FILE_H__
/**
* @file core_file.h
* @brief CORE File I/O Handling
*/
#include "core.h"
#include "core_time.h"
#include "core_errno.h"
#include "core_param.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup file_io File I/O Handling Functions
* @ingroup CORE
* @{
*/
/** filetype_e values for the filetype member of the
* file_info_t structure
* @warning: Not all of the filetypes below can be determined.
* For example, a given platform might not correctly report
* a socket descriptor as CORE_SOCK if that type isn't
* well-identified on that platform. In such cases where
* a filetype exists but cannot be described by the recognized
* flags below, the filetype will be CORE_UNKFILE. If the
* filetype member is not determined, the type will be CORE_NOFILE.
*/
typedef enum {
FILE_NOFILE = 0, /**< no file type determined */
FILE_REG, /**< a regular file */
FILE_DIR, /**< a directory */
FILE_CHR, /**< a character device */
FILE_BLK, /**< a block device */
FILE_PIPE, /**< a FIFO / pipe */
FILE_LNK, /**< a symbolic link */
FILE_SOCK, /**< a [unix domain] socket */
FILE_UNKFILE = 127 /**< a file of some other unknown type */
} filetype_e;
/**
* @defgroup file_permissions File Permissions flags
* @{
*/
#define FILE_USETID 0x8000 /**< Set user id */
#define FILE_UREAD 0x0400 /**< Read by user */
#define FILE_UWRITE 0x0200 /**< Write by user */
#define FILE_UEXECUTE 0x0100 /**< Execute by user */
#define FILE_GSETID 0x4000 /**< Set group id */
#define FILE_GREAD 0x0040 /**< Read by group */
#define FILE_GWRITE 0x0020 /**< Write by group */
#define FILE_GEXECUTE 0x0010 /**< Execute by group */
#define FILE_WSTICKY 0x2000 /**< Sticky bit */
#define FILE_WREAD 0x0004 /**< Read by others */
#define FILE_WWRITE 0x0002 /**< Write by others */
#define FILE_WEXECUTE 0x0001 /**< Execute by others */
#define FILE_OS_DEFAULT 0x0FFF /**< use OS's default permissions */
/* additional permission flags for file_copy and file_append */
#define FILE_SOURCE_PERMS 0x1000 /**< Copy source file's permissions */
/** @} */
/**
* @defgroup file_open_flags File Open Flags/Routines
* @{
*/
/* Note to implementors: Values in the range 0x00100000--0x80000000
are reserved for platform-specific values. */
#define FILE_READ 0x00001 /**< Open the file for reading */
#define FILE_WRITE 0x00002 /**< Open the file for writing */
#define FILE_CREATE 0x00004 /**< Create the file if not there */
#define FILE_APPEND 0x00008 /**< Append to the end of the file */
#define FILE_TRUNCATE 0x00010 /**< Open the file and truncate
to 0 length */
#define FILE_BINARY 0x00020 /**< Open the file in binary mode */
#define FILE_EXCL 0x00040 /**< Open should fail if FILE_CREATE
and file exists. */
#define FILE_DELONCLOSE 0x00100 /**< Delete the file after close */
/** @} */
/**
* @defgroup file_seek_flags File Seek Flags
* @{
*/
/* flags for file_seek */
/** Set the file position */
#define FILE_SET SEEK_SET
/** Current */
#define FILE_CUR SEEK_CUR
/** Go to end of file */
#define FILE_END SEEK_END
/** @} */
/**
* @defgroup file_attrs_set_flags File Attribute Flags
* @{
*/
/* flags for file_attrs_set */
#define ATTR_READONLY 0x01 /**< File is read-only */
#define ATTR_EXECUTABLE 0x02 /**< File is executable */
#define ATTR_HIDDEN 0x04 /**< File is hidden */
/** @} */
/**
* @defgroup file_writev{_full} max iovec size
* @{
*/
#if defined(DOXYGEN)
#define MAX_IOVEC_SIZE 1024 /**< System dependent maximum
size of an iovec array */
#elif defined(IOV_MAX)
#define MAX_IOVEC_SIZE IOV_MAX
#elif defined(MAX_IOVEC)
#define MAX_IOVEC_SIZE MAX_IOVEC
#else
#define MAX_IOVEC_SIZE 1024
#endif
/** @} */
/** File attributes */
typedef c_uint32_t file_attrs_t;
/** Type to pass as whence argument to file_seek. */
typedef int seek_where_t;
/**
* Structure for referencing files.
*/
typedef struct file_t file_t;
/**
* Structure for referencing directories.
*/
typedef struct dir_t dir_t;
/**
* Structure for determining file permissions.
*/
typedef c_int32_t file_perms_t;
#if (defined WIN32) || (defined NETWARE)
/**
* Structure for determining the device the file is on.
*/
typedef c_uint32_t dev_t;
#endif
/** @} */
/**
* @defgroup file_stat Stat Functions
* @{
*/
/** file info structure */
typedef struct file_info_t file_info_t;
#define FILE_INFO_LINK 0x00000001 /**< Stat the link not the file itself
if it is a link */
#define FILE_INFO_MTIME 0x00000010 /**< Modification Time */
#define FILE_INFO_CTIME 0x00000020 /**< Creation or inode-changed time */
#define FILE_INFO_ATIME 0x00000040 /**< Access Time */
#define FILE_INFO_SIZE 0x00000100 /**< Size of the file */
#define FILE_INFO_CSIZE 0x00000200 /**< Storage size consumed by the file */
#define FILE_INFO_DEV 0x00001000 /**< Device */
#define FILE_INFO_INODE 0x00002000 /**< Inode */
#define FILE_INFO_NLINK 0x00004000 /**< Number of links */
#define FILE_INFO_TYPE 0x00008000 /**< Type */
#define FILE_INFO_USER 0x00010000 /**< User */
#define FILE_INFO_GROUP 0x00020000 /**< Group */
#define FILE_INFO_UPROT 0x00100000 /**< User protection bits */
#define FILE_INFO_GPROT 0x00200000 /**< Group protection bits */
#define FILE_INFO_WPROT 0x00400000 /**< World protection bits */
#define FILE_INFO_ICASE 0x01000000 /**< if dev is case insensitive */
#define FILE_INFO_NAME 0x02000000 /**< ->name in proper case */
#define FILE_INFO_MIN 0x00008170 /**< type, mtime, ctime, atime, size */
#define FILE_INFO_IDENT 0x00003000 /**< dev and inode */
#define FILE_INFO_OWNER 0x00030000 /**< user and group */
#define FILE_INFO_PROT 0x00700000 /**< all protections */
#define FILE_INFO_NORM 0x0073b170 /**< an atomic unix file_stat() */
#define FILE_INFO_DIRENT 0x02000000 /**< an atomic unix dir_read() */
/**
* The file information structure. This is analogous to the POSIX
* stat structure.
*/
struct file_info_t {
/** The bitmask describing valid fields of this c_file_info_t structure
* including all available 'wanted' fields and potentially more */
c_int32_t valid;
/** The access permissions of the file. Mimics Unix access rights. */
file_perms_t protection;
/** The type of file. One of CORE_REG, CORE_DIR, CORE_CHR, CORE_BLK,
CORE_PIPE, CORE_LNK or CORE_SOCK. If the type is undetermined,
the value is CORE_NOFILE.
* If the type cannot be determined, the value is CORE_UNKFILE.
*/
filetype_e filetype;
/** The user id that owns the file */
uid_t user;
/** The group id that owns the file */
gid_t group;
/** The inode of the file. */
ino_t inode;
/** The id of the device the file is on. */
dev_t device;
/** The number of hard links to the file. */
c_int32_t nlink;
/** The size of the file */
off_t size;
/** The storage size consumed by the file */
off_t csize;
/** The time the file was last accessed */
c_time_t atime;
/** The time the file was last modified */
c_time_t mtime;
/** The time the file was created, or the inode was last changed */
c_time_t ctime;
/** The pathname of the file (possibly unrooted) */
char fname[MAX_FILENAME_SIZE];
/** The file's name (no path) in filesystem case */
char name[MAX_FILENAME_SIZE];
/** The file's handle, if accessed (can be submitted to c_duphandle) */
struct c_file_t *filehand;
};
/** @} */
/**
* Initialize the file utility.
*/
CORE_DECLARE(status_t) file_init(void);
/**
* Finalize the file utility.
*/
CORE_DECLARE(status_t) file_final(void);
/**
* Open the specified file.
* @param newf The opened file descriptor.
* @param fname The full path to the file (using / on all systems)
* @param flag Or'ed value of:
*
* FILE_READ open for reading
* FILE_WRITE open for writing
* FILE_CREATE create the file if not there
* FILE_APPEND file ptr is set to end prior to all writes
* FILE_TRUNCATE set length to zero if file exists
* FILE_BINARY not a text file (This flag is ignored on
* UNIX because it has no meaning)
* FILE_EXCL return error if FILE_CREATE and file exists
* FILE_DELONCLOSE delete the file after closing.
*
* @param perm Access permissions for file.
* @remark If perm is FILE_OS_DEFAULT and the file is being created,
* appropriate default permissions will be used.
*/
CORE_DECLARE(status_t) file_open(file_t **newf,
const char *fname, c_int32_t flag, file_perms_t perm);
/**
* Close the specified file.
* @param file The file descriptor to close.
*/
CORE_DECLARE(status_t) file_close(file_t *file);
/**
* Delete the specified file.
* @param path The full path to the file (using / on all systems)
* @remark If the file is open, it won't be removed until all
* instances are closed.
*/
CORE_DECLARE(status_t) file_remove(const char *path);
/**
* Rename the specified file.
* @param from_path The full path to the original file (using / on all systems)
* @param to_path The full path to the new file (using / on all systems)
* @warning If a file exists at the new location, then it will be
* overwritten. Moving files or directories across devices may not be
* possible.
*/
CORE_DECLARE(status_t) file_rename(const char *from_path, const char *to_path);
/**
* Create a hard link to the specified file.
* @param from_path The full path to the original file (using / on all systems)
* @param to_path The full path to the new file (using / on all systems)
* @remark Both files must reside on the same device.
*/
CORE_DECLARE(status_t) file_link(const char *from_path, const char *to_path);
/**
* Copy the specified file to another file.
* @param from_path The full path to the original file (using / on all systems)
* @param to_path The full path to the new file (using / on all systems)
* @param perms Access permissions for the new file if it is created.
* In place of the usual or'd combination of file permissions, the
* value CORE_SOURCE_PERMS may be given, in which case the source
* file's permissions are copied.
* @remark The new file does not need to exist, it will be created if required.
* @warning If the new file already exists, its contents will be overwritten.
*/
CORE_DECLARE(status_t) file_copy(
const char *from_path, const char *to_path, file_perms_t perms);
/**
* Append the specified file to another file.
* @param from_path The full path to the source file (use / on all systems)
* @param to_path The full path to the destination file (use / on all systems)
* @param perms Access permissions for the destination file if it is created.
* In place of the usual or'd combination of file permissions, the
* value CORE_SOURCE_PERMS may be given, in which case the source
* file's permissions are copied.
* @remark The new file does not need to exist, it will be created if required.
*/
CORE_DECLARE(status_t) file_append(
const char *from_path, const char *to_path, file_perms_t perms);
/**
* Are we at the end of the file
* @param fptr The core file we are testing.
* @remark Returns CORE_EOF if we are at the end of file,
* CORE_OK otherwise.
*/
CORE_DECLARE(status_t) file_eof(file_t *fptr);
/**
* Read data from the specified file.
* @param thefile The file descriptor to read from.
* @param buf The buffer to store the data to.
* @param nbytes On entry, the number of bytes to read; on exit, the number
* of bytes read.
*
* @remark file_read will read up to the specified number of
* bytes, but never more. If there isn't enough data to fill that
* number of bytes, all of the available data is read. The third
* argument is modified to reflect the number of bytes read. If a
* char was put back into the stream via ungetc, it will be the first
* character returned.
*
* @remark It is not possible for both bytes to be read and an CORE_EOF
* or other error to be returned. CORE_EINTR is never returned.
*/
CORE_DECLARE(status_t) file_read(file_t *thefile, void *buf, size_t *nbytes);
/**
* Write data to the specified file.
* @param thefile The file descriptor to write to.
* @param buf The buffer which contains the data.
* @param nbytes On entry, the number of bytes to write; on exit, the number
* of bytes written.
*
* @remark file_write will write up to the specified number of
* bytes, but never more. If the OS cannot write that many bytes, it
* will write as many as it can. The third argument is modified to
* reflect the * number of bytes written.
*
* @remark It is possible for both bytes to be written and an error to
* be returned. CORE_EINTR is never returned.
*/
CORE_DECLARE(status_t) file_write(
file_t *thefile, const void *buf, size_t *nbytes);
/**
* Write data from iovec array to the specified file.
* @param thefile The file descriptor to write to.
* @param vec The array from which to get the data to write to the file.
* @param nvec The number of elements in the struct iovec array. This must
* be smaller than MAX_IOVEC_SIZE. If it isn't, the function
* will fail with CORE_EINVAL.
* @param nbytes The number of bytes written.
*
* @remark It is possible for both bytes to be written and an error to
* be returned. CORE_EINTR is never returned.
*
* @remark file_writev is available even if the underlying
* operating system doesn't provide writev().
*/
CORE_DECLARE(status_t) file_writev(file_t *thefile,
const struct iovec *vec, size_t nvec, size_t *nbytes);
/**
* Read data from the specified file, ensuring that the buffer is filled
* before returning.
* @param thefile The file descriptor to read from.
* @param buf The buffer to store the data to.
* @param nbytes The number of bytes to read.
* @param bytes_read If non-NULL, this will contain the number of bytes read.
*
* @remark file_read will read up to the specified number of
* bytes, but never more. If there isn't enough data to fill that
* number of bytes, then the process/thread will block until it is
* available or EOF is reached. If a char was put back into the
* stream via ungetc, it will be the first character returned.
*
* @remark It is possible for both bytes to be read and an error to be
* returned. And if *bytes_read is less than nbytes, an accompanying
* error is _always_ returned.
*
* @remark CORE_EINTR is never returned.
*/
CORE_DECLARE(status_t) file_read_full(file_t *thefile, void *buf,
size_t nbytes, size_t *bytes_read);
/**
* Write data to the specified file, ensuring that all of the data is
* written before returning.
* @param thefile The file descriptor to write to.
* @param buf The buffer which contains the data.
* @param nbytes The number of bytes to write.
* @param bytes_written If non-NULL, set to the number of bytes written.
*
* @remark file_write will write up to the specified number of
* bytes, but never more. If the OS cannot write that many bytes, the
* process/thread will block until they can be written. Exceptional
* error such as "out of space" or "pipe closed" will terminate with
* an error.
*
* @remark It is possible for both bytes to be written and an error to
* be returned. And if *bytes_written is less than nbytes, an
* accompanying error is _always_ returned.
*
* @remark CORE_EINTR is never returned.
*/
CORE_DECLARE(status_t) file_write_full(file_t *thefile,
const void *buf, size_t nbytes, size_t *bytes_written);
/**
* Write data from iovec array to the specified file, ensuring that all of the
* data is written before returning.
* @param thefile The file descriptor to write to.
* @param vec The array from which to get the data to write to the file.
* @param nvec The number of elements in the struct iovec array. This must
* be smaller than MAX_IOVEC_SIZE. If it isn't, the function
* will fail with CORE_EINVAL.
* @param nbytes The number of bytes written.
*
* @remark file_writev_full is available even if the underlying
* operating system doesn't provide writev().
*/
CORE_DECLARE(status_t) file_writev_full(file_t *thefile,
const struct iovec *vec, size_t nvec, size_t *nbytes);
/**
* Write a character into the specified file.
* @param ch The character to write.
* @param thefile The file descriptor to write to
*/
CORE_DECLARE(status_t) file_putc(char ch, file_t *thefile);
/**
* Read a character from the specified file.
* @param ch The character to read into
* @param thefile The file descriptor to read from
*/
CORE_DECLARE(status_t) file_getc(char *ch, file_t *thefile);
/**
* Put a character back onto a specified stream.
* @param ch The character to write.
* @param thefile The file descriptor to write to
*/
CORE_DECLARE(status_t) file_ungetc(char ch, file_t *thefile);
/**
* Read a string from the specified file.
* @param str The buffer to store the string in.
* @param len The length of the string
* @param thefile The file descriptor to read from
* @remark The buffer will be NUL-terminated if any characters are stored.
*/
CORE_DECLARE(status_t) file_gets(char *str, int len, file_t *thefile);
/**
* Write the string into the specified file.
* @param str The string to write.
* @param thefile The file descriptor to write to
*/
CORE_DECLARE(status_t) file_puts(const char *str, file_t *thefile);
/**
* Transfer all file modified data and metadata to disk.
* @param thefile The file descriptor to sync
*/
CORE_DECLARE(status_t) file_sync(file_t *thefile);
/**
* Move the read/write file offset to a specified byte within a file.
* @param thefile The file descriptor
* @param where How to move the pointer, one of:
*
* CORE_SET -- set the offset to offset
* CORE_CUR -- add the offset to the current position
* CORE_END -- add the offset to the current file size
*
* @param offset The offset to move the pointer to.
* @remark The third argument is modified to be the offset the pointer
was actually moved to.
*/
CORE_DECLARE(status_t) file_seek(file_t *thefile,
seek_where_t where, off_t *offset);
/**accessor and general file_io functions. */
/**
* return the file name of the current file.
* @param new_path The path of the file.
* @param thefile The currently open file.
*/
CORE_DECLARE(status_t) file_name_get(const char **fname, file_t *thefile);
/**
* set the specified file's permission bits.
* @param fname The file (name) to apply the permissions to.
* @param perms The permission bits to apply to the file.
*
* @warning Some platforms may not be able to apply all of the
* available permission bits; CORE_INCOMPLETE will be returned if some
* permissions are specified which could not be set.
*
* @warning Platforms which do not implement this feature will return
* CORE_ENOTIMPL.
*/
CORE_DECLARE(status_t) file_perms_set(const char *fname, file_perms_t perms);
/**
* Set attributes of the specified file.
* @param fname The full path to the file (using / on all systems)
* @param attributes Or'd combination of
*
* ATTR_READONLY - make the file readonly
* ATTR_EXECUTABLE - make the file executable
* ATTR_HIDDEN - make the file hidden
*
* @param attr_mask Mask of valid bits in attributes.
* @remark This function should be used in preference to explict manipulation
* of the file permissions, because the operations to provide these
* attributes are platform specific and may involve more than simply
* setting permission bits.
* @warning Platforms which do not implement this feature will return
* CORE_ENOTIMPL.
*/
CORE_DECLARE(status_t) file_attrs_set(const char *fname,
file_attrs_t attributes, file_attrs_t attr_mask);
/**
* Set the mtime of the specified file.
* @param fname The full path to the file (using / on all systems)
* @param mtime The mtime to apply to the file.
* @warning Platforms which do not implement this feature will return
* CORE_ENOTIMPL.
*/
CORE_DECLARE(status_t) file_mtime_set(const char *fname, c_time_t mtime);
/**
* Create a new directory on the file system.
* @param path the path for the directory to be created. (use / on all systems)
* @param perm Permissions for the new direcoty.
*/
CORE_DECLARE(status_t) dir_make(const char *path, file_perms_t perm);
/** Creates a new directory on the file system, but behaves like
* 'mkdir -p'. Creates intermediate directories as required. No error
* will be reported if PATH already exists.
* @param path the path for the directory to be created. (use / on all systems)
* @param perm Permissions for the new direcoty.
*/
CORE_DECLARE(void) path_remove_last_component(char *dir, const char *path);
CORE_DECLARE(status_t) dir_make_recursive(const char *path, file_perms_t perm);
/**
* Remove directory from the file system.
* @param path the path for the directory to be removed. (use / on all systems)
* @remark Removing a directory which is in-use (e.g., the current working
* directory, or during core_dir_read, or with an open file) is not portable.
*/
CORE_DECLARE(status_t) dir_remove(const char *path);
/**
* get the specified file's stats.
* @param finfo Where to store the information about the file.
* @param wanted The desired file_info_t fields, as a bit flag of
* CORE_FINFO_ values
* @param thefile The file to get information about.
*/
CORE_DECLARE(status_t) file_info_get(file_info_t *finfo,
c_int32_t wanted, file_t *thefile);
/**
* Truncate the file's length to the specified offset
* @param fp The file to truncate
* @param offset The offset to truncate to.
* @remark The read/write file offset is repositioned to offset.
*/
CORE_DECLARE(status_t) file_trunc(file_t *fp, off_t offset);
/**
* Retrieve the flags that were passed into file_open()
* when the file was opened.
* @return c_int32_t the flags
*/
CORE_DECLARE(c_int32_t) file_flags_get(file_t *f);
/**
* get the specified file's stats. The file is specified by filename,
* instead of using a pre-opened file.
* @param finfo Where to store the information about the file, which is
* never touched if the call fails.
* @param fname The name of the file to stat.
* @param wanted The desired file_info_t fields, as a bit flag of FILE_INFO_
values
*
* @note If @c CORE_INCOMPLETE is returned all the fields in @a finfo may
* not be filled in, and you need to check the @c finfo->valid bitmask
* to verify that what you're looking for is there.
*/
CORE_DECLARE(status_t) file_stat(file_info_t *finfo,
const char *fname, c_int32_t wanted);
/**
* Find an existing directory suitable as a temporary storage location.
* @param temp_dir The temp directory.
* @remark
* This function uses an algorithm to search for a directory that an
* an application can use for temporary storage.
*
*/
CORE_DECLARE(status_t) temp_dir_get(char *temp_dir);
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ! __CORE_FILE_H__ */
nextepc-0.3.10/lib/core/include/core_fsm.h 0000664 0000000 0000000 00000002260 13335533574 0020343 0 ustar 00root root 0000000 0000000 #ifndef __CORE_FSM_H__
#define __CORE_FSM_H__
#include "core.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
extern char *FSM_NAME_INIT_SIG;
extern char *FSM_NAME_ENTRY_SIG;
extern char *FSM_NAME_EXIT_SIG;
typedef enum _fsm_signal_t {
FSM_ENTRY_SIG,
FSM_EXIT_SIG,
FSM_USER_SIG
} fsm_signal_t;
typedef c_uintptr_t fsm_event_t;
typedef c_uintptr_t fsm_state_t;
typedef void (*fsm_handler_t)(void *s, void *e);
typedef struct _fsm_t {
fsm_handler_t initial;
fsm_handler_t final;
fsm_handler_t state;
} fsm_t;
#define fsm_create(__s, __i, __f) \
(((__s)->initial = (__s)->state = (fsm_handler_t)(__i)), \
(__s)->final = (fsm_handler_t)(__f))
#define fsm_clear(__s) \
((__s)->initial = (__s)->state = (__s)->final = NULL)
CORE_DECLARE(void) fsm_init(void *s, void *e);
CORE_DECLARE(void) fsm_dispatch(void *s, void *e);
CORE_DECLARE(void) fsm_final(void *s, void *e);
#define FSM_TRAN(__s, __target) \
((fsm_t *)__s)->state = (fsm_handler_t)(__target)
#define FSM_STATE(__s) \
(((fsm_t *)__s)->state)
#define FSM_CHECK(__s, __f) \
(FSM_STATE(__s) == (fsm_handler_t)__f)
#ifdef __cplusplus
}
#endif
#endif /* ! __CORE_FSM_H__ */
nextepc-0.3.10/lib/core/include/core_general.h 0000664 0000000 0000000 00000007210 13335533574 0021173 0 ustar 00root root 0000000 0000000 #ifndef __CORE_GENERAL_H__
#define __CORE_GENERAL_H__
/**
* @file core_general.h
* This is collection of oddballs that didn't fit anywhere else,
* and might move to more appropriate headers with the release
* of CORE 1.0.
* @brief CORE Miscellaneous library routines
*/
#include "core.h"
#include "core_errno.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup core_general Miscellaneous library routines
* @ingroup CORE
* This is collection of oddballs that didn't fit anywhere else,
* and might move to more appropriate headers with the release
* of CORE 1.0.
* @{
*/
/** a space */
#define ASCII_BLANK '\040'
/** a carrige return */
#define ASCII_CR '\015'
/** a line feed */
#define ASCII_LF '\012'
/** a tab */
#define ASCII_TAB '\011'
/**
* Alignment macros
*/
/* C_ALIGN() is only to be used to align on a power of 2 boundary */
#define C_ALIGN(size, boundary) \
(((size) + ((boundary) - 1)) & ~((boundary) - 1))
/** Default alignment */
#define C_ALIGN_DEFAULT(size) C_ALIGN(size, 8)
/**
* String and memory functions
*/
/* STRINGIFY is defined here, and also in core_release.h, so wrap it */
#ifndef STRINGIFY
/** Properly quote a value as a string in the C preprocessor */
#define STRINGIFY(n) STRINGIFY_HELPER(n)
/** Helper macro for STRINGIFY */
#define STRINGIFY_HELPER(n) #n
#endif
/** @} */
/**
* @defgroup core_library Library initialization and termination
* @{
*/
/**
* Setup any CORE internal data structures. This MUST be the first function
* called for any CORE library.
* @remark See core_app_initialize if this is an application, rather than
* a library consumer of core.
*/
CORE_DECLARE(status_t) core_initialize(void);
/**
* Set up an application with normalized argc, argv (and optionally env) in
* order to deal with platform-specific oddities, such as Win32 services,
* code pages and signals. This must be the first function called for any
* CORE program.
* @param argc Pointer to the argc that may be corrected
* @param argv Pointer to the argv that may be corrected
* @param env Pointer to the env that may be corrected, may be NULL
* @remark See core_initialize if this is a library consumer of core.
* Otherwise, this call is identical to core_initialize, and must be closed
* with a call to core_terminate at the end of program execution.
*/
CORE_DECLARE(status_t) core_app_initialize(int *argc,
char const * const * *argv,
char const * const * *env);
/**
* Tear down any CORE internal data structures which aren't torn down
* automatically.
* @remark An CORE program must call this function at termination once it
* has stopped using CORE services. The CORE developers suggest using
* atexit to ensure this is called. When using CORE from a language
* other than C that has problems with the calling convention, use
* core_terminate2() instead.
*/
CORE_DECLARE_NONSTD(void) core_terminate(void);
/**
* Tear down any CORE internal data structures which aren't torn down
* automatically, same as core_terminate
* @remark An CORE program must call either the core_terminate or
* core_terminate2 function once it it has finished using CORE
* services. The CORE developers suggest using atexit(core_terminate)
* to ensure this is done. core_terminate2 exists to allow non-c
* language apps to tear down core, while core_terminate is
* recommended from c language applications.
*/
CORE_DECLARE(void) core_terminate2(void);
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ! CORE_GENERAL_H */
nextepc-0.3.10/lib/core/include/core_hash.h 0000664 0000000 0000000 00000015270 13335533574 0020506 0 ustar 00root root 0000000 0000000 #ifndef __HASH_H__
#define __HASH_H__
#include "core.h"
/**
* @file hash.h
* @brief CORE Hash Tables
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup hash Hash Tables
* @ingroup CORE
* @{
*/
/**
* When passing a key to hash_set or hash_get, this value can be
* passed to indicate a string-valued key, and have hash compute the
* length automatically.
*
* @remark hash will use strlen(key) for the length. The NUL terminator
* is not included in the hash value (why throw a constant in?).
* Since the hash table merely references the provided key (rather
* than copying it), hash_this() will return the NUL-term'd key.
*/
#define HASH_KEY_STRING (-1)
/**
* Abstract type for hash tables.
*/
typedef struct hash_t hash_t;
/**
* Abstract type for scanning hash tables.
*/
typedef struct hash_index_t hash_index_t;
/**
* Callback functions for calculating hash values.
* @param key The key.
* @param klen The length of the key, or HASH_KEY_STRING to use the string
* length. If HASH_KEY_STRING then returns the actual key length.
*/
typedef unsigned int (*hashfunc_t)(const char *key, int *klen);
/**
* The default hash function.
*/
CORE_DECLARE_NONSTD(unsigned int)
core_hashfunc_default(const char *key, int *klen);
/**
* Create a hash table.
* @return The hash table just created
*/
CORE_DECLARE(hash_t *) hash_make();
/**
* Create a hash table with a custom hash function
* @param hash_func A custom hash function.
* @return The hash table just created
*/
CORE_DECLARE(hash_t *) hash_make_custom(hashfunc_t hash_func);
/* Destroy hash memory */
CORE_DECLARE(void) hash_destroy(hash_t *ht);
/**
* Associate a value with a key in a hash table.
* @param ht The hash table
* @param key Pointer to the key
* @param klen Length of the key. Can be HASH_KEY_STRING to use the string length.
* @param val Value to associate with the key
* @remark If the value is NULL the hash entry is deleted. The key is stored as is,
* and so must have a lifetime at least as long as the hash table's pool.
*/
CORE_DECLARE(void) hash_set(hash_t *ht,
const void *key, int klen, const void *val);
/**
* Look up the value associated with a key in a hash table.
* @param ht The hash table
* @param key Pointer to the key
* @param klen Length of the key. Can be HASH_KEY_STRING to use the string length.
* @return Returns NULL if the key is not present.
*/
CORE_DECLARE(void *) hash_get(hash_t *ht, const void *key, int klen);
/**
* Look up the value associated with a key in a hash table, or if none exists
* associate a value.
* @param ht The hash table
* @param key Pointer to the key
* @param klen Length of the key. Can be HASH_KEY_STRING to use the string
* length.
* @param val Value to associate with the key (if none exists).
* @return Returns the existing value if any, the given value otherwise.
* @remark If the given value is NULL and a hash entry exists, nothing is done.
*/
CORE_DECLARE(void *) hash_get_or_set(hash_t *ht,
const void *key, int klen, const void *val);
/**
* Start iterating over the entries in a hash table.
* @param ht The hash table
* @return The iteration state
* @remark There is no restriction on adding or deleting hash entries during
* an iteration (although the results may be unpredictable unless all you do
* is delete the current entry) and multiple iterations can be in
* progress at the same time.
*
* @par Example:
*
* @code
* int sum_values(hash_t *ht)
* {
* hash_index_t *hi;
* void *val;
* int sum = 0;
* for (hi = hash_first(ht); hi; hi = hash_next(hi)) {
* hash_this(hi, NULL, NULL, &val);
* sum += *(int *)val;
* }
* return sum;
* }
* @endcode
*/
CORE_DECLARE(hash_index_t *) hash_first(hash_t *ht);
/**
* Continue iterating over the entries in a hash table.
* @param hi The iteration state
* @return a pointer to the updated iteration state. NULL if there are no more
* entries.
*/
CORE_DECLARE(hash_index_t *) hash_next(hash_index_t *hi);
/**
* Get the current entry's details from the iteration state.
* @param hi The iteration state
* @param key Return pointer for the pointer to the key.
* @param klen Return pointer for the key length.
* @param val Return pointer for the associated value.
* @remark The return pointers should point to a variable that will be set to the
* corresponding data, or they may be NULL if the data isn't interesting.
*/
CORE_DECLARE(void) hash_this(hash_index_t *hi,
const void **key, int *klen, void **val);
/**
* Get the current entry's key from the iteration state.
* @param hi The iteration state
* @return The pointer to the key
*/
CORE_DECLARE(const void*) hash_this_key(hash_index_t *hi);
/**
* Get the current entry's key length from the iteration state.
* @param hi The iteration state
* @return The key length
*/
CORE_DECLARE(int) hash_this_key_len(hash_index_t *hi);
/**
* Get the current entry's value from the iteration state.
* @param hi The iteration state
* @return The pointer to the value
*/
CORE_DECLARE(void*) hash_this_val(hash_index_t *hi);
/**
* Get the number of key/value pairs in the hash table.
* @param ht The hash table
* @return The number of key/value pairs in the hash table.
*/
CORE_DECLARE(unsigned int) hash_count(hash_t *ht);
/**
* Clear any key/value pairs in the hash table.
* @param ht The hash table
*/
CORE_DECLARE(void) hash_clear(hash_t *ht);
/**
* Declaration prototype for the iterator callback function of hash_do().
*
* @param rec The data passed as the first argument to hash_[v]do()
* @param key The key from this iteration of the hash table
* @param klen The key length from this iteration of the hash table
* @param value The value from this iteration of the hash table
* @remark Iteration continues while this callback function returns non-zero.
* To export the callback function for hash_do() it must be declared
* in the _NONSTD convention.
*/
typedef int (hash_do_callback_fn_t)(
void *rec, const void *key, int klen, const void *value);
/**
* Iterate over a hash table running the provided function once for every
* element in the hash table. The @param comp function will be invoked for
* every element in the hash table.
*
* @param comp The function to run
* @param rec The data to pass as the first argument to the function
* @param ht The hash table to iterate over
* @return FALSE if one of the comp() iterations returned zero; TRUE if all
* iterations returned non-zero
* @see hash_do_callback_fn_t
*/
CORE_DECLARE(int) hash_do(hash_do_callback_fn_t *comp,
void *rec, const hash_t *ht);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* __HASH_H__ */
nextepc-0.3.10/lib/core/include/core_index.h 0000664 0000000 0000000 00000005664 13335533574 0020700 0 ustar 00root root 0000000 0000000 #ifndef __CORE_INDEX_H__
#define __CORE_INDEX_H__
#include "core.h"
#include "core_mutex.h"
typedef c_uint32_t index_t;
#define INVALID_INDEX 0
#define index_declare(__name, __type, __size) \
typedef struct { \
int head, tail; \
int size, avail; \
index_t free_index[__size]; \
__type *index_pool[__size + 1]; \
__type *free_pool[__size], node_pool[__size]; \
mutex_id mut; \
} index_##__name##_t; \
index_##__name##_t __name
#define index_init(__pname, __size) do { \
int __i; \
mutex_create(&(__pname)->mut, MUTEX_DEFAULT); \
(__pname)->size = (__pname)->avail = __size; \
(__pname)->head = (__pname)->tail = 0; \
for (__i = 0; __i < __size; __i++) \
{ \
(__pname)->free_index[__i] = (__i + 1); \
(__pname)->index_pool[__i + 1] = NULL; \
(__pname)->free_pool[__i] = &((__pname)->node_pool[__i]); \
} \
} while (0)
#define index_final(__pname) \
((__pname)->mut ? mutex_delete((__pname)->mut) : CORE_OK)
#define index_init_wo_lock(__pname, __size) do { \
int __i; \
(__pname)->mut = 0; \
(__pname)->size = (__pname)->avail = __size; \
(__pname)->head = (__pname)->tail = 0; \
for (__i = 0; __i < __size; __i++) \
{ \
(__pname)->free_index[__i] = (__i + 1); \
(__pname)->index_pool[__i + 1] = NULL; \
(__pname)->free_pool[__i] = &((__pname)->node_pool[__i]); \
} \
} while (0)
#define index_alloc(__pname, __pptr_node) do { \
if ((__pname)->mut) mutex_lock((__pname)->mut); \
if ((__pname)->avail > 0) { \
(__pname)->avail--; \
*(__pptr_node) = (void*)(__pname)->free_pool[(__pname)->head]; \
memset(*(__pptr_node), 0, sizeof(**(__pptr_node))); \
(__pname)->free_pool[(__pname)->head] = NULL; \
((*(__pptr_node))->index) = (__pname)->free_index[(__pname)->head]; \
(__pname)->index_pool[((*(__pptr_node))->index)] = *(__pptr_node); \
(__pname)->free_index[(__pname)->head] = INVALID_INDEX; \
(__pname)->head = ((__pname)->head + 1) % ((__pname)->size); \
} \
if ((__pname)->mut) mutex_unlock((__pname)->mut); \
} while (0)
#define index_free(__pname, __ptr_node) do { \
if ((__pname)->mut) mutex_lock((__pname)->mut); \
if ((__pname)->avail < (__pname)->size) { \
(__pname)->avail++; \
(__pname)->index_pool[((__ptr_node)->index)] = NULL; \
(__pname)->free_index[(__pname)->tail] = ((__ptr_node)->index); \
(__pname)->free_pool[(__pname)->tail] = (void*)(__ptr_node); \
(__pname)->tail = ((__pname)->tail + 1) % ((__pname)->size); \
} \
if ((__pname)->mut) mutex_unlock((__pname)->mut); \
} while (0)
#define index_find(__pname, __index) (void*)(__pname)->index_pool[(__index)];
#define index_size(__pname) ((__pname)->size)
#define index_avail(__pname) ((__pname)->avail)
#define index_used(__pname) (index_size(__pname) - index_avail(__pname))
#endif /* ! __CORE_INDEX_H__ */
nextepc-0.3.10/lib/core/include/core_lib.h 0000664 0000000 0000000 00000010444 13335533574 0020327 0 ustar 00root root 0000000 0000000 #ifndef __CORE_LIB_H__
#define __CORE_LIB_H__
/**
* @file c_lib.h
* This is collection of oddballs that didn't fit anywhere else,
* and might move to more appropriate headers with the release
* of CORE 1.0.
* @brief CORE general purpose library routines
*/
#include "core.h"
#include "core_errno.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup c_lib General Purpose Library Routines
* @ingroup CORE
* This is collection of oddballs that didn't fit anywhere else,
* and might move to more appropriate headers with the release
* of CORE 1.0.
* @{
*/
/*
* Define the structures used by the CORE general-purpose library.
*/
/** @} */
/**
* @defgroup c_ctype ctype functions
* These macros allow correct support of 8-bit characters on systems which
* support 8-bit characters. Pretty dumb how the cast is required, but
* that's legacy libc for ya. These new macros do not support EOF like
* the standard macros do. Tough.
* @{
*/
/** @see isalnum */
#define c_isalnum(c) (isalnum(((unsigned char)(c))))
/** @see isalpha */
#define c_isalpha(c) (isalpha(((unsigned char)(c))))
/** @see iscntrl */
#define c_iscntrl(c) (iscntrl(((unsigned char)(c))))
/** @see isdigit */
#define c_isdigit(c) (isdigit(((unsigned char)(c))))
/** @see isgraph */
#define c_isgraph(c) (isgraph(((unsigned char)(c))))
/** @see islower*/
#define c_islower(c) (islower(((unsigned char)(c))))
/** @see isascii */
#ifdef isascii
#define c_isascii(c) (isascii(((unsigned char)(c))))
#else
#define c_isascii(c) (((c) & ~0x7f)==0)
#endif
/** @see isprint */
#define c_isprint(c) (isprint(((unsigned char)(c))))
/** @see ispunct */
#define c_ispunct(c) (ispunct(((unsigned char)(c))))
/** @see isspace */
#define c_isspace(c) (isspace(((unsigned char)(c))))
/** @see isupper */
#define c_isupper(c) (isupper(((unsigned char)(c))))
/** @see isxdigit */
#define c_isxdigit(c) (isxdigit(((unsigned char)(c))))
/** @see tolower */
#define c_tolower(c) (tolower(((unsigned char)(c))))
/** @see toupper */
#define c_toupper(c) (toupper(((unsigned char)(c))))
#define c_max(x , y) (((x) > (y)) ? (x) : (y))
#define c_min(x , y) (((x) < (y)) ? (x) : (y))
#define c_uint64_to_array(array, uint64) \
{ \
int i = 0; \
for (i = 0; i < 8; i++) array[i] = ((uint64 >> (8-1-i) * 8) & 0xff); \
}
CORE_DECLARE(status_t) core_generate_random_bytes(
c_uint8_t *buf, int length);
#define CORE_HEX(I, I_LEN, O) core_ascii_to_hex(I, I_LEN, O, sizeof(O))
CORE_DECLARE(void *) core_ascii_to_hex(
char *in, int in_len, void *out, int out_len);
CORE_DECLARE(void *) core_hex_to_ascii(
void *in, int in_len, void *out, int out_len);
CORE_DECLARE(void *) core_uint64_to_buffer(
c_uint64_t num, int size, void *buffer);
CORE_DECLARE(c_uint64_t) core_buffer_to_uint64(void *buffer, int size);
CORE_DECLARE(void *) core_bcd_to_buffer(c_int8_t *in, void *out, int *out_len);
CORE_DECLARE(void *) core_buffer_to_bcd(c_uint8_t *in, int in_len, void *out);
/*
* Apache's "replacement" for the strncpy() function. We roll our
* own to implement these specific changes:
* (1) strncpy() doesn't always null terminate and we want it to.
* (2) strncpy() null fills, which is bogus, esp. when copy 8byte
* strings into 8k blocks.
* (3) Instead of returning the pointer to the beginning of
* the destination string, we return a pointer to the
* terminating '\0' to allow us to "check" for truncation
* (4) If src is NULL, null terminate dst (empty string copy)
*
* apr_cpystrn() follows the same call structure as strncpy().
*/
CORE_DECLARE(char *)core_cpystrn(char *dst, const char *src, size_t dst_size);
/**
* Get the value of an environment variable
* @param value the returned value, allocated from @a pool
* @param envvar the name of the environment variable
*/
CORE_DECLARE(char *) core_env_get(const char *envvar);
/**
* Set the value of an environment variable
* @param envvar the name of the environment variable
* @param value the value to set
*/
CORE_DECLARE(status_t) core_env_set(const char *envvar, const char *value);
/**
* Delete a variable from the environment
* @param envvar the name of the environment variable
*/
CORE_DECLARE(status_t) core_env_delete(const char *envvar);
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ! __CORE_LIB_H__ */
nextepc-0.3.10/lib/core/include/core_list.h 0000664 0000000 0000000 00000006427 13335533574 0020542 0 ustar 00root root 0000000 0000000 #ifndef __CORE_LIST_H__
#define __CORE_LIST_H__
#include "core.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
struct _ln_t {
struct _ln_t *prev;
struct _ln_t *next;
};
typedef struct _ln_t ln_t;
typedef struct _ln_t list_t;
typedef struct _ln_t lnode_t;
#define list_init(__pname) do {\
(__pname)->prev = NULL; \
(__pname)->next = NULL; \
} while (0)
#define list_first(__pname) ((void*)((__pname)->next))
#define list_last(__pname) ((void*)((__pname)->prev))
#define list_prev(__ptr_node) ((void*)(((ln_t *)(__ptr_node))->prev))
#define list_next(__ptr_node) ((void*)(((ln_t *)(__ptr_node))->next))
#define list_is_empty(__pname) ((__pname)->next == NULL)
#define list_prepend(__pname, __ptr_new) do { \
((ln_t*)(__ptr_new))->prev = NULL; \
((ln_t*)(__ptr_new))->next = (__pname)->next; \
if ((__pname)->next) \
((__pname)->next)->prev = (ln_t*)(__ptr_new); \
else \
(__pname)->prev = (ln_t*)(__ptr_new); \
(__pname)->next = (ln_t*)(__ptr_new); \
} while (0)
#define list_append(__pname, __ptr_new) do { \
((ln_t*)(__ptr_new))->prev = (__pname)->prev; \
((ln_t*)(__ptr_new))->next = NULL; \
if ((__pname)->prev) \
((__pname)->prev)->next = (ln_t*)(__ptr_new); \
else \
(__pname)->next = (ln_t*)(__ptr_new); \
((__pname)->prev) = (ln_t*)(__ptr_new); \
} while (0)
#define list_insert_prev(__pname, __ptr_node, __ptr_new) do { \
((ln_t*)(__ptr_new))->prev = ((ln_t*)(__ptr_node))->prev; \
((ln_t*)(__ptr_new))->next = (ln_t*)(__ptr_node); \
if (((ln_t*)(__ptr_node))->prev) \
((ln_t*)(__ptr_node))->prev->next = (ln_t*)(__ptr_new); \
else \
(__pname)->next = (ln_t*)(__ptr_new); \
((ln_t*)(__ptr_node))->prev = ((ln_t*)(__ptr_new)); \
} while (0)
#define list_insert_next(__pname, __ptr_node, __ptr_new) do { \
((ln_t*)(__ptr_new))->prev = (ln_t*)(__ptr_node); \
((ln_t*)(__ptr_new))->next = ((ln_t*)(__ptr_node))->next; \
if (((ln_t*)(__ptr_node))->next) \
((ln_t*)(__ptr_node))->next->prev = (ln_t*)(__ptr_new); \
else \
(__pname)->prev = (ln_t*)(__ptr_new); \
((ln_t*)(__ptr_node))->next = ((ln_t*)(__ptr_new)); \
} while (0)
#define list_remove(__pname, __ptr_node) do { \
ln_t *_iter = (__pname)->next; \
while (_iter) { \
if (_iter == (ln_t*)(__ptr_node)) { \
if (_iter->prev) \
_iter->prev->next = _iter->next; \
else \
(__pname)->next = _iter->next; \
if (_iter->next) \
_iter->next->prev = _iter->prev; \
else \
(__pname)->prev = _iter->prev; \
break; \
} \
_iter = _iter->next; \
} \
} while (0)
typedef int (*ln_cmp_cb)(lnode_t *pnode1, lnode_t *pnode2);
#define list_insert_sorted(__pname, __ptr_new, __cmp_callback) do { \
ln_cmp_cb __pcb = (ln_cmp_cb)__cmp_callback; \
ln_t *_iter = list_first(__pname); \
while (_iter) { \
if ((*__pcb)((ln_t*)(__ptr_new), _iter) < 0) { \
list_insert_prev(__pname, _iter, __ptr_new); \
break; \
} \
_iter = list_next(_iter); \
} \
if (_iter == NULL) \
list_append(__pname, __ptr_new); \
} while (0)
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ! __CORE_LIST_H__ */
nextepc-0.3.10/lib/core/include/core_msgq.h 0000664 0000000 0000000 00000003352 13335533574 0020530 0 ustar 00root root 0000000 0000000 #ifndef __CORE_MSGQ_H__
#define __CORE_MSGQ_H__
/**
* @file core_msgq.h
* @brief Message queue header
*/
#include "core.h"
#include "core_time.h"
#include "core_errno.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef c_uintptr_t msgq_id;
#define MAX_MSG_LEN 0xffff
/**
* @return CORE_OK or CORE_ERROR.
*/
CORE_DECLARE(status_t) msgq_init(void);
/**
* @return CORE_OK or CORE_ERROR.
*/
CORE_DECLARE(status_t) msgq_final(void);
#define MSGQ_O_BLOCK 0x0
#define MSGQ_O_NONBLOCK 0x1
/**
* @param id
* @param msgsize
* @param opt
*
* @return If succeed, handler value. If fail, zero
*/
CORE_DECLARE(msgq_id) msgq_create(int qsize, int msgsize, int opt);
/**
* @param id
*
* @return If succeed, CORE_OK. If fail, CORE_ERROR.
*/
CORE_DECLARE(status_t) msgq_delete(msgq_id id);
/**
* @param id
* @param msg
* @param msglen
*
* @return the number of bytes to be sent. If there is insufficient room in
* ring buffer, return CORE_EAGAIN. If any error, CORE_ERROR.
*/
CORE_DECLARE(status_t) msgq_send(msgq_id id, const char *msg, int msglen);
/**
* @param id
* @param msg
* @param msglen
*
* @return the number of bytes to be read. If any error, CORE_ERROR.
* If ring buffer is empty and MSGQ_O_NONBLOCK set, CORE_EAGAIN.
*/
CORE_DECLARE(status_t) msgq_recv(msgq_id id, char *msg, int msglen);
/**
* @param id
* @param msg
* @param msglen
*
* @return the number of bytes to be read. If any error, CORE_ERROR.
* If ring buffer is empty and MSGQ_O_NONBLOCK set, CORE_EAGAIN.
* If time out with empty buffer, CORE_TIMEUP.
*/
CORE_DECLARE(status_t) msgq_timedrecv(msgq_id id, char *msg, int msglen,
c_time_t timeout);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* !__CORE_MSGQ_H__ */
nextepc-0.3.10/lib/core/include/core_mutex.h 0000664 0000000 0000000 00000004715 13335533574 0020727 0 ustar 00root root 0000000 0000000 #ifndef __MUTEX_H__
#define __MUTEX_H__
/**
* @file mutex.h
* @brief Core Mutex Routines
*/
#include "core.h"
#include "core_errno.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup mutex Thread Mutex Routines
* @ingroup CORE
* @{
*/
/** Opaque thread-local mutex structure */
typedef c_uintptr_t mutex_id;
#define MUTEX_DEFAULT 0x0 /**< platform-optimal lock behavior */
#define MUTEX_NESTED 0x1 /**< enable nested (recursive) locks */
#define MUTEX_UNNESTED 0x2 /**< disable nested locks */
/**
* Initialize Mutex Pool
*/
CORE_DECLARE(status_t) mutex_init(void);
/**
* Finalize Mutex Pool
*/
CORE_DECLARE(status_t) mutex_final(void);
/**
* Create and initialize a mutex that can be used to synchronize threads.
* @param id the memory address where the newly created mutex will be
* stored.
* @param flags Or'ed value of:
*
* MUTEX_DEFAULT platform-optimal lock behavior.
* MUTEX_NESTED enable nested (recursive) locks.
* MUTEX_UNNESTED disable nested locks (non-recursive).
*
* @param pool the pool from which to allocate the mutex.
* @warning Be cautious in using MUTEX_DEFAULT. While this is the
* most optimial mutex based on a given platform's performance charateristics,
* it will behave as either a nested or an unnested lock.
*/
CORE_DECLARE(status_t) mutex_create(mutex_id *id, unsigned int flags);
/**
* Acquire the lock for the given mutex. If the mutex is already locked,
* the current thread will be put to sleep until the lock becomes available.
* @param id the mutex on which to acquire the lock.
*/
CORE_DECLARE(status_t) mutex_lock(mutex_id id);
/**
* Attempt to acquire the lock for the given mutex. If the mutex has already
* been acquired, the call returns immediately with CORE_EBUSY. Note: it
* is important that the CORE_STATUS_IS_EBUSY(s) macro be used to determine
* if the return value was CORE_EBUSY, for portability reasons.
* @param id the mutex on which to attempt the lock acquiring.
*/
CORE_DECLARE(status_t) mutex_trylock(mutex_id id);
/**
* Release the lock for the given mutex.
* @param id the mutex from which to release the lock.
*/
CORE_DECLARE(status_t) mutex_unlock(mutex_id id);
/**
* Destroy the mutex and free the memory associated with the lock.
* @param id the mutex to destroy.
*/
CORE_DECLARE(status_t) mutex_delete(mutex_id id);
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ! __MUTEX_H__ */
nextepc-0.3.10/lib/core/include/core_network.h 0000664 0000000 0000000 00000022156 13335533574 0021255 0 ustar 00root root 0000000 0000000 #ifndef __CORE_NETWORK_H__
#define __CORE_NETWORK_H__
#include "core_errno.h"
#include "core_time.h"
#include "core_list.h"
#if HAVE_ARPA_INET_H
#include
#endif
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup sock_option Socket option definitions
* @{
*/
#define SOCK_O_LINGER (1 << 0) /**< Linger */
#define SOCK_O_KEEPALIVE (1 << 1) /**< Keepalive */
#define SOCK_O_DEBUG (1 << 2) /**< Debug */
#define SOCK_O_NONBLOCK (1 << 3) /**< Non-blocking IO */
#define SOCK_O_REUSEADDR (1 << 4) /**< Reuse addresses */
#define SOCK_O_SNDBUF (1 << 5) /**< Send buffer */
#define SOCK_O_RCVBUF (1 << 6) /**< Receive buffer */
#define SOCK_O_DISCONNECTED (1 << 7) /**< Disconnected */
#define SOCK_O_TCP_NODELAY (1 << 8) /**< For SCTP sockets, this is mapped
* to STCP_NODELAY internally.
*/
#define SOCK_O_TCP_NOPUSH (1 << 9) /**< No push */
#define SOCK_O_RESET_NODELAY (1 << 10) /**< This flag is ONLY set internally
* when we set SOCK_O_TCP_NOPUSH with
* SOCK_O_TCP_NODELAY set to tell us that
* SOCK_O_TCP_NODELAY should be turned on
* again when NOPUSH is turned off
*/
#define SOCK_O_INCOMPLETE_READ (1 << 11) /**< Set on non-blocking sockets
* (timeout != 0) on which the
* previous read() did not fill a buffer
* completely. the next sock_read()
* will first call select()/poll() rather than
* going straight into read(). (Can also
* be set by an application to force a
* select()/poll() call before the next
* read, in cases where the app expects
* that an immediate read would fail.)
*/
#define SOCK_O_INCOMPLETE_WRITE (1 << 12) /**< like SOCK_O_INCOMPLETE_READ, but
* for write
* @see SOCK_O_INCOMPLETE_READ
*/
#define SOCK_O_IPV6_V6ONLY (1 << 13) /**< Don't accept IPv4 connections
* on a IPv6 listening socket.
*/
#define SOCK_O_TCP_DEFER_ACCEPT (1 << 14) /**< Delay accepting of new
* connections until data is available.
* @see apr_socket_accept_filter
*/
#define SOCK_O_BROADCAST (1 << 15) /**< Allow broadcast */
#define SOCK_O_FREEBIND (1 << 16) /**< Allow binding to addresses not
* owned by any interface
*/
typedef c_uintptr_t sock_id;
typedef int (*sock_handler)(sock_id sock, void *data);
typedef struct c_sockaddr_t c_sockaddr_t;
struct c_sockaddr_t {
/* Reserved Area
* - Should not add any atrribute in this area.
*
* e.g)
* struct sockaddr addr;
* ...
* sockaddr_len((c_sockaddr_t *)&addr);
*/
#define c_sa_family sa.sa_family
#define c_sa_port sin.sin_port
union {
struct sockaddr_storage ss;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
struct sockaddr sa;
};
/* User Area
* - Could add your attribute.
*/
c_sockaddr_t *next;
};
typedef struct _sock_node_t {
lnode_t node;
sock_id sock;
c_sockaddr_t *list;
} sock_node_t;
typedef struct ipsubnet_t {
int family;
c_uint32_t sub[4]; /* big enough for IPv4 and IPv6 addresses */
c_uint32_t mask[4];
} ipsubnet_t;
typedef struct _sctp_info_t {
c_uint32_t ppid;
c_uint16_t stream_no;
c_uint16_t inbound_streams;
c_uint16_t outbound_streams;
} sctp_info_t;
/*
* Init/Final
*/
CORE_DECLARE(status_t) network_init(void);
CORE_DECLARE(status_t) network_final(void);
/*
* Socket
*/
CORE_DECLARE(status_t) sock_create(sock_id *new);
CORE_DECLARE(status_t) sock_delete(sock_id id);
CORE_DECLARE(status_t) sock_delete_list(list_t *list);
CORE_DECLARE(status_t) sock_socket(
sock_id *id, int family, int type, int protocol);
CORE_DECLARE(status_t) sock_setsockopt(sock_id id, c_int32_t opt, c_int32_t on);
CORE_DECLARE(status_t) sock_bind(sock_id id, c_sockaddr_t *addr);
CORE_DECLARE(status_t) sock_connect(sock_id id, c_sockaddr_t *addr);
CORE_DECLARE(status_t) sock_listen(sock_id id);
CORE_DECLARE(status_t) sock_accept(sock_id *new, sock_id id);
CORE_DECLARE(int) sock_family(sock_id id);
CORE_DECLARE(c_sockaddr_t *) sock_local_addr(sock_id id);
CORE_DECLARE(c_sockaddr_t *) sock_remote_addr(sock_id id);
/*
* Socket Node
*/
CORE_DECLARE(status_t) sock_add_node(
list_t *list, sock_node_t **node, c_sockaddr_t *sa_list, int family);
CORE_DECLARE(status_t) sock_remove_node(list_t *list, sock_node_t *node);
CORE_DECLARE(status_t) sock_remove_all_nodes(list_t *list);
CORE_DECLARE(status_t) sock_probe_node(
list_t *list, list_t *list6, const char *dev, c_uint16_t port);
CORE_DECLARE(status_t) sock_fill_scope_id_in_local(c_sockaddr_t *sa_list);
/*
* Socket Address
*/
CORE_DECLARE(status_t) core_getaddrinfo(c_sockaddr_t **sa_list,
int family, const char *hostname, c_uint16_t port, int flags);
CORE_DECLARE(status_t) core_freeaddrinfo(c_sockaddr_t *sa_list);
CORE_DECLARE(status_t) core_addaddrinfo(c_sockaddr_t **sa_list,
int family, const char *hostname, c_uint16_t port, int flags);
CORE_DECLARE(status_t) core_copyaddrinfo(
c_sockaddr_t **dst, const c_sockaddr_t *src);
CORE_DECLARE(status_t) core_filteraddrinfo(c_sockaddr_t **sa_list, int family);
CORE_DECLARE(status_t) core_sortaddrinfo(c_sockaddr_t **sa_list, int family);
CORE_DECLARE(c_sockaddr_t *) core_link_local_addr_by_dev(const char *dev);
#define CORE_ADDRSTRLEN INET6_ADDRSTRLEN
#define CORE_ADDR(__aDDR, __bUF) \
core_inet_ntop(__aDDR, buf, CORE_ADDRSTRLEN)
#define CORE_PORT(__aDDR) \
ntohs((__aDDR)->c_sa_port)
#define INET_NTOP(src, dst) \
inet_ntop(AF_INET,(void *)(c_uintptr_t)(src),(dst),INET_ADDRSTRLEN)
#define INET6_NTOP(src, dst) \
inet_ntop(AF_INET6,(void *)(src),(dst),INET6_ADDRSTRLEN)
CORE_DECLARE(const char *)core_inet_ntop(void *addr, char *buf, int buflen);
CORE_DECLARE(status_t) core_inet_pton(int family, const char *src, void *addr);
CORE_DECLARE(socklen_t) sockaddr_len(const void *addr);
CORE_DECLARE(int) sockaddr_is_equal(void *p, void *q);
CORE_DECLARE(status_t) core_ipsubnet(
ipsubnet_t *ipsub, const char *ipstr, const char *mask_or_numbits);
/*
* UDP Socket
*/
CORE_DECLARE(status_t) udp_socket(sock_id *new, int family);
CORE_DECLARE(status_t) udp_server(sock_id *new, c_sockaddr_t *sa_list);
CORE_DECLARE(status_t) udp_client(sock_id *new, c_sockaddr_t *sa_list);
CORE_DECLARE(status_t) udp_connect(sock_id id, c_sockaddr_t *sa_list);
/*
* TCP Socket
*/
CORE_DECLARE(status_t) tcp_server(sock_id *new, c_sockaddr_t *sa_list);
CORE_DECLARE(status_t) tcp_client(sock_id *new, c_sockaddr_t *sa_list);
/*
* SCTP Socket
*/
CORE_DECLARE(void) sctp_set_num_ostreams(int sctp_streams);
CORE_DECLARE(status_t) sctp_socket(sock_id *new, int family, int type);
CORE_DECLARE(status_t) sctp_server(sock_id *new,
int type, c_sockaddr_t *sa_list);
CORE_DECLARE(status_t) sctp_client(sock_id *new,
int type, c_sockaddr_t *sa_list);
CORE_DECLARE(status_t) sctp_connect(sock_id id, c_sockaddr_t *sa_list);
CORE_DECLARE(int) core_sctp_sendmsg(sock_id id, const void *msg, size_t len,
c_sockaddr_t *to, c_uint32_t ppid, c_uint16_t stream_no);
CORE_DECLARE(int) core_sctp_recvmsg(sock_id id, void *msg, size_t len,
c_sockaddr_t *from, sctp_info_t *sinfo, int *msg_flags);
CORE_DECLARE(int) core_sctp_recvdata(sock_id id, void *msg, size_t len,
c_sockaddr_t *from, sctp_info_t *sinfo);
/*
* TUN Driver
*/
CORE_DECLARE(status_t) tun_open(sock_id *new,
char *ifname, int is_tap);
CORE_DECLARE(status_t) tun_set_ip(sock_id id, ipsubnet_t *gw, ipsubnet_t *sub);
/*
* Send/Recv
*/
CORE_DECLARE(ssize_t) sock_write(sock_id id, const void *buf, size_t len);
CORE_DECLARE(ssize_t) sock_read(sock_id id, void *buf, size_t len);
CORE_DECLARE(ssize_t) core_send(sock_id id,
const void *buf, size_t len, int flags);
CORE_DECLARE(ssize_t) core_sendto(sock_id id,
const void *buf, size_t len, int flags, const c_sockaddr_t *to);
CORE_DECLARE(ssize_t) core_recv(sock_id id, void *buf, size_t len, int flags);
CORE_DECLARE(ssize_t) core_recvfrom(sock_id id,
void *buf, size_t len, int flags, c_sockaddr_t *from);
/*
* Select Loop
*/
CORE_DECLARE(status_t) sock_register(sock_id id,
sock_handler handler, void *data);
CORE_DECLARE(status_t) sock_unregister(sock_id id);
CORE_DECLARE(int) sock_is_registered(sock_id id);
CORE_DECLARE(int) sock_select_loop(c_time_t timeout);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
nextepc-0.3.10/lib/core/include/core_param.h 0000664 0000000 0000000 00000001204 13335533574 0020653 0 ustar 00root root 0000000 0000000 #ifndef __CORE_PARAM_H__
#define __CORE_PARAM_H__
#define MAX_NUM_OF_THREAD 128
#define MAX_NUM_OF_THREADATTR MAX_NUM_OF_THREAD
#define MAX_NUM_OF_PROC 128
#define MAX_NUM_OF_MUTEX 512
#define MAX_NUM_OF_COND 512
#define MAX_NUM_OF_RWLOCK 512
#define MAX_NUM_OF_SEMAPHORE 512
#define MAX_NUM_OF_FILE 256
#define MAX_FILENAME_SIZE 256
#define MAX_DIRNAME_SIZE 256
#define MAX_NUM_OF_TIMER 1024
#define MAX_SIG_DESC_SIZE 256
#define HUGE_STRING_LEN 8192
#define MAX_FILEPATH_LEN 256
#define MAX_ERROR_STRING_LEN 1024
#endif /* ! __CORE_PARAM_H__ */
nextepc-0.3.10/lib/core/include/core_pkbuf.h 0000664 0000000 0000000 00000012623 13335533574 0020671 0 ustar 00root root 0000000 0000000 #ifndef __CORE_PKBUF_H__
#define __CORE_PKBUF_H__
/**
* @file core_pkbuf.h
* @brief Packet Buffer Routines
*/
#include "core.h"
#include "core_debug.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* Cluster buffer structre */
typedef struct _clbuf_t {
/**
* reference count */
c_uint16_t ref;
/**
* pointer to cluster */
void *cluster;
/**
* the size of cluster */
c_uint16_t size;
} clbuf_t;
/**
* Packet buffer structure */
typedef struct _pkbuf_t {
/** next pkbuf in singly linked pkbuf chain */
struct _pkbuf_t *next;
/** pointer to cluster */
clbuf_t *clbuf;
/** this buffer */
void *payload;
/**
* total length of this buffer and all next buffers in chain
* belonging to the same packet.
*
* For non-queue packet chains this is the invariant:
* p->tot_len == p->len + (p->next? p->next->tot_len: 0)
*/
c_uint16_t tot_len;
/** length of this buffer */
c_uint16_t len;
/** misc flags */
c_uint8_t flags;
} pkbuf_t;
/**
* Initializes the packet buffer library */
CORE_DECLARE(status_t) pkbuf_init(void);
/**
* Finalizes the packet buffer library */
CORE_DECLARE(status_t) pkbuf_final(void);
/**
* Show the pkbuf/clbuf/cluster count */
CORE_DECLARE(void) pkbuf_show(void);
/**
* Allocates a pkbuf of the given type (possibly a chain).
*
* The actual memory allocated for the pkbuf is determined by the
* headroom at which the pkbuf is allocated and the requested size
* (from the headroom parameter).
*
* @param headroom define header size
* @param type define header size
* should be allocated as follows:
*
* @return the allocated pkbuf. If multiple pkbufs where allocated, this
* is the first pkbuf of a pkbuf chain.
*/
#define MAX_SIZEOF_HEADROOM 128
CORE_DECLARE(pkbuf_t *) pkbuf_alloc(c_uint16_t headroom, c_uint16_t length);
/**
* Dereference a pkbuf chain and deallocate any no-longer-used
* pkbufs at the head of this chain.
*
* Decrements the reference count of the pkbuf's cluster buffer.
* If it reaches zero, the pkbuf is deallocated.
*
* For a pkbuf chain, this is repeated for each pkbuf in the chain,
* up to the first pkbuf which has a non-zero reference count after
* decrementing. So, when all reference counts are one, the whole
* chain is free'd.
*
* @param pkbuf The pkbuf (chain) to be dereferenced.
*
* @return the number of pkbufs that were de-allocated
* from the head of the chain.
*/
CORE_DECLARE(void) pkbuf_free(pkbuf_t *pkbuf);
/**
* Adjusts the payload pointer to hide or reveal headers in the payload.
*
* Adjusts the ->payload pointer so that space for a header
* (dis)appears in the pkbuf payload.
*
* The ->payload, ->tot_len and ->len fields are adjusted.
*
* @param pkbuf pkbuf to change the header size.
* @param size Number of bytes to increment header size which
* increases the size of the pkbuf. New space is on the front.
* (Using a negative value decreases the header size.)
* If hdr_size_inc is 0, this function does nothing and returns succesful.
*
* @return non-zero on failure, zero on success.
*/
CORE_DECLARE(status_t) pkbuf_header(pkbuf_t *pkbuf, c_int16_t size);
/**
* Concatenate two pkbufs (each may be a pkbuf chain) and take over
* the caller's reference of the tail pkbuf.
*
* @note The caller MAY NOT reference the tail pkbuf afterwards.
* Use pkbuf_chain() for that purpose.
*
* @see pkbuf_chain()
*/
CORE_DECLARE(void) pkbuf_join(pkbuf_t *h, pkbuf_t *t);
/**
* Create copies of pkbufs.
*
* @param pkbuf pkbuf source of the copy
*/
CORE_DECLARE(pkbuf_t*) pkbuf_copy(pkbuf_t *pkbuf);
/**
* Create copies of some part of pkbufs.
*
* @param pkbuf pkbuf source of the copy
* @param offset offset into the packet buffer from where to begin copying
* len bytes
* @param len length of data to copy
*/
CORE_DECLARE(pkbuf_t*) pkbuf_copy_partial(pkbuf_t *pkbuf,
c_uint16_t offset, c_uint16_t len);
/**
* Copy the whole contents of a packet buffer to an application supplied
* buffer.
*
* @param pkbuf pkbuf from which to copy data
* @param buf buffer to copy to
* @param buflen
*/
CORE_DECLARE(status_t) pkbuf_tobuf(pkbuf_t *pkbuf,
void *buf, c_uint16_t *buflen);
/**
* Copy part of the contents of a packet buffer to an application supplied
* buffer.
*
* @param pkbuf pkbuf from which to copy data
* @param buf buffer to copy to
* @param buflen
* @param offset offset into the packet buffer from where
* to begin copying len bytes
* @param len length of data to copy
*/
CORE_DECLARE(status_t) pkbuf_tobuf_partial(pkbuf_t *pkbuf,
void *buf, c_uint16_t *buflen, c_uint16_t offset, c_uint16_t len);
/**
* Get the total length of packet buffer */
#define pkbuf_length(__pkbuf) (__pkbuf) ? ((__pkbuf)->tot_len : -1)
/* memory handling library like OS-function(malloc,free) */
CORE_DECLARE(void *) core_malloc(size_t size);
#define CORE_FREE(__pTR) d_assert(core_free(__pTR) == CORE_OK,,);
CORE_DECLARE(status_t) core_free(void *ptr);
CORE_DECLARE(void *) core_calloc(size_t nmemb, size_t size);
CORE_DECLARE(void *) core_realloc(void *ptr, size_t size);
CORE_DECLARE(char *) core_strdup(const char *s);
CORE_DECLARE(char *) core_strndup(const char *s, size_t n);
CORE_DECLARE(void *) core_memdup(const void *m, size_t n);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ! __PKBUF_H__ */
nextepc-0.3.10/lib/core/include/core_pool.h 0000664 0000000 0000000 00000004103 13335533574 0020525 0 ustar 00root root 0000000 0000000 #ifndef __CORE_POOL_H__
#define __CORE_POOL_H__
#include "core.h"
#include "core_mutex.h"
#define pool_declare(__name, __type, __size) \
typedef struct { \
int head, tail; \
int size, avail; \
__type *free[__size], pool[__size]; \
mutex_id mut; \
} pool_##__name##_t; \
pool_##__name##_t __name
#define pool_init(__pname, __size) do { \
int __i; \
mutex_create(&(__pname)->mut, MUTEX_DEFAULT); \
(__pname)->size = (__pname)->avail = __size; \
(__pname)->head = (__pname)->tail = 0; \
for (__i = 0; __i < __size; __i++) \
(__pname)->free[__i] = &((__pname)->pool[__i]); \
} while (0)
#define pool_final(__pname) \
((__pname)->mut ? mutex_delete((__pname)->mut) : CORE_OK)
#define pool_init_wo_lock(__pname, __size) do { \
int __i; \
(__pname)->mut = 0; \
(__pname)->size = (__pname)->avail = __size; \
(__pname)->head = (__pname)->tail = 0; \
for (__i = 0; __i < __size; __i++) \
(__pname)->free[__i] = &((__pname)->pool[__i]); \
} while (0)
#define pool_alloc_node(__pname, __pptr_node) do { \
*(__pptr_node) = NULL; \
if ((__pname)->mut) mutex_lock((__pname)->mut); \
if ((__pname)->avail > 0) { \
(__pname)->avail--; \
*(__pptr_node) = (void*)(__pname)->free[(__pname)->head]; \
(__pname)->free[(__pname)->head] = NULL; \
(__pname)->head = ((__pname)->head + 1) % ((__pname)->size); \
} \
if ((__pname)->mut) mutex_unlock((__pname)->mut); \
} while (0)
#define pool_free_node(__pname, __ptr_node) do { \
if ((__pname)->mut) mutex_lock((__pname)->mut); \
if ((__pname)->avail < (__pname)->size) { \
(__pname)->avail++; \
(__pname)->free[(__pname)->tail] = (void*)(__ptr_node); \
(__pname)->tail = ((__pname)->tail + 1) % ((__pname)->size); \
} \
if ((__pname)->mut) mutex_unlock((__pname)->mut); \
} while (0)
#define pool_size(__pname) ((__pname)->size)
#define pool_avail(__pname) ((__pname)->avail)
#define pool_used(__pname) (pool_size(__pname) - pool_avail(__pname))
#endif /* ! __CORE_POOL_H__ */
nextepc-0.3.10/lib/core/include/core_portable.h 0000664 0000000 0000000 00000004061 13335533574 0021367 0 ustar 00root root 0000000 0000000 /* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* This header file is where you should put ANY platform specific information.
* This should be the only header file that programs need to include that
* actually has platform dependent code which refers to the .
*/
#ifndef __CORE_PORTABLE_H__
#define __CORE_PORTABLE_H__
#include "core_thread.h"
#include "core_network.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef int os_file_t; /**< native file */
typedef pthread_t os_thread_t; /**< native thread */
typedef pid_t os_proc_t; /**< native pid */
typedef int os_sock_t; /**< native socket */
/**
* convert the thread to os specific type from core type.
* @param thethd The core thread to convert
* @param thd The os specific thread we are converting to
*/
CORE_DECLARE(status_t) os_thread_get(os_thread_t **thethd, thread_id id);
/**
* Get the thread ID
*/
CORE_DECLARE(os_thread_t) os_thread_current(void);
/**
* Convert the socket from an core type to an OS specific socket
* @param thesock The socket to convert.
* @param sock The os specific equivalent of the core socket..
*/
CORE_DECLARE(status_t) os_sock_get(os_sock_t *thesock, sock_id id);
#ifdef __cplusplus
}
#endif
#endif /* __CORE_PORTABLE_H__ */
nextepc-0.3.10/lib/core/include/core_queue.h 0000664 0000000 0000000 00000002221 13335533574 0020677 0 ustar 00root root 0000000 0000000 #ifndef __CORE_QUEUE_H__
#define __CORE_QUEUE_H__
#include "core.h"
#define que_declare(__name, __type, __size) \
struct { \
int head, tail, size, used; \
__type pool[(__size)]; \
} __name
#define que_init(__pname, __size) \
((__pname)->head = (__pname)->tail = 0, \
(__pname)->used = 0, \
(__pname)->size = __size)
#define que_push(__pname, __ptr_node) \
((__pname)->used == ((__pname)->size) ? -1 : \
(((__pname)->pool[(__pname)->head] = *(__ptr_node), \
(__pname)->head = ((__pname)->head + 1) % ((__pname)->size), \
++(__pname)->used)))
#define que_pop(__pname, __ptr_node) \
((__pname)->used == 0 ? -1 : \
((*(__ptr_node) = (__pname)->pool[(__pname)->tail], \
(__pname)->tail = ((__pname)->tail + 1) % ((__pname)->size), \
--(__pname)->used)))
#define que_is_empty(__pname) ((__pname)->used == 0)
#define que_is_full(__pname) ((__pname)->used == (__pname)->size)
#define que_size(__pname) ((__pname)->size)
#define que_used(__pname) ((__pname)->used)
#define que_avail(__pname) (que_size(__pname) - que_used(__pname))
#endif /* ! __CORE_QUEUE_H__ */
nextepc-0.3.10/lib/core/include/core_ringbuf.h 0000664 0000000 0000000 00000002643 13335533574 0021217 0 ustar 00root root 0000000 0000000 #ifndef __CORE_RINGBUF_H__
#define __CORE_RINGBUF_H__
#include "core.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
struct _rbuf_header_t {
int head, tail, size;
char *pool;
};
#define rbuf_declare(__name, __size) \
struct { \
struct _rbuf_header_t h; \
char int_pool[(__size) + 1]; \
} __name
#define rbuf_declare_ext(__name) \
struct { \
struct _rbuf_header_t h; \
} __name
#define rbuf_init(__pname, __size) \
((__pname)->h.head = (__pname)->h.tail = 0, \
(__pname)->h.size = __size, \
(__pname)->h.pool = (__pname)->int_pool)
#define rbuf_init_ext(__pname, __size, __ext_pool) \
((__pname)->h.head = (__pname)->h.tail = 0, \
(__pname)->h.size = __size, \
(__pname)->h.pool = (char *)(__ext_pool))
#define rbuf_size(__pname) ((__pname)->h.size)
#define rbuf_is_empty(__pname) ((__pname)->h.head == (__pname)->h.tail)
#define rbuf_is_full(__pname) (rbuf_free_bytes(__pname) == 0)
CORE_DECLARE(int) rbuf_bytes(void *__pname);
CORE_DECLARE(int) rbuf_free_bytes(void *__pname);
CORE_DECLARE(int) rbuf_skip_write_pos(void *__pname, int __len);
CORE_DECLARE(int) rbuf_write(void *__pname, const char *__buf, int __buf_len);
CORE_DECLARE(int) rbuf_skip_read_pos(void *__pname, int __len);
CORE_DECLARE(int) rbuf_read(void *__pname, char *__buf, int __buf_len);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ! __CORE_RINGBUF_H__ */
nextepc-0.3.10/lib/core/include/core_rwlock.h 0000664 0000000 0000000 00000006710 13335533574 0021063 0 ustar 00root root 0000000 0000000 #ifndef __CORE_RWLOCK_H__
#define __CORE_RWLOCK_H__
/**
* @file rwlock.h
* @brief CORE Reader/Writer Lock Routines
*/
#include "core.h"
#include "core_errno.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup rwlock Reader/Writer Lock Routines
* @ingroup CORE
* @{
*/
/** Opaque read-write thread-safe lock. */
typedef c_uintptr_t rwlock_id;
/**
* Initialize Read-Write Lock Pool
*/
CORE_DECLARE(status_t) rwlock_init(void);
/**
* Finalize Read-Write Lock Pool
*/
CORE_DECLARE(status_t) rwlock_final(void);
/**
* Note: The following operations have undefined results: unlocking a
* read-write lock which is not locked in the calling thread; write
* locking a read-write lock which is already locked by the calling
* thread; destroying a read-write lock more than once; clearing or
* destroying the pool from which a locked read-write lock is
* allocated.
*/
/**
* Create and initialize a read-write lock that can be used to synchronize
* threads.
* @param id the memory address where the newly created readwrite lock
* will be stored.
*/
CORE_DECLARE(status_t) rwlock_create(rwlock_id *id);
/**
* Acquire a shared-read lock on the given read-write lock. This will allow
* multiple threads to enter the same critical section while they have acquired
* the read lock.
* @param id the read-write lock on which to acquire the shared read.
*/
CORE_DECLARE(status_t) rwlock_rdlock(rwlock_id id);
/**
* Attempt to acquire the shared-read lock on the given read-write lock. This
* is the same as rwlock_rdlock(), only that the function fails
* if there is another thread holding the write lock, or if there are any
* write threads blocking on the lock. If the function fails for this case,
* CORE_EBUSY will be returned. Note: it is important that the
* CORE_STATUS_IS_EBUSY(s) macro be used to determine if the return value was
* CORE_EBUSY, for portability reasons.
* @param id the rwlock on which to attempt the shared read.
*/
CORE_DECLARE(status_t) rwlock_tryrdlock(rwlock_id id);
/**
* Acquire an exclusive-write lock on the given read-write lock. This will
* allow only one single thread to enter the critical sections. If there
* are any threads currently holding the read-lock, this thread is put to
* sleep until it can have exclusive access to the lock.
* @param id the read-write lock on which to acquire the exclusive write.
*/
CORE_DECLARE(status_t) rwlock_wrlock(rwlock_id id);
/**
* Attempt to acquire the exclusive-write lock on the given read-write lock.
* This is the same as rwlock_wrlock(), only that the function fails
* if there is any other thread holding the lock (for reading or writing),
* in which case the function will return CORE_EBUSY. Note: it is important
* that the CORE_STATUS_IS_EBUSY(s) macro be used to determine if the return
* value was CORE_EBUSY, for portability reasons.
* @param id the rwlock on which to attempt the exclusive write.
*/
CORE_DECLARE(status_t) rwlock_trywrlock(rwlock_id id);
/**
* Release either the read or write lock currently held by the calling thread
* associated with the given read-write lock.
* @param id the read-write lock to be released (unlocked).
*/
CORE_DECLARE(status_t) rwlock_unlock(rwlock_id id);
/**
* Destroy the read-write lock and free the associated memory.
* @param id the rwlock to destroy.
*/
CORE_DECLARE(status_t) rwlock_delete(rwlock_id id);
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ! __CORE_RWLOCK_H__ */
nextepc-0.3.10/lib/core/include/core_semaphore.h 0000664 0000000 0000000 00000003750 13335533574 0021546 0 ustar 00root root 0000000 0000000 #ifndef __SEMAPHORE_H__
#define __SEMAPHORE_H__
/**
* @file semaphore.h
* @brief Core Mutex Routines
*/
#include "core.h"
#include "core_errno.h"
#include "core_time.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup semaphore Routines
* @ingroup CORE
* @{
*/
/** Opaque semaphore structure */
typedef c_uintptr_t semaphore_id;
/**
* Initialize Mutex Pool
*/
CORE_DECLARE(status_t) semaphore_init(void);
/**
* Finalize Mutex Pool
*/
CORE_DECLARE(status_t) semaphore_final(void);
/**
* Create and initialize a semaphore that can be used to synchronize processes.
* @param id the memory address where the newly created semaphore will be
* stored.
* @value initial value for semaphore
*/
CORE_DECLARE(status_t) semaphore_create(semaphore_id *id, c_uint32_t value);
/**
* Put the active calling thread to sleep until signaled to wake up.
* @param id the semaphore variable on which to block.
*/
CORE_DECLARE(status_t) semaphore_wait(semaphore_id id);
#if HAVE_SEM_TIMEDWAIT
/**
* Put the active calling thread to sleep until signaled to wake up or
* the timeout is reached.
* @param id the semaphore variable on which to block.
* @param timeout The amount of time in microsesemaphores to wait. This is
* a maximum, not a minimum. If the semaphoreition is signaled, we
* will wake up before this time, otherwise the error CORE_TIMEUP
* is returned.
*/
CORE_DECLARE(status_t) semaphore_timedwait(semaphore_id id, c_time_t timeout);
#endif
/**
* Posts a single thread, if one exists, that is blocking on the given
* semaphore variable.
* @param id the semaphore variable on which to produce the signal.
*/
CORE_DECLARE(status_t) semaphore_post(semaphore_id id);
/**
* Destroy the semaphore and free the memory associated with the lock.
* @param semaphore the semaphore to destroy.
*/
CORE_DECLARE(status_t) semaphore_delete(semaphore_id id);
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ! __SEMAPHORE_H__ */
nextepc-0.3.10/lib/core/include/core_sha1.h 0000664 0000000 0000000 00000003426 13335533574 0020417 0 ustar 00root root 0000000 0000000 /*
* sha1.h
*
* Copyright (C) 1998, 2009
* Paul E. Jones
* All Rights Reserved
*
*****************************************************************************
* $Id: sha1.h 12 2009-06-22 19:34:25Z paulej $
*****************************************************************************
*
* Description:
* This class implements the Secure Hashing Standard as defined
* in FIPS PUB 180-1 published April 17, 1995.
*
* Many of the variable names in the sha1_ctx, especially the
* single character names, were used because those were the names
* used in the publication.
*
* Please read the file sha1.c for more information.
*
*/
#ifndef _CORE_SHA1_H_
#define _CORE_SHA1_H_
#include "core.h"
#define SHA1_DIGEST_SIZE (160 / 8)
#define SHA1_BLOCK_SIZE (512 / 8)
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct sha1_ctx
{
unsigned Message_Digest[5]; /* Message Digest (output) */
unsigned Length_Low; /* Message length in bits */
unsigned Length_High; /* Message length in bits */
unsigned char Message_Block[64]; /* 512-bit message blocks */
int Message_Block_Index; /* Index into message block array */
int Computed; /* Is the digest computed? */
int Corrupted; /* Is the message digest corruped? */
} sha1_ctx;
CORE_DECLARE(void) sha1_init(sha1_ctx *ctx);
CORE_DECLARE(void) sha1_update(sha1_ctx *ctx, const c_uint8_t *message,
c_uint32_t len);
CORE_DECLARE(void) sha1_final(sha1_ctx *ctx, c_uint8_t *digest);
CORE_DECLARE(void) sha1(const c_uint8_t *message, c_uint32_t len,
c_uint8_t *digest);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _CORE_SHA1_H_ */
nextepc-0.3.10/lib/core/include/core_sha1_hmac.h 0000664 0000000 0000000 00000005345 13335533574 0021411 0 ustar 00root root 0000000 0000000 /*-
* HMAC-SHA-224/256/384/512 implementation
* Last update: 06/15/2005
* Issue date: 06/15/2005
*
* Copyright (C) 2005 Olivier Gay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CORE_HMAC_SHA1_H
#define _CORE_HMAC_SHA1_H
#include "core_sha1.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
sha1_ctx ctx_inside;
sha1_ctx ctx_outside;
/* for hmac_reinit */
sha1_ctx ctx_inside_reinit;
sha1_ctx ctx_outside_reinit;
c_uint8_t block_ipad[SHA1_BLOCK_SIZE];
c_uint8_t block_opad[SHA1_BLOCK_SIZE];
} hmac_sha1_ctx;
CORE_DECLARE(void) hmac_sha1_init(hmac_sha1_ctx *ctx, c_uint8_t *key,
c_uint32_t key_size);
CORE_DECLARE(void) hmac_sha1_reinit(hmac_sha1_ctx *ctx);
CORE_DECLARE(void) hmac_sha1_update(hmac_sha1_ctx *ctx, c_uint8_t *message,
c_uint32_t message_len);
CORE_DECLARE(void) hmac_sha1_final(hmac_sha1_ctx *ctx, c_uint8_t *mac,
c_uint32_t mac_size);
CORE_DECLARE(void) hmac_sha1(c_uint8_t *key, c_uint32_t key_size,
c_uint8_t *message, c_uint32_t message_len,
c_uint8_t *mac, c_uint32_t mac_size);
#ifdef __cplusplus
}
#endif
#endif /* ! _CORE_HMAC_SHA1_H */
nextepc-0.3.10/lib/core/include/core_sha2.h 0000664 0000000 0000000 00000007411 13335533574 0020416 0 ustar 00root root 0000000 0000000 /*
* FIPS 180-2 SHA-224/256/384/512 implementation
* Last update: 02/02/2007
* Issue date: 04/30/2005
*
* Copyright (C) 2005, 2007 Olivier Gay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CORE_SHA2_H_
#define _CORE_SHA2_H_
#include "core.h"
#define SHA224_DIGEST_SIZE ( 224 / 8)
#define SHA256_DIGEST_SIZE ( 256 / 8)
#define SHA384_DIGEST_SIZE ( 384 / 8)
#define SHA512_DIGEST_SIZE ( 512 / 8)
#define SHA256_BLOCK_SIZE ( 512 / 8)
#define SHA512_BLOCK_SIZE (1024 / 8)
#define SHA384_BLOCK_SIZE SHA512_BLOCK_SIZE
#define SHA224_BLOCK_SIZE SHA256_BLOCK_SIZE
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct {
c_uint32_t tot_len;
c_uint32_t len;
c_uint8_t block[2 * SHA256_BLOCK_SIZE];
c_uint32_t h[8];
} sha256_ctx;
typedef struct {
c_uint32_t tot_len;
c_uint32_t len;
c_uint8_t block[2 * SHA512_BLOCK_SIZE];
c_uint64_t h[8];
} sha512_ctx;
typedef sha512_ctx sha384_ctx;
typedef sha256_ctx sha224_ctx;
CORE_DECLARE(void) sha224_init(sha224_ctx *ctx);
CORE_DECLARE(void) sha224_update(sha224_ctx *ctx, const c_uint8_t *message,
c_uint32_t len);
CORE_DECLARE(void) sha224_final(sha224_ctx *ctx, c_uint8_t *digest);
CORE_DECLARE(void) sha224(const c_uint8_t *message, c_uint32_t len,
c_uint8_t *digest);
CORE_DECLARE(void) sha256_init(sha256_ctx * ctx);
CORE_DECLARE(void) sha256_update(sha256_ctx *ctx, const c_uint8_t *message,
c_uint32_t len);
CORE_DECLARE(void) sha256_final(sha256_ctx *ctx, c_uint8_t *digest);
CORE_DECLARE(void) sha256(const c_uint8_t *message, c_uint32_t len,
c_uint8_t *digest);
CORE_DECLARE(void) sha384_init(sha384_ctx *ctx);
CORE_DECLARE(void) sha384_update(sha384_ctx *ctx, const c_uint8_t *message,
c_uint32_t len);
CORE_DECLARE(void) sha384_final(sha384_ctx *ctx, c_uint8_t *digest);
CORE_DECLARE(void) sha384(const c_uint8_t *message, c_uint32_t len,
c_uint8_t *digest);
CORE_DECLARE(void) sha512_init(sha512_ctx *ctx);
CORE_DECLARE(void) sha512_update(sha512_ctx *ctx, const c_uint8_t *message,
c_uint32_t len);
CORE_DECLARE(void) sha512_final(sha512_ctx *ctx, c_uint8_t *digest);
CORE_DECLARE(void) sha512(const c_uint8_t *message, c_uint32_t len,
c_uint8_t *digest);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* !_CORE_SHA2_H_ */
nextepc-0.3.10/lib/core/include/core_sha2_hmac.h 0000664 0000000 0000000 00000012676 13335533574 0021417 0 ustar 00root root 0000000 0000000 /*-
* HMAC-SHA-224/256/384/512 implementation
* Last update: 06/15/2005
* Issue date: 06/15/2005
*
* Copyright (C) 2005 Olivier Gay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CORE_HMAC_SHA2_H
#define _CORE_HMAC_SHA2_H
#include "core_sha2.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
sha224_ctx ctx_inside;
sha224_ctx ctx_outside;
/* for hmac_reinit */
sha224_ctx ctx_inside_reinit;
sha224_ctx ctx_outside_reinit;
c_uint8_t block_ipad[SHA224_BLOCK_SIZE];
c_uint8_t block_opad[SHA224_BLOCK_SIZE];
} hmac_sha224_ctx;
typedef struct {
sha256_ctx ctx_inside;
sha256_ctx ctx_outside;
/* for hmac_reinit */
sha256_ctx ctx_inside_reinit;
sha256_ctx ctx_outside_reinit;
c_uint8_t block_ipad[SHA256_BLOCK_SIZE];
c_uint8_t block_opad[SHA256_BLOCK_SIZE];
} hmac_sha256_ctx;
typedef struct {
sha384_ctx ctx_inside;
sha384_ctx ctx_outside;
/* for hmac_reinit */
sha384_ctx ctx_inside_reinit;
sha384_ctx ctx_outside_reinit;
c_uint8_t block_ipad[SHA384_BLOCK_SIZE];
c_uint8_t block_opad[SHA384_BLOCK_SIZE];
} hmac_sha384_ctx;
typedef struct {
sha512_ctx ctx_inside;
sha512_ctx ctx_outside;
/* for hmac_reinit */
sha512_ctx ctx_inside_reinit;
sha512_ctx ctx_outside_reinit;
c_uint8_t block_ipad[SHA512_BLOCK_SIZE];
c_uint8_t block_opad[SHA512_BLOCK_SIZE];
} hmac_sha512_ctx;
CORE_DECLARE(void) hmac_sha224_init(hmac_sha224_ctx *ctx, c_uint8_t *key,
c_uint32_t key_size);
CORE_DECLARE(void) hmac_sha224_reinit(hmac_sha224_ctx *ctx);
CORE_DECLARE(void) hmac_sha224_update(hmac_sha224_ctx *ctx, c_uint8_t *message,
c_uint32_t message_len);
CORE_DECLARE(void) hmac_sha224_final(hmac_sha224_ctx *ctx, c_uint8_t *mac,
c_uint32_t mac_size);
CORE_DECLARE(void) hmac_sha224(c_uint8_t *key, c_uint32_t key_size,
c_uint8_t *message, c_uint32_t message_len,
c_uint8_t *mac, c_uint32_t mac_size);
CORE_DECLARE(void) hmac_sha256_init(hmac_sha256_ctx *ctx, c_uint8_t *key,
c_uint32_t key_size);
CORE_DECLARE(void) hmac_sha256_reinit(hmac_sha256_ctx *ctx);
CORE_DECLARE(void) hmac_sha256_update(hmac_sha256_ctx *ctx, c_uint8_t *message,
c_uint32_t message_len);
CORE_DECLARE(void) hmac_sha256_final(hmac_sha256_ctx *ctx, c_uint8_t *mac,
c_uint32_t mac_size);
CORE_DECLARE(void) hmac_sha256(c_uint8_t *key, c_uint32_t key_size,
c_uint8_t *message, c_uint32_t message_len,
c_uint8_t *mac, c_uint32_t mac_size);
CORE_DECLARE(void) hmac_sha384_init(hmac_sha384_ctx *ctx, c_uint8_t *key,
c_uint32_t key_size);
CORE_DECLARE(void) hmac_sha384_reinit(hmac_sha384_ctx *ctx);
CORE_DECLARE(void) hmac_sha384_update(hmac_sha384_ctx *ctx, c_uint8_t *message,
c_uint32_t message_len);
CORE_DECLARE(void) hmac_sha384_final(hmac_sha384_ctx *ctx, c_uint8_t *mac,
c_uint32_t mac_size);
CORE_DECLARE(void) hmac_sha384(c_uint8_t *key, c_uint32_t key_size,
c_uint8_t *message, c_uint32_t message_len,
c_uint8_t *mac, c_uint32_t mac_size);
CORE_DECLARE(void) hmac_sha512_init(hmac_sha512_ctx *ctx, c_uint8_t *key,
c_uint32_t key_size);
CORE_DECLARE(void) hmac_sha512_reinit(hmac_sha512_ctx *ctx);
CORE_DECLARE(void) hmac_sha512_update(hmac_sha512_ctx *ctx, c_uint8_t *message,
c_uint32_t message_len);
CORE_DECLARE(void) hmac_sha512_final(hmac_sha512_ctx *ctx, c_uint8_t *mac,
c_uint32_t mac_size);
CORE_DECLARE(void) hmac_sha512(c_uint8_t *key, c_uint32_t key_size,
c_uint8_t *message, c_uint32_t message_len,
c_uint8_t *mac, c_uint32_t mac_size);
#ifdef __cplusplus
}
#endif
#endif /* ! _CORE_HMAC_SHA2_H */
nextepc-0.3.10/lib/core/include/core_signal.h 0000664 0000000 0000000 00000004414 13335533574 0021036 0 ustar 00root root 0000000 0000000 #ifndef CORE_SIGNAL_H
#define CORE_SIGNAL_H
/**
* @file core_signal.h
* @brief CORE Signal Handling
*/
#include "core.h"
#include "core_errno.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup core_signal Signal Handling
* @ingroup CORE
* @{
*/
/**
* Terminate a process.
* @param proc The process to terminate.
* @param sig How to kill the process.
*/
CORE_DECLARE(status_t) core_kill(pid_t pid, int sig);
#if HAVE_SIGACTION
#if defined(DARWIN) && !defined(__cplusplus) && !defined(_ANSI_SOURCE)
/* work around Darwin header file bugs
* http://www.opensource.apple.com/bugs/X/BSD%20Kernel/2657228.html
*/
#undef SIG_DFL
#undef SIG_IGN
#undef SIG_ERR
#define SIG_DFL (void (*)(int))0
#define SIG_IGN (void (*)(int))1
#define SIG_ERR (void (*)(int))-1
#endif
/** Function prototype for signal handlers */
typedef void core_sigfunc_t(int);
/**
* Set the signal handler function for a given signal
* @param signo The signal (eg... SIGWINCH)
* @param func the function to get called
*/
CORE_DECLARE(core_sigfunc_t *) core_signal(int signo, core_sigfunc_t * func);
#if defined(SIG_IGN) && !defined(SIG_ERR)
#define SIG_ERR ((core_sigfunc_t *) -1)
#endif
#else /* !HAVE_SIGACTION */
#define core_signal(a, b) signal(a, b)
#endif
/**
* Setup the process for a single thread to be used for all signal handling.
* @warning This must be called before any threads are created
*/
CORE_DECLARE(status_t) signal_init(void);
/**
* Make the current thread listen for signals. This thread will loop
* forever, calling a provided function whenever it receives a signal. That
* functions should return 1 if the signal has been handled, 0 otherwise.
* @param signal_handler The function to call when a signal is received
* apr_status_t apr_signal_thread((int)(*signal_handler)(int signum))
*/
CORE_DECLARE(status_t) signal_thread(int(*signal_handler)(int signum));
/**
* Block the delivery of a particular signal
* @param signum The signal number
* @return status
*/
CORE_DECLARE(status_t) signal_block(int signum);
/**
* Enable the delivery of a particular signal
* @param signum The signal number
* @return status
*/
CORE_DECLARE(status_t) signal_unblock(int signum);
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* CORE_SIGNAL_H */
nextepc-0.3.10/lib/core/include/core_tcp.h 0000664 0000000 0000000 00000000576 13335533574 0020354 0 ustar 00root root 0000000 0000000 #ifndef __CORE_TCP_H__
#define __CORE_TCP_H__
#include "core_sock.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
CORE_DECLARE(status_t) tcp_open(sock_id *new,
int family,
const char *local_host, c_uint16_t local_port,
const char *remote_host, c_uint16_t remote_port,
int flags);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
nextepc-0.3.10/lib/core/include/core_thread.h 0000664 0000000 0000000 00000004600 13335533574 0021025 0 ustar 00root root 0000000 0000000 #ifndef __CORE_THREAD_H__
#define __CORE_THREAD_H__
#include "core.h"
#include "core_errno.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/** Opaque Thread structure. */
typedef c_uintptr_t thread_id;
/** Opaque Thread attributes structure. */
typedef struct threadattr_t threadattr_t;
typedef void *(THREAD_FUNC *thread_start_t)(thread_id id, void*);
/**
* Check if Thread Should Stop
*/
CORE_DECLARE(int) thread_should_stop(void);
/**
* Initialize Thread
*/
CORE_DECLARE(status_t) thread_init(void);
/**
* Finalize Thread
*/
CORE_DECLARE(status_t) thread_final(void);
/**
* Create and initialize a new threadattr variable
* @param new_attr The newly created threadattr.
*/
CORE_DECLARE(status_t) threadattr_create(threadattr_t **new_attr);
/**
* Set the stack size of newly created threads.
* @param attr The threadattr to affect
* @param stacksize The stack size in bytes
*/
CORE_DECLARE(status_t) threadattr_stacksize_set(
threadattr_t *attr, size_t stacksize);
/**
* Delete and initialize a new threadattr variable
* @param new_attr The newly created threadattr.
*/
CORE_DECLARE(status_t) threadattr_delete(threadattr_t *attr);
/**
* Create a new thread of execution
* @param id The newly created thread handle.
* @param attr The threadattr to use to determine how to create the thread
* @param func The function to start the new thread in
* @param data Any data to be passed to the starting function
*/
CORE_DECLARE(status_t) thread_create(thread_id *id,
threadattr_t *attr, thread_start_t func, void *data);
/**
* Delete a new thread of execution
* @param id The thread to delete
*/
CORE_DECLARE(status_t) thread_delete(thread_id id);
/**
* detach a thread
* @param thd The thread to detach
*/
CORE_DECLARE(status_t) thread_detach(thread_id id);
/**
* stop the current thread
* @param thd The thread to stop
* @param retval The return value to pass back to any thread that cares
*/
CORE_DECLARE(status_t) thread_exit(thread_id id, status_t retval);
/**
* block until the desired thread stops executing.
* @param retval The return value from the dead thread.
* @param thd The thread to join
*/
CORE_DECLARE(status_t) thread_join(status_t *retval, thread_id id);
/**
* force the current thread to yield the processor
*/
CORE_DECLARE(void) thread_yield(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ! __CORE_THREAD_H__ */
nextepc-0.3.10/lib/core/include/core_time.h 0000664 0000000 0000000 00000012565 13335533574 0020525 0 ustar 00root root 0000000 0000000 #ifndef __CORE_TIME_H__
#define __CORE_TIME_H__
/**
* @file core_time.h
* @brief CORE Time Library
*/
#include "core.h"
#include "core_errno.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup core_time Time Routines
* @ingroup CORE
* @{
*/
/** month names */
CORE_DECLARE_DATA extern const char month_snames[12][4];
/** day names */
CORE_DECLARE_DATA extern const char day_snames[7][4];
/** number of microseconds since 00:00:00 january 1, 1970 UTC */
typedef c_int64_t c_time_t;
/** mechanism to properly type c_time_t literals */
#define TIME_C(val) INT64_C(val)
/** mechanism to properly print c_time_t values */
#define TIME_T_FMT INT64_T_FMT
/** number of microseconds per second */
#define USEC_PER_SEC TIME_C(1000000)
/** @return c_time_t as a second */
#define time_sec(time) ((time) / USEC_PER_SEC)
/** @return c_time_t as a usec */
#define time_usec(time) ((time) % USEC_PER_SEC)
/** @return c_time_t as a msec */
#define time_msec(time) (((time) / 1000) % 1000)
/** @return c_time_t as a msec */
#define time_as_msec(time) ((time) / 1000)
/** @return milliseconds as an c_time_t */
#define time_from_msec(msec) ((c_time_t)(msec) * 1000)
/** @return seconds as an c_time_t */
#define time_from_sec(sec) ((c_time_t)(sec) * USEC_PER_SEC)
/** @return a second and usec combination as an c_time_t */
#define time_make(sec, usec) ((c_time_t)(sec) * USEC_PER_SEC \
+ (c_time_t)(usec))
/** @see time_exp_t */
typedef struct time_exp_t time_exp_t;
/**
* a structure similar to ANSI struct tm with the following differences:
* - tm_usec isn't an ANSI field
* - tm_gmtoff isn't an ANSI field (it's a bsdism)
*/
struct time_exp_t {
/** microseconds past tm_sec */
int32_t tm_usec;
/** (0-61) seconds past tm_min */
int32_t tm_sec;
/** (0-59) minutes past tm_hour */
int32_t tm_min;
/** (0-23) hours past midnight */
int32_t tm_hour;
/** (1-31) day of the month */
int32_t tm_mday;
/** (0-11) month of the year */
int32_t tm_mon;
/** year since 1900 */
int32_t tm_year;
/** (0-6) days since sunday */
int32_t tm_wday;
/** (0-365) days since jan 1 */
int32_t tm_yday;
/** daylight saving time */
int32_t tm_isdst;
/** seconds east of UTC */
int32_t tm_gmtoff;
};
/**
* @return the current time
*/
CORE_DECLARE(c_time_t) time_now(void);
/**
* Sleep for the specified number of micro-seconds.
* @param t desired amount of time to sleep.
* @warning May sleep for longer than the specified time.
*/
CORE_DECLARE(void) core_sleep(c_time_t t);
/**
* convert an ansi time_t to an c_time_t
* @param result the resulting c_time_t
* @param input the time_t to convert
*/
CORE_DECLARE(status_t) time_ansi_put(c_time_t *result, time_t input);
/**
* convert a time to its human readable components using an offset
* from GMT
* @param result the exploded time
* @param input the time to explode
* @param offs the number of seconds offset to apply
*/
CORE_DECLARE(status_t) time_exp_tz(time_exp_t *result,
c_time_t input, int32_t offs);
/**
* convert a time to its human readable components in GMT timezone
* @param result the exploded time
* @param input the time to explode
*/
CORE_DECLARE(status_t) time_exp_gmt(time_exp_t *result, c_time_t input);
/**
* convert a time to its human readable components in local timezone
* @param result the exploded time
* @param input the time to explode
*/
CORE_DECLARE(status_t) time_exp_lt(time_exp_t *result, c_time_t input);
/**
* Convert time value from human readable format to a numeric c_time_t
* e.g. elapsed usec since epoch
* @param result the resulting imploded time
* @param input the input exploded time
*/
CORE_DECLARE(status_t) time_exp_get(c_time_t *result, time_exp_t *input);
/**
* Convert time value from human readable format to a numeric c_time_t that
* always represents GMT
* @param result the resulting imploded time
* @param input the input exploded time
*/
CORE_DECLARE(status_t) time_exp_gmt_get(c_time_t *result, time_exp_t *input);
/** length of a RFC822 Date */
#define APR_RFC822_DATE_LEN (30)
/**
* rfc822_date formats dates in the RFC822
* format in an efficient manner. It is a fixed length
* format which requires the indicated amount of storage,
* including the trailing NUL terminator.
* @param date_str String to write to.
* @param t the time to convert
*/
CORE_DECLARE(status_t) rfc822_date(char *date_str, c_time_t t);
/** length of a CTIME date */
#define CTIME_LEN (25)
/**
* ctime formats dates in the ctime() format
* in an efficient manner. it is a fixed length format
* and requires the indicated amount of storage including
* the trailing NUL terminator.
* Unlike ANSI/ISO C ctime(), ctime() does not include
* a \n at the end of the string.
* @param date_str String to write to.
* @param t the time to convert
*/
CORE_DECLARE(status_t) core_ctime(char *date_str, c_time_t t);
/**
* formats the exploded time according to the format specified
* @param s string to write to
* @param retsize The length of the returned string
* @param max The maximum length of the string
* @param format The format for the time string
* @param tm The time to convert
*/
CORE_DECLARE(status_t) core_strftime(char *s, size_t *retsize,
size_t max, const char *format,
time_exp_t *tm);
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ! __CORE_TIME_H__ */
nextepc-0.3.10/lib/core/include/core_timer.h 0000664 0000000 0000000 00000003764 13335533574 0020710 0 ustar 00root root 0000000 0000000 #ifndef __CORE_TIMER_H__
#define __CORE_TIMER_H__
#include "core.h"
#include "core_errno.h"
#include "core_list.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef enum _tm_type {
TIMER_TYPE_ONE_SHOT,
TIMER_TYPE_PERIODIC
} tm_type_e;
typedef struct _tm_service_t {
list_t active_list;
list_t idle_list;
/* timer basic element */
} tm_service_t;
typedef c_uintptr_t tm_block_id;
typedef void (*expire_func_t)(c_uintptr_t data,
c_uintptr_t param1, c_uintptr_t param2, c_uintptr_t param3,
c_uintptr_t param4, c_uintptr_t param5, c_uintptr_t param6);
typedef struct _tm_desc_t {
tm_type_e type;
c_uint32_t duration;
expire_func_t expire_func;
c_uintptr_t param1;
c_uintptr_t param2;
c_uintptr_t param3;
c_uintptr_t param4;
c_uintptr_t param5;
c_uintptr_t param6;
} tm_desc_t;
CORE_DECLARE(status_t) tm_init(void);
CORE_DECLARE(status_t) tm_final(void);
CORE_DECLARE(c_uint32_t) tm_pool_avail(void);
CORE_DECLARE(void) tm_service_init(tm_service_t *tm_service);
CORE_DECLARE(status_t) tm_execute_tm_service(
tm_service_t *p_tm_s, c_uintptr_t data);
CORE_DECLARE(tm_block_id) tm_create(tm_service_t *tm_service,
tm_type_e type, c_uint32_t duration, expire_func_t expire_func);
CORE_DECLARE(void) tm_delete(tm_block_id id);
CORE_DECLARE(status_t) tm_set_duration(tm_block_id id, c_uint32_t duration);
CORE_DECLARE(status_t) tm_set_param1(tm_block_id id, c_uintptr_t param);
CORE_DECLARE(status_t) tm_set_param2(tm_block_id id, c_uintptr_t param);
CORE_DECLARE(status_t) tm_set_param3(tm_block_id id, c_uintptr_t param);
CORE_DECLARE(status_t) tm_set_param4(tm_block_id id, c_uintptr_t param);
CORE_DECLARE(status_t) tm_set_param5(tm_block_id id, c_uintptr_t param);
CORE_DECLARE(status_t) tm_set_param6(tm_block_id id, c_uintptr_t param);
CORE_DECLARE(status_t) tm_start(tm_block_id id);
CORE_DECLARE(status_t) tm_stop(tm_block_id id);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
nextepc-0.3.10/lib/core/include/core_tlv.h 0000664 0000000 0000000 00000005012 13335533574 0020361 0 ustar 00root root 0000000 0000000 #ifndef __CORE_TLV_H__
#define __CORE_TLV_H__
#include "core.h"
#include "core_pool.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define TLV_MODE_T1_L1 1
#define TLV_MODE_T1_L2 2
#define TLV_MODE_T1_L2_I1 3
#define TLV_MODE_T2_L2 4
#define NUM_OF_TLV_NODE 100
/* tlv_t struncture */
typedef struct _tlv_t
{
/* for tlv management */
struct _tlv_t* head;
struct _tlv_t* tail; /* this is used only for head tlv_t */
struct _tlv_t* next;
struct _tlv_t* parent;
struct _tlv_t* embedded;
/* tlv basic element */
c_uint32_t type;
c_uint32_t length;
c_uint8_t instance;
void* value;
/* can be needed in encoding tlv_t*/
c_uint8_t buff_allocated;
c_uint32_t buff_len;
c_uint8_t* buff_ptr;
c_uint8_t* buff;
} tlv_t;
#define tlv_type(pTlv) pTlv->type
#define tlv_length(pTlv) pTlv->length
#define tlv_instance(pTlv) pTlv->instance
#define tlv_value(pTlv) pTlv->value
/* tlv_t pool related functions */
CORE_DECLARE(tlv_t*) tlv_get(void);
CORE_DECLARE(void) tlv_free(tlv_t *pTlv);
CORE_DECLARE(void) tlv_free_all(tlv_t *rootTlv);
CORE_DECLARE(status_t) tlv_init(void);
CORE_DECLARE(status_t) tlv_final(void);
/* tlv_t encoding functions */
CORE_DECLARE(tlv_t*) tlv_add(tlv_t *headTlv,
c_uint32_t type, c_uint32_t length, c_uint8_t instance, c_uint8_t *value);
CORE_DECLARE(tlv_t*) tlv_copy(c_uint8_t *buff, c_uint32_t buff_len,
c_uint32_t type, c_uint32_t length, c_uint8_t instance, c_uint8_t *value);
CORE_DECLARE(tlv_t*) tlv_embed(tlv_t *parent_tlv,
c_uint32_t type, c_uint32_t length, c_uint8_t instance, c_uint8_t *value);
CORE_DECLARE(c_uint32_t) tlv_render(
tlv_t *rootTlv, c_uint8_t *blk, c_uint32_t length, c_uint8_t mode);
/* tlv_t parsing functions */
CORE_DECLARE(tlv_t*) tlv_parse_block(
c_uint32_t length, c_uint8_t *blk, c_uint8_t mode);
CORE_DECLARE(tlv_t*) tlv_parse_embedded_block(tlv_t* pTlv, c_uint8_t mode);
/* tlv operation-related function */
CORE_DECLARE(tlv_t*) tlv_find(tlv_t* pTlv, c_uint32_t type);
CORE_DECLARE(tlv_t*) tlv_find_root(tlv_t* pTlv);
CORE_DECLARE(c_uint32_t) tlv_pool_avail(void);
CORE_DECLARE(c_uint32_t) tlv_calc_length(tlv_t *p_tlv, c_uint8_t mode);
CORE_DECLARE(c_uint32_t) tlv_calc_count(tlv_t *p_tlv);
CORE_DECLARE(c_uint8_t) tlv_value_8(tlv_t *tlv);
CORE_DECLARE(c_uint16_t) tlv_value_16(tlv_t *tlv);
CORE_DECLARE(c_uint32_t) tlv_value_32(tlv_t *tlv);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* !__CORE_TLV_H__ */
nextepc-0.3.10/lib/core/include/core_tlv_msg.h 0000664 0000000 0000000 00000006457 13335533574 0021245 0 ustar 00root root 0000000 0000000 #ifndef __TLV_MSG_H__
#define __TLV_MSG_H__
#include "core_tlv.h"
#include "core_pkbuf.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define TLV_MAX_HEADROOM 16
#define TLV_VARIABLE_LEN 0
#define TLV_MAX_MORE 8
#define TLV_1_OR_MORE(__v) __v[TLV_MAX_MORE]
#define TLV_MAX_CHILD_DESC 128
typedef enum {
TLV_UINT8,
TLV_UINT16,
TLV_UINT24,
TLV_UINT32,
TLV_INT8,
TLV_INT16,
TLV_INT24,
TLV_INT32,
TLV_FIXED_STR,
TLV_VAR_STR,
TLV_NULL,
TLV_MORE,
TLV_COMPOUND,
TLV_MESSAGE,
} tlv_type_e;
typedef struct _tlv_desc_t {
tlv_type_e ctype;
c_int8_t *name;
c_uint16_t type;
c_uint16_t length;
c_uint8_t instance;
c_uint16_t vsize;
void *child_descs[TLV_MAX_CHILD_DESC];
} tlv_desc_t;
extern tlv_desc_t tlv_desc_more1;
extern tlv_desc_t tlv_desc_more2;
extern tlv_desc_t tlv_desc_more3;
extern tlv_desc_t tlv_desc_more4;
extern tlv_desc_t tlv_desc_more5;
extern tlv_desc_t tlv_desc_more6;
extern tlv_desc_t tlv_desc_more7;
extern tlv_desc_t tlv_desc_more8;
typedef c_uint64_t tlv_presence_t;
/* 8-bit Unsigned integer */
typedef struct _tlv_uint8_t {
tlv_presence_t presence;
c_uint8_t u8;
} tlv_uint8_t;
/* 16-bit Unsigned integer */
typedef struct _tlv_uint16_t {
tlv_presence_t presence;
c_uint16_t u16;
} tlv_uint16_t;
/* 24-bit Unsigned integer */
typedef struct _tlv_uint24_t {
tlv_presence_t presence;
c_uint32_t u24; /* Only 3 bytes valid */
} tlv_uint24_t;
/* 32-bit Unsigned integer */
typedef struct _tlv_uint32_t {
tlv_presence_t presence;
c_uint32_t u32;
} tlv_uint32_t;
/* 8-bit Signed integer */
typedef struct _tlv_int8_t {
tlv_presence_t presence;
c_int8_t i8;
} tlv_int8_t;
/* 16-bit Signed integer */
typedef struct _tlv_int16t {
tlv_presence_t presence;
c_int16_t i16;
} tlv_int16_t;
/* 24-bit Signed integer */
typedef struct _tlv_int24_t {
tlv_presence_t presence;
c_int32_t i24; /* Only 3 bytes valid */
} tlv_int24_t;
/* 32-bit Signed integer */
typedef struct _tlv_int32_t {
tlv_presence_t presence;
c_int32_t i32;
} tlv_int32_t;
/* Octets */
#define TLV_CLEAR_DATA(__dATA) \
do { \
d_assert((__dATA), , "Null param"); \
if ((__dATA)->data) \
{ \
CORE_FREE((__dATA)->data); \
(__dATA)->data = NULL; \
(__dATA)->len = 0; \
(__dATA)->presence = 0; \
} \
} while(0)
#define TLV_STORE_DATA(__dST, __sRC) \
do { \
d_assert((__sRC),, "Null param") \
d_assert((__sRC)->data,, "Null param") \
d_assert((__dST),, "Null param") \
TLV_CLEAR_DATA(__dST); \
(__dST)->presence = (__sRC)->presence; \
(__dST)->len = (__sRC)->len; \
(__dST)->data = core_calloc((__dST)->len, sizeof(c_uint8_t)); \
memcpy((__dST)->data, (__sRC)->data, (__dST)->len); \
} while(0)
typedef struct _tlv_octet_t {
tlv_presence_t presence;
void *data;
c_uint32_t len;
} tlv_octet_t;
/* No value */
typedef struct _tlv_null {
tlv_presence_t presence;
} tlv_null_t;
CORE_DECLARE(status_t) tlv_build_msg(
pkbuf_t **pkbuf, tlv_desc_t *desc, void *msg, int mode);
CORE_DECLARE(status_t) tlv_parse_msg(
void *msg, tlv_desc_t *desc, pkbuf_t *pkbuf, int mode);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __TLV_MSG_H__ */
nextepc-0.3.10/lib/core/include/core_udp.h 0000664 0000000 0000000 00000000576 13335533574 0020356 0 ustar 00root root 0000000 0000000 #ifndef __CORE_UDP_H__
#define __CORE_UDP_H__
#include "core_sock.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
CORE_DECLARE(status_t) udp_open(sock_id *new,
int family,
const char *local_host, c_uint16_t local_port,
const char *remote_host, c_uint16_t remote_port,
int flags);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
nextepc-0.3.10/lib/core/include/core_version.h 0000664 0000000 0000000 00000010413 13335533574 0021242 0 ustar 00root root 0000000 0000000 #ifndef __CORE_VERSION_H__
#define __CORE_VERSION_H__
/**
* @file version.h
* @brief CORE Versioning Interface
*
* CORE's Version
*
* There are several different mechanisms for accessing the version. There
* is a string form, and a set of numbers; in addition, there are constants
* which can be compiled into your application, and you can query the library
* being used for its actual version.
*
* Note that it is possible for an application to detect that it has been
* compiled against a different version of CORE by use of the compile-time
* constants and the use of the run-time query function.
*
*/
/* The numeric compile-time version constants. These constants are the
* authoritative version numbers for CORE.
*/
/** major version
* Major API changes that could cause compatibility problems for older
* programs such as structure size changes. No binary compatibility is
* possible across a change in the major version.
*/
#define CORE_MAJOR_VERSION 1
/** minor version
* Minor API changes that do not cause binary compatibility problems.
* Reset to 0 when upgrading CORE_MAJOR_VERSION
*/
#define CORE_MINOR_VERSION 0
/** patch level
* The Patch Level never includes API changes, simply bug fixes.
* Reset to 0 when upgrading CORE_MINOR_VERSION
*/
#define CORE_PATCH_VERSION 0
/**
* The symbol CORE_IS_DEV_VERSION is only defined for internal,
* "development" copies of CORE. It is undefined for released versions
* of CORE.
*/
#define CORE_IS_DEV_VERSION
/**
* Check at compile time if the CORE version is at least a certain
* level.
* @param major The major version component of the version checked
* for (e.g., the "1" of "1.3.0").
* @param minor The minor version component of the version checked
* for (e.g., the "3" of "1.3.0").
* @param patch The patch level component of the version checked
* for (e.g., the "0" of "1.3.0").
* @remark This macro is available with CORE versions starting with
* 1.3.0.
*/
#define CORE_VERSION_AT_LEAST(major,minor,patch) \
(((major) < CORE_MAJOR_VERSION) \
|| ((major) == CORE_MAJOR_VERSION && (minor) < CORE_MINOR_VERSION) \
|| ((major) == CORE_MAJOR_VERSION && (minor) == CORE_MINOR_VERSION && (patch) <= CORE_PATCH_VERSION))
#if defined(CORE_IS_DEV_VERSION) || defined(DOXYGEN)
/** Internal: string form of the "is dev" flag */
#define CORE_IS_DEV_STRING "-dev"
#else
#define CORE_IS_DEV_STRING ""
#endif
/* STRINGIFY is defined here, and also in general.h, so wrap it */
#ifndef STRINGIFY
/** Properly quote a value as a string in the C preprocessor */
#define STRINGIFY(n) STRINGIFY_HELPER(n)
/** Helper macro for STRINGIFY */
#define STRINGIFY_HELPER(n) #n
#endif
/** The formatted string of CORE's version */
#define CORE_VERSION_STRING \
STRINGIFY(CORE_MAJOR_VERSION) "." \
STRINGIFY(CORE_MINOR_VERSION) "." \
STRINGIFY(CORE_PATCH_VERSION) \
CORE_IS_DEV_STRING
/** An alternative formatted string of CORE's version */
/* macro for Win32 .rc files using numeric csv representation */
#define CORE_VERSION_STRING_CSV CORE_MAJOR_VERSION ##, \
##CORE_MINOR_VERSION ##, \
##CORE_PATCH_VERSION
#ifndef __CORE_VERSION_ONLY__
/* The C language API to access the version at run time,
* as opposed to compile time. CORE_VERSION_ONLY may be defined
* externally when preprocessing version.h to obtain strictly
* the C Preprocessor macro declarations.
*/
#include "core.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* The numeric version information is broken out into fields within this
* structure.
*/
typedef struct
{
int major; /**< major number */
int minor; /**< minor number */
int patch; /**< patch number */
int is_dev; /**< is development (1 or 0) */
} core_version_t;
/**
* Return CORE's version information information in a numeric form.
*
* @param pvsn Pointer to a version structure for returning the version
* information.
*/
CORE_DECLARE(void) core_version(core_version_t *pvsn);
/** Return CORE's version information as a string. */
CORE_DECLARE(const char *) core_version_string(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ndef CORE_VERSION_ONLY */
#endif /* ndef CORE_VERSION_H */
nextepc-0.3.10/lib/core/src/ 0000775 0000000 0000000 00000000000 13335533574 0015541 5 ustar 00root root 0000000 0000000 nextepc-0.3.10/lib/core/src/3gpp_types.c 0000664 0000000 0000000 00000010247 13335533574 0020006 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _types
#include "core_debug.h"
#include "core_lib.h"
#include "core_pkbuf.h"
#include "3gpp_types.h"
#define PLMN_ID_DIGIT1(x) (((x) / 100) % 10)
#define PLMN_ID_DIGIT2(x) (((x) / 10) % 10)
#define PLMN_ID_DIGIT3(x) ((x) % 10)
c_uint16_t plmn_id_mcc(plmn_id_t *plmn_id)
{
return plmn_id->mcc1 * 100 + plmn_id->mcc2 * 10 + plmn_id->mcc3;
}
c_uint16_t plmn_id_mnc(plmn_id_t *plmn_id)
{
return plmn_id->mnc1 == 0xf ? plmn_id->mnc2 * 10 + plmn_id->mnc3 :
plmn_id->mnc1 * 100 + plmn_id->mnc2 * 10 + plmn_id->mnc3;
}
c_uint16_t plmn_id_mnc_len(plmn_id_t *plmn_id)
{
return plmn_id->mnc1 == 0xf ? 2 : 3;
}
void *plmn_id_build(plmn_id_t *plmn_id,
c_uint16_t mcc, c_uint16_t mnc, c_uint16_t mnc_len)
{
plmn_id->mcc1 = PLMN_ID_DIGIT1(mcc);
plmn_id->mcc2 = PLMN_ID_DIGIT2(mcc);
plmn_id->mcc3 = PLMN_ID_DIGIT3(mcc);
if (mnc_len == 2)
plmn_id->mnc1 = 0xf;
else
plmn_id->mnc1 = PLMN_ID_DIGIT1(mnc);
plmn_id->mnc2 = PLMN_ID_DIGIT2(mnc);
plmn_id->mnc3 = PLMN_ID_DIGIT3(mnc);
return plmn_id;
}
c_int16_t apn_build(c_int8_t *dst, c_int8_t *src, c_int16_t length)
{
int i = 0, j = 0;
for (i = 0, j = 0; i < length; i++, j++)
{
if (src[i] == '.')
{
dst[i-j] = j;
j = -1;
}
else
{
dst[i+1] = src[i];
}
}
dst[i-j] = j;
return length+1;
}
c_int16_t apn_parse(c_int8_t *dst, c_int8_t *src, c_int16_t length)
{
int i = 0, j = 0;
c_uint8_t len = 0;
do
{
len = src[i++];
memcpy(&dst[j], &src[i], len);
i += len;
j += len;
if (i < length)
dst[j++] = '.';
else
dst[j] = 0;
} while(i < length);
return j;
}
/* 8.13 Protocol Configuration Options (PCO)
* 10.5.6.3 Protocol configuration options in 3GPP TS 24.008 */
c_int16_t pco_parse(pco_t *pco, void *data, int data_len)
{
pco_t *source = (pco_t *)data;
c_int16_t size = 0;
int i = 0;
d_assert(pco, return -1, "Null param");
d_assert(data, return -1, "Null param");
d_assert(data_len, return -1, "Null param");
memset(pco, 0, sizeof(pco_t));
pco->ext = source->ext;
pco->configuration_protocol = source->configuration_protocol;
size++;
while(size < data_len && i < MAX_NUM_OF_PROTOCOL_OR_CONTAINER_ID)
{
pco_id_t *id = &pco->ids[i];
d_assert(size + sizeof(id->id) <= data_len,
return -1, "decode error");
memcpy(&id->id, data + size, sizeof(id->id));
id->id = ntohs(id->id);
size += sizeof(id->id);
d_assert(size + sizeof(id->len) <= data_len,
return -1, "decode error");
memcpy(&id->len, data + size, sizeof(id->len));
size += sizeof(id->len);
id->data = data + size;
size += id->len;
i++;
}
pco->num_of_id = i;
d_assert(size == data_len, return -1,
"decode error(%d != %d)", size, data_len);
return size;
}
c_int16_t pco_build(void *data, int data_len, pco_t *pco)
{
pco_t target;
c_int16_t size = 0;
int i = 0;
d_assert(pco, return -1, "Null param");
d_assert(data, return -1, "Null param");
d_assert(data_len, return -1, "Null param");
memcpy(&target, pco, sizeof(pco_t));
d_assert(size + 1 <= data_len, return -1, "encode error");
memcpy(data + size, &target, 1);
size += 1;
d_assert(target.num_of_id <= MAX_NUM_OF_PROTOCOL_OR_CONTAINER_ID,
return -1, "encode error");
for (i = 0; i < target.num_of_id; i++)
{
pco_id_t *id = &target.ids[i];
d_assert(size + sizeof(id->id) <= data_len,
return -1, "encode error");
id->id = htons(id->id);
memcpy(data + size, &id->id, sizeof(id->id));
size += sizeof(id->id);
d_assert(size + sizeof(id->len) <= data_len,
return -1, "encode error");
memcpy(data + size, &id->len, sizeof(id->len));
size += sizeof(id->len);
d_assert(size + id->len <= data_len, return -1, "encode error");
memcpy(data + size, id->data, id->len);
size += id->len;
}
return size;
}
nextepc-0.3.10/lib/core/src/Makefile.am 0000664 0000000 0000000 00000004105 13335533574 0017575 0 ustar 00root root 0000000 0000000 ## Process this file with automake to produce Makefile.in
pkglib_LTLIBRARIES = libcore.la
libcore_la_SOURCES = \
../include/core_aes_cmac.h ../include/core_aes.h ../include/core_cond.h \
../include/core_debug.h ../include/core_errno.h ../include/core_file.h \
../include/core_fsm.h ../include/core_general.h ../include/core.h \
../include/core.h.in ../include/core_index.h ../include/core_lib.h \
../include/core_list.h ../include/core_msgq.h ../include/core_mutex.h \
../include/core_network.h ../include/core_param.h ../include/core_pkbuf.h \
../include/core_pool.h ../include/core_queue.h ../include/core_ringbuf.h \
../include/core_rwlock.h ../include/core_semaphore.h ../include/core_sha1.h \
../include/core_sha1_hmac.h ../include/core_sha2.h ../include/core_sha2_hmac.h \
../include/core_signal.h ../include/core_thread.h ../include/core_time.h \
../include/core_timer.h ../include/core_tlv.h ../include/core_tlv_msg.h \
../include/core_atomic.h ../include/core_portable.h \
../include/core_version.h ../include/core_event.h ../include/core_hash.h \
../include/3gpp_types.h \
\
debug.c version.c fsm.c msgq.c ringbuf.c timer.c tlv.c tlv_msg.c hash.c \
aes.c aes_cmac.c sha1.c sha1_hmac.c sha2.c sha2_hmac.c misc.c event.c \
3gpp_types.c \
\
../include/arch/core_private_common.h \
../include/arch/unix/core_arch_file.h \
../include/arch/unix/core_arch_mutex.h \
../include/arch/unix/core_arch_semaphore.h \
../include/arch/unix/core_arch_thread.h \
unix/start.c unix/errorcodes.c unix/pkbuf.c \
unix/rand.c unix/time.c unix/file.c \
unix/thread.c unix/signal.c \
unix/atomic.c unix/cond.c unix/mutex.c unix/rwlock.c unix/semaphore.c \
unix/socket.c unix/sockaddr.c unix/udp.c unix/tcp.c unix/tun.c \
$(NULL)
if !USRSCTP
libcore_la_SOURCES += unix/sctp.c
endif
AM_LDFLAGS = \
-version-info @LIBVERSION@ \
$(NULL)
AM_CPPFLAGS = \
-I$(top_srcdir)/lib/core/include/arch/@OSDIR@ \
-I$(top_srcdir)/lib/core/include \
$(NULL)
AM_CFLAGS = \
-Wall -Werror \
@OSCPPFLAGS@ \
$(NULL)
MAINTAINERCLEANFILES = Makefile.in
MOSTLYCLEANFILES = core *.stackdump
nextepc-0.3.10/lib/core/src/aes.c 0000664 0000000 0000000 00000173044 13335533574 0016466 0 ustar 00root root 0000000 0000000 #define FULL_UNROLL
#define TRACE_MODULE _aes
#include "core_debug.h"
#include "core_aes.h"
static const c_uint32_t Te0[256] =
{
0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
};
static const c_uint32_t Te1[256] =
{
0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
};
static const c_uint32_t Te2[256] =
{
0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
};
static const c_uint32_t Te3[256] =
{
0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
};
static const c_uint32_t Te4[256] =
{
0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
};
static const c_uint32_t Td0[256] =
{
0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
};
static const c_uint32_t Td1[256] =
{
0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
};
static const c_uint32_t Td2[256] =
{
0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
};
static const c_uint32_t Td3[256] =
{
0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
};
static const c_uint32_t Td4[256] =
{
0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
};
static const c_uint32_t rcon[] =
{
0x01000000, 0x02000000, 0x04000000, 0x08000000,
0x10000000, 0x20000000, 0x40000000, 0x80000000,
0x1B000000, 0x36000000,
/* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
};
#define GETU32(plaintext) (((c_uint32_t)(plaintext)[0] << 24) ^ \
((c_uint32_t)(plaintext)[1] << 16) ^ \
((c_uint32_t)(plaintext)[2] << 8) ^ \
((c_uint32_t)(plaintext)[3]))
#define PUTU32(ciphertext, st) { (ciphertext)[0] = (c_uint8_t)((st) >> 24); \
(ciphertext)[1] = (c_uint8_t)((st) >> 16); \
(ciphertext)[2] = (c_uint8_t)((st) >> 8); \
(ciphertext)[3] = (c_uint8_t)(st); }
/**
* Expand the cipher key into the encryption key schedule.
*
* @return the number of rounds for the given cipher key size.
*/
int aes_setup_enc(c_uint32_t *rk, const c_uint8_t *key, int keybits)
{
int i = 0;
c_uint32_t temp;
rk[0] = GETU32(key );
rk[1] = GETU32(key + 4);
rk[2] = GETU32(key + 8);
rk[3] = GETU32(key + 12);
if (keybits == 128)
{
for (;;)
{
temp = rk[3];
rk[4] = rk[0] ^
(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
(Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
(Te4[(temp ) & 0xff] & 0x0000ff00) ^
(Te4[(temp >> 24) ] & 0x000000ff) ^
rcon[i];
rk[5] = rk[1] ^ rk[4];
rk[6] = rk[2] ^ rk[5];
rk[7] = rk[3] ^ rk[6];
if (++i == 10)
return 10;
rk += 4;
}
}
rk[4] = GETU32(key + 16);
rk[5] = GETU32(key + 20);
if (keybits == 192)
{
for (;;)
{
temp = rk[ 5];
rk[ 6] = rk[ 0] ^
(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
(Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
(Te4[(temp ) & 0xff] & 0x0000ff00) ^
(Te4[(temp >> 24) ] & 0x000000ff) ^
rcon[i];
rk[ 7] = rk[ 1] ^ rk[ 6];
rk[ 8] = rk[ 2] ^ rk[ 7];
rk[ 9] = rk[ 3] ^ rk[ 8];
if (++i == 8)
return 12;
rk[10] = rk[ 4] ^ rk[ 9];
rk[11] = rk[ 5] ^ rk[10];
rk += 6;
}
}
rk[6] = GETU32(key + 24);
rk[7] = GETU32(key + 28);
if (keybits == 256)
{
for (;;)
{
temp = rk[ 7];
rk[ 8] = rk[ 0] ^
(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
(Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
(Te4[(temp ) & 0xff] & 0x0000ff00) ^
(Te4[(temp >> 24) ] & 0x000000ff) ^
rcon[i];
rk[ 9] = rk[ 1] ^ rk[ 8];
rk[10] = rk[ 2] ^ rk[ 9];
rk[11] = rk[ 3] ^ rk[10];
if (++i == 7)
return 14;
temp = rk[11];
rk[12] = rk[ 4] ^
(Te4[(temp >> 24) ] & 0xff000000) ^
(Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(temp ) & 0xff] & 0x000000ff);
rk[13] = rk[ 5] ^ rk[12];
rk[14] = rk[ 6] ^ rk[13];
rk[15] = rk[ 7] ^ rk[14];
rk += 8;
}
}
return 0;
}
/**
* Expand the cipher key into the decryption key schedule.
*
* @return the number of rounds for the given cipher key size.
*/
int aes_setup_dec(c_uint32_t *rk, const c_uint8_t *key, int keybits)
{
int nrounds, i, j;
c_uint32_t temp;
/* expand the cipher key: */
nrounds = aes_setup_enc(rk, key, keybits);
/* invert the order of the round keys: */
for (i = 0, j = 4*nrounds; i < j; i += 4, j -= 4)
{
temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
}
/* apply the inverse MixColumn transform to all round keys but the first and the last: */
for (i = 1; i < nrounds; i++)
{
rk += 4;
rk[0] =
Td0[Te4[(rk[0] >> 24) ] & 0xff] ^
Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^
Td3[Te4[(rk[0] ) & 0xff] & 0xff];
rk[1] =
Td0[Te4[(rk[1] >> 24) ] & 0xff] ^
Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^
Td3[Te4[(rk[1] ) & 0xff] & 0xff];
rk[2] =
Td0[Te4[(rk[2] >> 24) ] & 0xff] ^
Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^
Td3[Te4[(rk[2] ) & 0xff] & 0xff];
rk[3] =
Td0[Te4[(rk[3] >> 24) ] & 0xff] ^
Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^
Td3[Te4[(rk[3] ) & 0xff] & 0xff];
}
return nrounds;
}
void aes_encrypt(const c_uint32_t *rk, int nrounds, const c_uint8_t plaintext[16],
c_uint8_t ciphertext[16])
{
c_uint32_t s0, s1, s2, s3, t0, t1, t2, t3;
#ifndef FULL_UNROLL
int r;
#endif /* ?FULL_UNROLL */
/*
* map byte array block to cipher state
* and add initial round key:
*/
s0 = GETU32(plaintext ) ^ rk[0];
s1 = GETU32(plaintext + 4) ^ rk[1];
s2 = GETU32(plaintext + 8) ^ rk[2];
s3 = GETU32(plaintext + 12) ^ rk[3];
#ifdef FULL_UNROLL
/* round 1: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
/* round 2: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
/* round 3: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
/* round 4: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
/* round 5: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
/* round 6: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
/* round 7: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
/* round 8: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
/* round 9: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
if (nrounds > 10)
{
/* round 10: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
/* round 11: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
if (nrounds > 12)
{
/* round 12: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
/* round 13: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
}
}
rk += nrounds << 2;
#else /* !FULL_UNROLL */
/*
* nrounds - 1 full rounds:
*/
r = nrounds >> 1;
for (;;)
{
t0 =
Te0[(s0 >> 24) ] ^
Te1[(s1 >> 16) & 0xff] ^
Te2[(s2 >> 8) & 0xff] ^
Te3[(s3 ) & 0xff] ^
rk[4];
t1 =
Te0[(s1 >> 24) ] ^
Te1[(s2 >> 16) & 0xff] ^
Te2[(s3 >> 8) & 0xff] ^
Te3[(s0 ) & 0xff] ^
rk[5];
t2 =
Te0[(s2 >> 24) ] ^
Te1[(s3 >> 16) & 0xff] ^
Te2[(s0 >> 8) & 0xff] ^
Te3[(s1 ) & 0xff] ^
rk[6];
t3 =
Te0[(s3 >> 24) ] ^
Te1[(s0 >> 16) & 0xff] ^
Te2[(s1 >> 8) & 0xff] ^
Te3[(s2 ) & 0xff] ^
rk[7];
rk += 8;
if (--r == 0)
break;
s0 =
Te0[(t0 >> 24) ] ^
Te1[(t1 >> 16) & 0xff] ^
Te2[(t2 >> 8) & 0xff] ^
Te3[(t3 ) & 0xff] ^
rk[0];
s1 =
Te0[(t1 >> 24) ] ^
Te1[(t2 >> 16) & 0xff] ^
Te2[(t3 >> 8) & 0xff] ^
Te3[(t0 ) & 0xff] ^
rk[1];
s2 =
Te0[(t2 >> 24) ] ^
Te1[(t3 >> 16) & 0xff] ^
Te2[(t0 >> 8) & 0xff] ^
Te3[(t1 ) & 0xff] ^
rk[2];
s3 =
Te0[(t3 >> 24) ] ^
Te1[(t0 >> 16) & 0xff] ^
Te2[(t1 >> 8) & 0xff] ^
Te3[(t2 ) & 0xff] ^
rk[3];
}
#endif /* ?FULL_UNROLL */
/*
* apply last round and
* map cipher state to byte array block:
*/
s0 =
(Te4[(t0 >> 24) ] & 0xff000000) ^
(Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t3 ) & 0xff] & 0x000000ff) ^
rk[0];
PUTU32(ciphertext , s0);
s1 =
(Te4[(t1 >> 24) ] & 0xff000000) ^
(Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t0 ) & 0xff] & 0x000000ff) ^
rk[1];
PUTU32(ciphertext + 4, s1);
s2 =
(Te4[(t2 >> 24) ] & 0xff000000) ^
(Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t1 ) & 0xff] & 0x000000ff) ^
rk[2];
PUTU32(ciphertext + 8, s2);
s3 =
(Te4[(t3 >> 24) ] & 0xff000000) ^
(Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t2 ) & 0xff] & 0x000000ff) ^
rk[3];
PUTU32(ciphertext + 12, s3);
}
void aes_decrypt(const c_uint32_t *rk, int nrounds, const c_uint8_t ciphertext[16],
c_uint8_t plaintext[16])
{
c_uint32_t s0, s1, s2, s3, t0, t1, t2, t3;
#ifndef FULL_UNROLL
int r;
#endif /* ?FULL_UNROLL */
/*
* map byte array block to cipher state
* and add initial round key:
*/
s0 = GETU32(ciphertext ) ^ rk[0];
s1 = GETU32(ciphertext + 4) ^ rk[1];
s2 = GETU32(ciphertext + 8) ^ rk[2];
s3 = GETU32(ciphertext + 12) ^ rk[3];
#ifdef FULL_UNROLL
/* round 1: */
t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
/* round 2: */
s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
/* round 3: */
t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
/* round 4: */
s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
/* round 5: */
t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
/* round 6: */
s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
/* round 7: */
t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
/* round 8: */
s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
/* round 9: */
t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
if (nrounds > 10)
{
/* round 10: */
s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
/* round 11: */
t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
if (nrounds > 12)
{
/* round 12: */
s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
/* round 13: */
t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
}
}
rk += nrounds << 2;
#else /* !FULL_UNROLL */
/*
* nrounds - 1 full rounds:
*/
r = nrounds >> 1;
for (;;)
{
t0 =
Td0[(s0 >> 24) ] ^
Td1[(s3 >> 16) & 0xff] ^
Td2[(s2 >> 8) & 0xff] ^
Td3[(s1 ) & 0xff] ^
rk[4];
t1 =
Td0[(s1 >> 24) ] ^
Td1[(s0 >> 16) & 0xff] ^
Td2[(s3 >> 8) & 0xff] ^
Td3[(s2 ) & 0xff] ^
rk[5];
t2 =
Td0[(s2 >> 24) ] ^
Td1[(s1 >> 16) & 0xff] ^
Td2[(s0 >> 8) & 0xff] ^
Td3[(s3 ) & 0xff] ^
rk[6];
t3 =
Td0[(s3 >> 24) ] ^
Td1[(s2 >> 16) & 0xff] ^
Td2[(s1 >> 8) & 0xff] ^
Td3[(s0 ) & 0xff] ^
rk[7];
rk += 8;
if (--r == 0)
break;
s0 =
Td0[(t0 >> 24) ] ^
Td1[(t3 >> 16) & 0xff] ^
Td2[(t2 >> 8) & 0xff] ^
Td3[(t1 ) & 0xff] ^
rk[0];
s1 =
Td0[(t1 >> 24) ] ^
Td1[(t0 >> 16) & 0xff] ^
Td2[(t3 >> 8) & 0xff] ^
Td3[(t2 ) & 0xff] ^
rk[1];
s2 =
Td0[(t2 >> 24) ] ^
Td1[(t1 >> 16) & 0xff] ^
Td2[(t0 >> 8) & 0xff] ^
Td3[(t3 ) & 0xff] ^
rk[2];
s3 =
Td0[(t3 >> 24) ] ^
Td1[(t2 >> 16) & 0xff] ^
Td2[(t1 >> 8) & 0xff] ^
Td3[(t0 ) & 0xff] ^
rk[3];
}
#endif /* ?FULL_UNROLL */
/*
* apply last round and
* map cipher state to byte array block:
*/
s0 =
(Td4[(t0 >> 24) ] & 0xff000000) ^
(Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t1 ) & 0xff] & 0x000000ff) ^
rk[0];
PUTU32(plaintext , s0);
s1 =
(Td4[(t1 >> 24) ] & 0xff000000) ^
(Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t2 ) & 0xff] & 0x000000ff) ^
rk[1];
PUTU32(plaintext + 4, s1);
s2 =
(Td4[(t2 >> 24) ] & 0xff000000) ^
(Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t3 ) & 0xff] & 0x000000ff) ^
rk[2];
PUTU32(plaintext + 8, s2);
s3 =
(Td4[(t3 >> 24) ] & 0xff000000) ^
(Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t0 ) & 0xff] & 0x000000ff) ^
rk[3];
PUTU32(plaintext + 12, s3);
}
status_t aes_cbc_encrypt(const c_uint8_t *key, const c_uint32_t keybits,
c_uint8_t *ivec, const c_uint8_t *in, const c_uint32_t inlen,
c_uint8_t *out, c_uint32_t *outlen)
{
c_uint32_t n;
c_uint32_t len = inlen;
const c_uint8_t *iv = ivec;
c_uint32_t rk[RKLENGTH(MAX_KEY_BITS)];
int nrounds;
d_assert(key, return CORE_ERROR, "Null param");
d_assert(keybits >= 128, return CORE_ERROR,
"param 'keybits' must be larger than 128");
d_assert(ivec, return CORE_ERROR, "Null param");
d_assert(in, return CORE_ERROR, "Null param");
d_assert(inlen, return CORE_ERROR, "param 'inlen' is zero");
d_assert(out, return CORE_ERROR, "Null param");
d_assert(outlen, return CORE_ERROR, "Null param");
if (*outlen < ((inlen - 1) / AES_BLOCK_SIZE + 1) * AES_BLOCK_SIZE)
{
return CORE_ERROR;
}
*outlen = ((inlen - 1) / AES_BLOCK_SIZE + 1) * AES_BLOCK_SIZE;
nrounds = aes_setup_enc(rk, key, keybits);
while (len >= AES_BLOCK_SIZE)
{
for(n=0; n < AES_BLOCK_SIZE; ++n)
out[n] = in[n] ^ iv[n];
aes_encrypt(rk, nrounds, out, out);
iv = out;
len -= AES_BLOCK_SIZE;
in += AES_BLOCK_SIZE;
out += AES_BLOCK_SIZE;
}
if (len)
{
for(n=0; n < len; ++n)
out[n] = in[n] ^ iv[n];
for(n=len; n < AES_BLOCK_SIZE; ++n)
out[n] = iv[n];
aes_encrypt(rk, nrounds, out, out);
iv = out;
}
memcpy(ivec, iv, AES_BLOCK_SIZE);
return CORE_OK;
}
status_t aes_cbc_decrypt(const c_uint8_t *key, const c_uint32_t keybits,
c_uint8_t *ivec, const c_uint8_t *in, const c_uint32_t inlen,
c_uint8_t *out, c_uint32_t *outlen)
{
c_uint32_t n;
c_uint32_t len = inlen;
c_uint8_t tmp[AES_BLOCK_SIZE];
const c_uint8_t *iv = ivec;
c_uint32_t rk[RKLENGTH(MAX_KEY_BITS)];
int nrounds;
d_assert(key, return CORE_ERROR, "Null param");
d_assert(keybits >= 128, return CORE_ERROR,
"param 'keybits' must be larger than 128");
d_assert(ivec, return CORE_ERROR, "Null param");
d_assert(in, return CORE_ERROR, "Null param");
d_assert(inlen, return CORE_ERROR, "param 'inlen' is zero");
d_assert(out, return CORE_ERROR, "Null param");
d_assert(outlen, return CORE_ERROR, "Null param");
if (inlen % AES_BLOCK_SIZE != 0)
{
return CORE_ERROR;
}
*outlen = inlen;
nrounds = aes_setup_dec(rk, key, keybits);
if (in != out)
{
while (len >= AES_BLOCK_SIZE)
{
aes_decrypt(rk, nrounds, in, out);
for(n=0; n < AES_BLOCK_SIZE; ++n)
out[n] ^= iv[n];
iv = in;
len -= AES_BLOCK_SIZE;
in += AES_BLOCK_SIZE;
out += AES_BLOCK_SIZE;
}
if (len)
{
aes_decrypt(rk, nrounds, in, tmp);
for(n=0; n < len; ++n)
out[n] = tmp[n] ^ iv[n];
iv = in;
}
memcpy(ivec, iv, AES_BLOCK_SIZE);
}
else
{
while (len >= AES_BLOCK_SIZE)
{
memcpy(tmp, in, AES_BLOCK_SIZE);
aes_decrypt(rk, nrounds, in, out);
for(n=0; n < AES_BLOCK_SIZE; ++n)
out[n] ^= ivec[n];
memcpy(ivec, tmp, AES_BLOCK_SIZE);
len -= AES_BLOCK_SIZE;
in += AES_BLOCK_SIZE;
out += AES_BLOCK_SIZE;
}
if (len)
{
memcpy(tmp, in, AES_BLOCK_SIZE);
aes_decrypt(rk, nrounds, tmp, out);
for(n=0; n < len; ++n)
out[n] ^= ivec[n];
for(n=len; n < AES_BLOCK_SIZE; ++n)
out[n] = tmp[n];
memcpy(ivec, tmp, AES_BLOCK_SIZE);
}
}
return CORE_OK;
}
static void ctr128_inc(c_uint8_t *counter)
{
c_uint32_t n = 16, c = 1;
do {
--n;
c += counter[n];
counter[n] = (c_uint8_t)c;
c >>= 8;
} while (n);
}
static void ctr128_inc_aligned(c_uint8_t *counter)
{
size_t *data, c, d, n;
const union {
long one;
char little;
} is_endian = {
1
};
if (is_endian.little || ((size_t)counter % sizeof(size_t)) != 0) {
ctr128_inc(counter);
return;
}
data = (size_t *)counter;
c = 1;
n = 16 / sizeof(size_t);
do {
--n;
d = data[n] += c;
/* did addition carry? */
c = ((d - c) & ~d) >> (sizeof(size_t) * 8 - 1);
} while (n);
}
status_t aes_ctr128_encrypt(const c_uint8_t *key,
c_uint8_t *ivec, const c_uint8_t *in, const c_uint32_t inlen,
c_uint8_t *out)
{
c_uint8_t ecount_buf[16];
c_uint32_t len = inlen;
c_uint32_t rk[RKLENGTH(MAX_KEY_BITS)];
int nrounds;
c_uint32_t n = 0;
size_t l = 0;
d_assert(key, return CORE_ERROR, "Null param");
d_assert(ivec, return CORE_ERROR, "Null param");
d_assert(in, return CORE_ERROR, "Null param");
d_assert(len, return CORE_ERROR, "param 'inlen' is zero");
d_assert(out, return CORE_ERROR, "Null param");
memset(ecount_buf, 0, 16);
nrounds = aes_setup_enc(rk, key, 128);
while (n && len)
{
*(out++) = *(in++) ^ ecount_buf[n];
--len;
n = (n + 1) % 16;
}
while (len >= 16)
{
aes_encrypt(rk, nrounds, ivec, ecount_buf);
ctr128_inc_aligned(ivec);
for (n = 0; n < 16; n += sizeof(size_t))
*(size_t *)(out + n) =
*(size_t *)(in + n) ^ *(size_t *)(ecount_buf + n);
len -= 16;
out += 16;
in += 16;
n = 0;
}
if (len)
{
aes_encrypt(rk, nrounds, ivec, ecount_buf);
ctr128_inc_aligned(ivec);
while (len--)
{
out[n] = in[n] ^ ecount_buf[n];
++n;
}
}
return CORE_OK;
/* low-performance for understanding the aes-ctr128 */
while (l < len)
{
if (n == 0)
{
aes_encrypt(rk, nrounds, ivec, ecount_buf);
ctr128_inc(ivec);
}
out[l] = in[l] ^ ecount_buf[n];
++l;
n = (n + 1) % 16;
}
return CORE_OK;
}
nextepc-0.3.10/lib/core/src/aes_cmac.c 0000664 0000000 0000000 00000025332 13335533574 0017445 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _cmac
#include "core.h"
#include "core_debug.h"
#include "core_aes_cmac.h"
#if (AES_BLOCK_SIZE != 16)
#error "Wrong AES block size"
#endif
/* From RFC 4493
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Algorithm Generate_Subkey +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ +
+ Input : K (128-bit key) +
+ Output : K1 (128-bit first subkey) +
+ K2 (128-bit second subkey) +
+-------------------------------------------------------------------+
+ +
+ Constants: const_Zero is 0x00000000000000000000000000000000 +
+ const_Rb is 0x00000000000000000000000000000087 +
+ Variables: L for output of AES-128 applied to 0^128 +
+ +
+ Step 1. L := AES-128(K, const_Zero); +
+ Step 2. if MSB(L) is equal to 0 +
+ then K1 := L << 1; +
+ else K1 := (L << 1) XOR const_Rb; +
+ Step 3. if MSB(K1) is equal to 0 +
+ then K2 := K1 << 1; +
+ else K2 := (K1 << 1) XOR const_Rb; +
+ Step 4. return K1, K2; +
+ +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
static status_t _generate_subkey(c_uint8_t *k1, c_uint8_t *k2,
const c_uint8_t *key)
{
c_uint8_t zero[16] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
c_uint8_t rb[16] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x87
};
c_uint8_t L[16];
c_uint32_t rk[RKLENGTH(MAX_KEY_BITS)];
int i, nrounds;
/* Step 1. L := AES-128(K, const_Zero) */
nrounds = aes_setup_enc(rk, key, 128);
aes_encrypt(rk, nrounds, zero, L);
/* Step 2. if MSB(L) is equal to 0 */
if ((L[0] & 0x80) == 0)
{
/* then k1 := L << 1; */
for (i = 0; i < 15; i++)
k1[i] = ((L[i] << 1) & 0xfe) | ((L[i + 1] & 0x80) ? 1 : 0);
k1[15] = ((L[15] << 1) & 0xfe);
}
else
{
/* else k1 := (L << 1) XOR const_Rb; */
for (i = 0; i < 15; i++)
k1[i] = (((L[i] << 1) & 0xfe) | ((L[i + 1] & 0x80) ? 1 : 0))
^ rb[i];
k1[15] = ((L[15] << 1) & 0xfe) ^ rb[15];
}
/* Step 3. if MSB(k1) is equal to 0 */
if ((k1[0] & 0x80) == 0)
{
/* then k2 := k2 << 1; */
for (i = 0; i < 15; i++)
k2[i] = ((k1[i] << 1) & 0xfe) | ((k1[i + 1] & 0x80) ? 1 : 0);
k2[15] = ((k1[15] << 1) & 0xfe);
}
else
{
/* else k2 := (k2 << 1) XOR const_Rb; */
for (i = 0; i < 15; i++)
k2[i] = (((k1[i] << 1) & 0xfe) | ((k1[i + 1] & 0x80) ? 1 : 0))
^ rb[i];
k2[15] = ((k1[15] << 1) & 0xfe) ^ rb[15];
}
return CORE_OK;
}
/* From RFC 4493
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Algorithm AES-CMAC +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ +
+ Input : K ( 128-bit key ) +
+ : M ( message to be authenticated ) +
+ : len ( length of the message in octets ) +
+ Output : T ( message authentication code ) +
+ +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Constants: const_Zero is 0x00000000000000000000000000000000 +
+ const_Bsize is 16 +
+ +
+ Variables: K1, K2 for 128-bit subkeys +
+ M_i is the i-th block (i=1..ceil(len/const_Bsize)) +
+ M_last is the last block xor-ed with K1 or K2 +
+ n for number of blocks to be processed +
+ r for number of octets of last block +
+ flag for denoting if last block is complete or not +
+ +
+ Step 1. (K1,K2) := Generate_Subkey(K); +
+ Step 2. n := ceil(len/const_Bsize); +
+ Step 3. if n = 0 +
+ then +
+ n := 1; +
+ flag := false; +
+ else +
+ if len mod const_Bsize is 0 +
+ then flag := true; +
+ else flag := false; +
+ +
+ Step 4. if flag is true +
+ then M_last := M_n XOR K1; +
+ else M_last := padding(M_n) XOR K2; +
+ Step 5. X := const_Zero; +
+ Step 6. for i := 1 to n-1 do +
+ begin +
+ Y := X XOR M_i; +
+ X := AES-128(K,Y); +
+ end +
+ Y := M_last XOR X; +
+ T := AES-128(K,Y); +
+ Step 7. return T; +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
status_t aes_cmac_calculate(c_uint8_t *cmac, const c_uint8_t *key,
const c_uint8_t *msg, const c_uint32_t len)
{
c_uint8_t x[16] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
c_uint8_t y[16], m_last[16];
c_uint8_t k1[16], k2[16];
int i, j, n, bs, flag;
c_uint32_t rk[RKLENGTH(MAX_KEY_BITS)];
int nrounds;
d_assert(cmac, return CORE_ERROR, "Null param");
d_assert(key, return CORE_ERROR, "Null param");
d_assert(msg, return CORE_ERROR, "Null param");
/* Step 1. (K1,K2) := Generate_Subkey(K); */
_generate_subkey(k1, k2, key);
/* Step 2. n := ceil(len/const_Bsize); */
n = (len + 15) / AES_BLOCK_SIZE;
/* Step 3. if n = 0
then
n := 1;
flag := false;
else
if len mod const_Bsize is 0
then flag := true;
else flag := false;
*/
if (n == 0)
{
n = 1;
flag = 0;
}
else
{
if (len % AES_BLOCK_SIZE == 0)
flag = 1;
else
flag = 0;
}
/* Step 4. if flag is true
then M_last := M_n XOR K1;
else M_last := padding(M_n) XOR K2;
*/
bs = (n - 1) * AES_BLOCK_SIZE;
if (flag)
{
for (i = 0; i < 16; i++)
m_last[i] = msg[bs + i] ^ k1[i];
}
else
{
for (i = 0; i < len % AES_BLOCK_SIZE; i++)
m_last[i] = msg[bs + i] ^ k2[i];
m_last[i] = 0x80 ^ k2[i];
for (i = i + 1; i < AES_BLOCK_SIZE; i++)
m_last[i] = 0x00 ^ k2[i];
}
/* Step 5. X := const_Zero; */
/* Step 6. for i := 1 to n-1 do
begin
Y := X XOR M_i;
X := AES-128(K,Y);
end
Y := M_last XOR X;
T := AES-128(K,Y);
*/
nrounds = aes_setup_enc(rk, key, 128);
for (i = 0; i <= n - 2; i++)
{
bs = i * AES_BLOCK_SIZE;
for (j = 0; j < 16; j++)
y[j] = x[j] ^ msg[bs + j];
aes_encrypt(rk, nrounds, y, x);
}
bs = (n - 1) * AES_BLOCK_SIZE;
for (j = 0; j < 16; j++)
y[j] = m_last[j] ^ x[j];
aes_encrypt(rk, nrounds, y, cmac);
return CORE_OK;
}
/* From RFC 4493
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Algorithm Verify_MAC +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ +
+ Input : K ( 128-bit Key ) +
+ : M ( message to be verified ) +
+ : len ( length of the message in octets ) +
+ : T' ( the received MAC to be verified ) +
+ Output : INVALID or VALID +
+ +
+-------------------------------------------------------------------+
+ +
+ Step 1. T* := AES-CMAC(K,M,len); +
+ Step 2. if T* is equal to T' +
+ then +
+ return VALID; +
+ else +
+ return INVALID; +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
status_t aes_cmac_verify(c_uint8_t *cmac, const c_uint8_t *key,
const c_uint8_t *msg, const c_uint32_t len)
{
status_t rv;
c_uint8_t cmac_calc[16];
rv = aes_cmac_calculate(cmac_calc, key, msg, len);
if (rv != CORE_OK)
return rv;
if (memcmp(cmac_calc, cmac, 16) != 0)
return ERR_INVALID_CMAC;
return CORE_OK;
}
nextepc-0.3.10/lib/core/src/debug.c 0000664 0000000 0000000 00000042371 13335533574 0017002 0 ustar 00root root 0000000 0000000 #include "core_debug.h"
#include "core_param.h"
#include "core_file.h"
#include "core_thread.h"
#include
#include
#include
#include
int g_trace_mask = 1;
int g_msg_to = D_MSG_TO_STDOUT;
int g_console_connected = 0;
int g_syslog_connected = 0;
int g_network_connected = 0;
int g_file_connected = 0;
int g_log_level_console = D_LOG_LEVEL_FULL;
int g_log_level_stdout = D_LOG_LEVEL_FULL;
int g_log_level_syslog = D_LOG_LEVEL_FULL;
int g_log_level_network = D_LOG_LEVEL_FULL;
int g_log_level_file = D_LOG_LEVEL_FULL;
static int g_console_fd = -1;
static int g_network_fd = -1;
static struct sockaddr_un g_network_addr;
static thread_id network_thread = 0;
static void *THREAD_FUNC network_main(thread_id id, void *data);
static int network_handler(const char *path);
static file_t *g_file = NULL;
status_t d_msg_console_init(int console_fd)
{
d_assert(console_fd >= 0, return CORE_ERROR,
"param 'console_fd' is invalid");
g_console_fd = console_fd;
g_console_connected = 1;
return CORE_OK;
}
void d_msg_console_final()
{
g_console_connected = 0;
g_console_fd = -1;
}
void d_msg_syslog_init(const char *name)
{
d_assert(name, return, );
openlog(name, 0, LOG_DAEMON);
g_syslog_connected = 1;
}
void d_msg_syslog_final()
{
g_syslog_connected = 0;
closelog();
}
status_t d_msg_network_init(const char *name)
{
d_assert(name, return CORE_ERROR, );
g_network_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
d_assert(g_network_fd >= 0, return CORE_ERROR,
"socket() failed. (%d:%s)\n", errno, strerror(errno));
g_network_addr.sun_family = AF_UNIX;
strcpy(g_network_addr.sun_path, name);
return CORE_OK;
}
status_t d_msg_network_start(const char *file)
{
status_t rv;
d_assert(file, return CORE_ERROR, );
rv = thread_create(&network_thread, NULL, network_main, (void*)file);
d_assert(rv == CORE_OK, return CORE_ERROR,
"network thread creation failed");
g_network_connected = 1;
d_msg_to(D_MSG_TO_NETWORK, 1);
return CORE_OK;
}
void d_msg_network_stop()
{
d_msg_to(D_MSG_TO_NETWORK, 0);
g_network_connected = 0;
if (network_thread)
thread_delete(network_thread);
}
void d_msg_network_final()
{
close(g_network_fd);
g_network_fd = -1;
}
static void *THREAD_FUNC network_main(thread_id id, void *data)
{
int ret;
char *path = data;
ret = network_handler(path);
if (ret != 0)
{
d_error("Failed to initialize logger.");
d_error("Check file permission for `%s`", path);
}
return NULL;
}
static int network_handler(const char *path)
{
status_t rv;
int ret;
size_t nbytes;
ssize_t r;
int us;
fd_set readfd;
struct timeval timer_val;
struct sockaddr_un svaddr;
file_t *file = NULL;
char g_buffer[HUGE_STRING_LEN];
us = socket(AF_UNIX, SOCK_DGRAM, 0);
if (us < 0)
{
d_error("socket() failed. (%d:%s)", errno, strerror(errno));
return -1;
}
memcpy(&svaddr, &g_network_addr, sizeof(struct sockaddr_un));
ret = bind(us, (struct sockaddr *)&svaddr, sizeof(svaddr));
if (ret != 0)
{
if (errno == EADDRINUSE)
{
ret = file_remove(svaddr.sun_path);
if (ret != 0)
{
d_error("unlink(`%s`) failed. (%d:%s)",
svaddr.sun_path, errno, strerror(errno));
return -1;
}
ret = bind(us, (struct sockaddr *)&svaddr, sizeof(svaddr));
if (ret != 0)
{
d_error("bind() failed 2. (%d:%s)", errno, strerror(errno));
return -1;
}
}
else
{
d_error("bind() failed. (%d:%s)", errno, strerror(errno));
return -1;
}
}
rv = file_open(&file, path,
FILE_CREATE | FILE_WRITE| FILE_APPEND,
FILE_UREAD | FILE_UWRITE | FILE_GREAD);
if (rv != CORE_OK)
{
d_error("Cannot open log file '%s'", path);
close(us);
return -1;
}
while (!thread_should_stop())
{
timer_val.tv_sec = 0;
timer_val.tv_usec = 50000;
FD_ZERO(&readfd);
FD_SET(us, &readfd);
r = select (us+1, &readfd, NULL, NULL, &timer_val);
if (r == -1)
{
if (errno == EINTR)
break;
d_error("select() error(%d: %s)", errno, strerror(errno));
}
if (r == 0)
continue;
if (FD_ISSET(us, &readfd))
{
r = read(us, g_buffer, sizeof(g_buffer));
if (r < 0)
{
if (errno == EINTR)
break;
d_error("read() failed. (%d:%s)", errno, strerror(errno));
continue;
}
if (r == 0)
continue;
nbytes = r;
rv = file_write(file, g_buffer, &nbytes);
if (rv != CORE_OK || r != nbytes)
{
d_error("Cannot write %ld bytes to log file (%ld written)",
(long)r, (long)nbytes);
}
}
}
file_close(file);
close(us);
file_remove(svaddr.sun_path);
return 0;
}
status_t d_msg_file_init(const char *file)
{
status_t rv;
d_assert(file, return CORE_ERROR, );
rv = file_open(&g_file, file,
FILE_CREATE | FILE_WRITE| FILE_APPEND,
FILE_UREAD | FILE_UWRITE | FILE_GREAD);
if (rv != CORE_OK)
{
d_error("CHECK PERMISSION of Installation Directory...");
d_error("Cannot create LOG file '%s'", file);
return CORE_ERROR;
}
g_file_connected = 1;
d_msg_to(D_MSG_TO_FILE, 1);
return CORE_OK;
}
void d_msg_file_final()
{
d_msg_to(D_MSG_TO_FILE, 0);
g_file_connected = 0;
file_close(g_file);
}
void d_msg_to(int to, int on_off)
{
switch (to)
{
case D_MSG_TO_CONSOLE:
g_msg_to = on_off ?
g_msg_to | D_MSG_TO_CONSOLE :
g_msg_to & ~D_MSG_TO_CONSOLE;
break;
case D_MSG_TO_STDOUT:
g_msg_to = on_off ?
g_msg_to | D_MSG_TO_STDOUT :
g_msg_to & ~D_MSG_TO_STDOUT;
break;
case D_MSG_TO_SYSLOG:
g_msg_to = on_off ?
g_msg_to | D_MSG_TO_SYSLOG :
g_msg_to & ~D_MSG_TO_SYSLOG;
break;
case D_MSG_TO_NETWORK:
g_msg_to = on_off ?
g_msg_to | D_MSG_TO_NETWORK :
g_msg_to & ~D_MSG_TO_NETWORK;
break;
case D_MSG_TO_FILE:
g_msg_to = on_off ?
g_msg_to | D_MSG_TO_FILE :
g_msg_to & ~D_MSG_TO_FILE;
break;
case D_MSG_TO_ALL:
g_msg_to = on_off ? D_MSG_TO_ALL : 0;
break;
default:
break;
}
}
int d_msg_get_to()
{
return g_msg_to;
}
void d_log_set_level(int to, int level)
{
switch (to)
{
case D_MSG_TO_CONSOLE:
g_log_level_console = level;
break;
case D_MSG_TO_STDOUT:
g_log_level_stdout = level;
break;
case D_MSG_TO_SYSLOG:
g_log_level_syslog = level;
break;
case D_MSG_TO_NETWORK:
g_log_level_network = level;
break;
case D_MSG_TO_FILE:
g_log_level_file = level;
break;
case D_MSG_TO_ALL:
g_log_level_console = level;
g_log_level_stdout = level;
g_log_level_syslog = level;
g_log_level_network = level;
g_log_level_file = level;
break;
default:
break;
}
}
int d_log_get_level(int to)
{
switch (to)
{
case D_MSG_TO_CONSOLE:
return g_log_level_console;
case D_MSG_TO_STDOUT:
return g_log_level_stdout;
case D_MSG_TO_SYSLOG:
return g_log_level_syslog;
case D_MSG_TO_NETWORK:
return g_log_level_network;
case D_MSG_TO_FILE:
return g_log_level_file;
default:
break;
}
return -1;
}
void d_log_full(int to)
{
switch (to)
{
case D_MSG_TO_CONSOLE:
g_log_level_console = D_LOG_LEVEL_FULL;
break;
case D_MSG_TO_STDOUT:
g_log_level_stdout = D_LOG_LEVEL_FULL;
break;
case D_MSG_TO_SYSLOG:
g_log_level_syslog = D_LOG_LEVEL_FULL;
break;
case D_MSG_TO_NETWORK:
g_log_level_network = D_LOG_LEVEL_FULL;
break;
case D_MSG_TO_FILE:
g_log_level_file = D_LOG_LEVEL_FULL;
break;
case D_MSG_TO_ALL:
g_log_level_console = D_LOG_LEVEL_FULL;
g_log_level_stdout = D_LOG_LEVEL_FULL;
g_log_level_syslog = D_LOG_LEVEL_FULL;
g_log_level_network = D_LOG_LEVEL_FULL;
g_log_level_file = D_LOG_LEVEL_FULL;
break;
default:
break;
}
}
void d_log_off(int to)
{
switch (to)
{
case D_MSG_TO_CONSOLE:
g_log_level_console = D_LOG_LEVEL_NONE;
break;
case D_MSG_TO_STDOUT:
g_log_level_stdout = D_LOG_LEVEL_NONE;
break;
case D_MSG_TO_SYSLOG:
g_log_level_syslog = D_LOG_LEVEL_NONE;
break;
case D_MSG_TO_NETWORK:
g_log_level_network = D_LOG_LEVEL_NONE;
break;
case D_MSG_TO_FILE:
g_log_level_file = D_LOG_LEVEL_NONE;
break;
case D_MSG_TO_ALL:
g_log_level_console = D_LOG_LEVEL_NONE;
g_log_level_stdout = D_LOG_LEVEL_NONE;
g_log_level_syslog = D_LOG_LEVEL_NONE;
g_log_level_network = D_LOG_LEVEL_NONE;
g_log_level_file = D_LOG_LEVEL_NONE;
break;
default:
break;
}
}
void d_trace_global_on()
{
g_trace_mask = 1;
}
void d_trace_global_off()
{
g_trace_mask = 0;
}
void d_trace_level(int *mod_name, int level)
{
*mod_name = level;
}
void d_trace_off(int *mod_name)
{
*mod_name = 0;
}
#define TA_NOR "\033[0m" /* all off */
#define TA_BOLD "\033[1m" /* bold */
#define TA_UNDER "\033[4m" /* underscore */
#define TA_BLINK "\033[5m" /* blink */
#define TA_REVERSE "\033[7m" /* reverse video */
#define TA_CONCEALED "\033[8m" /* concealed */
#define TA_FGC_BLACK "\033[30m" /* Black */
#define TA_FGC_RED "\033[31m" /* Red */
#define TA_FGC_GREEN "\033[32m" /* Green */
#define TA_FGC_YELLOW "\033[33m" /* Yellow */
#define TA_FGC_BLUE "\033[34m" /* Blue */
#define TA_FGC_MAGENTA "\033[35m" /* Magenta */
#define TA_FGC_CYAN "\033[36m" /* Cyan */
#define TA_FGC_WHITE "\033[37m" /* White */
#define TA_FGC_DEFAULT "\033[39m" /* default */
#define TA_BGC_BLACK "\033[40m" /* Black */
#define TA_BGC_RED "\033[41m" /* Red */
#define TA_BGC_GREEN "\033[42m" /* Green */
#define TA_BGC_YELLOW "\033[43m" /* Yellow */
#define TA_BGC_BLUE "\033[44m" /* Blue */
#define TA_BGC_MAGENTA "\033[45m" /* Magenta */
#define TA_BGC_CYAN "\033[46m" /* Cyan */
#define TA_BGC_WHITE "\033[47m" /* White */
#define TA_BGC_DEFAULT "\033[49m" /* default */
#define TIME_FMT_STR "%02d/%02d %02d:%02d:%02d.%03d"
#define TIME_FMT_STR2 "%02d.%06d"
#define TIME_FMT_STR3 "%04d/%02d/%02d %02d:%02d:%02d.%03d"
int d_msg(int tp, int lv, c_time_t t, char *fn, int ln, char *fmt, ...)
{
char str[HUGE_STRING_LEN+1] = {0}, fstr[HUGE_STRING_LEN+1] = {0}, *ac_str;
time_exp_t te;
size_t n;
char *lv_str[5] = {"NONE", "FATL", "ERRR", "WARN", "INFO"};
va_list args;
va_start(args, fmt);
if (t)
{
time_exp_lt(&te, t);
}
switch (tp)
{
case D_MSG_TYPE_RAW:
{
n = vsprintf(fstr, fmt, args);
if (g_msg_to & D_MSG_TO_STDOUT)
{
printf("%s", fstr);
}
if (g_syslog_connected && (g_msg_to & D_MSG_TO_SYSLOG))
{
syslog(LOG_DEBUG, "%s", fstr);
}
if (g_network_connected && (g_msg_to & D_MSG_TO_NETWORK))
{
sendto(g_network_fd, fstr, n, 0,
(struct sockaddr *)&g_network_addr, sizeof(g_network_addr));
}
if (g_file_connected && (g_msg_to & D_MSG_TO_FILE))
{
size_t nbytes = n;
file_write(g_file, fstr, &nbytes);
}
if (g_console_connected && (g_msg_to & D_MSG_TO_CONSOLE))
{
if (fstr[n-1] == '\n')
{
fstr[n-1] = '\r'; fstr[n++] = '\n';
}
write(g_console_fd, fstr, n);
}
break;
}
case D_MSG_TYPE_TRACE:
{
vsprintf(str, fmt, args);
n = snprintf(fstr, HUGE_STRING_LEN, "["TIME_FMT_STR"] %s",
te.tm_mon + 1, te.tm_mday, te.tm_hour,
te.tm_min, te.tm_sec, te.tm_usec/1000, str);
if (g_msg_to & D_MSG_TO_STDOUT)
{
printf("%s", fstr);
}
if (g_syslog_connected && (g_msg_to & D_MSG_TO_SYSLOG))
{
syslog(LOG_DEBUG, "%s", fstr);
}
if (g_network_connected && (g_msg_to & D_MSG_TO_NETWORK))
{
sendto(g_network_fd, fstr, n, 0,
(struct sockaddr *)&g_network_addr, sizeof(g_network_addr));
}
if (g_file_connected && (g_msg_to & D_MSG_TO_FILE))
{
size_t nbytes = n;
file_write(g_file, fstr, &nbytes);
}
if (g_console_connected && (g_msg_to & D_MSG_TO_CONSOLE))
{
if (fstr[n-1] == '\n')
{
fstr[n-1] = '\r'; fstr[n++] = '\n';
}
write(g_console_fd, fstr, n);
}
break;
}
case D_MSG_TYPE_LOG:
{
switch(lv)
{
case D_LOG_LEVEL_INFO: ac_str = TA_FGC_WHITE; break;
case D_LOG_LEVEL_WARN: ac_str = TA_FGC_CYAN; break;
case D_LOG_LEVEL_ERROR: ac_str = TA_FGC_YELLOW; break;
case D_LOG_LEVEL_FATAL: ac_str = TA_FGC_RED; break;
default: ac_str = NULL; break;
}
vsprintf(str, fmt, args);
n = snprintf(fstr, HUGE_STRING_LEN,
"["TIME_FMT_STR"] %s: %s (%s:%d)",
te.tm_mon + 1, te.tm_mday, te.tm_hour,
te.tm_min, te.tm_sec, te.tm_usec/1000,
lv_str[lv], str, fn, ln);
if ((g_msg_to & D_MSG_TO_STDOUT) &&
lv <= g_log_level_stdout)
{
printf("%s%s" TA_NOR "\n", ac_str, fstr);
}
if (g_syslog_connected && (g_msg_to & D_MSG_TO_SYSLOG) &&
lv <= g_log_level_syslog)
{
syslog(LOG_INFO, "[%s\n", fstr + 13);
}
if (g_network_connected && (g_msg_to & D_MSG_TO_NETWORK) &&
lv <= g_log_level_network)
{
fstr[n++] = '\n';
sendto(g_network_fd, fstr, n, 0,
(struct sockaddr *)&g_network_addr, sizeof(g_network_addr));
}
if (g_file_connected && (g_msg_to & D_MSG_TO_FILE))
{
size_t nbytes;
fstr[n++] = '\n';
nbytes = n;
file_write(g_file, fstr, &nbytes);
}
if (g_console_connected && (g_msg_to & D_MSG_TO_CONSOLE) &&
lv <= g_log_level_console)
{
fstr[n++] = '\r'; /* fstr[n++] = '\n'; FIXME: */
write(g_console_fd, fstr, n);
}
break;
}
case D_MSG_TYPE_ASSERT:
{
vsprintf(str, fmt, args);
n = snprintf(fstr, HUGE_STRING_LEN,
"[" TIME_FMT_STR "] ASSERT: %s (%s:%d)",
te.tm_mon + 1, te.tm_mday, te.tm_hour,
te.tm_min, te.tm_sec, te.tm_usec/1000, str, fn, ln);
if (g_msg_to & D_MSG_TO_STDOUT)
{
printf(TA_BOLD TA_FGC_RED "%s" TA_NOR "\n", fstr);
}
if (g_syslog_connected && (g_msg_to & D_MSG_TO_SYSLOG))
{
syslog(LOG_CRIT, "[%s\n", fstr + 13);
}
if (g_network_connected && (g_msg_to & D_MSG_TO_NETWORK))
{
fstr[n++] = '\n';
sendto(g_network_fd, fstr, n, 0,
(struct sockaddr *)&g_network_addr, sizeof(g_network_addr));
}
if (g_file_connected && (g_msg_to & D_MSG_TO_FILE))
{
size_t nbytes;
fstr[n++] = '\n';
nbytes = n;
file_write(g_file, fstr, &nbytes);
}
if (g_console_connected && (g_msg_to & D_MSG_TO_CONSOLE))
{
fstr[n++] = '\r'; /* fstr[n++] = '\n'; FIXME: */
write(g_console_fd, fstr, n);
}
break;
}
default:
break;
}
return CORE_OK;
}
nextepc-0.3.10/lib/core/src/event.c 0000664 0000000 0000000 00000005072 13335533574 0017032 0 ustar 00root root 0000000 0000000 /**
* @file event.c
*/
/* Core libaray */
#define TRACE_MODULE _event
#include "core_debug.h"
#include "core_msgq.h"
#include "core_event.h"
#define EVT_Q_DEPTH 16
char *EVT_NAME_UNKNOWN = "UNKNOWN";
msgq_id event_create(int opt)
{
msgq_id queue_id = 0;
/* Start threads */
queue_id = msgq_create(EVT_Q_DEPTH, EVENT_SIZE, opt);
d_assert(queue_id != 0, return CORE_ERROR, "Message queue creation failed");
return queue_id;
}
status_t event_delete(msgq_id queue_id)
{
msgq_delete(queue_id);
return CORE_OK;
}
status_t event_send(msgq_id queue_id, event_t *e)
{
status_t rv;
d_assert(e, return -1, "Null param");
d_assert(queue_id, return -1, "event queue isn't initialized");
rv = msgq_send(queue_id, (const char*)e, EVENT_SIZE);
if (rv == CORE_EAGAIN)
{
d_warn("msgq_send full");
}
else if (rv == CORE_ERROR)
{
d_error("msgq_send failed");
}
return rv;
}
status_t event_recv(msgq_id queue_id, event_t *e)
{
status_t rv;
d_assert(e, return -1, "Null param");
d_assert(queue_id, return -1, "event queue isn't initialized");
rv = msgq_recv(queue_id, (char*)e, EVENT_SIZE);
if (rv == CORE_ERROR)
{
d_error("msgq_timedrecv failed", rv);
}
return rv;
}
status_t event_timedrecv(msgq_id queue_id, event_t *e, c_time_t timeout)
{
status_t rv;
d_assert(e, return -1, "Null param");
d_assert(queue_id, return -1, "event queue isn't initialized");
rv = msgq_timedrecv(queue_id, (char*)e, EVENT_SIZE, timeout);
if (rv == CORE_ERROR)
{
d_error("msgq_timedrecv failed", rv);
}
return rv;
}
void* event_timer_expire_func(c_uintptr_t queue_id, c_uintptr_t param1,
c_uintptr_t param2, c_uintptr_t param3, c_uintptr_t param4,
c_uintptr_t param5, c_uintptr_t param6)
{
event_t e;
status_t rv;
d_assert(queue_id, return NULL, "Null param");
event_set(&e, param1);
event_set_param1(&e, param2);
event_set_param2(&e, param3);
event_set_param3(&e, param4);
event_set_param4(&e, param5);
event_set_param5(&e, param6);
rv = event_send(queue_id, &e);
if (rv != CORE_OK)
{
d_error("event_send error:%d", rv);
}
return NULL;
}
tm_block_id event_timer_create(tm_service_t *tm_service, tm_type_e type,
c_uint32_t duration, c_uintptr_t event)
{
tm_block_id id;
id = tm_create(tm_service,
type, duration, (expire_func_t)event_timer_expire_func);
tm_set_param1(id, event);
d_assert(id, return 0, "tm_create() failed");
return id;
}
nextepc-0.3.10/lib/core/src/fsm.c 0000664 0000000 0000000 00000003615 13335533574 0016477 0 ustar 00root root 0000000 0000000 #include "core_fsm.h"
typedef struct _event_t {
fsm_event_t event;
} event_t;
static event_t entry_event = {
FSM_ENTRY_SIG,
};
static event_t exit_event = {
FSM_EXIT_SIG,
};
char *FSM_NAME_INIT_SIG = "INIT";
char *FSM_NAME_ENTRY_SIG = "ENTRY";
char *FSM_NAME_EXIT_SIG = "EXIT";
void fsm_init(void *s, void *_e)
{
fsm_t *fsm = s;
event_t *e = _e;
if (fsm->initial != NULL)
{
(*fsm->initial)(s, e);
if (fsm->initial != fsm->state)
{
if (e)
{
e->event = FSM_ENTRY_SIG;
(*fsm->state)(s, e);
}
else
{
(*fsm->state)(s, &entry_event);
}
}
}
}
void fsm_dispatch(void *s, void *_e)
{
fsm_t *fsm = s;
event_t *e = _e;
fsm_handler_t tmp = fsm->state;
#if OLD_FSM_DISPATCH
fsm->state = (fsm_handler_t)0;
#endif
(*tmp)(s, e);
#if OLD_FSM_DISPATCH
if (fsm->state != NULL)
#else
if (fsm->state != tmp)
#endif
{
if (e)
{
e->event = FSM_EXIT_SIG;
(*tmp)(s, e);
}
else
{
(*tmp)(s, &exit_event);
}
if (e)
{
e->event = FSM_ENTRY_SIG;
(*fsm->state)(s, e);
}
else
{
#if OLD_FSM_DISPATCH
(*tmp)(s, &entry_event);
#else
(*fsm->state)(s, &entry_event);
#endif
}
}
#if OLD_FSM_DISPATCH
else
{
fsm->state = tmp;
}
#endif
}
void fsm_final(void *s, void *_e)
{
fsm_t *fsm = s;
event_t *e = _e;
if (fsm->final != fsm->state)
{
if (e)
{
e->event = FSM_EXIT_SIG;
(*fsm->state)(s, e);
}
else
{
(*fsm->state)(s, &exit_event);
}
}
if (fsm->final != NULL)
{
(*fsm->final)(s, e);
}
fsm->state = fsm->initial;
}
nextepc-0.3.10/lib/core/src/hash.c 0000664 0000000 0000000 00000024461 13335533574 0016637 0 ustar 00root root 0000000 0000000 #include "core_debug.h"
#include "core_pkbuf.h"
#include "core_time.h"
#include "core_hash.h"
/*
* The internal form of a hash table.
*
* The table is an array indexed by the hash of the key; collisions
* are resolved by hanging a linked list of hash entries off each
* element of the array. Although this is a really simple design it
* isn't too bad given that pools have a low allocation overhead.
*/
typedef struct hash_entry_t hash_entry_t;
struct hash_entry_t {
hash_entry_t *next;
unsigned int hash;
const void *key;
int klen;
const void *val;
};
/*
* Data structure for iterating through a hash table.
*
* We keep a pointer to the next hash entry here to allow the current
* hash entry to be freed or otherwise mangled between calls to
* hash_next().
*/
struct hash_index_t {
hash_t *ht;
hash_entry_t *this, *next;
unsigned int index;
};
/*
* The size of the array is always a power of two. We use the maximum
* index rather than the size so that we can use bitwise-AND for
* modular arithmetic.
* The count of hash entries may be greater depending on the chosen
* collision rate.
*/
struct hash_t {
hash_entry_t **array;
hash_index_t iterator; /* For hash_first(NULL, ...) */
unsigned int count, max, seed;
hashfunc_t hash_func;
hash_entry_t *free; /* List of recycled entries */
};
#define INITIAL_MAX 15 /* tunable == 2^n - 1 */
/*
* Hash creation functions.
*/
static hash_entry_t **alloc_array(hash_t *ht, unsigned int max)
{
return core_calloc(1, sizeof(*ht->array) * (max + 1));
}
CORE_DECLARE(hash_t *) hash_make()
{
hash_t *ht;
c_time_t now = time_now();
ht = core_malloc(sizeof(hash_t));
ht->free = NULL;
ht->count = 0;
ht->max = INITIAL_MAX;
ht->seed = (unsigned int)((now >> 32) ^ now ^
(c_uintptr_t)ht ^ (c_uintptr_t)&now) - 1;
ht->array = alloc_array(ht, ht->max);
ht->hash_func = NULL;
return ht;
}
CORE_DECLARE(hash_t *) hash_make_custom(hashfunc_t hash_func)
{
hash_t *ht = hash_make();
ht->hash_func = hash_func;
return ht;
}
CORE_DECLARE(void) hash_destroy(hash_t *ht)
{
hash_entry_t *he = NULL, *next_he = NULL;
d_assert(ht, return, "Null param");
d_assert(ht->array, return, "Null param");
hash_clear(ht);
he = ht->free;
while(he)
{
next_he = he->next;
CORE_FREE(he);
he = next_he;
}
CORE_FREE(ht->array);
CORE_FREE(ht);
}
/*
* Hash iteration functions.
*/
CORE_DECLARE(hash_index_t *) hash_next(hash_index_t *hi)
{
hi->this = hi->next;
while (!hi->this) {
if (hi->index > hi->ht->max)
return NULL;
hi->this = hi->ht->array[hi->index++];
}
hi->next = hi->this->next;
return hi;
}
CORE_DECLARE(hash_index_t *) hash_first(hash_t *ht)
{
hash_index_t *hi;
hi = &ht->iterator;
hi->ht = ht;
hi->index = 0;
hi->this = NULL;
hi->next = NULL;
return hash_next(hi);
}
CORE_DECLARE(void) hash_this(hash_index_t *hi,
const void **key, int *klen, void **val)
{
if (key) *key = hi->this->key;
if (klen) *klen = hi->this->klen;
if (val) *val = (void *)hi->this->val;
}
CORE_DECLARE(const void *) hash_this_key(hash_index_t *hi)
{
const void *key;
hash_this(hi, &key, NULL, NULL);
return key;
}
CORE_DECLARE(int) hash_this_key_len(hash_index_t *hi)
{
int klen;
hash_this(hi, NULL, &klen, NULL);
return klen;
}
CORE_DECLARE(void *) hash_this_val(hash_index_t *hi)
{
void *val;
hash_this(hi, NULL, NULL, &val);
return val;
}
/*
* Expanding a hash table
*/
static void expand_array(hash_t *ht)
{
hash_index_t *hi;
hash_entry_t **new_array;
unsigned int new_max;
new_max = ht->max * 2 + 1;
new_array = alloc_array(ht, new_max);
for (hi = hash_first(ht); hi; hi = hash_next(hi)) {
unsigned int i = hi->this->hash & new_max;
hi->this->next = new_array[i];
new_array[i] = hi->this;
}
CORE_FREE(ht->array);
ht->array = new_array;
ht->max = new_max;
}
static unsigned int hashfunc_default(
const char *char_key, int *klen, unsigned int hash)
{
const unsigned char *key = (const unsigned char *)char_key;
const unsigned char *p;
int i;
/*
* This is the popular `times 33' hash algorithm which is used by
* perl and also appears in Berkeley DB. This is one of the best
* known hash functions for strings because it is both computed
* very fast and distributes very well.
*
* The originator may be Dan Bernstein but the code in Berkeley DB
* cites Chris Torek as the source. The best citation I have found
* is "Chris Torek, Hash function for text in C, Usenet message
* <27038@mimsy.umd.edu> in comp.lang.c , October, 1990." in Rich
* Salz's USENIX 1992 paper about INN which can be found at
* .
*
* The magic of number 33, i.e. why it works better than many other
* constants, prime or not, has never been adequately explained by
* anyone. So I try an explanation: if one experimentally tests all
* multipliers between 1 and 256 (as I did while writing a low-level
* data structure library some time ago) one detects that even
* numbers are not useable at all. The remaining 128 odd numbers
* (except for the number 1) work more or less all equally well.
* They all distribute in an acceptable way and this way fill a hash
* table with an average percent of approx. 86%.
*
* If one compares the chi^2 values of the variants (see
* Bob Jenkins ``Hashing Frequently Asked Questions'' at
* http://burtleburtle.net/bob/hash/hashfaq.html for a description
* of chi^2), the number 33 not even has the best value. But the
* number 33 and a few other equally good numbers like 17, 31, 63,
* 127 and 129 have nevertheless a great advantage to the remaining
* numbers in the large set of possible multipliers: their multiply
* operation can be replaced by a faster operation based on just one
* shift plus either a single addition or subtraction operation. And
* because a hash function has to both distribute good _and_ has to
* be very fast to compute, those few numbers should be preferred.
*
* -- Ralf S. Engelschall
*/
if (*klen == HASH_KEY_STRING) {
for (p = key; *p; p++) {
hash = hash * 33 + *p;
}
*klen = p - key;
}
else {
for (p = key, i = *klen; i; i--, p++) {
hash = hash * 33 + *p;
}
}
return hash;
}
CORE_DECLARE_NONSTD(unsigned int) core_hashfunc_default(
const char *char_key, int *klen)
{
return hashfunc_default(char_key, klen, 0);
}
/*
* This is where we keep the details of the hash function and control
* the maximum collision rate.
*
* If val is non-NULL it creates and initializes a new hash entry if
* there isn't already one there; it returns an updatable pointer so
* that hash entries can be removed.
*/
static hash_entry_t **find_entry(hash_t *ht,
const void *key, int klen, const void *val)
{
hash_entry_t **hep, *he;
unsigned int hash;
if (ht->hash_func)
hash = ht->hash_func(key, &klen);
else
hash = hashfunc_default(key, &klen, ht->seed);
/* scan linked list */
for (hep = &ht->array[hash & ht->max], he = *hep;
he; hep = &he->next, he = *hep) {
if (he->hash == hash
&& he->klen == klen
&& memcmp(he->key, key, klen) == 0)
break;
}
if (he || !val)
return hep;
/* add a new entry for non-NULL values */
if ((he = ht->free) != NULL)
ht->free = he->next;
else
he = core_malloc(sizeof(*he));
he->next = NULL;
he->hash = hash;
he->key = key;
he->klen = klen;
he->val = val;
*hep = he;
ht->count++;
return hep;
}
CORE_DECLARE(void *) hash_get(hash_t *ht, const void *key, int klen)
{
hash_entry_t *he;
he = *find_entry(ht, key, klen, NULL);
if (he)
return (void *)he->val;
else
return NULL;
}
CORE_DECLARE(void) hash_set(hash_t *ht,
const void *key, int klen, const void *val)
{
hash_entry_t **hep;
hep = find_entry(ht, key, klen, val);
if (*hep) {
if (!val) {
/* delete entry */
hash_entry_t *old = *hep;
*hep = (*hep)->next;
old->next = ht->free;
ht->free = old;
--ht->count;
}
else {
/* replace entry */
(*hep)->val = val;
/* check that the collision rate isn't too high */
if (ht->count > ht->max) {
expand_array(ht);
}
}
}
/* else key not present and val==NULL */
}
CORE_DECLARE(void *) hash_get_or_set(hash_t *ht,
const void *key, int klen, const void *val)
{
hash_entry_t **hep;
hep = find_entry(ht, key, klen, val);
if (*hep) {
val = (*hep)->val;
/* check that the collision rate isn't too high */
if (ht->count > ht->max) {
expand_array(ht);
}
return (void *)val;
}
/* else key not present and val==NULL */
return NULL;
}
CORE_DECLARE(unsigned int) hash_count(hash_t *ht)
{
return ht->count;
}
CORE_DECLARE(void) hash_clear(hash_t *ht)
{
hash_index_t *hi;
for (hi = hash_first(ht); hi; hi = hash_next(hi))
hash_set(ht, hi->this->key, hi->this->klen, NULL);
}
/* This is basically the following...
* for every element in hash table {
* comp elemeny.key, element.value
* }
*
* Like with table_do, the comp callback is called for each and every
* element of the hash table.
*/
CORE_DECLARE(int) hash_do(hash_do_callback_fn_t *comp,
void *rec, const hash_t *ht)
{
hash_index_t hix;
hash_index_t *hi;
int rv, dorv = 1;
hix.ht = (hash_t *)ht;
hix.index = 0;
hix.this = NULL;
hix.next = NULL;
if ((hi = hash_next(&hix))) {
/* Scan the entire table */
do {
rv = (*comp)(rec, hi->this->key, hi->this->klen, hi->this->val);
} while (rv && (hi = hash_next(hi)));
if (rv == 0) {
dorv = 0;
}
}
return dorv;
}
nextepc-0.3.10/lib/core/src/misc.c 0000664 0000000 0000000 00000007613 13335533574 0016647 0 ustar 00root root 0000000 0000000 #include "core_errno.h"
#include "core_lib.h"
void *core_ascii_to_hex(char *in, int in_len, void *out, int out_len)
{
int i = 0, j = 0, k = 0, hex;
c_uint8_t *out_p = out;
while(i < in_len && j < out_len)
{
if (!c_isspace(in[i]))
{
hex = c_isdigit(in[i]) ? in[i] - '0' :
c_islower(in[i]) ? in[i] - 'a' + 10 : in[i] - 'A' + 10;
if ((k & 0x1) == 0)
{
out_p[j] = (hex << 4);
}
else
{
out_p[j] |= hex;
j++;
}
k++;
}
i++;
}
return out;
}
void *core_hex_to_ascii(void *in, int in_len, void *out, int out_len)
{
char *p;
int i = 0, l, off = 0;
p = out;
p[0] = 0;
l = (in_len - off) > out_len ? out_len : in_len - off;
for (i = 0; i < l; i++)
{
p += sprintf(p, "%02X", ((char*)in)[off+i] & 0xff);
if ((i & 0x3) == 3 && (i != (l-1))) p += sprintf(p, " ");
}
return out;
}
void *core_uint64_to_buffer(c_uint64_t num, int size, void *buffer)
{
int i;
c_uint8_t *buffer_p = buffer;
for (i = 0; i < size; i++)
buffer_p[i] = (num >> ((size-1-i) * 8)) & 0xff;
return buffer;
}
c_uint64_t core_buffer_to_uint64(void *buffer, int size)
{
c_uint64_t num = 0;
c_uint8_t *buffer_p = buffer;
int i;
for (i = 0; i < size; i++)
{
num |= (((c_uint64_t)buffer_p[i]) << ((size-1-i) * 8));
}
return num;
}
void *core_bcd_to_buffer(c_int8_t *in, void *out, int *out_len)
{
int i = 0;
c_uint8_t *out_p = out;
int in_len = strlen(in);
for (i = 0; i < in_len; i++)
{
if (i & 0x01)
out_p[i>>1] = out_p[i>>1] | (((in[i] - 0x30) << 4) & 0xF0);
else
out_p[i>>1] = (in[i] - 0x30) & 0x0F;
}
*out_len = (in_len + 1) / 2;
if (in_len & 0x01)
{
out_p[(*out_len)-1] |= 0xF0;
}
return out;
}
void *core_buffer_to_bcd(c_uint8_t *in, int in_len, void *out)
{
int i = 0;
c_uint8_t *out_p = out;
for (i = 0; i < in_len-1; i++)
{
out_p[i*2] = 0x30 + (in[i] & 0x0F);
out_p[i*2+1] = 0x30 + ((in[i] & 0xF0) >> 4);
}
if ((in[i] & 0xF0) == 0xF0)
{
out_p[i*2] = 0x30 + (in[i] & 0x0F);
out_p[i*2+1] = 0;
}
else
{
out_p[i*2] = 0x30 + (in[i] & 0x0F);
out_p[i*2+1] = 0x30 + ((in[i] & 0xF0) >> 4);
out_p[i*2+2] = 0;
}
return out;
}
char *core_cpystrn(char *dst, const char *src, size_t dst_size)
{
char *d = dst, *end;
if (dst_size == 0) {
return (dst);
}
if (src) {
end = dst + dst_size - 1;
for (; d < end; ++d, ++src) {
if (!(*d = *src)) {
return (d);
}
}
}
*d = '\0'; /* always null terminate */
return (d);
}
char *core_env_get(const char *envvar)
{
#ifdef HAVE_GETENV
return getenv(envvar);
#else
return NULL;
#endif
}
status_t core_env_set(const char *envvar, const char *value)
{
#if defined(HAVE_SETENV)
if (0 > setenv(envvar, value, 1))
return CORE_ENOMEM;
return CORE_OK;
#elif defined(HAVE_PUTENV)
char buf[HUGE_STRING_LEN];
if (snprintf(buf, HUGE_STRING_LEN, "%s=%s", envvar, value) < 0)
return CORE_ENOMEM;
if (0 > putenv(buf))
return CORE_ENOMEM;
return CORE_OK;
#else
return CORE_ENOTIMPL;
#endif
}
status_t core_env_delete(const char *envvar)
{
#ifdef HAVE_UNSETENV
unsetenv(envvar);
return CORE_OK;
#else
/* hint: some platforms allow envvars to be unset via
* putenv("varname")... that isn't Single Unix spec,
* but if your platform doesn't have unsetenv() it is
* worth investigating and potentially adding a
* configure check to decide when to use that form of
* putenv() here
*/
return CORE_ENOTIMPL;
#endif
}
nextepc-0.3.10/lib/core/src/msgq.c 0000664 0000000 0000000 00000015030 13335533574 0016653 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _msgq
#include "core_debug.h"
#include "core_pool.h"
#include "core_ringbuf.h"
#include "core_cond.h"
#include "core_mutex.h"
#include "core_msgq.h"
#include "core_pkbuf.h"
#include "core_list.h"
typedef struct _msq_desc_t {
mutex_id mut_c, mut_r, mut_w;
cond_id cond;
int opt;
int qdepth, msgsize, used;
rbuf_declare_ext(rbuf);
unsigned char *pool;
} msg_desc_t;
#define SIZE_OF_MSGQ_POOL 5 /* MME 1, SGW 2, PGW 2 */
pool_declare(msgqpool, msg_desc_t, SIZE_OF_MSGQ_POOL);
status_t msgq_init(void)
{
pool_init(&msgqpool, SIZE_OF_MSGQ_POOL);
return CORE_OK;
}
status_t msgq_final(void)
{
pool_final(&msgqpool);
return CORE_OK;
}
msgq_id msgq_create(int qdepth, int msgsize, int opt)
{
msg_desc_t *md;
int s;
status_t rv;
if (qdepth == 0 || msgsize == 0)
return 0;
pool_alloc_node(&msgqpool, &md);
d_assert(md != NULL, return 0, "empty msgq pool");
memset((void*)md, 0, sizeof(msg_desc_t));
rv = mutex_create(&md->mut_c, MUTEX_DEFAULT);
d_assert(rv == CORE_OK,
goto error_final, "mutex creation failed");
rv = mutex_create(&md->mut_r, MUTEX_DEFAULT);
d_assert(rv == CORE_OK,
goto error_final, "mutex creation failed");
rv = mutex_create(&md->mut_w, MUTEX_DEFAULT);
d_assert(rv == CORE_OK,
goto error_final, "mutex creation failed");
rv = cond_create(&md->cond);
d_assert(rv == CORE_OK,
goto error_final, "mutex creation failed");
s = qdepth * msgsize;
md->pool = core_malloc(s);
d_assert(md->pool != NULL,
goto error_final, "can't allocate msg q buffer %d bytes", s);
rbuf_init_ext(&(md->rbuf), s, md->pool);
md->opt = opt;
md->qdepth = qdepth;
md->msgsize = msgsize;
md->used = 0;
return (msgq_id)md;
error_final:
if (md->pool) CORE_FREE(md->pool);
if (md->mut_c) mutex_delete(md->mut_c);
if (md->mut_r) mutex_delete(md->mut_r);
if (md->mut_w) mutex_delete(md->mut_w);
if (md->cond) cond_delete(md->cond);
pool_free_node(&msgqpool, md);
return 0;
}
status_t msgq_delete(msgq_id id)
{
msg_desc_t *md = (msg_desc_t*)id;
d_assert(md != NULL, return CORE_ERROR, "param 'id' is null");
if (md->pool) CORE_FREE(md->pool);
if (md->mut_c) mutex_delete(md->mut_c);
if (md->mut_r) mutex_delete(md->mut_r);
if (md->mut_w) mutex_delete(md->mut_w);
if (md->cond) cond_delete(md->cond);
pool_free_node(&msgqpool, md);
return CORE_OK;
}
status_t msgq_send(msgq_id id, const char *msg, int msglen)
{
msg_desc_t *md = (msg_desc_t*)id;
int n;
d_assert(md != NULL, return CORE_ERROR, "param 'id' is null");
d_assert(msg != NULL, return CORE_ERROR, "param 'msg' is null");
d_assert(msglen <= md->msgsize, return CORE_ERROR,
"'msglen' is bigger than the msg size of queue");
d_assert(md->pool != NULL, return CORE_ERROR, "msgq has no ring buffer");
mutex_lock(md->mut_w);
n = rbuf_free_bytes(&md->rbuf);
if (n == 0)
{
mutex_unlock(md->mut_w);
return CORE_EAGAIN;
}
n = rbuf_write(&md->rbuf, msg, msglen);
d_trace(2, "ring write. head:%d tail:%d size:%d len:%d\n",
md->rbuf.h.head, md->rbuf.h.tail, md->rbuf.h.size, msglen);
d_assert(n == msglen,
mutex_unlock(md->mut_w); return CORE_ERROR,
"msgq integrity broken n:%d len:%d", n, msglen);
d_trace(1, "msg (%d bytes) pushed.\n", msglen);
mutex_unlock(md->mut_w);
mutex_lock(md->mut_c);
cond_signal(md->cond);
mutex_unlock(md->mut_c);
return CORE_OK;
}
status_t msgq_recv(msgq_id id, char *msg, int msglen)
{
msg_desc_t *md = (msg_desc_t*)id;
int n;
d_assert(md != NULL, return CORE_ERROR, "param 'id' is null");
d_assert(msg != NULL, return CORE_ERROR, "param 'msg' is null");
d_assert(msglen >= md->msgsize, return CORE_ERROR,
"'msglen' is smaller than msgsize");
d_assert(md->pool != NULL, return CORE_ERROR, "msgq has no ring buffer");
mutex_lock(md->mut_r);
n = rbuf_bytes(&md->rbuf);
if (!(md->opt & MSGQ_O_NONBLOCK) && (n < md->msgsize))
{
mutex_lock(md->mut_c);
while(rbuf_is_empty(&md->rbuf) &&
cond_wait(md->cond, md->mut_c) == CORE_OK);
mutex_unlock(md->mut_c);
n = rbuf_bytes(&md->rbuf);
d_assert(n >= md->msgsize,
mutex_unlock(md->mut_r); return CORE_ERROR,
"msgq integrity broken");
}
else if (n < md->msgsize)
{
mutex_unlock(md->mut_r);
return CORE_EAGAIN;
}
n = rbuf_read(&md->rbuf, msg, msglen);
d_trace(2, "ring read. head:%d tail:%d size:%d len:%d\n",
md->rbuf.h.head, md->rbuf.h.tail, md->rbuf.h.size, msglen);
d_assert(n == msglen,
mutex_unlock(md->mut_r); return CORE_ERROR,
"msgq integrity broken n:%d len:%d", n, msglen);
d_trace(1, "msg (%d bytes) pop.\n", msglen);
mutex_unlock(md->mut_r);
return CORE_OK;
}
status_t msgq_timedrecv(msgq_id id, char *msg, int msglen, c_time_t timeout)
{
msg_desc_t *md = (msg_desc_t*)id;
int n;
status_t rv;
d_assert(md != NULL, return CORE_ERROR, "param 'id' is null");
d_assert(msg != NULL, return CORE_ERROR, "param 'msg' is null");
d_assert(msglen >= md->msgsize, return CORE_ERROR,
"'msglen' is smaller than msgsize");
d_assert(md->pool != NULL, return CORE_ERROR, "msgq has no ring buffer");
mutex_lock(md->mut_r);
n = rbuf_bytes(&md->rbuf);
if (!(md->opt & MSGQ_O_NONBLOCK) && (n < md->msgsize))
{
mutex_lock(md->mut_c);
while(rbuf_is_empty(&md->rbuf) &&
(rv = cond_timedwait(md->cond, md->mut_c, timeout)) == CORE_OK);
mutex_unlock(md->mut_c);
if (rv == CORE_TIMEUP)
{
mutex_unlock(md->mut_r);
return CORE_TIMEUP;
}
n = rbuf_bytes(&md->rbuf);
d_assert(n >= md->msgsize,
mutex_unlock(md->mut_r); return CORE_ERROR,
"msgq integrity broken");
}
else if (n < md->msgsize)
{
mutex_unlock(md->mut_r);
return CORE_EAGAIN;
}
n = rbuf_read(&md->rbuf, msg, msglen);
d_trace(2, "ring read. head:%d tail:%d size:%d len:%d\n",
md->rbuf.h.head, md->rbuf.h.tail, md->rbuf.h.size, msglen);
d_assert(n == msglen,
mutex_unlock(md->mut_r); return CORE_ERROR,
"msgq integrity broken n:%d len:%d", n, msglen);
d_trace(1, "msg (%d bytes) pop.\n", msglen);
mutex_unlock(md->mut_r);
return CORE_OK;
}
nextepc-0.3.10/lib/core/src/ringbuf.c 0000664 0000000 0000000 00000010237 13335533574 0017344 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _ringbuf
#include "core_debug.h"
#include "core_ringbuf.h"
#define _rbuf_bytes(__h, __t, __s) \
(((__h) < (__t)) ? (__h) + (__s) - (__t) + 1 : (__h) - (__t))
#define _rbuf_free_bytes(__h, __t, __s) \
(((__h) < (__t)) ? (__t) - (__h) - 1 : (__t) + (__s) - (__h))
int rbuf_bytes(void *__pname)
{
int h, t;
struct _rbuf_header_t *ptr_h = (struct _rbuf_header_t*)__pname;
/* Store for thread safety */
h = ptr_h->head; t = ptr_h->tail;
return _rbuf_bytes(h, t, ptr_h->size);
}
int rbuf_free_bytes(void *__pname)
{
int h, t;
struct _rbuf_header_t *ptr_h = (struct _rbuf_header_t*)__pname;
/* Store for thread safety */
h = ptr_h->head; t = ptr_h->tail;
return _rbuf_free_bytes(h, t, ptr_h->size);
}
#define rbuf_is_empty(__pname) ((__pname)->h.head == (__pname)->h.tail)
#define rbuf_is_full(__pname) (rbuf_free_bytes(__pname) == 0)
int rbuf_skip_write_pos(void *__pname, int __len)
{
/* Write operation must handle only head pointer */
int n, h, t;
struct _rbuf_header_t *ptr_h = (struct _rbuf_header_t*)__pname;
if (ptr_h == NULL)
return -1;
t = ptr_h->tail; /* Store for thread safety with read thread */
h = ptr_h->head;
/* Check available buffer size */
n = _rbuf_free_bytes(h, t, ptr_h->size);
/* If no space, return */
if (n == 0)
return -1;
/* Determin the number of bytes to be skipped */
n = n < __len ? n : __len;
/* In this function, only ptr_h->head should be updated */
ptr_h->head = (h + n) % (ptr_h->size + 1);
return n;
}
int rbuf_write(void *__pname, const char *__buf, int __buf_len)
{
/* Write operation must handle only head pointer */
int n, h, t;
struct _rbuf_header_t *ptr_h = (struct _rbuf_header_t*)__pname;
if (ptr_h == NULL)
return -1;
t = ptr_h->tail; /* Store for thread safety with read thread */
h = ptr_h->head;
/* Check available buffer size */
n = _rbuf_free_bytes(h, t, ptr_h->size);
/* If no space, return */
if (n == 0)
return -1;
/* Determin the number of bytes to be written */
n = n < __buf_len ? n : __buf_len;
if ((t > h) || (n < ptr_h->size - h + 1))
{
memcpy(ptr_h->pool + h, __buf, n);
}
else
{
memcpy(ptr_h->pool + h, __buf, ptr_h->size - h + 1);
memcpy(ptr_h->pool, __buf + (ptr_h->size - h + 1),
n - (ptr_h->size - h + 1));
}
/* In this function, only ptr_h->head should be updated */
ptr_h->head = (h + n) % (ptr_h->size + 1);
return n;
}
int rbuf_skip_read_pos(void *__pname, int __len)
{
/* Read operation must handle only tail pointer */
int n, h, t;
struct _rbuf_header_t *ptr_h = (struct _rbuf_header_t*)__pname;
if (ptr_h == NULL)
return -1;
h = ptr_h->head; /* Store for thread safety with write thread */
t = ptr_h->tail;
/* Check filled buffer size */
n = _rbuf_bytes(h, t, ptr_h->size);
/* If empty, return */
if (n == 0)
return -1;
/* Determine the number of bytes to be skipped */
n = n < __len ? n : __len;
/* In this function, only ptr_h->tail should be updated */
ptr_h->tail = (t + n) % (ptr_h->size + 1);
return n;
}
int rbuf_read(void *__pname, char *__buf, int __buf_len)
{
/* Read operation must handle only tail pointer */
int n, h, t;
struct _rbuf_header_t *ptr_h = (struct _rbuf_header_t*)__pname;
if (ptr_h == NULL)
return -1;
h = ptr_h->head; /* Store for thread safety with write thread */
t = ptr_h->tail;
/* Check filled buffer size */
n = _rbuf_bytes(h, t, ptr_h->size);
/* If empty, return */
if (n == 0)
return -1;
/* Determine the number of bytes to be read */
n = n < __buf_len ? n : __buf_len;
if (t < h || (n < ptr_h->size - t + 1))
{
memcpy(__buf, ptr_h->pool + t, n);
}
else
{
memcpy(__buf, ptr_h->pool + t, ptr_h->size - t + 1);
memcpy(__buf + (ptr_h->size - t + 1), ptr_h->pool,
n - (ptr_h->size - t + 1));
}
/* In this function, only ptr_h->tail should be updated */
ptr_h->tail = (t + n) % (ptr_h->size + 1);
return n;
}
nextepc-0.3.10/lib/core/src/sha1.c 0000664 0000000 0000000 00000025254 13335533574 0016551 0 ustar 00root root 0000000 0000000 /*
* sha1.c
*
* Copyright (C) 1998, 2009
* Paul E. Jones
* All Rights Reserved
*
*****************************************************************************
* $Id: sha1.c 12 2009-06-22 19:34:25Z paulej $
*****************************************************************************
*
* Description:
* This file implements the Secure Hashing Standard as defined
* in FIPS PUB 180-1 published April 17, 1995.
*
* The Secure Hashing Standard, which uses the Secure Hashing
* Algorithm (SHA), produces a 160-bit message digest for a
* given data stream. In theory, it is highly improbable that
* two messages will produce the same message digest. Therefore,
* this algorithm can serve as a means of providing a "fingerprint"
* for a message.
*
* Portability Issues:
* SHA-1 is defined in terms of 32-bit "words". This code was
* written with the expectation that the processor has at least
* a 32-bit machine word size. If the machine word size is larger,
* the code should still function properly. One caveat to that
* is that the input functions taking characters and character
* arrays assume that only 8 bits of information are stored in each
* character.
*
* Caveats:
* SHA-1 is designed to work with messages less than 2^64 bits
* long. Although SHA-1 allows a message digest to be generated for
* messages of any number of bits less than 2^64, this
* implementation only works with messages with a length that is a
* multiple of the size of an 8-bit character.
*
*/
#include "core_sha1.h"
/*
* Define the circular shift macro
*/
#define SHA1CircularShift(bits,word) \
((((word) << (bits)) & 0xFFFFFFFF) | \
((word) >> (32-(bits))))
/* Function prototypes */
static void SHA1ProcessMessageBlock(sha1_ctx *);
static void SHA1PadMessage(sha1_ctx *);
/*
* sha1_init
*
* Description:
* This function will initialize the sha1_ctx in preparation
* for computing a new message digest.
*
* Parameters:
* context: [in/out]
* The context to reset.
*
* Returns:
* Nothing.
*
* Comments:
*
*/
void sha1_init(sha1_ctx *ctx)
{
ctx->Length_Low = 0;
ctx->Length_High = 0;
ctx->Message_Block_Index = 0;
ctx->Message_Digest[0] = 0x67452301;
ctx->Message_Digest[1] = 0xEFCDAB89;
ctx->Message_Digest[2] = 0x98BADCFE;
ctx->Message_Digest[3] = 0x10325476;
ctx->Message_Digest[4] = 0xC3D2E1F0;
ctx->Computed = 0;
ctx->Corrupted = 0;
}
/*
* sha1_final
*
* Description:
* This function will return the 160-bit message digest into the
* Message_Digest array within the sha1_ctx provided
*
* Parameters:
* context: [in/out]
* The context to use to calculate the SHA-1 hash.
*
* Returns:
* 1 if successful, 0 if it failed.
*
* Comments:
*
*/
#if 0 /* modifed by anoveth */
void sha1_final(sha1_ctx *ctx)
#else
void sha1_final(sha1_ctx *ctx, c_uint8_t *digest)
#endif
{
#if 0 /* blocked by anoveth */
if (ctx->Corrupted)
{
return 0;
}
#endif
if (!ctx->Computed)
{
SHA1PadMessage(ctx);
ctx->Computed = 1;
}
#if 0 /* modified by anoveth */
return 1;
#else
{
#if WORDS_BIGENDIAN
memcpy(digest, ctx->Message_Digest, SHA1_DIGEST_SIZE);
#else
#define ROTR(a) ((((unsigned)(a))>>8)|((a)<<24))
#define ROTL(a) (((a)<<8)|(((unsigned)(a))>>24))
#define SWAP32(a) (ROTL((a)&0xff00ff00)|ROTR((a)&0x00ff00ff))
c_uint32_t n[5];
n[0] = SWAP32(ctx->Message_Digest[0]);
n[1] = SWAP32(ctx->Message_Digest[1]);
n[2] = SWAP32(ctx->Message_Digest[2]);
n[3] = SWAP32(ctx->Message_Digest[3]);
n[4] = SWAP32(ctx->Message_Digest[4]);
memcpy(digest, n, SHA1_DIGEST_SIZE);
}
#endif
#endif
}
/*
* sha1_update
*
* Description:
* This function accepts an array of octets as the next portion of
* the message.
*
* Parameters:
* context: [in/out]
* The SHA-1 context to update
* message_array: [in]
* An array of characters representing the next portion of the
* message.
* length: [in]
* The length of the message in message_array
*
* Returns:
* Nothing.
*
* Comments:
*
*/
void sha1_update(sha1_ctx *ctx, const c_uint8_t *message_array,
c_uint32_t length)
{
if (!length)
{
return;
}
if (ctx->Computed || ctx->Corrupted)
{
ctx->Corrupted = 1;
return;
}
while(length-- && !ctx->Corrupted)
{
ctx->Message_Block[ctx->Message_Block_Index++] =
(*message_array & 0xFF);
ctx->Length_Low += 8;
/* Force it to 32 bits */
ctx->Length_Low &= 0xFFFFFFFF;
if (ctx->Length_Low == 0)
{
ctx->Length_High++;
/* Force it to 32 bits */
ctx->Length_High &= 0xFFFFFFFF;
if (ctx->Length_High == 0)
{
/* Message is too long */
ctx->Corrupted = 1;
}
}
if (ctx->Message_Block_Index == 64)
{
SHA1ProcessMessageBlock(ctx);
}
message_array++;
}
}
/*
* SHA1ProcessMessageBlock
*
* Description:
* This function will process the next 512 bits of the message
* stored in the Message_Block array.
*
* Parameters:
* None.
*
* Returns:
* Nothing.
*
* Comments:
* Many of the variable names in the SHAContext, especially the
* single character names, were used because those were the names
* used in the publication.
*
*
*/
static void SHA1ProcessMessageBlock(sha1_ctx *ctx)
{
const unsigned K[] = /* Constants defined in SHA-1 */
{
0x5A827999,
0x6ED9EBA1,
0x8F1BBCDC,
0xCA62C1D6
};
int t; /* Loop counter */
unsigned temp; /* Temporary word value */
unsigned W[80]; /* Word sequence */
unsigned A, B, C, D, E; /* Word buffers */
/*
* Initialize the first 16 words in the array W
*/
for(t = 0; t < 16; t++)
{
W[t] = ((unsigned) ctx->Message_Block[t * 4]) << 24;
W[t] |= ((unsigned) ctx->Message_Block[t * 4 + 1]) << 16;
W[t] |= ((unsigned) ctx->Message_Block[t * 4 + 2]) << 8;
W[t] |= ((unsigned) ctx->Message_Block[t * 4 + 3]);
}
for(t = 16; t < 80; t++)
{
W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
}
A = ctx->Message_Digest[0];
B = ctx->Message_Digest[1];
C = ctx->Message_Digest[2];
D = ctx->Message_Digest[3];
E = ctx->Message_Digest[4];
for(t = 0; t < 20; t++)
{
temp = SHA1CircularShift(5,A) +
((B & C) | ((~B) & D)) + E + W[t] + K[0];
temp &= 0xFFFFFFFF;
E = D;
D = C;
C = SHA1CircularShift(30,B);
B = A;
A = temp;
}
for(t = 20; t < 40; t++)
{
temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
temp &= 0xFFFFFFFF;
E = D;
D = C;
C = SHA1CircularShift(30,B);
B = A;
A = temp;
}
for(t = 40; t < 60; t++)
{
temp = SHA1CircularShift(5,A) +
((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
temp &= 0xFFFFFFFF;
E = D;
D = C;
C = SHA1CircularShift(30,B);
B = A;
A = temp;
}
for(t = 60; t < 80; t++)
{
temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
temp &= 0xFFFFFFFF;
E = D;
D = C;
C = SHA1CircularShift(30,B);
B = A;
A = temp;
}
ctx->Message_Digest[0] =
(ctx->Message_Digest[0] + A) & 0xFFFFFFFF;
ctx->Message_Digest[1] =
(ctx->Message_Digest[1] + B) & 0xFFFFFFFF;
ctx->Message_Digest[2] =
(ctx->Message_Digest[2] + C) & 0xFFFFFFFF;
ctx->Message_Digest[3] =
(ctx->Message_Digest[3] + D) & 0xFFFFFFFF;
ctx->Message_Digest[4] =
(ctx->Message_Digest[4] + E) & 0xFFFFFFFF;
ctx->Message_Block_Index = 0;
}
/*
* SHA1PadMessage
*
* Description:
* According to the standard, the message must be padded to an even
* 512 bits. The first padding bit must be a '1'. The last 64
* bits represent the length of the original message. All bits in
* between should be 0. This function will pad the message
* according to those rules by filling the Message_Block array
* accordingly. It will also call SHA1ProcessMessageBlock()
* appropriately. When it returns, it can be assumed that the
* message digest has been computed.
*
* Parameters:
* context: [in/out]
* The context to pad
*
* Returns:
* Nothing.
*
* Comments:
*
*/
static void SHA1PadMessage(sha1_ctx *ctx)
{
/*
* Check to see if the current message block is too small to hold
* the initial padding bits and length. If so, we will pad the
* block, process it, and then continue padding into a second
* block.
*/
if (ctx->Message_Block_Index > 55)
{
ctx->Message_Block[ctx->Message_Block_Index++] = 0x80;
while(ctx->Message_Block_Index < 64)
{
ctx->Message_Block[ctx->Message_Block_Index++] = 0;
}
SHA1ProcessMessageBlock(ctx);
while(ctx->Message_Block_Index < 56)
{
ctx->Message_Block[ctx->Message_Block_Index++] = 0;
}
}
else
{
ctx->Message_Block[ctx->Message_Block_Index++] = 0x80;
while(ctx->Message_Block_Index < 56)
{
ctx->Message_Block[ctx->Message_Block_Index++] = 0;
}
}
/*
* Store the message length as the last 8 octets
*/
ctx->Message_Block[56] = (ctx->Length_High >> 24) & 0xFF;
ctx->Message_Block[57] = (ctx->Length_High >> 16) & 0xFF;
ctx->Message_Block[58] = (ctx->Length_High >> 8) & 0xFF;
ctx->Message_Block[59] = (ctx->Length_High) & 0xFF;
ctx->Message_Block[60] = (ctx->Length_Low >> 24) & 0xFF;
ctx->Message_Block[61] = (ctx->Length_Low >> 16) & 0xFF;
ctx->Message_Block[62] = (ctx->Length_Low >> 8) & 0xFF;
ctx->Message_Block[63] = (ctx->Length_Low) & 0xFF;
SHA1ProcessMessageBlock(ctx);
}
void sha1(const c_uint8_t *message, c_uint32_t len, c_uint8_t *digest)
{
sha1_ctx ctx;
sha1_init(&ctx);
sha1_update(&ctx, message, len);
sha1_final(&ctx, digest);
}
nextepc-0.3.10/lib/core/src/sha1_hmac.c 0000664 0000000 0000000 00000010237 13335533574 0017534 0 ustar 00root root 0000000 0000000 /*-
* HMAC-SHA-224/256/384/512 implementation
* Last update: 06/15/2005
* Issue date: 06/15/2005
*
* Copyright (C) 2005 Olivier Gay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include
#include "core_sha1_hmac.h"
void hmac_sha1_init(hmac_sha1_ctx *ctx, c_uint8_t *key,
c_uint32_t key_size)
{
c_uint32_t fill;
c_uint32_t num;
c_uint8_t *key_used;
c_uint8_t key_temp[SHA1_DIGEST_SIZE];
int i;
if (key_size == SHA1_BLOCK_SIZE) {
key_used = key;
num = SHA1_BLOCK_SIZE;
} else {
if (key_size > SHA1_BLOCK_SIZE){
key_used = key_temp;
num = SHA1_DIGEST_SIZE;
sha1(key, key_size, key_used);
} else { /* key_size > SHA1_BLOCK_SIZE */
key_used = key;
num = key_size;
}
fill = SHA1_BLOCK_SIZE - num;
memset(ctx->block_ipad + num, 0x36, fill);
memset(ctx->block_opad + num, 0x5c, fill);
}
for (i = 0; i < num; i++) {
ctx->block_ipad[i] = key_used[i] ^ 0x36;
ctx->block_opad[i] = key_used[i] ^ 0x5c;
}
sha1_init(&ctx->ctx_inside);
sha1_update(&ctx->ctx_inside, ctx->block_ipad, SHA1_BLOCK_SIZE);
sha1_init(&ctx->ctx_outside);
sha1_update(&ctx->ctx_outside, ctx->block_opad,
SHA1_BLOCK_SIZE);
/* for hmac_reinit */
memcpy(&ctx->ctx_inside_reinit, &ctx->ctx_inside,
sizeof(sha1_ctx));
memcpy(&ctx->ctx_outside_reinit, &ctx->ctx_outside,
sizeof(sha1_ctx));
}
void hmac_sha1_reinit(hmac_sha1_ctx *ctx)
{
memcpy(&ctx->ctx_inside, &ctx->ctx_inside_reinit,
sizeof(sha1_ctx));
memcpy(&ctx->ctx_outside, &ctx->ctx_outside_reinit,
sizeof(sha1_ctx));
}
void hmac_sha1_update(hmac_sha1_ctx *ctx, c_uint8_t *message,
c_uint32_t message_len)
{
sha1_update(&ctx->ctx_inside, message, message_len);
}
void hmac_sha1_final(hmac_sha1_ctx *ctx, c_uint8_t *mac,
c_uint32_t mac_size)
{
c_uint8_t digest_inside[SHA1_DIGEST_SIZE];
c_uint8_t mac_temp[SHA1_DIGEST_SIZE];
sha1_final(&ctx->ctx_inside, digest_inside);
sha1_update(&ctx->ctx_outside, digest_inside, SHA1_DIGEST_SIZE);
sha1_final(&ctx->ctx_outside, mac_temp);
memcpy(mac, mac_temp, mac_size);
}
void hmac_sha1(c_uint8_t *key, c_uint32_t key_size,
c_uint8_t *message, c_uint32_t message_len,
c_uint8_t *mac, c_uint32_t mac_size)
{
hmac_sha1_ctx ctx;
hmac_sha1_init(&ctx, key, key_size);
hmac_sha1_update(&ctx, message, message_len);
hmac_sha1_final(&ctx, mac, mac_size);
}
nextepc-0.3.10/lib/core/src/sha2.c 0000664 0000000 0000000 00000067522 13335533574 0016556 0 ustar 00root root 0000000 0000000 /*
* FIPS 180-2 SHA-224/256/384/512 implementation
* Last update: 02/02/2007
* Issue date: 04/30/2005
*
* Copyright (C) 2005, 2007 Olivier Gay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if 0
#define UNROLL_LOOPS /* Enable loops unrolling */
#endif
#define TRACE_MODULE _sha2
#include "core_debug.h"
#include "core_sha2.h"
#define SHFR(x, n) (x >> n)
#define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n)))
#define ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n)))
#define CH(x, y, z) ((x & y) ^ (~x & z))
#define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
#define SHA256_F1(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
#define SHA256_F2(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
#define SHA256_F3(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHFR(x, 3))
#define SHA256_F4(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10))
#define SHA512_F1(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
#define SHA512_F2(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
#define SHA512_F3(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHFR(x, 7))
#define SHA512_F4(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHFR(x, 6))
#define UNPACK32(x, str) \
{ \
*((str) + 3) = (c_uint8_t) ((x) ); \
*((str) + 2) = (c_uint8_t) ((x) >> 8); \
*((str) + 1) = (c_uint8_t) ((x) >> 16); \
*((str) + 0) = (c_uint8_t) ((x) >> 24); \
}
#define PACK32(str, x) \
{ \
*(x) = ((c_uint32_t) *((str) + 3) ) \
| ((c_uint32_t) *((str) + 2) << 8) \
| ((c_uint32_t) *((str) + 1) << 16) \
| ((c_uint32_t) *((str) + 0) << 24); \
}
#define UNPACK64(x, str) \
{ \
*((str) + 7) = (c_uint8_t) ((x) ); \
*((str) + 6) = (c_uint8_t) ((x) >> 8); \
*((str) + 5) = (c_uint8_t) ((x) >> 16); \
*((str) + 4) = (c_uint8_t) ((x) >> 24); \
*((str) + 3) = (c_uint8_t) ((x) >> 32); \
*((str) + 2) = (c_uint8_t) ((x) >> 40); \
*((str) + 1) = (c_uint8_t) ((x) >> 48); \
*((str) + 0) = (c_uint8_t) ((x) >> 56); \
}
#define PACK64(str, x) \
{ \
*(x) = ((c_uint64_t) *((str) + 7) ) \
| ((c_uint64_t) *((str) + 6) << 8) \
| ((c_uint64_t) *((str) + 5) << 16) \
| ((c_uint64_t) *((str) + 4) << 24) \
| ((c_uint64_t) *((str) + 3) << 32) \
| ((c_uint64_t) *((str) + 2) << 40) \
| ((c_uint64_t) *((str) + 1) << 48) \
| ((c_uint64_t) *((str) + 0) << 56); \
}
/* Macros used for loops unrolling */
#define SHA256_SCR(i) \
{ \
w[i] = SHA256_F4(w[i - 2]) + w[i - 7] \
+ SHA256_F3(w[i - 15]) + w[i - 16]; \
}
#define SHA512_SCR(i) \
{ \
w[i] = SHA512_F4(w[i - 2]) + w[i - 7] \
+ SHA512_F3(w[i - 15]) + w[i - 16]; \
}
#define SHA256_EXP(a, b, c, d, e, f, g, h, j) \
{ \
t1 = wv[h] + SHA256_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) \
+ sha256_k[j] + w[j]; \
t2 = SHA256_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]); \
wv[d] += t1; \
wv[h] = t1 + t2; \
}
#define SHA512_EXP(a, b, c, d, e, f, g ,h, j) \
{ \
t1 = wv[h] + SHA512_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) \
+ sha512_k[j] + w[j]; \
t2 = SHA512_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]); \
wv[d] += t1; \
wv[h] = t1 + t2; \
}
c_uint32_t sha224_h0[8] =
{0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4};
c_uint32_t sha256_h0[8] =
{0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
c_uint64_t sha384_h0[8] =
{0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL,
0x9159015a3070dd17ULL, 0x152fecd8f70e5939ULL,
0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL,
0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL};
c_uint64_t sha512_h0[8] =
{0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL};
c_uint32_t sha256_k[64] =
{0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
c_uint64_t sha512_k[80] =
{0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL};
/* SHA-256 functions */
void sha256_transf(sha256_ctx *ctx, const c_uint8_t *message,
c_uint32_t block_nb)
{
c_uint32_t w[64];
c_uint32_t wv[8];
c_uint32_t t1, t2;
const c_uint8_t *sub_block;
int i;
#ifndef UNROLL_LOOPS
int j;
#endif
for (i = 0; i < (int) block_nb; i++) {
sub_block = message + (i << 6);
#ifndef UNROLL_LOOPS
for (j = 0; j < 16; j++) {
PACK32(&sub_block[j << 2], &w[j]);
}
for (j = 16; j < 64; j++) {
SHA256_SCR(j);
}
for (j = 0; j < 8; j++) {
wv[j] = ctx->h[j];
}
for (j = 0; j < 64; j++) {
t1 = wv[7] + SHA256_F2(wv[4]) + CH(wv[4], wv[5], wv[6])
+ sha256_k[j] + w[j];
t2 = SHA256_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]);
wv[7] = wv[6];
wv[6] = wv[5];
wv[5] = wv[4];
wv[4] = wv[3] + t1;
wv[3] = wv[2];
wv[2] = wv[1];
wv[1] = wv[0];
wv[0] = t1 + t2;
}
for (j = 0; j < 8; j++) {
ctx->h[j] += wv[j];
}
#else
PACK32(&sub_block[ 0], &w[ 0]); PACK32(&sub_block[ 4], &w[ 1]);
PACK32(&sub_block[ 8], &w[ 2]); PACK32(&sub_block[12], &w[ 3]);
PACK32(&sub_block[16], &w[ 4]); PACK32(&sub_block[20], &w[ 5]);
PACK32(&sub_block[24], &w[ 6]); PACK32(&sub_block[28], &w[ 7]);
PACK32(&sub_block[32], &w[ 8]); PACK32(&sub_block[36], &w[ 9]);
PACK32(&sub_block[40], &w[10]); PACK32(&sub_block[44], &w[11]);
PACK32(&sub_block[48], &w[12]); PACK32(&sub_block[52], &w[13]);
PACK32(&sub_block[56], &w[14]); PACK32(&sub_block[60], &w[15]);
SHA256_SCR(16); SHA256_SCR(17); SHA256_SCR(18); SHA256_SCR(19);
SHA256_SCR(20); SHA256_SCR(21); SHA256_SCR(22); SHA256_SCR(23);
SHA256_SCR(24); SHA256_SCR(25); SHA256_SCR(26); SHA256_SCR(27);
SHA256_SCR(28); SHA256_SCR(29); SHA256_SCR(30); SHA256_SCR(31);
SHA256_SCR(32); SHA256_SCR(33); SHA256_SCR(34); SHA256_SCR(35);
SHA256_SCR(36); SHA256_SCR(37); SHA256_SCR(38); SHA256_SCR(39);
SHA256_SCR(40); SHA256_SCR(41); SHA256_SCR(42); SHA256_SCR(43);
SHA256_SCR(44); SHA256_SCR(45); SHA256_SCR(46); SHA256_SCR(47);
SHA256_SCR(48); SHA256_SCR(49); SHA256_SCR(50); SHA256_SCR(51);
SHA256_SCR(52); SHA256_SCR(53); SHA256_SCR(54); SHA256_SCR(55);
SHA256_SCR(56); SHA256_SCR(57); SHA256_SCR(58); SHA256_SCR(59);
SHA256_SCR(60); SHA256_SCR(61); SHA256_SCR(62); SHA256_SCR(63);
wv[0] = ctx->h[0]; wv[1] = ctx->h[1];
wv[2] = ctx->h[2]; wv[3] = ctx->h[3];
wv[4] = ctx->h[4]; wv[5] = ctx->h[5];
wv[6] = ctx->h[6]; wv[7] = ctx->h[7];
SHA256_EXP(0,1,2,3,4,5,6,7, 0); SHA256_EXP(7,0,1,2,3,4,5,6, 1);
SHA256_EXP(6,7,0,1,2,3,4,5, 2); SHA256_EXP(5,6,7,0,1,2,3,4, 3);
SHA256_EXP(4,5,6,7,0,1,2,3, 4); SHA256_EXP(3,4,5,6,7,0,1,2, 5);
SHA256_EXP(2,3,4,5,6,7,0,1, 6); SHA256_EXP(1,2,3,4,5,6,7,0, 7);
SHA256_EXP(0,1,2,3,4,5,6,7, 8); SHA256_EXP(7,0,1,2,3,4,5,6, 9);
SHA256_EXP(6,7,0,1,2,3,4,5,10); SHA256_EXP(5,6,7,0,1,2,3,4,11);
SHA256_EXP(4,5,6,7,0,1,2,3,12); SHA256_EXP(3,4,5,6,7,0,1,2,13);
SHA256_EXP(2,3,4,5,6,7,0,1,14); SHA256_EXP(1,2,3,4,5,6,7,0,15);
SHA256_EXP(0,1,2,3,4,5,6,7,16); SHA256_EXP(7,0,1,2,3,4,5,6,17);
SHA256_EXP(6,7,0,1,2,3,4,5,18); SHA256_EXP(5,6,7,0,1,2,3,4,19);
SHA256_EXP(4,5,6,7,0,1,2,3,20); SHA256_EXP(3,4,5,6,7,0,1,2,21);
SHA256_EXP(2,3,4,5,6,7,0,1,22); SHA256_EXP(1,2,3,4,5,6,7,0,23);
SHA256_EXP(0,1,2,3,4,5,6,7,24); SHA256_EXP(7,0,1,2,3,4,5,6,25);
SHA256_EXP(6,7,0,1,2,3,4,5,26); SHA256_EXP(5,6,7,0,1,2,3,4,27);
SHA256_EXP(4,5,6,7,0,1,2,3,28); SHA256_EXP(3,4,5,6,7,0,1,2,29);
SHA256_EXP(2,3,4,5,6,7,0,1,30); SHA256_EXP(1,2,3,4,5,6,7,0,31);
SHA256_EXP(0,1,2,3,4,5,6,7,32); SHA256_EXP(7,0,1,2,3,4,5,6,33);
SHA256_EXP(6,7,0,1,2,3,4,5,34); SHA256_EXP(5,6,7,0,1,2,3,4,35);
SHA256_EXP(4,5,6,7,0,1,2,3,36); SHA256_EXP(3,4,5,6,7,0,1,2,37);
SHA256_EXP(2,3,4,5,6,7,0,1,38); SHA256_EXP(1,2,3,4,5,6,7,0,39);
SHA256_EXP(0,1,2,3,4,5,6,7,40); SHA256_EXP(7,0,1,2,3,4,5,6,41);
SHA256_EXP(6,7,0,1,2,3,4,5,42); SHA256_EXP(5,6,7,0,1,2,3,4,43);
SHA256_EXP(4,5,6,7,0,1,2,3,44); SHA256_EXP(3,4,5,6,7,0,1,2,45);
SHA256_EXP(2,3,4,5,6,7,0,1,46); SHA256_EXP(1,2,3,4,5,6,7,0,47);
SHA256_EXP(0,1,2,3,4,5,6,7,48); SHA256_EXP(7,0,1,2,3,4,5,6,49);
SHA256_EXP(6,7,0,1,2,3,4,5,50); SHA256_EXP(5,6,7,0,1,2,3,4,51);
SHA256_EXP(4,5,6,7,0,1,2,3,52); SHA256_EXP(3,4,5,6,7,0,1,2,53);
SHA256_EXP(2,3,4,5,6,7,0,1,54); SHA256_EXP(1,2,3,4,5,6,7,0,55);
SHA256_EXP(0,1,2,3,4,5,6,7,56); SHA256_EXP(7,0,1,2,3,4,5,6,57);
SHA256_EXP(6,7,0,1,2,3,4,5,58); SHA256_EXP(5,6,7,0,1,2,3,4,59);
SHA256_EXP(4,5,6,7,0,1,2,3,60); SHA256_EXP(3,4,5,6,7,0,1,2,61);
SHA256_EXP(2,3,4,5,6,7,0,1,62); SHA256_EXP(1,2,3,4,5,6,7,0,63);
ctx->h[0] += wv[0]; ctx->h[1] += wv[1];
ctx->h[2] += wv[2]; ctx->h[3] += wv[3];
ctx->h[4] += wv[4]; ctx->h[5] += wv[5];
ctx->h[6] += wv[6]; ctx->h[7] += wv[7];
#endif /* !UNROLL_LOOPS */
}
}
void sha256(const c_uint8_t *message, c_uint32_t len, c_uint8_t *digest)
{
sha256_ctx ctx;
sha256_init(&ctx);
sha256_update(&ctx, message, len);
sha256_final(&ctx, digest);
}
void sha256_init(sha256_ctx *ctx)
{
#ifndef UNROLL_LOOPS
int i;
for (i = 0; i < 8; i++) {
ctx->h[i] = sha256_h0[i];
}
#else
ctx->h[0] = sha256_h0[0]; ctx->h[1] = sha256_h0[1];
ctx->h[2] = sha256_h0[2]; ctx->h[3] = sha256_h0[3];
ctx->h[4] = sha256_h0[4]; ctx->h[5] = sha256_h0[5];
ctx->h[6] = sha256_h0[6]; ctx->h[7] = sha256_h0[7];
#endif /* !UNROLL_LOOPS */
ctx->len = 0;
ctx->tot_len = 0;
}
void sha256_update(sha256_ctx *ctx, const c_uint8_t *message,
c_uint32_t len)
{
c_uint32_t block_nb;
c_uint32_t new_len, rem_len, tmp_len;
const c_uint8_t *shifted_message;
tmp_len = SHA256_BLOCK_SIZE - ctx->len;
rem_len = len < tmp_len ? len : tmp_len;
memcpy(&ctx->block[ctx->len], message, rem_len);
if (ctx->len + len < SHA256_BLOCK_SIZE) {
ctx->len += len;
return;
}
new_len = len - rem_len;
block_nb = new_len / SHA256_BLOCK_SIZE;
shifted_message = message + rem_len;
sha256_transf(ctx, ctx->block, 1);
sha256_transf(ctx, shifted_message, block_nb);
rem_len = new_len % SHA256_BLOCK_SIZE;
memcpy(ctx->block, &shifted_message[block_nb << 6],
rem_len);
ctx->len = rem_len;
ctx->tot_len += (block_nb + 1) << 6;
}
void sha256_final(sha256_ctx *ctx, c_uint8_t *digest)
{
c_uint32_t block_nb;
c_uint32_t pm_len;
c_uint32_t len_b;
#ifndef UNROLL_LOOPS
int i;
#endif
block_nb = (1 + ((SHA256_BLOCK_SIZE - 9)
< (ctx->len % SHA256_BLOCK_SIZE)));
len_b = (ctx->tot_len + ctx->len) << 3;
pm_len = block_nb << 6;
memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
ctx->block[ctx->len] = 0x80;
UNPACK32(len_b, ctx->block + pm_len - 4);
sha256_transf(ctx, ctx->block, block_nb);
#ifndef UNROLL_LOOPS
for (i = 0 ; i < 8; i++) {
UNPACK32(ctx->h[i], &digest[i << 2]);
}
#else
UNPACK32(ctx->h[0], &digest[ 0]);
UNPACK32(ctx->h[1], &digest[ 4]);
UNPACK32(ctx->h[2], &digest[ 8]);
UNPACK32(ctx->h[3], &digest[12]);
UNPACK32(ctx->h[4], &digest[16]);
UNPACK32(ctx->h[5], &digest[20]);
UNPACK32(ctx->h[6], &digest[24]);
UNPACK32(ctx->h[7], &digest[28]);
#endif /* !UNROLL_LOOPS */
}
/* SHA-512 functions */
void sha512_transf(sha512_ctx *ctx, const c_uint8_t *message,
c_uint32_t block_nb)
{
c_uint64_t w[80];
c_uint64_t wv[8];
c_uint64_t t1, t2;
const c_uint8_t *sub_block;
int i, j;
for (i = 0; i < (int) block_nb; i++) {
sub_block = message + (i << 7);
#ifndef UNROLL_LOOPS
for (j = 0; j < 16; j++) {
PACK64(&sub_block[j << 3], &w[j]);
}
for (j = 16; j < 80; j++) {
SHA512_SCR(j);
}
for (j = 0; j < 8; j++) {
wv[j] = ctx->h[j];
}
for (j = 0; j < 80; j++) {
t1 = wv[7] + SHA512_F2(wv[4]) + CH(wv[4], wv[5], wv[6])
+ sha512_k[j] + w[j];
t2 = SHA512_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]);
wv[7] = wv[6];
wv[6] = wv[5];
wv[5] = wv[4];
wv[4] = wv[3] + t1;
wv[3] = wv[2];
wv[2] = wv[1];
wv[1] = wv[0];
wv[0] = t1 + t2;
}
for (j = 0; j < 8; j++) {
ctx->h[j] += wv[j];
}
#else
PACK64(&sub_block[ 0], &w[ 0]); PACK64(&sub_block[ 8], &w[ 1]);
PACK64(&sub_block[ 16], &w[ 2]); PACK64(&sub_block[ 24], &w[ 3]);
PACK64(&sub_block[ 32], &w[ 4]); PACK64(&sub_block[ 40], &w[ 5]);
PACK64(&sub_block[ 48], &w[ 6]); PACK64(&sub_block[ 56], &w[ 7]);
PACK64(&sub_block[ 64], &w[ 8]); PACK64(&sub_block[ 72], &w[ 9]);
PACK64(&sub_block[ 80], &w[10]); PACK64(&sub_block[ 88], &w[11]);
PACK64(&sub_block[ 96], &w[12]); PACK64(&sub_block[104], &w[13]);
PACK64(&sub_block[112], &w[14]); PACK64(&sub_block[120], &w[15]);
SHA512_SCR(16); SHA512_SCR(17); SHA512_SCR(18); SHA512_SCR(19);
SHA512_SCR(20); SHA512_SCR(21); SHA512_SCR(22); SHA512_SCR(23);
SHA512_SCR(24); SHA512_SCR(25); SHA512_SCR(26); SHA512_SCR(27);
SHA512_SCR(28); SHA512_SCR(29); SHA512_SCR(30); SHA512_SCR(31);
SHA512_SCR(32); SHA512_SCR(33); SHA512_SCR(34); SHA512_SCR(35);
SHA512_SCR(36); SHA512_SCR(37); SHA512_SCR(38); SHA512_SCR(39);
SHA512_SCR(40); SHA512_SCR(41); SHA512_SCR(42); SHA512_SCR(43);
SHA512_SCR(44); SHA512_SCR(45); SHA512_SCR(46); SHA512_SCR(47);
SHA512_SCR(48); SHA512_SCR(49); SHA512_SCR(50); SHA512_SCR(51);
SHA512_SCR(52); SHA512_SCR(53); SHA512_SCR(54); SHA512_SCR(55);
SHA512_SCR(56); SHA512_SCR(57); SHA512_SCR(58); SHA512_SCR(59);
SHA512_SCR(60); SHA512_SCR(61); SHA512_SCR(62); SHA512_SCR(63);
SHA512_SCR(64); SHA512_SCR(65); SHA512_SCR(66); SHA512_SCR(67);
SHA512_SCR(68); SHA512_SCR(69); SHA512_SCR(70); SHA512_SCR(71);
SHA512_SCR(72); SHA512_SCR(73); SHA512_SCR(74); SHA512_SCR(75);
SHA512_SCR(76); SHA512_SCR(77); SHA512_SCR(78); SHA512_SCR(79);
wv[0] = ctx->h[0]; wv[1] = ctx->h[1];
wv[2] = ctx->h[2]; wv[3] = ctx->h[3];
wv[4] = ctx->h[4]; wv[5] = ctx->h[5];
wv[6] = ctx->h[6]; wv[7] = ctx->h[7];
j = 0;
do {
SHA512_EXP(0,1,2,3,4,5,6,7,j); j++;
SHA512_EXP(7,0,1,2,3,4,5,6,j); j++;
SHA512_EXP(6,7,0,1,2,3,4,5,j); j++;
SHA512_EXP(5,6,7,0,1,2,3,4,j); j++;
SHA512_EXP(4,5,6,7,0,1,2,3,j); j++;
SHA512_EXP(3,4,5,6,7,0,1,2,j); j++;
SHA512_EXP(2,3,4,5,6,7,0,1,j); j++;
SHA512_EXP(1,2,3,4,5,6,7,0,j); j++;
} while (j < 80);
ctx->h[0] += wv[0]; ctx->h[1] += wv[1];
ctx->h[2] += wv[2]; ctx->h[3] += wv[3];
ctx->h[4] += wv[4]; ctx->h[5] += wv[5];
ctx->h[6] += wv[6]; ctx->h[7] += wv[7];
#endif /* !UNROLL_LOOPS */
}
}
void sha512(const c_uint8_t *message, c_uint32_t len,
c_uint8_t *digest)
{
sha512_ctx ctx;
sha512_init(&ctx);
sha512_update(&ctx, message, len);
sha512_final(&ctx, digest);
}
void sha512_init(sha512_ctx *ctx)
{
#ifndef UNROLL_LOOPS
int i;
for (i = 0; i < 8; i++) {
ctx->h[i] = sha512_h0[i];
}
#else
ctx->h[0] = sha512_h0[0]; ctx->h[1] = sha512_h0[1];
ctx->h[2] = sha512_h0[2]; ctx->h[3] = sha512_h0[3];
ctx->h[4] = sha512_h0[4]; ctx->h[5] = sha512_h0[5];
ctx->h[6] = sha512_h0[6]; ctx->h[7] = sha512_h0[7];
#endif /* !UNROLL_LOOPS */
ctx->len = 0;
ctx->tot_len = 0;
}
void sha512_update(sha512_ctx *ctx, const c_uint8_t *message,
c_uint32_t len)
{
c_uint32_t block_nb;
c_uint32_t new_len, rem_len, tmp_len;
const c_uint8_t *shifted_message;
tmp_len = SHA512_BLOCK_SIZE - ctx->len;
rem_len = len < tmp_len ? len : tmp_len;
memcpy(&ctx->block[ctx->len], message, rem_len);
if (ctx->len + len < SHA512_BLOCK_SIZE) {
ctx->len += len;
return;
}
new_len = len - rem_len;
block_nb = new_len / SHA512_BLOCK_SIZE;
shifted_message = message + rem_len;
sha512_transf(ctx, ctx->block, 1);
sha512_transf(ctx, shifted_message, block_nb);
rem_len = new_len % SHA512_BLOCK_SIZE;
memcpy(ctx->block, &shifted_message[block_nb << 7],
rem_len);
ctx->len = rem_len;
ctx->tot_len += (block_nb + 1) << 7;
}
void sha512_final(sha512_ctx *ctx, c_uint8_t *digest)
{
c_uint32_t block_nb;
c_uint32_t pm_len;
c_uint32_t len_b;
#ifndef UNROLL_LOOPS
int i;
#endif
block_nb = 1 + ((SHA512_BLOCK_SIZE - 17)
< (ctx->len % SHA512_BLOCK_SIZE));
len_b = (ctx->tot_len + ctx->len) << 3;
pm_len = block_nb << 7;
memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
ctx->block[ctx->len] = 0x80;
UNPACK32(len_b, ctx->block + pm_len - 4);
sha512_transf(ctx, ctx->block, block_nb);
#ifndef UNROLL_LOOPS
for (i = 0 ; i < 8; i++) {
UNPACK64(ctx->h[i], &digest[i << 3]);
}
#else
UNPACK64(ctx->h[0], &digest[ 0]);
UNPACK64(ctx->h[1], &digest[ 8]);
UNPACK64(ctx->h[2], &digest[16]);
UNPACK64(ctx->h[3], &digest[24]);
UNPACK64(ctx->h[4], &digest[32]);
UNPACK64(ctx->h[5], &digest[40]);
UNPACK64(ctx->h[6], &digest[48]);
UNPACK64(ctx->h[7], &digest[56]);
#endif /* !UNROLL_LOOPS */
}
/* SHA-384 functions */
void sha384(const c_uint8_t *message, c_uint32_t len,
c_uint8_t *digest)
{
sha384_ctx ctx;
sha384_init(&ctx);
sha384_update(&ctx, message, len);
sha384_final(&ctx, digest);
}
void sha384_init(sha384_ctx *ctx)
{
#ifndef UNROLL_LOOPS
int i;
for (i = 0; i < 8; i++) {
ctx->h[i] = sha384_h0[i];
}
#else
ctx->h[0] = sha384_h0[0]; ctx->h[1] = sha384_h0[1];
ctx->h[2] = sha384_h0[2]; ctx->h[3] = sha384_h0[3];
ctx->h[4] = sha384_h0[4]; ctx->h[5] = sha384_h0[5];
ctx->h[6] = sha384_h0[6]; ctx->h[7] = sha384_h0[7];
#endif /* !UNROLL_LOOPS */
ctx->len = 0;
ctx->tot_len = 0;
}
void sha384_update(sha384_ctx *ctx, const c_uint8_t *message,
c_uint32_t len)
{
c_uint32_t block_nb;
c_uint32_t new_len, rem_len, tmp_len;
const c_uint8_t *shifted_message;
tmp_len = SHA384_BLOCK_SIZE - ctx->len;
rem_len = len < tmp_len ? len : tmp_len;
memcpy(&ctx->block[ctx->len], message, rem_len);
if (ctx->len + len < SHA384_BLOCK_SIZE) {
ctx->len += len;
return;
}
new_len = len - rem_len;
block_nb = new_len / SHA384_BLOCK_SIZE;
shifted_message = message + rem_len;
sha512_transf(ctx, ctx->block, 1);
sha512_transf(ctx, shifted_message, block_nb);
rem_len = new_len % SHA384_BLOCK_SIZE;
memcpy(ctx->block, &shifted_message[block_nb << 7],
rem_len);
ctx->len = rem_len;
ctx->tot_len += (block_nb + 1) << 7;
}
void sha384_final(sha384_ctx *ctx, c_uint8_t *digest)
{
c_uint32_t block_nb;
c_uint32_t pm_len;
c_uint32_t len_b;
#ifndef UNROLL_LOOPS
int i;
#endif
block_nb = (1 + ((SHA384_BLOCK_SIZE - 17)
< (ctx->len % SHA384_BLOCK_SIZE)));
len_b = (ctx->tot_len + ctx->len) << 3;
pm_len = block_nb << 7;
memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
ctx->block[ctx->len] = 0x80;
UNPACK32(len_b, ctx->block + pm_len - 4);
sha512_transf(ctx, ctx->block, block_nb);
#ifndef UNROLL_LOOPS
for (i = 0 ; i < 6; i++) {
UNPACK64(ctx->h[i], &digest[i << 3]);
}
#else
UNPACK64(ctx->h[0], &digest[ 0]);
UNPACK64(ctx->h[1], &digest[ 8]);
UNPACK64(ctx->h[2], &digest[16]);
UNPACK64(ctx->h[3], &digest[24]);
UNPACK64(ctx->h[4], &digest[32]);
UNPACK64(ctx->h[5], &digest[40]);
#endif /* !UNROLL_LOOPS */
}
/* SHA-224 functions */
void sha224(const c_uint8_t *message, c_uint32_t len,
c_uint8_t *digest)
{
sha224_ctx ctx;
sha224_init(&ctx);
sha224_update(&ctx, message, len);
sha224_final(&ctx, digest);
}
void sha224_init(sha224_ctx *ctx)
{
#ifndef UNROLL_LOOPS
int i;
for (i = 0; i < 8; i++) {
ctx->h[i] = sha224_h0[i];
}
#else
ctx->h[0] = sha224_h0[0]; ctx->h[1] = sha224_h0[1];
ctx->h[2] = sha224_h0[2]; ctx->h[3] = sha224_h0[3];
ctx->h[4] = sha224_h0[4]; ctx->h[5] = sha224_h0[5];
ctx->h[6] = sha224_h0[6]; ctx->h[7] = sha224_h0[7];
#endif /* !UNROLL_LOOPS */
ctx->len = 0;
ctx->tot_len = 0;
}
void sha224_update(sha224_ctx *ctx, const c_uint8_t *message,
c_uint32_t len)
{
c_uint32_t block_nb;
c_uint32_t new_len, rem_len, tmp_len;
const c_uint8_t *shifted_message;
tmp_len = SHA224_BLOCK_SIZE - ctx->len;
rem_len = len < tmp_len ? len : tmp_len;
memcpy(&ctx->block[ctx->len], message, rem_len);
if (ctx->len + len < SHA224_BLOCK_SIZE) {
ctx->len += len;
return;
}
new_len = len - rem_len;
block_nb = new_len / SHA224_BLOCK_SIZE;
shifted_message = message + rem_len;
sha256_transf(ctx, ctx->block, 1);
sha256_transf(ctx, shifted_message, block_nb);
rem_len = new_len % SHA224_BLOCK_SIZE;
memcpy(ctx->block, &shifted_message[block_nb << 6],
rem_len);
ctx->len = rem_len;
ctx->tot_len += (block_nb + 1) << 6;
}
void sha224_final(sha224_ctx *ctx, c_uint8_t *digest)
{
c_uint32_t block_nb;
c_uint32_t pm_len;
c_uint32_t len_b;
#ifndef UNROLL_LOOPS
int i;
#endif
block_nb = (1 + ((SHA224_BLOCK_SIZE - 9)
< (ctx->len % SHA224_BLOCK_SIZE)));
len_b = (ctx->tot_len + ctx->len) << 3;
pm_len = block_nb << 6;
memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
ctx->block[ctx->len] = 0x80;
UNPACK32(len_b, ctx->block + pm_len - 4);
sha256_transf(ctx, ctx->block, block_nb);
#ifndef UNROLL_LOOPS
for (i = 0 ; i < 7; i++) {
UNPACK32(ctx->h[i], &digest[i << 2]);
}
#else
UNPACK32(ctx->h[0], &digest[ 0]);
UNPACK32(ctx->h[1], &digest[ 4]);
UNPACK32(ctx->h[2], &digest[ 8]);
UNPACK32(ctx->h[3], &digest[12]);
UNPACK32(ctx->h[4], &digest[16]);
UNPACK32(ctx->h[5], &digest[20]);
UNPACK32(ctx->h[6], &digest[24]);
#endif /* !UNROLL_LOOPS */
}
nextepc-0.3.10/lib/core/src/sha2_hmac.c 0000664 0000000 0000000 00000027603 13335533574 0017542 0 ustar 00root root 0000000 0000000 /*-
* HMAC-SHA-224/256/384/512 implementation
* Last update: 06/15/2005
* Issue date: 06/15/2005
*
* Copyright (C) 2005 Olivier Gay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include
#include "core_sha2_hmac.h"
/* HMAC-SHA-224 functions */
void hmac_sha224_init(hmac_sha224_ctx *ctx, c_uint8_t *key,
c_uint32_t key_size)
{
c_uint32_t fill;
c_uint32_t num;
c_uint8_t *key_used;
c_uint8_t key_temp[SHA224_DIGEST_SIZE];
int i;
if (key_size == SHA224_BLOCK_SIZE) {
key_used = key;
num = SHA224_BLOCK_SIZE;
} else {
if (key_size > SHA224_BLOCK_SIZE){
key_used = key_temp;
num = SHA224_DIGEST_SIZE;
sha224(key, key_size, key_used);
} else { /* key_size > SHA224_BLOCK_SIZE */
key_used = key;
num = key_size;
}
fill = SHA224_BLOCK_SIZE - num;
memset(ctx->block_ipad + num, 0x36, fill);
memset(ctx->block_opad + num, 0x5c, fill);
}
for (i = 0; i < num; i++) {
ctx->block_ipad[i] = key_used[i] ^ 0x36;
ctx->block_opad[i] = key_used[i] ^ 0x5c;
}
sha224_init(&ctx->ctx_inside);
sha224_update(&ctx->ctx_inside, ctx->block_ipad, SHA224_BLOCK_SIZE);
sha224_init(&ctx->ctx_outside);
sha224_update(&ctx->ctx_outside, ctx->block_opad,
SHA224_BLOCK_SIZE);
/* for hmac_reinit */
memcpy(&ctx->ctx_inside_reinit, &ctx->ctx_inside,
sizeof(sha224_ctx));
memcpy(&ctx->ctx_outside_reinit, &ctx->ctx_outside,
sizeof(sha224_ctx));
}
void hmac_sha224_reinit(hmac_sha224_ctx *ctx)
{
memcpy(&ctx->ctx_inside, &ctx->ctx_inside_reinit,
sizeof(sha224_ctx));
memcpy(&ctx->ctx_outside, &ctx->ctx_outside_reinit,
sizeof(sha224_ctx));
}
void hmac_sha224_update(hmac_sha224_ctx *ctx, c_uint8_t *message,
c_uint32_t message_len)
{
sha224_update(&ctx->ctx_inside, message, message_len);
}
void hmac_sha224_final(hmac_sha224_ctx *ctx, c_uint8_t *mac,
c_uint32_t mac_size)
{
c_uint8_t digest_inside[SHA224_DIGEST_SIZE];
c_uint8_t mac_temp[SHA224_DIGEST_SIZE];
sha224_final(&ctx->ctx_inside, digest_inside);
sha224_update(&ctx->ctx_outside, digest_inside, SHA224_DIGEST_SIZE);
sha224_final(&ctx->ctx_outside, mac_temp);
memcpy(mac, mac_temp, mac_size);
}
void hmac_sha224(c_uint8_t *key, c_uint32_t key_size,
c_uint8_t *message, c_uint32_t message_len,
c_uint8_t *mac, c_uint32_t mac_size)
{
hmac_sha224_ctx ctx;
hmac_sha224_init(&ctx, key, key_size);
hmac_sha224_update(&ctx, message, message_len);
hmac_sha224_final(&ctx, mac, mac_size);
}
/* HMAC-SHA-256 functions */
void hmac_sha256_init(hmac_sha256_ctx *ctx, c_uint8_t *key,
c_uint32_t key_size)
{
c_uint32_t fill;
c_uint32_t num;
c_uint8_t *key_used;
c_uint8_t key_temp[SHA256_DIGEST_SIZE];
int i;
if (key_size == SHA256_BLOCK_SIZE) {
key_used = key;
num = SHA256_BLOCK_SIZE;
} else {
if (key_size > SHA256_BLOCK_SIZE){
key_used = key_temp;
num = SHA256_DIGEST_SIZE;
sha256(key, key_size, key_used);
} else { /* key_size > SHA256_BLOCK_SIZE */
key_used = key;
num = key_size;
}
fill = SHA256_BLOCK_SIZE - num;
memset(ctx->block_ipad + num, 0x36, fill);
memset(ctx->block_opad + num, 0x5c, fill);
}
for (i = 0; i < num; i++) {
ctx->block_ipad[i] = key_used[i] ^ 0x36;
ctx->block_opad[i] = key_used[i] ^ 0x5c;
}
sha256_init(&ctx->ctx_inside);
sha256_update(&ctx->ctx_inside, ctx->block_ipad, SHA256_BLOCK_SIZE);
sha256_init(&ctx->ctx_outside);
sha256_update(&ctx->ctx_outside, ctx->block_opad,
SHA256_BLOCK_SIZE);
/* for hmac_reinit */
memcpy(&ctx->ctx_inside_reinit, &ctx->ctx_inside,
sizeof(sha256_ctx));
memcpy(&ctx->ctx_outside_reinit, &ctx->ctx_outside,
sizeof(sha256_ctx));
}
void hmac_sha256_reinit(hmac_sha256_ctx *ctx)
{
memcpy(&ctx->ctx_inside, &ctx->ctx_inside_reinit,
sizeof(sha256_ctx));
memcpy(&ctx->ctx_outside, &ctx->ctx_outside_reinit,
sizeof(sha256_ctx));
}
void hmac_sha256_update(hmac_sha256_ctx *ctx, c_uint8_t *message,
c_uint32_t message_len)
{
sha256_update(&ctx->ctx_inside, message, message_len);
}
void hmac_sha256_final(hmac_sha256_ctx *ctx, c_uint8_t *mac,
c_uint32_t mac_size)
{
c_uint8_t digest_inside[SHA256_DIGEST_SIZE];
c_uint8_t mac_temp[SHA256_DIGEST_SIZE];
sha256_final(&ctx->ctx_inside, digest_inside);
sha256_update(&ctx->ctx_outside, digest_inside, SHA256_DIGEST_SIZE);
sha256_final(&ctx->ctx_outside, mac_temp);
memcpy(mac, mac_temp, mac_size);
}
void hmac_sha256(c_uint8_t *key, c_uint32_t key_size,
c_uint8_t *message, c_uint32_t message_len,
c_uint8_t *mac, c_uint32_t mac_size)
{
hmac_sha256_ctx ctx;
hmac_sha256_init(&ctx, key, key_size);
hmac_sha256_update(&ctx, message, message_len);
hmac_sha256_final(&ctx, mac, mac_size);
}
/* HMAC-SHA-384 functions */
void hmac_sha384_init(hmac_sha384_ctx *ctx, c_uint8_t *key,
c_uint32_t key_size)
{
c_uint32_t fill;
c_uint32_t num;
c_uint8_t *key_used;
c_uint8_t key_temp[SHA384_DIGEST_SIZE];
int i;
if (key_size == SHA384_BLOCK_SIZE) {
key_used = key;
num = SHA384_BLOCK_SIZE;
} else {
if (key_size > SHA384_BLOCK_SIZE){
key_used = key_temp;
num = SHA384_DIGEST_SIZE;
sha384(key, key_size, key_used);
} else { /* key_size > SHA384_BLOCK_SIZE */
key_used = key;
num = key_size;
}
fill = SHA384_BLOCK_SIZE - num;
memset(ctx->block_ipad + num, 0x36, fill);
memset(ctx->block_opad + num, 0x5c, fill);
}
for (i = 0; i < num; i++) {
ctx->block_ipad[i] = key_used[i] ^ 0x36;
ctx->block_opad[i] = key_used[i] ^ 0x5c;
}
sha384_init(&ctx->ctx_inside);
sha384_update(&ctx->ctx_inside, ctx->block_ipad, SHA384_BLOCK_SIZE);
sha384_init(&ctx->ctx_outside);
sha384_update(&ctx->ctx_outside, ctx->block_opad,
SHA384_BLOCK_SIZE);
/* for hmac_reinit */
memcpy(&ctx->ctx_inside_reinit, &ctx->ctx_inside,
sizeof(sha384_ctx));
memcpy(&ctx->ctx_outside_reinit, &ctx->ctx_outside,
sizeof(sha384_ctx));
}
void hmac_sha384_reinit(hmac_sha384_ctx *ctx)
{
memcpy(&ctx->ctx_inside, &ctx->ctx_inside_reinit,
sizeof(sha384_ctx));
memcpy(&ctx->ctx_outside, &ctx->ctx_outside_reinit,
sizeof(sha384_ctx));
}
void hmac_sha384_update(hmac_sha384_ctx *ctx, c_uint8_t *message,
c_uint32_t message_len)
{
sha384_update(&ctx->ctx_inside, message, message_len);
}
void hmac_sha384_final(hmac_sha384_ctx *ctx, c_uint8_t *mac,
c_uint32_t mac_size)
{
c_uint8_t digest_inside[SHA384_DIGEST_SIZE];
c_uint8_t mac_temp[SHA384_DIGEST_SIZE];
sha384_final(&ctx->ctx_inside, digest_inside);
sha384_update(&ctx->ctx_outside, digest_inside, SHA384_DIGEST_SIZE);
sha384_final(&ctx->ctx_outside, mac_temp);
memcpy(mac, mac_temp, mac_size);
}
void hmac_sha384(c_uint8_t *key, c_uint32_t key_size,
c_uint8_t *message, c_uint32_t message_len,
c_uint8_t *mac, c_uint32_t mac_size)
{
hmac_sha384_ctx ctx;
hmac_sha384_init(&ctx, key, key_size);
hmac_sha384_update(&ctx, message, message_len);
hmac_sha384_final(&ctx, mac, mac_size);
}
/* HMAC-SHA-512 functions */
void hmac_sha512_init(hmac_sha512_ctx *ctx, c_uint8_t *key,
c_uint32_t key_size)
{
c_uint32_t fill;
c_uint32_t num;
c_uint8_t *key_used;
c_uint8_t key_temp[SHA512_DIGEST_SIZE];
int i;
if (key_size == SHA512_BLOCK_SIZE) {
key_used = key;
num = SHA512_BLOCK_SIZE;
} else {
if (key_size > SHA512_BLOCK_SIZE){
key_used = key_temp;
num = SHA512_DIGEST_SIZE;
sha512(key, key_size, key_used);
} else { /* key_size > SHA512_BLOCK_SIZE */
key_used = key;
num = key_size;
}
fill = SHA512_BLOCK_SIZE - num;
memset(ctx->block_ipad + num, 0x36, fill);
memset(ctx->block_opad + num, 0x5c, fill);
}
for (i = 0; i < num; i++) {
ctx->block_ipad[i] = key_used[i] ^ 0x36;
ctx->block_opad[i] = key_used[i] ^ 0x5c;
}
sha512_init(&ctx->ctx_inside);
sha512_update(&ctx->ctx_inside, ctx->block_ipad, SHA512_BLOCK_SIZE);
sha512_init(&ctx->ctx_outside);
sha512_update(&ctx->ctx_outside, ctx->block_opad,
SHA512_BLOCK_SIZE);
/* for hmac_reinit */
memcpy(&ctx->ctx_inside_reinit, &ctx->ctx_inside,
sizeof(sha512_ctx));
memcpy(&ctx->ctx_outside_reinit, &ctx->ctx_outside,
sizeof(sha512_ctx));
}
void hmac_sha512_reinit(hmac_sha512_ctx *ctx)
{
memcpy(&ctx->ctx_inside, &ctx->ctx_inside_reinit,
sizeof(sha512_ctx));
memcpy(&ctx->ctx_outside, &ctx->ctx_outside_reinit,
sizeof(sha512_ctx));
}
void hmac_sha512_update(hmac_sha512_ctx *ctx, c_uint8_t *message,
c_uint32_t message_len)
{
sha512_update(&ctx->ctx_inside, message, message_len);
}
void hmac_sha512_final(hmac_sha512_ctx *ctx, c_uint8_t *mac,
c_uint32_t mac_size)
{
c_uint8_t digest_inside[SHA512_DIGEST_SIZE];
c_uint8_t mac_temp[SHA512_DIGEST_SIZE];
sha512_final(&ctx->ctx_inside, digest_inside);
sha512_update(&ctx->ctx_outside, digest_inside, SHA512_DIGEST_SIZE);
sha512_final(&ctx->ctx_outside, mac_temp);
memcpy(mac, mac_temp, mac_size);
}
void hmac_sha512(c_uint8_t *key, c_uint32_t key_size,
c_uint8_t *message, c_uint32_t message_len,
c_uint8_t *mac, c_uint32_t mac_size)
{
hmac_sha512_ctx ctx;
hmac_sha512_init(&ctx, key, key_size);
hmac_sha512_update(&ctx, message, message_len);
hmac_sha512_final(&ctx, mac, mac_size);
}
nextepc-0.3.10/lib/core/src/timer.c 0000664 0000000 0000000 00000014153 13335533574 0017031 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _timer
#include "core_debug.h"
#include "core_timer.h"
#include "core_time.h"
#include "core_param.h"
#include "core_pool.h"
typedef struct _tm_block_t {
lnode_t node;
tm_service_t *tm_s;
c_uint32_t expire_time;
expire_func_t expire_func;
c_uintptr_t param1;
c_uintptr_t param2;
c_uintptr_t param3;
c_uintptr_t param4;
c_uintptr_t param5;
c_uintptr_t param6;
tm_type_e type;
c_uint8_t running;
c_uint32_t duration;
} tm_block_t;
pool_declare(timer_pool, tm_block_t, MAX_NUM_OF_TIMER);
static int _tm_cmp_func(lnode_t *pnode1, lnode_t *pnode2);
static tm_block_t *_tm_get(void);
static void _tm_free(tm_block_t *tm);
#define _tm_add(__l, __tm) \
list_insert_sorted(__l, __tm, _tm_cmp_func)
#define _tm_remove(__l, __tm) \
list_remove(__l, __tm)
status_t tm_init(void)
{
pool_init(&timer_pool, MAX_NUM_OF_TIMER);
return CORE_OK;
}
status_t tm_final(void)
{
if (pool_size(&timer_pool) != pool_avail(&timer_pool))
d_error("%d not freed in timer_pool[%d]",
pool_size(&timer_pool) - pool_avail(&timer_pool),
pool_size(&timer_pool));
d_trace(9, "%d not freed in timer_pool[%d]\n",
pool_size(&timer_pool) - pool_avail(&timer_pool),
pool_size(&timer_pool));
pool_final(&timer_pool);
return CORE_OK;
}
c_uint32_t tm_pool_avail(void)
{
return pool_avail(&timer_pool);
}
void tm_service_init(tm_service_t *tm_service)
{
memset(tm_service, 0x00, sizeof(tm_service_t));
list_init(&tm_service->active_list);
list_init(&tm_service->idle_list);
return;
}
status_t tm_execute_tm_service(tm_service_t *p_tm_s, c_uintptr_t data)
{
c_uint32_t cur_time;
tm_block_t *tm;
cur_time = time_as_msec(time_now());
tm = list_first(&(p_tm_s->active_list));
while(tm)
{
if(tm->expire_time < cur_time)
{
/* execute expiry function */
tm->expire_func(data, tm->param1, tm->param2, tm->param3,
tm->param4, tm->param5, tm->param6);
/* remove this tm_block from the active list */
_tm_remove(&(p_tm_s->active_list), tm);
if(tm->type == TIMER_TYPE_PERIODIC)
{
tm->expire_time = cur_time + tm->duration;
/* add this tm_block to the active list */
_tm_add(&(p_tm_s->active_list), tm);
}
else
{
/* add this tm_block to the idle list */
_tm_add(&(p_tm_s->idle_list), tm);
tm->running = 0;
}
tm = list_first(&(p_tm_s->active_list));
}
else
{
break;
}
}
return CORE_OK;
}
static int _tm_cmp_func(lnode_t *pnode1, lnode_t *pnode2)
{
tm_block_t *tm1 = (tm_block_t*)pnode1;
tm_block_t *tm2 = (tm_block_t*)pnode2;
if(tm1->expire_time < tm2->expire_time)
return -1;
else
return 1;
}
static tm_block_t *_tm_get(void)
{
tm_block_t *tm_b = NULL;
/* get timer node from node pool */
pool_alloc_node(&timer_pool, &tm_b);
/* check for error */
d_assert(tm_b != NULL, return NULL, "fail to get timer pool\n");
/* intialize timer node */
memset((char*)tm_b, 0x00, sizeof(tm_block_t));
return tm_b;
}
static void _tm_free(tm_block_t *tm)
{
/* free tlv node to the node pool */
pool_free_node(&timer_pool, tm);
return;
}
tm_block_id tm_create(tm_service_t *tm_service,
tm_type_e type, c_uint32_t duration, expire_func_t expire_func)
{
tm_block_t *tm = NULL;
tm = _tm_get();
d_assert(tm, return 0, "tm_create failed\n");
tm->tm_s = tm_service;
_tm_add(&(tm->tm_s->idle_list), tm);
tm->type = type;
tm->duration = duration;
tm->expire_func = expire_func;
return (tm_block_id)tm;
}
void tm_delete(tm_block_id id)
{
tm_block_t *tm = (tm_block_t *)id;
/* If running timer, pop it from active list */
if (tm->running == 1)
_tm_remove(&(tm->tm_s->active_list), tm);
/* If not running timer, pop it from idle list */
else
_tm_remove(&(tm->tm_s->idle_list), tm);
_tm_free(tm);
return;
}
status_t tm_set_duration(tm_block_id id, c_uint32_t duration)
{
tm_block_t *tm = (tm_block_t *)id;
tm->duration = duration;
return CORE_OK;
}
status_t tm_set_param1(tm_block_id id, c_uintptr_t param)
{
tm_block_t *tm = (tm_block_t *)id;
tm->param1 = param;
return CORE_OK;
}
status_t tm_set_param2(tm_block_id id, c_uintptr_t param)
{
tm_block_t *tm = (tm_block_t *)id;
tm->param2 = param;
return CORE_OK;
}
status_t tm_set_param3(tm_block_id id, c_uintptr_t param)
{
tm_block_t *tm = (tm_block_t *)id;
tm->param3 = param;
return CORE_OK;
}
status_t tm_set_param4(tm_block_id id, c_uintptr_t param)
{
tm_block_t *tm = (tm_block_t *)id;
tm->param4 = param;
return CORE_OK;
}
status_t tm_set_param5(tm_block_id id, c_uintptr_t param)
{
tm_block_t *tm = (tm_block_t *)id;
tm->param5 = param;
return CORE_OK;
}
status_t tm_set_param6(tm_block_id id, c_uintptr_t param)
{
tm_block_t *tm = (tm_block_t *)id;
tm->param6 = param;
return CORE_OK;
}
status_t tm_start(tm_block_id id)
{
c_uint32_t cur_time = time_as_msec(time_now());
tm_block_t *tm = (tm_block_t *)id;
/* If already running timer, pop it from active list for put again */
if (tm->running == 1)
_tm_remove(&(tm->tm_s->active_list), tm);
/* If not running, tm is in idle list. pop it */
else
_tm_remove(&(tm->tm_s->idle_list), tm);
/* Calculate expiration */
tm->expire_time = cur_time + tm->duration;
/* Push tm to active list */
_tm_add(&(tm->tm_s->active_list), tm);
tm->running = 1;
return CORE_OK;
}
status_t tm_stop(tm_block_id id)
{
tm_block_t *tm = (tm_block_t *)id;
/* If already stopped timer, no operations needed */
if (tm->running == 0)
return CORE_OK;
_tm_remove(&(tm->tm_s->active_list), tm);
_tm_add(&(tm->tm_s->idle_list), tm);
tm->running = 0;
return CORE_OK;
}
nextepc-0.3.10/lib/core/src/tlv.c 0000664 0000000 0000000 00000027227 13335533574 0016524 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _tlv
#include "core_debug.h"
#include "core_tlv.h"
#include "core_lib.h"
pool_declare(tlv_pool, tlv_t, NUM_OF_TLV_NODE);
/* tlv_t common functions */
tlv_t* tlv_get(void)
{
tlv_t *tlv = NULL;
/* get tlv node from node pool */
pool_alloc_node(&tlv_pool, &tlv);
/* check for error */
d_assert(tlv != NULL, return NULL, "fail to get tlv pool\n");
/* intialize tlv node */
memset((char*)tlv, 0x00, sizeof(tlv_t));
return tlv;
}
void tlv_free(tlv_t *p_tlv)
{
/* free tlv node to the node pool */
pool_free_node(&tlv_pool, p_tlv);
return;
}
status_t tlv_init(void)
{
pool_init(&tlv_pool, NUM_OF_TLV_NODE);
return CORE_OK;
}
status_t tlv_final(void)
{
pool_final(&tlv_pool);
return CORE_OK;
}
c_uint32_t tlv_pool_avail(void)
{
return pool_avail(&tlv_pool);
}
void tlv_free_all(tlv_t *root_tlv)
{
/* free all tlv node to the node pool */
tlv_t *p_tlv = root_tlv;
tlv_t *next = NULL;
while(p_tlv)
{
if(p_tlv->embedded != NULL)
{
tlv_free_all(p_tlv->embedded);
}
next = p_tlv->next;
tlv_free(p_tlv);
p_tlv = next;
}
return;
}
c_uint8_t tlv_value_8(tlv_t *tlv)
{
return (*((c_uint8_t*)(tlv->value)));
}
c_uint16_t tlv_value_16(tlv_t *tlv)
{
c_uint16_t c_16;
c_uint8_t *v = tlv->value;
c_16 = ((v[0] << 8) & 0xff00) |
((v[1] ) & 0x00ff);
return c_16;
}
c_uint32_t tlv_value_32(tlv_t *tlv)
{
c_uint32_t c_32;
c_uint8_t *v = tlv->value;
c_32 = ((v[0] << 24) & 0xff000000) |
((v[1] << 16) & 0x00ff0000) |
((v[2] << 8) & 0x0000ff00) |
((v[3] ) & 0x000000ff);
return c_32;
}
c_uint32_t tlv_calc_length(tlv_t *p_tlv, c_uint8_t mode)
{
tlv_t *tmp_tlv = p_tlv;
c_uint32_t length = 0;
while(tmp_tlv)
{
/* this is length for type field */
switch(mode)
{
case TLV_MODE_T1_L1:
length += 2;
break;
case TLV_MODE_T1_L2:
length += 3;
break;
case TLV_MODE_T1_L2_I1:
case TLV_MODE_T2_L2:
length += 4;
break;
default:
d_assert(0, return 0, "Invalid mode(%d)", mode);
break;
}
/* this is length for type field */
if(tmp_tlv->embedded != NULL)
{
tmp_tlv->length = tlv_calc_length(tmp_tlv->embedded, mode);
}
/* this is length for value field */
length += tmp_tlv->length;
tmp_tlv = tmp_tlv->next;
}
return length;
}
c_uint32_t tlv_calc_count(tlv_t *p_tlv)
{
tlv_t *tmp_tlv = p_tlv;
c_uint32_t count = 0;
while(tmp_tlv)
{
if(tmp_tlv->embedded != NULL)
{
count += tlv_calc_count(tmp_tlv->embedded);
}
else
{
count++;
}
tmp_tlv = tmp_tlv->next;
}
return count;
}
c_uint8_t *_tlv_put_type(c_uint32_t type, c_uint8_t *pos, c_uint8_t mode)
{
switch(mode)
{
case TLV_MODE_T1_L1:
case TLV_MODE_T1_L2:
case TLV_MODE_T1_L2_I1:
*(pos++) = type & 0xFF;
break;
case TLV_MODE_T2_L2:
*(pos++) = (type >> 8) & 0xFF;
*(pos++) = type & 0xFF;
break;
default:
d_assert(0, return 0, "Invalid mode(%d)", mode);
break;
}
return pos;
}
c_uint8_t *_tlv_put_length(c_uint32_t length, c_uint8_t *pos, c_uint8_t mode)
{
switch(mode)
{
case TLV_MODE_T1_L1:
*(pos++) = length & 0xFF;
break;
case TLV_MODE_T1_L2:
case TLV_MODE_T1_L2_I1:
case TLV_MODE_T2_L2:
*(pos++) = (length >> 8) & 0xFF;
*(pos++) = length & 0xFF;
break;
default:
d_assert(0, return 0, "Invalid mode(%d)", mode);
break;
}
return pos;
}
c_uint8_t *_tlv_put_instance(c_uint8_t instance, c_uint8_t *pos, c_uint8_t mode)
{
switch(mode)
{
case TLV_MODE_T1_L2_I1:
*(pos++) = instance & 0xFF;
break;
default:
break;
}
return pos;
}
c_uint8_t *_tlv_get_element(tlv_t *p_tlv, c_uint8_t *tlvBlock, c_uint8_t mode)
{
c_uint8_t *pos = tlvBlock;
switch(mode)
{
case TLV_MODE_T1_L1:
p_tlv->type = *(pos++);
p_tlv->length = *(pos++);
break;
case TLV_MODE_T1_L2:
p_tlv->type = *(pos++);
p_tlv->length = *(pos++) << 8;
p_tlv->length += *(pos++);
break;
case TLV_MODE_T1_L2_I1:
p_tlv->type = *(pos++);
p_tlv->length = *(pos++) << 8;
p_tlv->length += *(pos++);
p_tlv->instance = *(pos++);
break;
case TLV_MODE_T2_L2:
p_tlv->type = *(pos++) << 8;
p_tlv->type += *(pos++);
p_tlv->length = *(pos++) << 8;
p_tlv->length += *(pos++);
break;
default:
d_assert(0, return 0, "Invalid mode(%d)", mode);
break;
}
p_tlv->value = pos;
return (pos + tlv_length(p_tlv));
}
void _tlv_alloc_buff_to_tlv(
tlv_t* head_tlv, c_uint8_t* buff, c_uint32_t buff_len)
{
head_tlv->buff_allocated = TRUE;
head_tlv->buff_len = buff_len;
head_tlv->buff_ptr = buff;
head_tlv->buff = buff;
}
tlv_t *tlv_find_root(tlv_t* p_tlv)
{
tlv_t *head_tlv = p_tlv->head;
tlv_t *parentTlv;
parentTlv = head_tlv->parent;
while(parentTlv)
{
head_tlv = parentTlv->head;
parentTlv = head_tlv->parent;
}
return head_tlv;
}
tlv_t *tlv_add(tlv_t *head_tlv,
c_uint32_t type, c_uint32_t length, c_uint8_t instance, c_uint8_t *value)
{
tlv_t* curr_tlv = head_tlv;
tlv_t* new_tlv = NULL;
new_tlv = tlv_get();
d_assert(new_tlv, return NULL, "can't get tlv node\n");
if(length != 0)
{
d_assert(value, return NULL, "tlv value is NULL\n");
}
new_tlv->type = type;
new_tlv->length = length;
new_tlv->instance = instance;
new_tlv->value = value;
if(head_tlv != NULL && head_tlv->buff_allocated == TRUE)
{
d_assert((head_tlv->buff_ptr - head_tlv->buff + length)<
head_tlv->buff_len, tlv_free(new_tlv); return NULL,
"overflow in tlv buffer\n");
memcpy(head_tlv->buff_ptr, value, length);
new_tlv->value = head_tlv->buff_ptr;
head_tlv->buff_ptr += length;
}
if(curr_tlv == NULL)
{
new_tlv->head = new_tlv;
new_tlv->tail = new_tlv;
}
else
{
head_tlv = head_tlv->head; /* in case head_tlv is not head */
new_tlv->head = head_tlv;
head_tlv->tail->next = new_tlv;
head_tlv->tail = new_tlv;
}
return new_tlv;
}
tlv_t *tlv_copy(c_uint8_t *buff, c_uint32_t buff_len,
c_uint32_t type, c_uint32_t length, c_uint8_t instance, c_uint8_t *value)
{
tlv_t* new_tlv = NULL;
new_tlv = tlv_get();
d_assert(new_tlv, return NULL, "can't get tlv node\n");
new_tlv->type = type;
new_tlv->length = length;
new_tlv->instance = instance;
new_tlv->value = value;
new_tlv->head = new_tlv->tail = new_tlv;
_tlv_alloc_buff_to_tlv(new_tlv, buff, buff_len);
memcpy(new_tlv->buff_ptr, value, length);
new_tlv->value = new_tlv->buff_ptr;
new_tlv->buff_ptr += length;
return new_tlv;
}
tlv_t *tlv_embed(tlv_t *parent_tlv,
c_uint32_t type, c_uint32_t length, c_uint8_t instance, c_uint8_t *value)
{
tlv_t* new_tlv = NULL, *root_tlv = NULL;
d_assert(parent_tlv, return NULL, "parent tlv is NULL\n");
new_tlv = tlv_get();
d_assert(new_tlv, return NULL, "can't get tlv node\n");
new_tlv->type = type;
new_tlv->length = length;
new_tlv->instance = instance;
new_tlv->value = value;
root_tlv = tlv_find_root(parent_tlv);
if(root_tlv->buff_allocated == TRUE)
{
d_assert((root_tlv->buff_ptr - root_tlv->buff + length)buff_len,
tlv_free(new_tlv); return NULL, "overflow in tlv buffer\n");
memcpy(root_tlv->buff_ptr, value, length);
new_tlv->value = root_tlv->buff_ptr;
root_tlv->buff_ptr += length;
}
if(parent_tlv->embedded == NULL)
{
parent_tlv->embedded = new_tlv->head = new_tlv->tail = new_tlv;
new_tlv->parent = parent_tlv;
}
else
{
new_tlv->head = parent_tlv->embedded;
parent_tlv->embedded->tail->next = new_tlv;
parent_tlv->embedded->tail = new_tlv;
}
return new_tlv;
}
c_uint32_t tlv_render(tlv_t *root_tlv,
c_uint8_t *blk, c_uint32_t length, c_uint8_t mode)
{
tlv_t* curr_tlv = root_tlv;
c_uint8_t* pos = blk;
c_uint32_t embedded_len = 0;
while(curr_tlv)
{
pos = _tlv_put_type(curr_tlv->type, pos, mode);
if(curr_tlv->embedded == NULL)
{
pos = _tlv_put_length(curr_tlv->length, pos, mode);
pos = _tlv_put_instance(curr_tlv->instance, pos, mode);
if((pos - blk) + tlv_length(curr_tlv) > length)
{
d_assert(FALSE, ;,
"tlv_t encoding error:overflow for given buff length\n");
memcpy((char*)pos, (char*)curr_tlv->value, length - (pos-blk));
pos += length - (pos-blk);
return (pos - blk);
}
memcpy((char*)pos, (char*)curr_tlv->value, curr_tlv->length);
pos += curr_tlv->length;
}
else
{
embedded_len = tlv_calc_length(curr_tlv->embedded, mode);
pos = _tlv_put_length(embedded_len, pos, mode);
pos = _tlv_put_instance(curr_tlv->instance, pos, mode);
tlv_render(curr_tlv->embedded,
pos, length - (c_uint32_t)(pos-blk), mode);
pos += embedded_len;
}
curr_tlv = curr_tlv->next;
}
return (pos - blk);
}
/* tlv_t parsing functions */
tlv_t *tlv_parse_block(c_uint32_t length, c_uint8_t *blk, c_uint8_t mode)
{
c_uint8_t* pos = blk;
tlv_t* root_tlv = NULL;
tlv_t* prev_tlv = NULL;
tlv_t* curr_tlv = NULL;
root_tlv = curr_tlv = tlv_get();
d_assert(curr_tlv, return NULL, "can't get tlv node\n");
pos = _tlv_get_element(curr_tlv, pos, mode);
d_assert(pos != NULL, tlv_free_all(root_tlv); return NULL,
"tlvGetElement Failed\n");
while(pos - blk < length)
{
prev_tlv = curr_tlv;
curr_tlv = tlv_get();
d_assert(curr_tlv, tlv_free_all(root_tlv); return NULL,
"can't get tlv node\n");
prev_tlv->next = curr_tlv;
pos = _tlv_get_element(curr_tlv, pos, mode);
d_assert(pos != NULL, tlv_free_all(root_tlv); return NULL,
"tlvGetElement Failed\n");
}
d_assert(length == (pos - blk),
tlv_free_all(root_tlv); return NULL,
"total size is not equal to sum of each tlv. %d %d",
length, pos - blk);
return root_tlv;
}
tlv_t *tlv_parse_embedded_block(tlv_t* p_tlv, c_uint8_t mode)
{
p_tlv->embedded = tlv_parse_block(p_tlv->length, p_tlv->value, mode);
return p_tlv->embedded;
}
/* tlv operation-related function */
tlv_t *tlv_find(tlv_t* p_tlv, c_uint32_t type)
{
tlv_t *tmp_tlv = p_tlv, *embed_tlv = NULL;
while(tmp_tlv)
{
if(tmp_tlv->type == type)
{
return tmp_tlv;
}
if(tmp_tlv->embedded != NULL)
{
embed_tlv = tlv_find(tmp_tlv->embedded, type);
if(embed_tlv != NULL)
{
return embed_tlv;
}
}
tmp_tlv = tmp_tlv->next;
}
/* tlv for the designated type doesn't exist */
return NULL;
}
nextepc-0.3.10/lib/core/src/tlv_msg.c 0000664 0000000 0000000 00000044762 13335533574 0017375 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _tlv_msg
#include "core_debug.h"
#include "core_tlv_msg.h"
tlv_desc_t tlv_desc_more1 = { TLV_MORE, "More", 0, 1, 0, 0, { NULL } };
tlv_desc_t tlv_desc_more2 = { TLV_MORE, "More", 0, 2, 0, 0, { NULL } };
tlv_desc_t tlv_desc_more3 = { TLV_MORE, "More", 0, 3, 0, 0, { NULL } };
tlv_desc_t tlv_desc_more4 = { TLV_MORE, "More", 0, 4, 0, 0, { NULL } };
tlv_desc_t tlv_desc_more5 = { TLV_MORE, "More", 0, 5, 0, 0, { NULL } };
tlv_desc_t tlv_desc_more6 = { TLV_MORE, "More", 0, 6, 0, 0, { NULL } };
tlv_desc_t tlv_desc_more7 = { TLV_MORE, "More", 0, 7, 0, 0, { NULL } };
tlv_desc_t tlv_desc_more8 = { TLV_MORE, "More", 0, 8, 0, 0, { NULL } };
static tlv_t* _tlv_add_leaf(
tlv_t *parent_tlv, tlv_t *tlv, tlv_desc_t *desc, void *msg)
{
switch (desc->ctype)
{
case TLV_UINT8:
case TLV_INT8:
{
tlv_uint8_t *v = (tlv_uint8_t *)msg;
d_trace2(25, "V_1B:%02x", v->u8);
if (parent_tlv)
tlv = tlv_embed(parent_tlv,
desc->type, 1, desc->instance, (c_uint8_t*)&v->u8);
else
tlv = tlv_add(tlv,
desc->type, 1, desc->instance, (c_uint8_t*)&v->u8);
d_assert(tlv, return NULL, "Can't add TLV");
break;
}
case TLV_UINT16:
{
tlv_uint16_t *v = (tlv_uint16_t *)msg;
d_trace2(25, "V_2B:%04x", v->u16);
v->u16 = htons(v->u16);
if (parent_tlv)
tlv = tlv_embed(parent_tlv,
desc->type, 2, desc->instance, (c_uint8_t*)&v->u16);
else
tlv = tlv_add(tlv,
desc->type, 2, desc->instance, (c_uint8_t*)&v->u16);
d_assert(tlv, return NULL, "Can't add TLV");
break;
}
case TLV_UINT24:
case TLV_INT24:
{
tlv_uint24_t *v = (tlv_uint24_t *)msg;
d_trace2(25, "V_3B:%06x", v->u24);
v->u24 = v->u24 << 8;
v->u24 = htonl(v->u24);
if (parent_tlv)
tlv = tlv_embed(parent_tlv,
desc->type, 3, desc->instance, (c_uint8_t*)&v->u24);
else
tlv = tlv_add(tlv,
desc->type, 3, desc->instance, (c_uint8_t*)&v->u24);
d_assert(tlv, return NULL, "Can't add TLV");
break;
}
case TLV_UINT32:
case TLV_INT32:
{
tlv_uint32_t *v = (tlv_uint32_t *)msg;
d_trace2(25, "V_4B:%08x", v->u32);
v->u32 = htonl(v->u32);
if (parent_tlv)
tlv = tlv_embed(parent_tlv,
desc->type, 4, desc->instance, (c_uint8_t*)&v->u32);
else
tlv = tlv_add(tlv,
desc->type, 4, desc->instance, (c_uint8_t*)&v->u32);
d_assert(tlv, return NULL, "Can't add TLV");
break;
}
case TLV_FIXED_STR:
{
tlv_octet_t *v = (tlv_octet_t *)msg;
d_trace2(25, "V_FSTR: ", v->data);
d_trace_hex(25, v->data, v->len);
if (parent_tlv)
tlv = tlv_embed(parent_tlv,
desc->type, desc->length, desc->instance, v->data);
else
tlv = tlv_add(tlv,
desc->type, desc->length, desc->instance, v->data);
d_assert(tlv, return NULL, "Can't add TLV");
break;
}
case TLV_VAR_STR:
{
tlv_octet_t *v = (tlv_octet_t *)msg;
d_assert(v->len > 0, return NULL, "Length is zero");
d_trace2(25, "V_VSTR: ", v->data);
d_trace_hex(25, v->data, v->len);
if (parent_tlv)
tlv = tlv_embed(parent_tlv,
desc->type, v->len, desc->instance, v->data);
else
tlv = tlv_add(tlv,
desc->type, v->len, desc->instance, v->data);
d_assert(tlv, return NULL, "Can't add TLV");
break;
}
case TLV_NULL:
{
d_trace2(25, "V_NULL" );
if (parent_tlv)
tlv = tlv_embed(parent_tlv,
desc->type, 0, desc->instance, NULL);
else
tlv = tlv_add(tlv,
desc->type, 0, desc->instance, NULL);
d_assert(tlv, return NULL, "Can't add TLV");
break;
}
default:
{
d_assert(0, return NULL, "Unknown class %d", desc->ctype);
break;
}
}
return tlv;
}
static c_uint32_t _tlv_add_compound(tlv_t **root, tlv_t *parent_tlv,
tlv_desc_t *parent_desc, void *msg, int depth)
{
tlv_presence_t *presence_p;
tlv_desc_t *desc = NULL, *next_desc = NULL;
tlv_t *tlv = NULL, *emb_tlv = NULL;
c_uint8_t *p = msg;
c_uint32_t offset = 0, count = 0;
int i, j, r;
char indent[17] = " "; /* 16 spaces */
d_assert(root, return 0, "Null param");
d_assert(parent_desc, return 0, "Null param");
d_assert(msg, return 0, "Null param");
d_assert(depth <= 8, return 0, "Too deep recursion");
indent[depth*2] = 0;
*root = NULL;
for (i = 0, desc = parent_desc->child_descs[i]; desc != NULL;
i++, desc = parent_desc->child_descs[i])
{
next_desc = parent_desc->child_descs[i+1];
if (next_desc != NULL && next_desc->ctype == TLV_MORE)
{
int offset2 = offset;
for (j = 0; j < next_desc->length; j++)
{
presence_p = (tlv_presence_t *)(p + offset2);
if (*presence_p == 0)
break;
if (desc->ctype == TLV_COMPOUND)
{
d_trace2(25, "\nBUILD %sC#%d [%s] T:%d I:%d (vsz=%d) off:%p ",
indent, i, desc->name, desc->type, desc->instance,
desc->vsize, p + offset2);
if (parent_tlv)
tlv = tlv_embed(parent_tlv,
desc->type, 0, desc->instance, NULL);
else
tlv = tlv_add(tlv, desc->type, 0, desc->instance, NULL);
r = _tlv_add_compound(&emb_tlv, tlv, desc,
p + offset2 + sizeof(tlv_presence_t), depth + 1);
d_assert(r > 0 && emb_tlv, return 0,
"Can't build compound TLV");
count += 1 + r;
}
else
{
d_trace2(25, "\nBUILD %sL#%d [%s] T:%d L:%d I:%d "
"(cls:%d vsz:%d) off:%p ",
indent, i, desc->name, desc->type, desc->length,
desc->instance, desc->ctype, desc->vsize,
p + offset2);
tlv = _tlv_add_leaf(parent_tlv, tlv, desc, p + offset2);
d_assert(tlv, return 0, "Can't build leaf TLV");
count++;
}
if (*root == NULL)
*root = tlv;
offset2 += desc->vsize;
}
offset += desc->vsize * next_desc->length;
i++;
}
else
{
presence_p = (tlv_presence_t *)(p + offset);
if (*presence_p)
{
if (desc->ctype == TLV_COMPOUND)
{
d_trace2(25, "\nBUILD %sC#%d [%s] T:%d I:%d (vsz=%d) off:%p ",
indent, i, desc->name, desc->type, desc->instance,
desc->vsize, p + offset);
if (parent_tlv)
tlv = tlv_embed(parent_tlv,
desc->type, 0, desc->instance, NULL);
else
tlv = tlv_add(tlv, desc->type, 0, desc->instance, NULL);
r = _tlv_add_compound(&emb_tlv, tlv, desc,
p + offset + sizeof(tlv_presence_t), depth + 1);
d_assert(r > 0 && emb_tlv, return 0,
"Can't build compound TLV");
count += 1 + r;
}
else
{
d_trace2(25, "\nBUILD %sL#%d [%s] T:%d L:%d I:%d "
"(cls:%d vsz:%d) off:%p ",
indent, i, desc->name, desc->type, desc->length,
desc->instance, desc->ctype, desc->vsize,
p + offset);
tlv = _tlv_add_leaf(parent_tlv, tlv, desc, p + offset);
d_assert(tlv, return 0, "Can't build leaf TLV");
count++;
}
if (*root == NULL)
*root = tlv;
}
offset += desc->vsize;
}
}
return count;
}
status_t tlv_build_msg(pkbuf_t **pkbuf, tlv_desc_t *desc, void *msg, int mode)
{
tlv_t *root = NULL;
c_uint32_t r, length, rendlen;
d_assert(pkbuf, return CORE_ERROR, "Null param");
d_assert(desc, return CORE_ERROR, "Null param");
d_assert(msg, return CORE_ERROR, "Null param");
d_assert(desc->ctype == TLV_MESSAGE, return CORE_ERROR,
"Not TLV message descriptor");
d_assert(desc->child_descs[0], return CORE_ERROR,
"TLV message descriptor has no members");
d_trace2(25, "\n");
d_trace2(25, "[GTP] Build %s\n", desc->name);
r = _tlv_add_compound(&root, NULL, desc, msg, 0);
d_assert(r > 0 && root, tlv_free_all(root); return CORE_ERROR,
"Can't build TLV message");
length = tlv_calc_length(root, mode);
*pkbuf = pkbuf_alloc(TLV_MAX_HEADROOM, length);
d_assert(*pkbuf, tlv_free_all(root); return CORE_ENOMEM,
"pkbuf_alloc() failed");
(*pkbuf)->len = length;
rendlen = tlv_render(root, (*pkbuf)->payload, length, mode);
d_assert(rendlen == length,
pkbuf_free(*pkbuf); tlv_free_all(root); return CORE_ERROR,
"Error while render TLV (%d != %d)", length, rendlen);
tlv_free_all(root);
return CORE_OK;
}
static tlv_desc_t* _tlv_find_desc(c_uint8_t *desc_index,
c_uint32_t *tlv_offset, tlv_desc_t *parent_desc, tlv_t *tlv)
{
tlv_desc_t *prev_desc = NULL, *desc = NULL;
int i, offset = 0;
d_assert(parent_desc, return NULL, "Null param");
d_assert(tlv, return NULL, "Null param");
d_trace2(25, "_tlv_find_desc:T(%d), I(%d) - ", tlv->type, tlv->instance);
for (i = 0, desc = parent_desc->child_descs[i]; desc != NULL;
i++, desc = parent_desc->child_descs[i])
{
d_trace2(25, "%d, ", desc->type);
if (desc->type == tlv->type && desc->instance == tlv->instance)
{
*desc_index = i;
*tlv_offset = offset;
break;
}
if (desc->ctype == TLV_MORE)
{
d_assert(prev_desc && prev_desc->ctype != TLV_MORE,
return NULL, "Invalid previous tlv_desc_t");
offset += prev_desc->vsize * (desc->length - 1);
}
else
{
offset += desc->vsize;
}
prev_desc = desc;
}
d_trace2(25, "\n");
return desc;
}
static status_t _tlv_parse_leaf(void *msg, tlv_desc_t *desc, tlv_t *tlv)
{
d_assert(msg, return CORE_ERROR, "Null param");
d_assert(desc, return CORE_ERROR, "Null param");
d_assert(tlv, return CORE_ERROR, "Null param");
switch (desc->ctype)
{
case TLV_UINT8:
case TLV_INT8:
{
tlv_uint8_t *v = (tlv_uint8_t *)msg;
if (tlv->length != 1)
{
d_error("Invalid TLV length %d. It should be 1", tlv->length);
return CORE_ERROR;
}
v->u8 = *(c_uint8_t*)(tlv->value);
d_trace2(25, "V_1B:%02x", v->u8);
break;
}
case TLV_UINT16:
case TLV_INT16:
{
tlv_uint16_t *v = (tlv_uint16_t *)msg;
if (tlv->length != 2)
{
d_error("Invalid TLV length %d. It should be 2", tlv->length);
return CORE_ERROR;
}
v->u16 = ((((c_uint8_t*)tlv->value)[0]<< 8)&0xff00) |
((((c_uint8_t*)tlv->value)[1] )&0x00ff);
d_trace2(25, "V_2B:%02x", v->u16);
break;
}
case TLV_UINT24:
case TLV_INT24:
{
tlv_uint24_t *v = (tlv_uint24_t *)msg;
if (tlv->length != 3)
{
d_error("Invalid TLV length %d. It should be 3", tlv->length);
return CORE_ERROR;
}
v->u24 = ((((c_uint8_t*)tlv->value)[0]<<16)&0x00ff0000) |
((((c_uint8_t*)tlv->value)[1]<< 8)&0x0000ff00) |
((((c_uint8_t*)tlv->value)[2] )&0x000000ff);
d_trace2(25, "V_3B:%06x", v->u24);
break;
}
case TLV_UINT32:
case TLV_INT32:
{
tlv_uint32_t *v = (tlv_uint32_t *)msg;
if (tlv->length != 4)
{
d_error("Invalid TLV length %d. It should be 4", tlv->length);
return CORE_ERROR;
}
v->u32 = ((((c_uint8_t*)tlv->value)[0]<<24)&0xff000000) |
((((c_uint8_t*)tlv->value)[1]<<16)&0x00ff0000) |
((((c_uint8_t*)tlv->value)[2]<< 8)&0x0000ff00) |
((((c_uint8_t*)tlv->value)[3] )&0x000000ff);
d_trace2(25, "V_4B:%08x", v->u32);
break;
}
case TLV_FIXED_STR:
{
tlv_octet_t *v = (tlv_octet_t *)msg;
if (tlv->length != desc->length)
{
d_error("Invalid TLV length %d. It should be %d",
tlv->length, desc->length);
return CORE_ERROR;
}
v->data = tlv->value;
v->len = tlv->length;
d_trace2(25, "V_FSTR: ", v->data);
d_trace_hex(25, v->data, v->len);
break;
}
case TLV_VAR_STR:
{
tlv_octet_t *v = (tlv_octet_t *)msg;
v->data = tlv->value;
v->len = tlv->length;
d_trace2(25, "V_VSTR: ", v->data);
d_trace_hex(25, v->data, v->len);
break;
}
case TLV_NULL:
{
if (tlv->length != 0)
{
d_error("Invalid TLV length %d. It should be 0", tlv->length);
return CORE_ERROR;
}
break;
}
default:
d_assert(0, return CORE_ERROR, "Unknown TLV class");
break;
}
return CORE_OK;
}
static status_t _tlv_parse_compound(void *msg, tlv_desc_t *parent_desc,
tlv_t *parent_tlv, int depth, int mode)
{
status_t rv;
tlv_presence_t *presence_p = (tlv_presence_t *)msg;
tlv_desc_t *desc = NULL, *next_desc = NULL;
tlv_t *tlv = NULL, *emb_tlv = NULL;
c_uint8_t *p = msg;
c_uint32_t offset = 0;
c_uint8_t index = 0;
int i = 0, j;
char indent[17] = " "; /* 16 spaces */
d_assert(msg, return CORE_ERROR, "Null param");
d_assert(parent_desc, return CORE_ERROR, "Null param");
d_assert(parent_tlv, return CORE_ERROR, "Null param");
d_assert(depth <= 8, return 0, "Too deep recursion");
indent[depth*2] = 0;
tlv = parent_tlv;
while(tlv)
{
desc = _tlv_find_desc(&index, &offset, parent_desc, tlv);
if (desc == NULL)
{
d_error("Unexpected TLV type:%d", tlv->type);
return CORE_ERROR;
}
presence_p = (tlv_presence_t *)(p + offset);
/* Multiple of the same type TLV may be included */
next_desc = parent_desc->child_descs[index+1];
if (next_desc != NULL && next_desc->ctype == TLV_MORE)
{
for (j = 0; j < next_desc->length; j++)
{
presence_p = (tlv_presence_t *)(p + offset + desc->vsize * j);
if (*presence_p == 0)
{
offset += desc->vsize * j;
break;
}
}
if (j == next_desc->length)
{
d_fatal("Multiple of the same type TLV need more room");
tlv = tlv->next;
continue;
}
}
if (desc->ctype == TLV_COMPOUND)
{
emb_tlv = tlv_parse_embedded_block(tlv, mode);
if (emb_tlv == NULL)
{
d_error("Error while parse TLV");
return CORE_ERROR;
}
d_trace2(25, "\nPARSE %sC#%d [%s] T:%d I:%d (vsz=%d) off:%p ",
indent, i++, desc->name, desc->type, desc->instance,
desc->vsize, p + offset);
offset += sizeof(tlv_presence_t);
rv = _tlv_parse_compound(
p + offset, desc, emb_tlv, depth + 1, mode);
if (rv != CORE_OK)
{
d_error("Can't parse compound TLV");
return CORE_ERROR;
}
*presence_p = 1;
}
else
{
d_trace2(25, "\nPARSE %sL#%d [%s] T:%d L:%d I:%d "
"(cls:%d vsz:%d) off:%p ",
indent, i++, desc->name, desc->type, desc->length,
desc->instance, desc->ctype, desc->vsize, p + offset);
rv = _tlv_parse_leaf(p + offset, desc, tlv);
if (rv != CORE_OK)
{
d_error("Can't parse leaf TLV");
return CORE_ERROR;
}
*presence_p = 1;
}
tlv = tlv->next;
}
d_trace2(25, "\n");
return CORE_OK;
}
status_t tlv_parse_msg(void *msg, tlv_desc_t *desc, pkbuf_t *pkbuf, int mode)
{
status_t rv;
tlv_t *root;
d_assert(msg, return CORE_ERROR, "Null param");
d_assert(desc, return CORE_ERROR, "Null param");
d_assert(pkbuf, return CORE_ERROR, "Null param");
d_assert(desc->ctype == TLV_MESSAGE, return CORE_ERROR,
"Not TLV message descriptor");
d_assert(desc->child_descs[0], return CORE_ERROR,
"TLV message descriptor has no members");
d_trace2(25, "\n");
d_trace2(25, "[GTP] Parse %s\n", desc->name);
root = tlv_parse_block(pkbuf->len, pkbuf->payload, mode);
if (root == NULL)
{
d_error("Can't parse TLV message");
return CORE_ERROR;
}
rv = _tlv_parse_compound(msg, desc, root, 0, mode);
tlv_free_all(root);
return rv;
}
nextepc-0.3.10/lib/core/src/unix/ 0000775 0000000 0000000 00000000000 13335533574 0016524 5 ustar 00root root 0000000 0000000 nextepc-0.3.10/lib/core/src/unix/atomic.c 0000664 0000000 0000000 00000010332 13335533574 0020143 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _atomic
#include "core_atomic.h"
#include "core_mutex.h"
#include "core_debug.h"
#if HAVE_ATOMIC_BUILTINS == 1
status_t atomic_init()
{
return CORE_OK;
}
status_t atomic_final()
{
return CORE_OK;
}
c_uint32_t atomic_read32(volatile c_uint32_t *mem)
{
return *mem;
}
void atomic_set32(volatile c_uint32_t *mem, c_uint32_t val)
{
*mem = val;
}
c_uint32_t atomic_add32(volatile c_uint32_t *mem, c_uint32_t val)
{
return __sync_fetch_and_add(mem, val);
}
void atomic_sub32(volatile c_uint32_t *mem, c_uint32_t val)
{
__sync_fetch_and_sub(mem, val);
}
c_uint32_t atomic_inc32(volatile c_uint32_t *mem)
{
return __sync_fetch_and_add(mem, 1);
}
int atomic_dec32(volatile c_uint32_t *mem)
{
return __sync_sub_and_fetch(mem, 1);
}
c_uint32_t atomic_cas32(volatile c_uint32_t *mem, c_uint32_t with,
c_uint32_t cmp)
{
return __sync_val_compare_and_swap(mem, cmp, with);
}
c_uint32_t atomic_xchg32(volatile c_uint32_t *mem, c_uint32_t val)
{
__sync_synchronize();
return __sync_lock_test_and_set(mem, val);
}
void* atomic_casptr(void *volatile *mem, void *with, const void *cmp)
{
return (void*) __sync_val_compare_and_swap(mem, (void *)cmp, with);
}
void* atomic_xchgptr(void *volatile *mem, void *with)
{
__sync_synchronize();
return (void*) __sync_lock_test_and_set(mem, with);
}
#else
#define DECLARE_MUTEX_LOCKED(name, mem) \
mutex_id name = mutex_hash(mem)
#define MUTEX_UNLOCK(name) \
d_assert(mutex_unlock(name) == CORE_OK,,);
#define NUM_ATOMIC_HASH 7
static mutex_id hash_mutex[NUM_ATOMIC_HASH];
/* shift by 2 to get rid of alignment issues */
#define ATOMIC_HASH(x) (unsigned int)(((unsigned long)(x)>>2)%(unsigned int)NUM_ATOMIC_HASH)
status_t atomic_init()
{
int i;
status_t rv;
for (i = 0; i < NUM_ATOMIC_HASH; i++)
{
rv = mutex_create(&hash_mutex[i], MUTEX_DEFAULT);
if (rv != CORE_OK)
{
return rv;
}
}
return CORE_OK;
}
status_t atomic_final()
{
status_t rv;
int i;
for (i = 0; i < NUM_ATOMIC_HASH; i++)
{
rv = mutex_delete(hash_mutex[i]);
if (rv != CORE_OK)
{
return rv;
}
}
return CORE_OK;
}
static CORE_INLINE mutex_id mutex_hash(volatile c_uint32_t *mem)
{
mutex_id id = hash_mutex[ATOMIC_HASH(mem)];
d_assert(mutex_lock(id) == CORE_OK, return (mutex_id)NULL,);
return id;
}
c_uint32_t atomic_read32(volatile c_uint32_t *mem)
{
return *mem;
}
void atomic_set32(volatile c_uint32_t *mem, c_uint32_t val)
{
DECLARE_MUTEX_LOCKED(mutex, mem);
*mem = val;
MUTEX_UNLOCK(mutex);
}
c_uint32_t atomic_add32(volatile c_uint32_t *mem, c_uint32_t val)
{
c_uint32_t old_value;
DECLARE_MUTEX_LOCKED(mutex, mem);
old_value = *mem;
*mem += val;
MUTEX_UNLOCK(mutex);
return old_value;
}
void atomic_sub32(volatile c_uint32_t *mem, c_uint32_t val)
{
DECLARE_MUTEX_LOCKED(mutex, mem);
*mem -= val;
MUTEX_UNLOCK(mutex);
}
c_uint32_t atomic_inc32(volatile c_uint32_t *mem)
{
return atomic_add32(mem, 1);
}
int atomic_dec32(volatile c_uint32_t *mem)
{
c_uint32_t new;
DECLARE_MUTEX_LOCKED(mutex, mem);
(*mem)--;
new = *mem;
MUTEX_UNLOCK(mutex);
return new;
}
c_uint32_t atomic_cas32(volatile c_uint32_t *mem, c_uint32_t with,
c_uint32_t cmp)
{
c_uint32_t prev;
DECLARE_MUTEX_LOCKED(mutex, mem);
prev = *mem;
if (prev == cmp) {
*mem = with;
}
MUTEX_UNLOCK(mutex);
return prev;
}
c_uint32_t atomic_xchg32(volatile c_uint32_t *mem, c_uint32_t val)
{
c_uint32_t prev;
DECLARE_MUTEX_LOCKED(mutex, mem);
prev = *mem;
*mem = val;
MUTEX_UNLOCK(mutex);
return prev;
}
void* atomic_casptr(void *volatile *mem, void *with, const void *cmp)
{
void *prev;
DECLARE_MUTEX_LOCKED(mutex, *mem);
prev = *(void **)mem;
if (prev == cmp) {
*mem = with;
}
MUTEX_UNLOCK(mutex);
return prev;
}
void* atomic_xchgptr(void *volatile *mem, void *with)
{
void *prev;
DECLARE_MUTEX_LOCKED(mutex, *mem);
prev = *(void **)mem;
*mem = with;
MUTEX_UNLOCK(mutex);
return prev;
}
#endif
nextepc-0.3.10/lib/core/src/unix/cond.c 0000664 0000000 0000000 00000003746 13335533574 0017625 0 ustar 00root root 0000000 0000000 #include "core.h"
#include "core_cond.h"
#include "core_arch_mutex.h"
#include "core_pool.h"
#include "core_param.h"
#include "core_general.h"
#include "core_debug.h"
typedef struct _cond_t {
pthread_cond_t cond;
} cond_t;
pool_declare(cond_pool, cond_t, MAX_NUM_OF_COND);
status_t cond_init(void)
{
pool_init(&cond_pool, MAX_NUM_OF_COND);
return CORE_OK;
}
status_t cond_final(void)
{
pool_final(&cond_pool);
return CORE_OK;
}
status_t cond_create(cond_id *id)
{
cond_t *new_cond = NULL;
status_t rv;
pool_alloc_node(&cond_pool, &new_cond);
d_assert(new_cond, return CORE_ENOMEM, "cond_pool(%d) is not enough\n",
MAX_NUM_OF_COND);
if ((rv = pthread_cond_init(&new_cond->cond, NULL)))
{
return rv;
}
*id = (cond_id)new_cond;
return CORE_OK;
}
status_t cond_wait(cond_id id, mutex_id mid)
{
status_t rv;
cond_t *cond = (cond_t *)id;
mutex_t *mutex = (mutex_t *)mid;
rv = pthread_cond_wait(&cond->cond, &mutex->mutex);
return rv;
}
status_t cond_timedwait(cond_id id,
mutex_id mid, c_time_t timeout)
{
status_t rv;
c_time_t then;
struct timespec abstime;
cond_t *cond = (cond_t *)id;
mutex_t *mutex = (mutex_t *)mid;
then = time_now() + timeout;
abstime.tv_sec = time_sec(then);
abstime.tv_nsec = time_usec(then) * 1000; /* nanoseconds */
rv = pthread_cond_timedwait(&cond->cond, &mutex->mutex, &abstime);
if (ETIMEDOUT == rv)
{
return CORE_TIMEUP;
}
return rv;
}
status_t cond_signal(cond_id id)
{
status_t rv;
cond_t *cond = (cond_t *)id;
rv = pthread_cond_signal(&cond->cond);
return rv;
}
status_t cond_broadcast(cond_id id)
{
status_t rv;
cond_t *cond = (cond_t *)id;
rv = pthread_cond_broadcast(&cond->cond);
return rv;
}
status_t cond_delete(cond_id id)
{
status_t rv;
cond_t *cond = (cond_t *)id;
rv = pthread_cond_destroy(&cond->cond);
pool_free_node(&cond_pool, cond);
return rv;
}
nextepc-0.3.10/lib/core/src/unix/errorcodes.c 0000664 0000000 0000000 00000033331 13335533574 0021042 0 ustar 00root root 0000000 0000000 /* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "core.h"
#include "core_lib.h"
#include "core_arch_network.h"
static char *stuffbuffer(char *buf, size_t bufsize, const char *s)
{
strncpy(buf,s,bufsize);
return buf;
}
static char *core_error_string(status_t statcode)
{
switch (statcode) {
case CORE_ENOPOOL:
return "A new pool could not be created.";
case CORE_EBADDATE:
return "An invalid date has been provided";
case CORE_EINVALSOCK:
return "An invalid socket was returned";
case CORE_ENOPROC:
return "No process was provided and one was required.";
case CORE_ENOTIME:
return "No time was provided and one was required.";
case CORE_ENODIR:
return "No directory was provided and one was required.";
case CORE_ENOLOCK:
return "No lock was provided and one was required.";
case CORE_ENOPOLL:
return "No poll structure was provided and one was required.";
case CORE_ENOSOCKET:
return "No socket was provided and one was required.";
case CORE_ENOTHREAD:
return "No thread was provided and one was required.";
case CORE_ENOTHDKEY:
return "No thread key structure was provided and one was required.";
case CORE_ENOSHMAVAIL:
return "No shared memory is currently available";
case CORE_EDSOOPEN:
return "DSO load failed";
case CORE_EBADIP:
return "The specified IP address is invalid.";
case CORE_EBADMASK:
return "The specified network mask is invalid.";
case CORE_INCHILD:
return
"Your code just forked, and you are currently executing in the "
"child process";
case CORE_INPARENT:
return
"Your code just forked, and you are currently executing in the "
"parent process";
case CORE_DETACH:
return "The specified thread is detached";
case CORE_NOTDETACH:
return "The specified thread is not detached";
case CORE_CHILD_DONE:
return "The specified child process is done executing";
case CORE_CHILD_NOTDONE:
return "The specified child process is not done executing";
case CORE_TIMEUP:
return "The timeout specified has expired";
case CORE_INCOMPLETE:
return "Partial results are valid but processing is incomplete";
case CORE_BADCH:
return "Bad character specified on command line";
case CORE_BADARG:
return "Missing parameter for the specified command line option";
case CORE_EOF:
return "End of file found";
case CORE_NOTFOUND:
return "Could not find specified socket in poll list.";
case CORE_ANONYMOUS:
return "Shared memory is implemented anonymously";
case CORE_FILEBASED:
return "Shared memory is implemented using files";
case CORE_KEYBASED:
return "Shared memory is implemented using a key system";
case CORE_EINIT:
return
"There is no error, this value signifies an initialized "
"error code";
case CORE_ENOTIMPL:
return "This function has not been implemented on this platform";
case CORE_EMISMATCH:
return "passwords do not match";
case CORE_EABSOLUTE:
return "The given path is absolute";
case CORE_ERELATIVE:
return "The given path is relative";
case CORE_EINCOMPLETE:
return "The given path is incomplete";
case CORE_EABOVEROOT:
return "The given path was above the root path";
case CORE_EBADPATH:
return "The given path is misformatted or contained invalid characters";
case CORE_EPATHWILD:
return "The given path contained wildcard characters";
case CORE_EPROC_UNKNOWN:
return "The process is not recognized.";
case CORE_EGENERAL:
return "Internal error";
default:
return "Error string not specified yet";
}
}
#ifdef OS2
#include
int core_canonical_error(status_t err);
static char *core_os_strerror(char* buf, size_t bufsize, int err)
{
char result[200];
unsigned char message[HUGE_STRING_LEN];
ULONG len;
char *pos;
int c;
if (err >= 10000 && err < 12000) { /* socket error codes */
return stuffbuffer(buf, bufsize,
strerror(core_canonical_error(err+OS_START_SYSERR)));
}
else if (DosGetMessage(NULL, 0, message, HUGE_STRING_LEN, err,
"OSO001.MSG", &len) == 0) {
len--;
message[len] = 0;
pos = result;
if (len >= sizeof(result))
len = sizeof(result) - 1;
for (c=0; c= 0) {
buf[i] = (char) msg[i];
} else {
buf[i] = '?';
}
}
#endif
#endif
if (!len) {
for (i = 0; gaErrorList[i].msg; ++i) {
if (gaErrorList[i].code == errcode) {
core_cpystrn(buf, gaErrorList[i].msg, bufsize);
len = strlen(buf);
break;
}
}
}
if (len) {
/* FormatMessage put the message in the buffer, but it may
* have embedded a newline (\r\n), and possible more than one.
* Remove the newlines replacing them with a space. This is not
* as visually perfect as moving all the remaining message over,
* but more efficient.
*/
i = len;
while (i) {
i--;
if ((buf[i] == '\r') || (buf[i] == '\n'))
buf[i] = ' ';
}
}
else {
/* Windows didn't provide us with a message. Even stuff like * WSAECONNREFUSED won't get a message.
*/
core_snprintf(buf, bufsize, "Unrecognized Win32 error code %d", errcode);
}
return buf;
}
#else
/* On Unix, core_os_strerror() handles error codes from the resolver
* (h_errno).
*/
static char *core_os_strerror(char* buf, size_t bufsize, int err)
{
#ifdef HAVE_HSTRERROR
return stuffbuffer(buf, bufsize, hstrerror(err));
#else /* HAVE_HSTRERROR */
const char *msg;
switch(err) {
case HOST_NOT_FOUND:
msg = "Unknown host";
break;
#if defined(NO_DATA)
case NO_DATA:
#if defined(NO_ADDRESS) && (NO_DATA != NO_ADDRESS)
case NO_ADDRESS:
#endif
msg = "No address for host";
break;
#elif defined(NO_ADDRESS)
case NO_ADDRESS:
msg = "No address for host";
break;
#endif /* NO_DATA */
default:
msg = "Unrecognized resolver error";
}
return stuffbuffer(buf, bufsize, msg);
#endif /* HAVE_STRERROR */
}
#endif
#if defined(HAVE_STRERROR_R) && defined(STRERROR_R_RC_INT) && !defined(BEOS)
/* AIX and Tru64 style */
static char *native_strerror(status_t statcode, char *buf,
size_t bufsize)
{
if (strerror_r(statcode, buf, bufsize) < 0) {
return stuffbuffer(buf, bufsize,
"CORE does not understand this error code");
}
else {
return buf;
}
}
#elif defined(HAVE_STRERROR_R)
/* glibc style */
/* BeOS has the function available, but it doesn't provide
* the prototype publically (doh!), so to avoid a build warning
* we add a suitable prototype here.
*/
#if defined(BEOS)
const char *strerror_r(status_t, char *, size_t);
#endif
static char *native_strerror(status_t statcode, char *buf,
size_t bufsize)
{
const char *msg;
buf[0] = '\0';
msg = strerror_r(statcode, buf, bufsize);
if (buf[0] == '\0') { /* libc didn't use our buffer */
return stuffbuffer(buf, bufsize, msg);
}
else {
return buf;
}
}
#else
/* plain old strerror();
* thread-safe on some platforms (e.g., Solaris, OS/390)
*/
static char *native_strerror(status_t statcode, char *buf,
size_t bufsize)
{
#ifdef _WIN32_WCE
static char err[32];
sprintf(err, "Native Error #%d", statcode);
return stuffbuffer(buf, bufsize, err);
#else
const char *err = strerror(statcode);
if (err) {
return stuffbuffer(buf, bufsize, err);
} else {
return stuffbuffer(buf, bufsize,
"CORE does not understand this error code");
}
#endif
}
#endif
char * core_strerror(status_t statcode, char *buf,
size_t bufsize)
{
if (statcode < OS_START_ERROR) {
return native_strerror(statcode, buf, bufsize);
}
else if (statcode < OS_START_USERERR) {
return stuffbuffer(buf, bufsize, core_error_string(statcode));
}
else if (statcode < OS_START_EAIERR) {
return stuffbuffer(buf, bufsize, "CORE does not understand this error code");
}
else if (statcode < OS_START_SYSERR) {
#if defined(HAVE_GAI_STRERROR)
statcode -= OS_START_EAIERR;
#if defined(NEGATIVE_EAI)
statcode = -statcode;
#endif
return stuffbuffer(buf, bufsize, gai_strerror(statcode));
#else
return stuffbuffer(buf, bufsize, "CORE does not understand this error code");
#endif
}
else {
return core_os_strerror(buf, bufsize, statcode - OS_START_SYSERR);
}
}
nextepc-0.3.10/lib/core/src/unix/file.c 0000664 0000000 0000000 00000061510 13335533574 0017612 0 ustar 00root root 0000000 0000000 #include "core_arch_file.h"
#include "core.h"
#include "core_errno.h"
#include "core_general.h"
#include "core_debug.h"
#include "core_pool.h"
pool_declare(file_pool, file_t, MAX_NUM_OF_FILE);
status_t file_init(void)
{
pool_init(&file_pool, MAX_NUM_OF_FILE);
return CORE_OK;
}
status_t file_final(void)
{
pool_final(&file_pool);
return CORE_OK;
}
#if !defined(OS2) && !defined(WIN32)
mode_t unix_perms2mode(file_perms_t perms)
{
mode_t mode = 0;
if (perms & FILE_USETID)
mode |= S_ISUID;
if (perms & FILE_UREAD)
mode |= S_IRUSR;
if (perms & FILE_UWRITE)
mode |= S_IWUSR;
if (perms & FILE_UEXECUTE)
mode |= S_IXUSR;
if (perms & FILE_GSETID)
mode |= S_ISGID;
if (perms & FILE_GREAD)
mode |= S_IRGRP;
if (perms & FILE_GWRITE)
mode |= S_IWGRP;
if (perms & FILE_GEXECUTE)
mode |= S_IXGRP;
#ifdef S_ISVTX
if (perms & FILE_WSTICKY)
mode |= S_ISVTX;
#endif
if (perms & FILE_WREAD)
mode |= S_IROTH;
if (perms & FILE_WWRITE)
mode |= S_IWOTH;
if (perms & FILE_WEXECUTE)
mode |= S_IXOTH;
return mode;
}
file_perms_t unix_mode2perms(mode_t mode)
{
file_perms_t perms = 0;
if (mode & S_ISUID)
perms |= FILE_USETID;
if (mode & S_IRUSR)
perms |= FILE_UREAD;
if (mode & S_IWUSR)
perms |= FILE_UWRITE;
if (mode & S_IXUSR)
perms |= FILE_UEXECUTE;
if (mode & S_ISGID)
perms |= FILE_GSETID;
if (mode & S_IRGRP)
perms |= FILE_GREAD;
if (mode & S_IWGRP)
perms |= FILE_GWRITE;
if (mode & S_IXGRP)
perms |= FILE_GEXECUTE;
#ifdef S_ISVTX
if (mode & S_ISVTX)
perms |= FILE_WSTICKY;
#endif
if (mode & S_IROTH)
perms |= FILE_WREAD;
if (mode & S_IWOTH)
perms |= FILE_WWRITE;
if (mode & S_IXOTH)
perms |= FILE_WEXECUTE;
return perms;
}
#endif
status_t file_open(file_t **new,
const char *fname, c_int32_t flag, file_perms_t perm)
{
os_file_t fd;
int oflags = 0;
d_assert(fname, return CORE_ERROR,);
if ((flag & FILE_READ) && (flag & FILE_WRITE))
{
oflags = O_RDWR;
}
else if (flag & FILE_READ)
{
oflags = O_RDONLY;
}
else if (flag & FILE_WRITE)
{
oflags = O_WRONLY;
}
else
{
return CORE_EACCES;
}
if (flag & FILE_CREATE)
{
oflags |= O_CREAT;
if (flag & FILE_EXCL)
{
oflags |= O_EXCL;
}
}
if ((flag & FILE_EXCL) && !(flag & FILE_CREATE))
{
return CORE_EACCES;
}
if (flag & FILE_APPEND)
{
oflags |= O_APPEND;
}
if (flag & FILE_TRUNCATE)
{
oflags |= O_TRUNC;
}
#ifdef O_BINARY
if (flag & FILE_BINARY)
{
oflags |= O_BINARY;
}
#endif
if (perm == FILE_OS_DEFAULT)
{
fd = open(fname, oflags, 0666);
}
else
{
fd = open(fname, oflags, unix_perms2mode(perm));
}
if (fd < 0)
{
return errno;
}
pool_alloc_node(&file_pool, &(*new));
d_assert((*new), return CORE_ENOMEM, "file_pool(%d) is not enough\n",
MAX_NUM_OF_FILE);
(*new)->flags = flag;
(*new)->filedes = fd;
strcpy((*new)->fname, fname);
(*new)->timeout = -1;
(*new)->eof_hit = 0;
(*new)->filePtr = 0;
return CORE_OK;
}
status_t file_close(file_t *file)
{
status_t rv = CORE_OK;
d_assert(file, return CORE_ERROR,);
if (close(file->filedes) == 0)
{
file->filedes = -1;
/* Only the parent process should delete the file! */
if (file->flags & FILE_DELONCLOSE)
{
unlink(file->fname);
}
}
else
{
/* Are there any error conditions other than EINTR or EBADF? */
rv = errno;
}
pool_free_node(&file_pool, file);
return rv;
}
status_t file_remove(const char *path)
{
d_assert(path, return CORE_ERROR,);
if (unlink(path) == 0)
{
return CORE_OK;
}
else
{
return errno;
}
}
static status_t file_transfer_contents(
const char *from_path, const char *to_path,
c_int32_t flags, file_perms_t to_perms)
{
file_t *s, *d;
status_t status;
file_info_t finfo;
file_perms_t perms;
d_assert(from_path, return CORE_ERROR,);
d_assert(to_path, return CORE_ERROR,);
/* Open source file. */
status = file_open(&s, from_path, FILE_READ, FILE_OS_DEFAULT);
if (status)
return status;
/* Maybe get its permissions. */
if (to_perms == FILE_SOURCE_PERMS)
{
status = file_info_get(&finfo, FILE_INFO_PROT, s);
if (status != CORE_OK && status != CORE_INCOMPLETE)
{
file_close(s); /* toss any error */
return status;
}
perms = finfo.protection;
}
else
perms = to_perms;
/* Open dest file. */
status = file_open(&d, to_path, flags, perms);
if (status)
{
file_close(s); /* toss any error */
return status;
}
#if BUFSIZ > FILE_DEFAULT_BUFSIZE
#define COPY_BUFSIZ BUFSIZ
#else
#define COPY_BUFSIZ FILE_DEFAULT_BUFSIZE
#endif
/* Copy bytes till the cows come home. */
while (1)
{
char buf[COPY_BUFSIZ];
size_t bytes_this_time = sizeof(buf);
status_t read_err;
status_t write_err;
/* Read 'em. */
read_err = file_read(s, buf, &bytes_this_time);
if (read_err && !STATUS_IS_EOF(read_err))
{
file_close(s); /* toss any error */
file_close(d); /* toss any error */
return read_err;
}
/* Write 'em. */
write_err = file_write_full(d, buf, bytes_this_time, NULL);
if (write_err)
{
file_close(s); /* toss any error */
file_close(d); /* toss any error */
return write_err;
}
if (read_err && STATUS_IS_EOF(read_err))
{
status = file_close(s);
if (status)
{
file_close(d); /* toss any error */
return status;
}
/* return the results of this close: an error, or success */
return file_close(d);
}
}
/* NOTREACHED */
}
status_t file_rename(const char *from_path, const char *to_path)
{
d_assert(from_path, return CORE_ERROR,);
d_assert(to_path, return CORE_ERROR,);
if (rename(from_path, to_path) != 0)
{
return errno;
}
return CORE_OK;
}
status_t file_link(const char *from_path, const char *to_path)
{
d_assert(from_path, return CORE_ERROR,);
d_assert(to_path, return CORE_ERROR,);
if (link(from_path, to_path) == -1)
{
return errno;
}
return CORE_OK;
}
status_t file_copy(
const char *from_path, const char *to_path, file_perms_t perms)
{
return file_transfer_contents(from_path, to_path,
(FILE_WRITE | FILE_CREATE | FILE_TRUNCATE), perms);
}
status_t file_append(
const char *from_path, const char *to_path, file_perms_t perms)
{
return file_transfer_contents(from_path, to_path,
(FILE_WRITE | FILE_CREATE | FILE_APPEND), perms);
}
status_t file_eof(file_t *fptr)
{
d_assert(fptr, return CORE_ERROR,);
if (fptr->eof_hit == 1)
{
return CORE_EOF;
}
return CORE_OK;
}
status_t file_read(file_t *thefile, void *buf, size_t *nbytes)
{
ssize_t rv;
size_t bytes_read;
d_assert(thefile, return CORE_ERROR,);
d_assert(nbytes, return CORE_ERROR,);
if (*nbytes <= 0)
{
*nbytes = 0;
return CORE_OK;
}
bytes_read = 0;
do
{
rv = read(thefile->filedes, buf, *nbytes);
} while (rv == -1 && errno == EINTR);
*nbytes = bytes_read;
if (rv == 0)
{
thefile->eof_hit = TRUE;
return CORE_EOF;
}
if (rv > 0)
{
*nbytes += rv;
return CORE_OK;
}
return errno;
}
status_t file_write(
file_t *thefile, const void *buf, size_t *nbytes)
{
size_t rv;
d_assert(thefile, return CORE_ERROR,);
d_assert(buf, return CORE_ERROR,);
d_assert(nbytes, return CORE_ERROR,);
do
{
rv = write(thefile->filedes, buf, *nbytes);
} while (rv == (size_t)-1 && errno == EINTR);
if (rv == (size_t)-1)
{
(*nbytes) = 0;
return errno;
}
*nbytes = rv;
return CORE_OK;
}
status_t file_writev(file_t *thefile,
const struct iovec *vec, size_t nvec, size_t *nbytes)
{
#ifdef HAVE_WRITEV
status_t rv;
ssize_t bytes;
d_assert(thefile, return CORE_ERROR,);
d_assert(vec, return CORE_ERROR,);
d_assert(nvec, return CORE_ERROR,);
d_assert(nbytes, return CORE_ERROR,);
if ((bytes = writev(thefile->filedes, vec, nvec)) < 0)
{
*nbytes = 0;
rv = errno;
}
else
{
*nbytes = bytes;
rv = CORE_OK;
}
return rv;
#else
/**
* The problem with trying to output the entire iovec is that we cannot
* maintain the behaviour that a real writev would have. If we iterate
* over the iovec one at a time, we lose the atomic properties of
* writev(). The other option is to combine the entire iovec into one
* buffer that we could then send in one call to write(). This is not
* reasonable since we do not know how much data an iovec could contain.
*
* The only reasonable option, that maintains the semantics of a real
* writev(), is to only write the first iovec. Callers of file_writev()
* must deal with partial writes as they normally would. If you want to
* ensure an entire iovec is written, use file_writev_full().
*/
*nbytes = vec[0].iov_len;
return file_write(thefile, vec[0].iov_base, nbytes);
#endif
}
status_t file_read_full(file_t *thefile, void *buf,
size_t nbytes, size_t *bytes_read)
{
status_t status;
size_t total_read = 0;
d_assert(thefile, return CORE_ERROR,);
d_assert(buf, return CORE_ERROR,);
do {
size_t amt = nbytes;
status = file_read(thefile, buf, &amt);
buf = (char *)buf + amt;
nbytes -= amt;
total_read += amt;
} while (status == CORE_OK && nbytes > 0);
if (bytes_read != NULL)
*bytes_read = total_read;
return status;
}
status_t file_write_full(file_t *thefile,
const void *buf, size_t nbytes, size_t *bytes_written)
{
status_t status;
size_t total_written = 0;
d_assert(thefile, return CORE_ERROR,);
d_assert(buf, return CORE_ERROR,);
do {
size_t amt = nbytes;
status = file_write(thefile, buf, &amt);
buf = (char *)buf + amt;
nbytes -= amt;
total_written += amt;
} while (status == CORE_OK && nbytes > 0);
if (bytes_written != NULL)
*bytes_written = total_written;
return status;
}
status_t file_writev_full(file_t *thefile,
const struct iovec *vec, size_t nvec, size_t *bytes_written)
{
status_t rv = CORE_OK;
size_t i;
size_t amt = 0;
size_t total = 0;
d_assert(thefile, return CORE_ERROR,);
d_assert(vec, return CORE_ERROR,);
d_assert(nvec, return CORE_ERROR,);
d_assert(bytes_written, return CORE_ERROR,);
for (i = 0; i < nvec; i++)
{
total += vec[i].iov_len;
}
rv = file_writev(thefile, vec, nvec, &amt);
if (bytes_written != NULL)
*bytes_written = amt;
if (rv != CORE_OK || (amt == total))
{
return rv;
}
for (i = 0; i < nvec && amt; i++)
{
if (amt >= vec[i].iov_len)
{
amt -= vec[i].iov_len;
}
else
{
break;
}
}
if (amt)
{
rv = file_write_full(thefile, (const char *)vec[i].iov_base + amt,
vec[i].iov_len - amt, NULL);
}
for (; i < nvec && rv == CORE_OK; i++)
{
rv = file_write_full(thefile, vec[i].iov_base,
vec[i].iov_len, &amt);
}
if (bytes_written != NULL)
*bytes_written = total;
return rv;
}
status_t file_putc(char ch, file_t *thefile)
{
size_t nbytes = 1;
d_assert(thefile, return CORE_ERROR,);
return file_write(thefile, &ch, &nbytes);
}
status_t file_getc(char *ch, file_t *thefile)
{
size_t nbytes = 1;
d_assert(thefile, return CORE_ERROR,);
return file_read(thefile, ch, &nbytes);
}
status_t file_gets(char *str, int len, file_t *thefile)
{
status_t rv = CORE_OK; /* get rid of gcc warning */
size_t nbytes;
const char *str_start = str;
char *final = str + len - 1;
d_assert(str, return CORE_ERROR,);
d_assert(thefile, return CORE_ERROR,);
if (len <= 1)
{
/* sort of like fgets(), which returns NULL and stores no bytes
*/
return CORE_OK;
}
while (str < final)
{ /* leave room for trailing '\0' */
nbytes = 1;
rv = file_read(thefile, str, &nbytes);
if (rv != CORE_OK)
{
break;
}
if (*str == '\n')
{
++str;
break;
}
++str;
}
/* We must store a terminating '\0' if we've stored any chars. We can
* get away with storing it if we hit an error first.
*/
*str = '\0';
if (str > str_start)
{
/* we stored chars; don't report EOF or any other errors;
* the app will find out about that on the next call
*/
return CORE_OK;
}
return rv;
}
status_t file_puts(const char *str, file_t *thefile)
{
d_assert(str, return CORE_ERROR,);
d_assert(thefile, return CORE_ERROR,);
return file_write_full(thefile, str, strlen(str), NULL);
}
status_t file_sync(file_t *thefile)
{
status_t rv = CORE_OK;
d_assert(thefile, return CORE_ERROR,);
if (fsync(thefile->filedes))
{
rv = get_os_error();
}
return rv;
}
status_t file_seek(file_t *thefile,
seek_where_t where, off_t *offset)
{
off_t rv;
d_assert(thefile, return CORE_ERROR,);
d_assert(offset, return CORE_ERROR,);
thefile->eof_hit = 0;
rv = lseek(thefile->filedes, *offset, where);
if (rv == -1)
{
*offset = -1;
return errno;
}
else
{
*offset = rv;
return CORE_OK;
}
}
status_t file_name_get(const char **fname, file_t *thefile)
{
d_assert(fname, return CORE_ERROR,);
d_assert(thefile, return CORE_ERROR,);
*fname = thefile->fname;
return CORE_OK;
}
status_t file_perms_set(const char *fname, file_perms_t perms)
{
mode_t mode = unix_perms2mode(perms);
d_assert(fname, return CORE_ERROR,);
if (chmod(fname, mode) == -1)
return errno;
return CORE_OK;
}
status_t file_attrs_set(const char *fname,
file_attrs_t attributes, file_attrs_t attr_mask)
{
status_t status;
file_info_t finfo;
d_assert(fname, return CORE_ERROR,);
/* Don't do anything if we can't handle the requested attributes */
if (!(attr_mask & (ATTR_READONLY | ATTR_EXECUTABLE)))
return CORE_OK;
status = file_stat(&finfo, fname, FILE_INFO_PROT);
if (status)
return status;
/* ### TODO: should added bits be umask'd? */
if (attr_mask & ATTR_READONLY)
{
if (attributes & ATTR_READONLY)
{
finfo.protection &= ~FILE_UWRITE;
finfo.protection &= ~FILE_GWRITE;
finfo.protection &= ~FILE_WWRITE;
}
else
{
/* ### umask this! */
finfo.protection |= FILE_UWRITE;
finfo.protection |= FILE_GWRITE;
finfo.protection |= FILE_WWRITE;
}
}
if (attr_mask & ATTR_EXECUTABLE)
{
if (attributes & ATTR_EXECUTABLE)
{
/* ### umask this! */
finfo.protection |= FILE_UEXECUTE;
finfo.protection |= FILE_GEXECUTE;
finfo.protection |= FILE_WEXECUTE;
}
else
{
finfo.protection &= ~FILE_UEXECUTE;
finfo.protection &= ~FILE_GEXECUTE;
finfo.protection &= ~FILE_WEXECUTE;
}
}
return file_perms_set(fname, finfo.protection);
}
status_t file_mtime_set(const char *fname, c_time_t mtime)
{
status_t status;
file_info_t finfo;
d_assert(fname, return CORE_ERROR,);
status = file_stat(&finfo, fname, FILE_INFO_ATIME);
if (status)
{
return status;
}
#ifdef HAVE_UTIMES
{
struct timeval tvp[2];
tvp[0].tv_sec = time_sec(finfo.atime);
tvp[0].tv_usec = time_usec(finfo.atime);
tvp[1].tv_sec = time_sec(mtime);
tvp[1].tv_usec = time_usec(mtime);
if (utimes(fname, tvp) == -1)
{
return errno;
}
}
#elif defined(HAVE_UTIME)
{
struct utimbuf buf;
buf.actime = (time_t) (finfo.atime / USEC_PER_SEC);
buf.modtime = (time_t) (mtime / USEC_PER_SEC);
if (utime(fname, &buf) == -1)
{
return errno;
}
}
#else
return CORE_ENOTIMPL;
#endif
return CORE_OK;
}
status_t dir_make(const char *path, file_perms_t perm)
{
mode_t mode = unix_perms2mode(perm);
d_assert(path, return CORE_ERROR,);
if (mkdir(path, mode) == 0)
{
return CORE_OK;
}
else
{
return errno;
}
}
#define PATH_SEPARATOR '/'
/* Remove trailing separators that don't affect the meaning of PATH. */
static void path_canonicalize (char *dir)
{
d_assert(dir, return,);
/* At some point this could eliminate redundant components. For
* now, it just makes sure there is no trailing slash. */
size_t len = strlen (dir);
size_t orig_len = len;
while ((len > 0) && (dir[len - 1] == PATH_SEPARATOR))
len--;
if (len != orig_len)
dir[len] = 0;
}
/* Remove one component off the end of PATH. */
void path_remove_last_component (char *dir, const char *path)
{
int i;
int len = 0;
d_assert(dir, return,);
d_assert(path, return,);
strcpy(dir, path);
path_canonicalize (dir);
for (i = (strlen(dir) - 1); i >= 0; i--) {
if (path[i] == PATH_SEPARATOR)
break;
}
len = (i < 0) ? 0 : i;
dir[len] = 0;
}
status_t dir_make_recursive(const char *path, file_perms_t perm)
{
status_t err = 0;
d_assert(path, return CORE_ERROR,);
err = dir_make(path, perm); /* Try to make PATH right out */
if (err == EEXIST) /* It's OK if PATH exists */
return CORE_OK;
if (err == ENOENT) /* Missing an intermediate dir */
{
char dir[MAX_DIRNAME_SIZE];
path_remove_last_component(dir, path);
/* If there is no path left, give up. */
if (dir[0] == '\0')
{
return err;
}
err = dir_make_recursive(dir, perm);
if (!err)
err = dir_make (path, perm);
}
return err;
}
status_t dir_remove(const char *path)
{
d_assert(path, return CORE_ERROR,);
if (rmdir(path) == 0)
{
return CORE_OK;
}
else {
return errno;
}
}
static filetype_e filetype_from_mode(mode_t mode)
{
filetype_e type;
switch (mode & S_IFMT)
{
case S_IFREG:
type = FILE_REG; break;
case S_IFDIR:
type = FILE_DIR; break;
case S_IFLNK:
type = FILE_LNK; break;
case S_IFCHR:
type = FILE_CHR; break;
case S_IFBLK:
type = FILE_BLK; break;
#if defined(S_IFFIFO)
case S_IFFIFO:
type = FILE_PIPE; break;
#endif
#if !defined(BEOS) && defined(S_IFSOCK)
case S_IFSOCK:
type = FILE_SOCK; break;
#endif
default:
/* Work around missing S_IFxxx values above
* for Linux et al.
*/
#if !defined(S_IFFIFO) && defined(S_ISFIFO)
if (S_ISFIFO(mode))
{
type = FILE_PIPE;
}
else
#endif
#if !defined(BEOS) && !defined(S_IFSOCK) && defined(S_ISSOCK)
if (S_ISSOCK(mode))
{
type = FILE_SOCK;
} else
#endif
type = FILE_UNKFILE;
}
return type;
}
static void fill_out_finfo(file_info_t *finfo, struct_stat *info,
c_int32_t wanted)
{
d_assert(finfo, return,);
d_assert(info, return,);
finfo->valid = FILE_INFO_MIN | FILE_INFO_IDENT | FILE_INFO_NLINK
| FILE_INFO_OWNER | FILE_INFO_PROT;
finfo->protection = unix_mode2perms(info->st_mode);
finfo->filetype = filetype_from_mode(info->st_mode);
finfo->user = info->st_uid;
finfo->group = info->st_gid;
finfo->size = info->st_size;
finfo->device = info->st_dev;
finfo->nlink = info->st_nlink;
/* Check for overflow if storing a 64-bit st_ino in a 32-bit
* ino_t for LFS builds: */
if (sizeof(ino_t) >= sizeof(info->st_ino)
|| (ino_t)info->st_ino == info->st_ino)
{
finfo->inode = info->st_ino;
} else
{
finfo->valid &= ~FILE_INFO_INODE;
}
time_ansi_put(&finfo->atime, info->st_atime);
#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
finfo->atime += info->st_atim.tv_nsec / TIME_C(1000);
#elif defined(HAVE_STRUCT_STAT_ST_ATIMENSEC)
finfo->atime += info->st_atimensec / TIME_C(1000);
#elif defined(HAVE_STRUCT_STAT_ST_ATIME_N)
finfo->ctime += info->st_atime_n / TIME_C(1000);
#endif
time_ansi_put(&finfo->mtime, info->st_mtime);
#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
finfo->mtime += info->st_mtim.tv_nsec / TIME_C(1000);
#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
finfo->mtime += info->st_mtimensec / TIME_C(1000);
#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
finfo->ctime += info->st_mtime_n / TIME_C(1000);
#endif
time_ansi_put(&finfo->ctime, info->st_ctime);
#ifdef HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC
finfo->ctime += info->st_ctim.tv_nsec / TIME_C(1000);
#elif defined(HAVE_STRUCT_STAT_ST_CTIMENSEC)
finfo->ctime += info->st_ctimensec / TIME_C(1000);
#elif defined(HAVE_STRUCT_STAT_ST_CTIME_N)
finfo->ctime += info->st_ctime_n / TIME_C(1000);
#endif
#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
#ifdef DEV_BSIZE
finfo->csize = (off_t)info->st_blocks * (off_t)DEV_BSIZE;
#else
finfo->csize = (off_t)info->st_blocks * (off_t)512;
#endif
finfo->valid |= FILE_INFO_CSIZE;
#endif
}
status_t file_info_get(file_info_t *finfo,
c_int32_t wanted, file_t *thefile)
{
struct_stat info;
d_assert(finfo, return CORE_ERROR,);
d_assert(thefile, return CORE_ERROR,);
if (fstat(thefile->filedes, &info) == 0)
{
strcpy(finfo->fname, thefile->fname);
fill_out_finfo(finfo, &info, wanted);
return (wanted & ~finfo->valid) ? CORE_INCOMPLETE : CORE_OK;
}
else {
return errno;
}
}
status_t file_trunc(file_t *fp, off_t offset)
{
d_assert(fp, return CORE_ERROR,);
if (ftruncate(fp->filedes, offset) == -1)
{
return errno;
}
return file_seek(fp, FILE_SET, &offset);
}
c_int32_t file_flags_get(file_t *f)
{
d_assert(f, return CORE_ERROR,);
return f->flags;
}
status_t file_stat(file_info_t *finfo,
const char *fname, c_int32_t wanted)
{
struct_stat info;
int srv;
d_assert(finfo, return CORE_ERROR,);
d_assert(fname, return CORE_ERROR,);
if (wanted & FILE_INFO_LINK)
srv = lstat(fname, &info);
else
srv = stat(fname, &info);
if (srv == 0)
{
strcpy(finfo->fname, fname);
fill_out_finfo(finfo, &info, wanted);
if (wanted & FILE_INFO_LINK)
wanted &= ~FILE_INFO_LINK;
return (wanted & ~finfo->valid) ? CORE_INCOMPLETE : CORE_OK;
}
else
{
#if !defined(ENOENT) || !defined(ENOTDIR)
#error ENOENT || ENOTDIR not defined; please see the
#error comments at this line in the source for a workaround.
/*
* If ENOENT || ENOTDIR is not defined in one of the your OS's
* include files, CORE cannot report a good reason why the stat()
* of the file failed; there are cases where it can fail even though
* the file exists. This opens holes in Apache, for example, because
* it becomes possible for someone to get a directory listing of a
* directory even though there is an index (eg. index.html) file in
* it. If you do not have a problem with this, delete the above
* #error lines and start the compile again. If you need to do this,
* please submit a bug report to http://www.apache.org/bug_report.html
* letting us know that you needed to do this. Please be sure to
* include the operating system you are using.
*/
/* WARNING: All errors will be handled as not found
*/
#if !defined(ENOENT)
return CORE_ENOENT;
#else
/* WARNING: All errors but not found will be handled as not directory
*/
if (errno != ENOENT)
return CORE_ENOENT;
else
return errno;
#endif
#else /* All was defined well, report the usual: */
return errno;
#endif
}
}
status_t temp_dir_get(char *temp_dir)
{
d_assert(temp_dir, return CORE_ERROR,);
strcpy(temp_dir, "/tmp");
return CORE_OK;
}
nextepc-0.3.10/lib/core/src/unix/mutex.c 0000664 0000000 0000000 00000005064 13335533574 0020037 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _mutex
#include "core.h"
#include "core_arch_mutex.h"
#include "core_errno.h"
#include "core_param.h"
#include "core_general.h"
#include "core_debug.h"
#include "core_pool.h"
pool_declare(mutex_pool, mutex_t, MAX_NUM_OF_MUTEX);
status_t mutex_init(void)
{
pool_init_wo_lock(&mutex_pool, MAX_NUM_OF_MUTEX);
return CORE_OK;
}
status_t mutex_final(void)
{
if (pool_size(&mutex_pool) != pool_avail(&mutex_pool))
d_error("%d not freed in mutex_pool[%d]",
pool_size(&mutex_pool) - pool_avail(&mutex_pool),
pool_size(&mutex_pool));
d_trace(9, "%d not freed in mutex_pool[%d]\n",
pool_size(&mutex_pool) - pool_avail(&mutex_pool),
pool_size(&mutex_pool));
pool_final(&mutex_pool);
return CORE_OK;
}
status_t mutex_create(mutex_id *id, unsigned int flags)
{
mutex_t *new_mutex;
status_t rv;
pool_alloc_node(&mutex_pool, &new_mutex);
d_assert(new_mutex, return CORE_ENOMEM,
"mutex_pool(%d) is not enough"
"(new_mutex=%p, mut:%p, avail:%d,size:%d,head:%d,tail:%d \n",
MAX_NUM_OF_MUTEX,
new_mutex, mutex_pool.mut,
mutex_pool.avail, mutex_pool.size,
mutex_pool.head, mutex_pool.tail);
if (flags & MUTEX_NESTED)
{
pthread_mutexattr_t mattr;
rv = pthread_mutexattr_init(&mattr);
if (rv) return rv;
rv = pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE);
if (rv)
{
pthread_mutexattr_destroy(&mattr);
return rv;
}
rv = pthread_mutex_init(&new_mutex->mutex, &mattr);
pthread_mutexattr_destroy(&mattr);
} else
rv = pthread_mutex_init(&new_mutex->mutex, NULL);
if (rv)
{
return rv;
}
*id = (mutex_id)new_mutex;
return CORE_OK;
}
status_t mutex_lock(mutex_id id)
{
status_t rv;
mutex_t *mutex = (mutex_t *)id;
rv = pthread_mutex_lock(&mutex->mutex);
return rv;
}
status_t mutex_trylock(mutex_id id)
{
status_t rv;
mutex_t *mutex = (mutex_t *)id;
rv = pthread_mutex_trylock(&mutex->mutex);
if (rv)
{
return (rv == EBUSY) ? CORE_EBUSY : rv;
}
return CORE_OK;
}
status_t mutex_unlock(mutex_id id)
{
status_t rv;
mutex_t *mutex = (mutex_t *)id;
rv = pthread_mutex_unlock(&mutex->mutex);
return rv;
}
status_t mutex_delete(mutex_id id)
{
status_t rv;
mutex_t *mutex = (mutex_t *)id;
rv = pthread_mutex_destroy(&mutex->mutex);
pool_free_node(&mutex_pool, mutex);
return rv;
}
nextepc-0.3.10/lib/core/src/unix/pkbuf.c 0000664 0000000 0000000 00000041154 13335533574 0020004 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _pkbuf
#include "core.h"
#include "core_pkbuf.h"
#include "core_errno.h"
#include "core_lib.h"
#include "core_debug.h"
#include "core_pool.h"
#define MAX_NUM_OF_CLBUF 256
#define MAX_NUM_OF_PKBUF 256
pool_declare(clbuf_pool, clbuf_t, MAX_NUM_OF_CLBUF);
pool_declare(pkbuf_pool, pkbuf_t, MAX_NUM_OF_PKBUF);
#undef BOUNDARY
#define BOUNDARY SIZEOF_VOIDP
#define SIZEOF_CLUSTER_128 CORE_ALIGN(128+MAX_SIZEOF_HEADROOM, BOUNDARY)
#define SIZEOF_CLUSTER_256 CORE_ALIGN(256+MAX_SIZEOF_HEADROOM, BOUNDARY)
#define SIZEOF_CLUSTER_512 CORE_ALIGN(512+MAX_SIZEOF_HEADROOM, BOUNDARY)
#define SIZEOF_CLUSTER_1024 CORE_ALIGN(1024+MAX_SIZEOF_HEADROOM, BOUNDARY)
#define SIZEOF_CLUSTER_2048 CORE_ALIGN(2048+MAX_SIZEOF_HEADROOM, BOUNDARY)
#define SIZEOF_CLUSTER_8192 CORE_ALIGN(8192+MAX_SIZEOF_HEADROOM, BOUNDARY)
#define MAX_NUM_OF_CLUSTER_128 256
#define MAX_NUM_OF_CLUSTER_256 256
#define MAX_NUM_OF_CLUSTER_512 256
#define MAX_NUM_OF_CLUSTER_1024 256
#define MAX_NUM_OF_CLUSTER_2048 256
#define MAX_NUM_OF_CLUSTER_8192 256
typedef c_uint8_t cluster_128_t[SIZEOF_CLUSTER_128];
typedef c_uint8_t cluster_256_t[SIZEOF_CLUSTER_256];
typedef c_uint8_t cluster_512_t[SIZEOF_CLUSTER_512];
typedef c_uint8_t cluster_1024_t[SIZEOF_CLUSTER_1024];
typedef c_uint8_t cluster_2048_t[SIZEOF_CLUSTER_2048];
typedef c_uint8_t cluster_8192_t[SIZEOF_CLUSTER_8192];
pool_declare(cluster_128_pool, cluster_128_t, MAX_NUM_OF_CLUSTER_128);
pool_declare(cluster_256_pool, cluster_256_t, MAX_NUM_OF_CLUSTER_256);
pool_declare(cluster_512_pool, cluster_512_t, MAX_NUM_OF_CLUSTER_512);
pool_declare(cluster_1024_pool, cluster_1024_t, MAX_NUM_OF_CLUSTER_1024);
pool_declare(cluster_2048_pool, cluster_2048_t, MAX_NUM_OF_CLUSTER_2048);
pool_declare(cluster_8192_pool, cluster_8192_t, MAX_NUM_OF_CLUSTER_8192);
static mutex_id mutex;
status_t pkbuf_init(void)
{
mutex_create(&mutex, MUTEX_DEFAULT);
pool_init(&clbuf_pool, MAX_NUM_OF_CLBUF);
pool_init(&pkbuf_pool, MAX_NUM_OF_PKBUF);
pool_init(&cluster_128_pool, MAX_NUM_OF_CLUSTER_128);
pool_init(&cluster_256_pool, MAX_NUM_OF_CLUSTER_256);
pool_init(&cluster_512_pool, MAX_NUM_OF_CLUSTER_512);
pool_init(&cluster_1024_pool, MAX_NUM_OF_CLUSTER_1024);
pool_init(&cluster_2048_pool, MAX_NUM_OF_CLUSTER_2048);
pool_init(&cluster_8192_pool, MAX_NUM_OF_CLUSTER_8192);
return CORE_OK;
}
status_t pkbuf_final(void)
{
pkbuf_show();
pool_final(&clbuf_pool);
pool_final(&pkbuf_pool);
pool_final(&cluster_128_pool);
pool_final(&cluster_256_pool);
pool_final(&cluster_512_pool);
pool_final(&cluster_1024_pool);
pool_final(&cluster_2048_pool);
pool_final(&cluster_8192_pool);
mutex_delete(mutex);
return CORE_OK;
}
void pkbuf_show(void)
{
if (pool_used(&pkbuf_pool))
d_error("%d not freed in pkbuf_pool[%d]",
pool_used(&pkbuf_pool), pool_size(&pkbuf_pool));
d_trace(9, "%d not freed in pkbuf_pool[%d]\n",
pool_used(&pkbuf_pool), pool_size(&pkbuf_pool));
if (pool_used(&clbuf_pool))
d_error("%d not freed in clbuf_pool[%d]",
pool_used(&clbuf_pool), pool_size(&clbuf_pool));
d_trace(9, "%d not freed in clbuf_pool[%d]\n",
pool_used(&clbuf_pool), pool_size(&clbuf_pool));
if (pool_used(&cluster_128_pool))
d_error("%d not freed in cluster128_pool[%d]",
pool_used(&cluster_128_pool), pool_size(&cluster_128_pool));
d_trace(9, "%d not freed in cluster128_pool[%d]\n",
pool_used(&cluster_128_pool), pool_size(&cluster_128_pool));
if (pool_used(&cluster_256_pool))
d_error("%d not freed in cluster256_pool[%d]",
pool_used(&cluster_256_pool), pool_size(&cluster_256_pool));
d_trace(9, "%d not freed in cluster256_pool[%d]\n",
pool_used(&cluster_256_pool), pool_size(&cluster_256_pool));
if (pool_used(&cluster_512_pool))
d_error("%d not freed in cluster512_pool[%d]",
pool_used(&cluster_512_pool), pool_size(&cluster_512_pool));
d_trace(9, "%d not freed in cluster512_pool[%d]\n",
pool_used(&cluster_512_pool), pool_size(&cluster_512_pool));
if (pool_used(&cluster_1024_pool))
d_error("%d not freed in cluster1024_pool[%d]",
pool_used(&cluster_1024_pool), pool_size(&cluster_1024_pool));
d_trace(9, "%d not freed in cluster1024_pool[%d]\n",
pool_used(&cluster_1024_pool), pool_size(&cluster_1024_pool));
if (pool_used(&cluster_2048_pool))
d_error("%d not freed in cluster2048_pool[%d]",
pool_used(&cluster_2048_pool), pool_size(&cluster_2048_pool));
d_trace(9, "%d not freed in cluster2048_pool[%d]\n",
pool_used(&cluster_2048_pool), pool_size(&cluster_2048_pool));
if (pool_used(&cluster_8192_pool))
d_error("%d not freed in cluster8192_pool[%d]",
pool_used(&cluster_8192_pool), pool_size(&cluster_8192_pool));
d_trace(9, "%d not freed in cluster8192_pool[%d]\n",
pool_used(&cluster_8192_pool), pool_size(&cluster_8192_pool));
}
static clbuf_t* clbuf_alloc(c_uint16_t length);
static void clbuf_free(clbuf_t *clbuf);
static clbuf_t* clbuf_alloc(c_uint16_t length)
{
clbuf_t *clbuf = NULL;
c_uint8_t *cluster = NULL;
pool_alloc_node(&clbuf_pool, &clbuf);
d_assert(clbuf, return NULL, "No more free clbuf. ");
if (length <= 128)
{
pool_alloc_node(&cluster_128_pool, &cluster);
clbuf->size = SIZEOF_CLUSTER_128;
}
else if (length <= 256)
{
pool_alloc_node(&cluster_256_pool, &cluster);
clbuf->size = SIZEOF_CLUSTER_256;
}
else if (length <= 512)
{
pool_alloc_node(&cluster_512_pool, &cluster);
clbuf->size = SIZEOF_CLUSTER_512;
}
else if (length <= 1024)
{
pool_alloc_node(&cluster_1024_pool, &cluster);
clbuf->size = SIZEOF_CLUSTER_1024;
}
else if (length <= 2048)
{
pool_alloc_node(&cluster_2048_pool, &cluster);
clbuf->size = SIZEOF_CLUSTER_2048;
}
else if (length <= 8192)
{
pool_alloc_node(&cluster_8192_pool, &cluster);
clbuf->size = SIZEOF_CLUSTER_8192;
}
d_assert(cluster, pool_free_node(&clbuf_pool, clbuf); return NULL,
"No more free cluster. length:%d requested", length);
clbuf->ref = 0;
clbuf->cluster = cluster;
return clbuf;
}
static void clbuf_free(clbuf_t *clbuf)
{
d_assert(clbuf, return, "Null param");
d_assert(clbuf->cluster, return, "clbuf has no cluster");
switch (clbuf->size)
{
case SIZEOF_CLUSTER_128:
pool_free_node(&cluster_128_pool, clbuf->cluster);
break;
case SIZEOF_CLUSTER_256:
pool_free_node(&cluster_256_pool, clbuf->cluster);
break;
case SIZEOF_CLUSTER_512:
pool_free_node(&cluster_512_pool, clbuf->cluster);
break;
case SIZEOF_CLUSTER_1024:
pool_free_node(&cluster_1024_pool, clbuf->cluster);
break;
case SIZEOF_CLUSTER_2048:
pool_free_node(&cluster_2048_pool, clbuf->cluster);
break;
case SIZEOF_CLUSTER_8192:
pool_free_node(&cluster_8192_pool, clbuf->cluster);
break;
default:
d_assert(0, return, "clbuf has invalid size %d", clbuf->size);
break;
}
pool_free_node(&clbuf_pool, clbuf);
return;
}
pkbuf_t* pkbuf_alloc(c_uint16_t headroom, c_uint16_t length)
{
pkbuf_t *np = NULL, *pnp, *ret;
clbuf_t *clbuf = NULL;
c_uint16_t rem_length;
d_assert(headroom <= MAX_SIZEOF_HEADROOM, return NULL,
"Max size of headroom is %d, but %d requested",
MAX_SIZEOF_HEADROOM, headroom);
clbuf = clbuf_alloc(length);
d_assert(clbuf, return NULL, "Can't allocate clbuf(length:%d)", length);
pool_alloc_node(&pkbuf_pool, &np);
d_assert(np, clbuf_free(clbuf); return NULL, "No more free pkbuf");
ret = np;
np->next = NULL;
np->clbuf = clbuf;
np->payload = (void*)CORE_ALIGN((c_uintptr_t)(clbuf->cluster + headroom),
BOUNDARY);
np->tot_len = length;
np->len = c_min(length, clbuf->size - (np->payload - clbuf->cluster));
np->flags = 0;
clbuf->ref = 1;
pnp = np;
rem_length = length - np->len;
while (rem_length > 0)
{
clbuf = clbuf_alloc(rem_length);
d_assert(clbuf, break, "Can't allocate clbuf");
pool_alloc_node(&pkbuf_pool, &np);
d_assert(np, clbuf_free(clbuf); break, "No more free pkbuf");
/* Chaining */
pnp->next = np;
np->next = NULL;
np->clbuf = clbuf;
np->payload = clbuf->cluster;
np->tot_len = rem_length;
np->len = c_min(rem_length, clbuf->size);
np->flags = 0;
clbuf->ref = 1;
pnp = np;
rem_length -= np->len;
}
/* Abnormal break */
if (rem_length > 0)
{
if (ret)
pkbuf_free(ret);
ret = NULL;
}
return ret;
}
status_t pkbuf_header(pkbuf_t *pkbuf, c_int16_t increment)
{
clbuf_t *clbuf;
d_assert(pkbuf, return CORE_ERROR, "Null param");
d_assert(pkbuf->clbuf, return CORE_ERROR, "pkbuf has no clbuf");
d_assert(pkbuf->clbuf->cluster, return CORE_ERROR, "clbuf has no cluster");
clbuf = pkbuf->clbuf;
/* No change */
if (increment == 0)
return CORE_OK;
if (increment > 0)
{
if (pkbuf->payload - clbuf->cluster < increment)
return CORE_ERROR;
}
else
{
if (pkbuf->len < -increment)
return CORE_ERROR;
}
pkbuf->payload -= increment;
pkbuf->tot_len += increment;
pkbuf->len += increment;
return CORE_OK;
}
void pkbuf_free(pkbuf_t *pkbuf)
{
pkbuf_t *p, *q;
d_assert(pkbuf, return, "Null param");
p = pkbuf;
while (p)
{
d_assert(p->clbuf, return, "param 'pkbuf' has no clbuf");
q = p->next;
mutex_lock(mutex);
p->clbuf->ref--;
mutex_unlock(mutex);
if (p->clbuf->ref == 0)
clbuf_free(p->clbuf);
pool_free_node(&pkbuf_pool, p);
p = q;
}
return;
}
void pkbuf_join(pkbuf_t *h, pkbuf_t *t)
{
pkbuf_t *p;
d_assert(h, return, "Null param");
d_assert(t, return, "Null param");
/* proceed to last pbuf of chain */
for (p = h; p->next != NULL; p = p->next)
{
/* add total length of second chain to all totals of first chain */
p->tot_len += t->tot_len;
}
d_assert(p->tot_len == p->len, return,
"p->tot_len(%d) == p->len(%d) (of last pbuf in chain)",
p->tot_len, p->len);
d_assert(p->next == NULL, return, "p->next == NULL");
/* add total length of second chain to last pbuf total of first chain */
p->tot_len += t->tot_len;
/* chain last pbuf of head (p) with first of tail (t) */
p->next = t;
/* p->next now references t, but the caller will drop its reference to t,
* so netto there is no change to the reference count of t. */
}
pkbuf_t* pkbuf_copy(pkbuf_t *pkbuf)
{
pkbuf_t *p, *np, *pnp = NULL, *ret = NULL;
d_assert(pkbuf, return NULL, "Null param");
p = pkbuf;
while (p)
{
pool_alloc_node(&pkbuf_pool, &np);
d_assert(np, break, "No more free pkbuf. ");
if (ret == NULL) ret = np;
if (pnp)
pnp->next = np;
np->next = NULL;
np->clbuf = p->clbuf;
np->payload = p->payload;
np->tot_len = p->tot_len;
np->len = p->len;
np->flags = p->flags;
mutex_lock(mutex);
p->clbuf->ref++;
mutex_unlock(mutex);
pnp = np;
p = p->next;
}
/* Abnormal break */
if (p)
{
if (ret)
pkbuf_free(ret);
ret = NULL;
}
return ret;
}
pkbuf_t* pkbuf_copy_partial(pkbuf_t *pkbuf, c_uint16_t offset, c_uint16_t len)
{
pkbuf_t *p, *np, *pnp = NULL, *ret = NULL;
c_uint16_t copied = 0, bytes = 0, skipped = 0;
d_assert(pkbuf, return NULL, "Null param");
if (pkbuf->tot_len < offset + len)
return NULL;
p = pkbuf;
while (p)
{
bytes += p->len;
if (bytes > offset)
{
pool_alloc_node(&pkbuf_pool, &np);
d_assert(np, break, "No more free pkbuf. ");
/* First block */
if (ret == NULL)
{
ret = np;
np->payload = p->payload + (offset - skipped);
np->tot_len = len;
np->len = p->len - (offset - skipped);
}
else
{
np->payload = p->payload;
np->tot_len = pnp->tot_len - pnp->len;
np->len = p->len;
}
np->next = NULL;
np->flags = p->flags;
np->clbuf = p->clbuf;
mutex_lock(mutex);
p->clbuf->ref++;
mutex_unlock(mutex);
if (pnp)
pnp->next = np;
pnp = np;
copied += np->len;
/* Check the last block */
if (copied >= len)
{
np->len -= copied - len;
break;
}
}
skipped += p->len;
p = p->next;
}
/* Abnormal break */
if (copied < len)
{
if (ret)
pkbuf_free(ret);
ret = NULL;
}
return ret;
}
status_t pkbuf_tobuf(pkbuf_t *pkbuf, void *buf, c_uint16_t *buflen)
{
pkbuf_t *p;
c_uint16_t copied = 0;
d_assert(pkbuf, return CORE_ERROR, "Null param");
d_assert(buf, return CORE_ERROR, "Null param");
d_assert(buflen, return CORE_ERROR, "Null param");
if (pkbuf->tot_len > *buflen)
return CORE_ERROR;
*buflen = 0;
p = pkbuf;
while (p)
{
d_assert(p->clbuf, return CORE_ERROR, "pkbuf has no clbuf");
d_assert(p->clbuf->cluster, return CORE_ERROR, "clbuf has no cluster");
memcpy(buf + copied, p->payload, p->len);
copied += p->len;
p = p->next;
}
d_assert(copied == pkbuf->tot_len, return CORE_ERROR,
"Copy length isn't same with total length");
*buflen = copied;
return CORE_OK;;
}
status_t pkbuf_tobuf_partial(pkbuf_t *pkbuf, void *buf, c_uint16_t *buflen,
c_uint16_t offset, c_uint16_t len)
{
return CORE_OK;
}
void *core_malloc(size_t size)
{
c_uint16_t headroom = 0;
pkbuf_t *p = NULL;
d_assert(size, return NULL, "if size == 0, then returns NULL");
headroom = sizeof(pkbuf_t *);
p = pkbuf_alloc(headroom, size);
d_assert(p, return NULL, "pkbuf_alloc failed(headroom:%d, size:%d)",
headroom, size);
d_assert(p->next == NULL, pkbuf_free(p);return NULL,
"core_malloc should not be fragmented");
memcpy(p->payload - headroom, &p, headroom);
return p->payload;
}
status_t core_free(void *ptr)
{
c_uint16_t headroom = sizeof(pkbuf_t *);
pkbuf_t *p = NULL;
if (!ptr)
return CORE_OK;
memcpy(&p, ptr - headroom, headroom);
d_assert(p, return CORE_ERROR, "Null param");
pkbuf_free(p);
return CORE_OK;
}
void *core_calloc(size_t nmemb, size_t size)
{
void *ptr = NULL;
ptr = core_malloc(nmemb * size);
d_assert(ptr, return NULL, "nmeb = %d, sizeo = %d", nmemb, size);
memset(ptr, 0, nmemb * size);
return ptr;
}
void *core_realloc(void *ptr, size_t size)
{
c_uint16_t headroom = sizeof(pkbuf_t *);
pkbuf_t *p = NULL;
if (!ptr)
{
return core_malloc(size);
}
memcpy(&p, ptr - headroom, headroom);
d_assert(p, return NULL, "Null param");
if (!size)
{
pkbuf_free(p);
return NULL;
}
d_assert(p->clbuf, return NULL, "Null param");
if (size >= (p->clbuf->size - headroom))
{
void *new = NULL;
new = core_malloc(size);
d_assert(new, return NULL, "Null param");
memcpy(new, ptr, p->len);
pkbuf_free(p);
return new;
}
else
{
p->tot_len = size;
p->len = c_min(size, p->clbuf->size - (p->payload - p->clbuf->cluster));
return ptr;
}
}
char *core_strdup(const char *s)
{
char *res;
size_t len;
if (s == NULL)
return NULL;
len = strlen(s) + 1;
res = core_memdup(s, len);
return res;
}
char *core_strndup(const char *s, size_t n)
{
char *res;
const char *end;
if (s == NULL)
return NULL;
end = memchr(s, '\0', n);
if (end != NULL)
n = end - s;
res = core_malloc(n + 1);
memcpy(res, s, n);
res[n] = '\0';
return res;
}
void *core_memdup(const void *m, size_t n)
{
void *res;
if (m == NULL)
return NULL;
res = core_malloc(n);
memcpy(res, m, n);
return res;
}
nextepc-0.3.10/lib/core/src/unix/rand.c 0000664 0000000 0000000 00000001630 13335533574 0017614 0 ustar 00root root 0000000 0000000 #include "core_errno.h"
#define DEV_RANDOM "/dev/urandom"
status_t core_generate_random_bytes(c_uint8_t *buf, int length)
{
int fd = -1;
/* On BSD/OS 4.1, /dev/random gives out 8 bytes at a time, then
* gives EOF, so reading 'length' bytes may require opening the
* device several times. */
do {
int rc;
if (fd == -1)
if ((fd = open(DEV_RANDOM, O_RDONLY)) == -1)
return errno;
do {
rc = read(fd, buf, length);
} while (rc == -1 && errno == EINTR);
if (rc < 0) {
int errnum = errno;
close(fd);
return errnum;
}
else if (rc == 0) {
close(fd);
fd = -1; /* force open() again */
}
else {
buf += rc;
length -= rc;
}
} while (length > 0);
close(fd);
return CORE_OK;
}
nextepc-0.3.10/lib/core/src/unix/rwlock.c 0000664 0000000 0000000 00000004004 13335533574 0020167 0 ustar 00root root 0000000 0000000 #include "core.h"
#include "core_rwlock.h"
#include "core_pool.h"
#include "core_debug.h"
#include "core_general.h"
#include "core_param.h"
typedef struct _rwlock_t {
pthread_rwlock_t rwlock;
} rwlock_t;
pool_declare(rwlock_pool, rwlock_t, MAX_NUM_OF_RWLOCK);
status_t rwlock_init(void)
{
pool_init(&rwlock_pool, MAX_NUM_OF_RWLOCK);
return CORE_OK;
}
status_t rwlock_final(void)
{
pool_final(&rwlock_pool);
return CORE_OK;
}
status_t rwlock_create(rwlock_id *id)
{
rwlock_t *new_rwlock;
status_t stat;
pool_alloc_node(&rwlock_pool, &new_rwlock);
d_assert(new_rwlock, return CORE_ENOMEM, "rwlock_pool(%d) is not enough\n",
MAX_NUM_OF_RWLOCK);
if ((stat = pthread_rwlock_init(&new_rwlock->rwlock, NULL)))
{
return stat;
}
*id = (rwlock_id)new_rwlock;
return CORE_OK;
}
status_t rwlock_rdlock(rwlock_id id)
{
status_t stat;
rwlock_t *rwlock = (rwlock_t *)id;
stat = pthread_rwlock_rdlock(&rwlock->rwlock);
return stat;
}
status_t rwlock_tryrdlock(rwlock_id id)
{
status_t stat;
rwlock_t *rwlock = (rwlock_t *)id;
stat = pthread_rwlock_tryrdlock(&rwlock->rwlock);
/* Normalize the return code. */
if (stat == EBUSY)
stat = CORE_EBUSY;
return stat;
}
status_t rwlock_wrlock(rwlock_id id)
{
status_t stat;
rwlock_t *rwlock = (rwlock_t *)id;
stat = pthread_rwlock_wrlock(&rwlock->rwlock);
return stat;
}
status_t rwlock_trywrlock(rwlock_id id)
{
status_t stat;
rwlock_t *rwlock = (rwlock_t *)id;
stat = pthread_rwlock_trywrlock(&rwlock->rwlock);
/* Normalize the return code. */
if (stat == EBUSY)
stat = CORE_EBUSY;
return stat;
}
status_t rwlock_unlock(rwlock_id id)
{
status_t stat;
rwlock_t *rwlock = (rwlock_t *)id;
stat = pthread_rwlock_unlock(&rwlock->rwlock);
return stat;
}
status_t rwlock_delete(rwlock_id id)
{
status_t stat;
rwlock_t *rwlock = (rwlock_t *)id;
stat = pthread_rwlock_destroy(&rwlock->rwlock);
return stat;
}
nextepc-0.3.10/lib/core/src/unix/sctp.c 0000664 0000000 0000000 00000026326 13335533574 0017652 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _sctp
#include "core_debug.h"
#include "core_arch_network.h"
#if HAVE_NETINET_SCTP_H
#include
#endif
static status_t subscribe_to_events(sock_id id);
static status_t set_paddrparams(sock_id id, c_uint32_t spp_hbinterval);
static status_t set_rtoinfo(sock_id id,
c_uint32_t srto_initial, c_uint32_t srto_min, c_uint32_t srto_max);
static status_t set_initmsg(sock_id id,
c_uint32_t sinit_num_ostreams, c_uint32_t sinit_max_instreams,
c_uint32_t sinit_max_attempts, c_uint32_t sinit_max_init_timeo);
static int sctp_num_ostreams = -1;
void sctp_set_num_ostreams(int sctp_streams)
{
sctp_num_ostreams = sctp_streams;
}
status_t sctp_socket(sock_id *new, int family, int type)
{
status_t rv;
rv = sock_socket(new, family, type, IPPROTO_SCTP);
d_assert(rv == CORE_OK, return CORE_ERROR,);
rv = subscribe_to_events(*new);
d_assert(rv == CORE_OK, return CORE_ERROR,);
/* heartbit interval : 5 secs */
rv = set_paddrparams(*new, 5000);
d_assert(rv == CORE_OK, return CORE_ERROR,);
/*
* RTO info
*
* initial : 3 secs
* min : 1 sec
* max : 5 secs
*/
rv = set_rtoinfo(*new, 3000, 1000, 5000);
d_assert(rv == CORE_OK, return CORE_ERROR,);
/*
* INITMSG
*
* max number of input streams : 65535
* max attemtps : 4
* max initial timeout : 8 secs
*/
rv = set_initmsg(*new, sctp_num_ostreams, 65535, 4, 8000);
d_assert(rv == CORE_OK, return CORE_ERROR,);
return CORE_OK;
}
status_t sctp_server(sock_id *new, int type, c_sockaddr_t *sa_list)
{
status_t rv;
c_sockaddr_t *addr;
char buf[CORE_ADDRSTRLEN];
addr = sa_list;
while(addr)
{
rv = sctp_socket(new, addr->c_sa_family, type);
if (rv == CORE_OK)
{
d_assert(sock_setsockopt(*new, SOCK_O_REUSEADDR, 1) == CORE_OK,
return CORE_ERROR,
"setsockopt [%s]:%d failed(%d:%s)",
CORE_ADDR(addr, buf), CORE_PORT(addr),
errno, strerror(errno));
if (sock_bind(*new, addr) == CORE_OK)
{
d_trace(1, "sctp_server() [%s]:%d\n",
CORE_ADDR(addr, buf), CORE_PORT(addr));
break;
}
rv = sock_delete(*new);
d_assert(rv == CORE_OK, return CORE_ERROR,);
}
addr = addr->next;
}
if (addr == NULL)
{
d_error("sctp_server() [%s]:%d failed(%d:%s)",
CORE_ADDR(sa_list, buf), CORE_PORT(sa_list),
errno, strerror(errno));
return CORE_ERROR;
}
rv = sock_listen(*new);
d_assert(rv == CORE_OK, return CORE_ERROR,);
return CORE_OK;
}
status_t sctp_client(sock_id *new, int type, c_sockaddr_t *sa_list)
{
status_t rv;
c_sockaddr_t *addr;
char buf[CORE_ADDRSTRLEN];
addr = sa_list;
while(addr)
{
rv = sctp_socket(new, addr->c_sa_family, type);
if (rv == CORE_OK)
{
if (sock_connect(*new, addr) == CORE_OK)
{
d_trace(1, "sctp_client() [%s]:%d\n",
CORE_ADDR(addr, buf), CORE_PORT(addr));
break;
}
rv = sock_delete(*new);
d_assert(rv == CORE_OK, return CORE_ERROR,);
}
addr = addr->next;
}
if (addr == NULL)
{
d_error("sctp_client() [%s]:%d failed(%d:%s)",
CORE_ADDR(sa_list, buf), CORE_PORT(sa_list),
errno, strerror(errno));
return CORE_ERROR;
}
return CORE_OK;
}
status_t sctp_connect(sock_id id, c_sockaddr_t *sa_list)
{
c_sockaddr_t *addr;
char buf[CORE_ADDRSTRLEN];
d_assert(id, return CORE_ERROR,);
addr = sa_list;
while(addr)
{
if (sock_connect(id, addr) == CORE_OK)
{
d_trace(1, "sctp_connect() [%s]:%d\n",
CORE_ADDR(addr, buf), CORE_PORT(addr));
break;
}
addr = addr->next;
}
if (addr == NULL)
{
d_error("sctp_connect() [%s]:%d failed(%d:%s)",
CORE_ADDR(sa_list, buf), CORE_PORT(sa_list),
errno, strerror(errno));
return CORE_ERROR;
}
return CORE_OK;
}
int core_sctp_sendmsg(sock_id id, const void *msg, size_t len,
c_sockaddr_t *to, c_uint32_t ppid, c_uint16_t stream_no)
{
sock_t *sock = (sock_t *)id;
int size;
socklen_t addrlen = 0;
d_assert(id, return -1, );
if (to)
addrlen = sockaddr_len(to);
size = sctp_sendmsg(sock->fd, msg, len,
to ? &to->sa : NULL, addrlen,
htonl(ppid),
0, /* flags */
stream_no,
0, /* timetolive */
0); /* context */
if (size < 0)
{
d_error("sctp_sendmsg(len:%ld) failed(%d:%s)",
len, errno, strerror(errno));
}
return size;
}
int core_sctp_recvmsg(sock_id id, void *msg, size_t len,
c_sockaddr_t *from, sctp_info_t *sinfo, int *msg_flags)
{
sock_t *sock = (sock_t *)id;
int size;
socklen_t addrlen = sizeof(struct sockaddr_storage);
int flags = 0;
struct sctp_sndrcvinfo sndrcvinfo;
d_assert(id, return -1,);
size = sctp_recvmsg(sock->fd, msg, len,
from ? &from->sa : NULL, from ? &addrlen : NULL,
&sndrcvinfo, &flags);
if (size < 0)
{
d_error("sctp_recvmsg(%d) failed(%d:%s)",
size, errno, strerror(errno));
return size;
}
if (msg_flags)
{
*msg_flags = flags;
}
if (sinfo)
{
sinfo->ppid = ntohl(sndrcvinfo.sinfo_ppid);
sinfo->stream_no = sndrcvinfo.sinfo_stream;
}
return size;
}
int core_sctp_recvdata(sock_id id, void *msg, size_t len,
c_sockaddr_t *from, sctp_info_t *sinfo)
{
int size;
int flags = 0;
do
{
size = core_sctp_recvmsg(id, msg, len, from, sinfo, &flags);
if (size < 0)
{
d_error("core_sctp_recvdata(%d) failed(%d:%s)",
size, errno, strerror(errno));
return size;
}
if (flags & MSG_NOTIFICATION)
{
/* Nothing */
}
else if (flags & MSG_EOR)
{
break;
}
else
{
d_assert(0, return -1,);
}
} while(1);
return size;
}
static status_t subscribe_to_events(sock_id id)
{
sock_t *sock = (sock_t *)id;
struct sctp_event_subscribe event;
d_assert(id, return CORE_ERROR,);
memset(&event, 0, sizeof(event));
event.sctp_data_io_event = 1;
event.sctp_association_event = 1;
event.sctp_send_failure_event = 1;
event.sctp_shutdown_event = 1;
if (setsockopt(sock->fd, IPPROTO_SCTP, SCTP_EVENTS,
&event, sizeof( event)) != 0 )
{
d_error("Unable to subscribe to SCTP events: (%d:%s)",
errno, strerror( errno ));
return CORE_ERROR;
}
return CORE_OK;
}
static status_t set_paddrparams(sock_id id, c_uint32_t spp_hbinterval)
{
sock_t *sock = (sock_t *)id;
struct sctp_paddrparams heartbeat;
socklen_t socklen;
d_assert(id, return CORE_ERROR,);
memset(&heartbeat, 0, sizeof(heartbeat));
socklen = sizeof(heartbeat);
if (getsockopt(sock->fd, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS,
&heartbeat, &socklen) != 0 )
{
d_error("getsockopt for SCTP_PEER_ADDR failed(%d:%s)",
errno, strerror(errno));
return CORE_ERROR;
}
d_trace(3,"Old spp _flags = 0x%x hbinter = %d pathmax = %d\n",
heartbeat.spp_flags,
heartbeat.spp_hbinterval,
heartbeat.spp_pathmaxrxt);
heartbeat.spp_hbinterval = spp_hbinterval;
if (setsockopt(sock->fd, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS,
&heartbeat, sizeof( heartbeat)) != 0 )
{
d_error("setsockopt for SCTP_PEER_ADDR_PARAMS failed(%d:%s)",
errno, strerror(errno));
return CORE_ERROR;
}
d_trace(3,"New spp _flags = 0x%x hbinter = %d pathmax = %d\n",
heartbeat.spp_flags,
heartbeat.spp_hbinterval,
heartbeat.spp_pathmaxrxt);
return CORE_OK;
}
static status_t set_rtoinfo(sock_id id,
c_uint32_t srto_initial, c_uint32_t srto_min, c_uint32_t srto_max)
{
sock_t *sock = (sock_t *)id;
struct sctp_rtoinfo rtoinfo;
socklen_t socklen;
d_assert(id, return CORE_ERROR,);
memset(&rtoinfo, 0, sizeof(rtoinfo));
socklen = sizeof(rtoinfo);
if (getsockopt(sock->fd, IPPROTO_SCTP, SCTP_RTOINFO,
&rtoinfo, &socklen) != 0 )
{
d_error("getsockopt for SCTP_RTOINFO failed(%d:%s)",
errno, strerror( errno ));
return CORE_ERROR;
}
d_trace(3,"Old RTO (initial:%d max:%d min:%d)\n",
rtoinfo.srto_initial,
rtoinfo.srto_max,
rtoinfo.srto_min);
rtoinfo.srto_initial = srto_initial;
rtoinfo.srto_min = srto_min;
rtoinfo.srto_max = srto_max;
if (setsockopt(sock->fd, IPPROTO_SCTP, SCTP_RTOINFO,
&rtoinfo, sizeof(rtoinfo)) != 0 )
{
d_error("setsockopt for SCTP_RTOINFO failed(%d:%s)",
errno, strerror( errno ));
return CORE_ERROR;
}
d_trace(3,"New RTO (initial:%d max:%d min:%d)\n",
rtoinfo.srto_initial,
rtoinfo.srto_max,
rtoinfo.srto_min);
return CORE_OK;
}
static status_t set_initmsg(sock_id id,
c_uint32_t sinit_num_ostreams, c_uint32_t sinit_max_instreams,
c_uint32_t sinit_max_attempts, c_uint32_t sinit_max_init_timeo)
{
sock_t *sock = (sock_t *)id;
struct sctp_initmsg initmsg;
socklen_t socklen;
d_assert(id, return CORE_ERROR,);
d_assert(sinit_num_ostreams > 1, return CORE_ERROR,
"Invalid SCTP number of output streams = %d\n", sctp_num_ostreams);
memset(&initmsg, 0, sizeof(initmsg));
socklen = sizeof(initmsg);
if (getsockopt(sock->fd, IPPROTO_SCTP, SCTP_INITMSG,
&initmsg, &socklen) != 0 )
{
d_error("getsockopt for SCTP_INITMSG failed(%d:%s)",
errno, strerror( errno ));
return CORE_ERROR;
}
d_trace(3,"Old INITMSG (numout:%d maxin:%d maxattempt:%d maxinit_to:%d)\n",
initmsg.sinit_num_ostreams,
initmsg.sinit_max_instreams,
initmsg.sinit_max_attempts,
initmsg.sinit_max_init_timeo);
initmsg.sinit_num_ostreams = sinit_num_ostreams;
initmsg.sinit_max_instreams = sinit_max_instreams;
initmsg.sinit_max_attempts = sinit_max_attempts;
initmsg.sinit_max_init_timeo = sinit_max_init_timeo;
if (setsockopt(sock->fd, IPPROTO_SCTP, SCTP_INITMSG,
&initmsg, sizeof(initmsg)) != 0 )
{
d_error("setsockopt for SCTP_INITMSG failed(%d:%s)",
errno, strerror( errno ));
return CORE_ERROR;
}
d_trace(3,"New INITMSG (numout:%d maxin:%d maxattempt:%d maxinit_to:%d)\n",
initmsg.sinit_num_ostreams,
initmsg.sinit_max_instreams,
initmsg.sinit_max_attempts,
initmsg.sinit_max_init_timeo);
return CORE_OK;
}
nextepc-0.3.10/lib/core/src/unix/semaphore.c 0000664 0000000 0000000 00000004155 13335533574 0020660 0 ustar 00root root 0000000 0000000 #include "core.h"
#include "core_arch_semaphore.h"
#include "core_errno.h"
#include "core_param.h"
#include "core_general.h"
#include "core_debug.h"
#include "core_pool.h"
pool_declare(semaphore_pool, semaphore_t, MAX_NUM_OF_SEMAPHORE);
status_t semaphore_init(void)
{
pool_init(&semaphore_pool, MAX_NUM_OF_SEMAPHORE);
return CORE_OK;
}
status_t semaphore_final(void)
{
pool_final(&semaphore_pool);
return CORE_OK;
}
status_t semaphore_create(semaphore_id *id, c_uint32_t value)
{
semaphore_t *new_semaphore;
c_time_t now = time_now();
char semname[64];
pool_alloc_node(&semaphore_pool, &new_semaphore);
d_assert(new_semaphore, return CORE_ENOMEM,
"semaphore_pool(%d) is not enough\n",
MAX_NUM_OF_SEMAPHORE);
sprintf(semname, "/CoRe%" C_UINT64_T_HEX_FMT, now);
new_semaphore->semaphore = sem_open(semname, O_CREAT | O_EXCL, 0644, value);
if (new_semaphore->semaphore == (sem_t *)SEM_FAILED)
{
return CORE_ERROR;
}
sem_unlink(semname);
*id = (semaphore_id)new_semaphore;
return CORE_OK;
}
status_t semaphore_wait(semaphore_id id)
{
status_t rv;
semaphore_t *semaphore = (semaphore_t *)id;
rv = sem_wait(semaphore->semaphore);
return rv;
}
#if HAVE_SEM_TIMEDWAIT
status_t semaphore_timedwait(semaphore_id id, c_time_t timeout)
{
status_t rv;
c_time_t then;
struct timespec abstime;
semaphore_t *semaphore = (semaphore_t *)id;
then = time_now() + timeout;
abstime.tv_sec = time_sec(then);
abstime.tv_nsec = time_usec(then) * 1000; /* nanosesemaphores */
rv = sem_timedwait(semaphore->semaphore, &abstime);
if (rv == -1 && ETIMEDOUT == errno)
{
return CORE_TIMEUP;
}
return rv;
}
#endif
status_t semaphore_post(semaphore_id id)
{
status_t rv;
semaphore_t *semaphore = (semaphore_t *)id;
rv = sem_post(semaphore->semaphore);
return rv;
}
status_t semaphore_delete(semaphore_id id)
{
status_t rv;
semaphore_t *semaphore = (semaphore_t *)id;
rv = sem_close(semaphore->semaphore);
pool_free_node(&semaphore_pool, semaphore);
return rv;
}
nextepc-0.3.10/lib/core/src/unix/signal.c 0000664 0000000 0000000 00000016252 13335533574 0020153 0 ustar 00root root 0000000 0000000 #include "core.h"
#include "core_signal.h"
CORE_DECLARE(status_t) core_kill(pid_t pid, int signum)
{
#ifdef OS2
/* SIGTERM's don't work too well in OS/2 (only affects other EMX
* programs). CGIs may not be, esp. REXX scripts, so use a native
* call instead
*/
if (signum == SIGTERM) {
return APR_FROM_OS_ERROR(DosSendSignalException(pid,
XCPT_SIGNAL_BREAK));
}
#endif /* OS2 */
if (kill(pid, signum) == -1) {
return errno;
}
return CORE_OK;
}
#if HAVE_SIGACTION
#if defined(__NetBSD__) || defined(DARWIN)
static void avoid_zombies(int signo)
{
int exit_status;
while (waitpid(-1, &exit_status, WNOHANG) > 0) {
/* do nothing */
}
}
#endif /* DARWIN */
/*
* Replace standard signal() with the more reliable sigaction equivalent
* from W. Richard Stevens' "Advanced Programming in the UNIX Environment"
* (the version that does not automatically restart system calls).
*/
core_sigfunc_t *core_signal(int signo, core_sigfunc_t *func)
{
struct sigaction act, oact;
act.sa_handler = func;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
#ifdef SA_INTERRUPT /* SunOS */
act.sa_flags |= SA_INTERRUPT;
#endif
#if defined(__osf__) && defined(__alpha)
/* XXX jeff thinks this should be enabled whenever SA_NOCLDWAIT is defined */
/* this is required on Tru64 to cause child processes to
* disappear gracefully - XPG4 compatible
*/
if ((signo == SIGCHLD) && (func == SIG_IGN))
{
act.sa_flags |= SA_NOCLDWAIT;
}
#endif
#if defined(__NetBSD__) || defined(DARWIN)
/* ignoring SIGCHLD or leaving the default disposition doesn't avoid zombies,
* and there is no SA_NOCLDWAIT flag, so catch the signal and reap status in
* the handler to avoid zombies
*/
if ((signo == SIGCHLD) && (func == SIG_IGN))
{
act.sa_handler = avoid_zombies;
}
#endif
if (sigaction(signo, &act, &oact) < 0)
return SIG_ERR;
return oact.sa_handler;
}
#endif
static void remove_sync_sigs(sigset_t *sig_mask)
{
#ifdef SIGABRT
sigdelset(sig_mask, SIGABRT);
#endif
#ifdef SIGBUS
sigdelset(sig_mask, SIGBUS);
#endif
#ifdef SIGEMT
sigdelset(sig_mask, SIGEMT);
#endif
#ifdef SIGFPE
sigdelset(sig_mask, SIGFPE);
#endif
#ifdef SIGILL
sigdelset(sig_mask, SIGILL);
#endif
#ifdef SIGIOT
sigdelset(sig_mask, SIGIOT);
#endif
#ifdef SIGPIPE
sigdelset(sig_mask, SIGPIPE);
#endif
#ifdef SIGSEGV
sigdelset(sig_mask, SIGSEGV);
#endif
#ifdef SIGSYS
sigdelset(sig_mask, SIGSYS);
#endif
#ifdef SIGTRAP
sigdelset(sig_mask, SIGTRAP);
#endif
#ifdef SIGCHLD
sigdelset(sig_mask, SIGCHLD);
#endif
#ifdef SIGWINCH
sigdelset(sig_mask, SIGWINCH);
#endif
/* the rest of the signals removed from the mask in this function
* absolutely must be removed; you cannot block synchronous signals
* (requirement of pthreads API)
*
* SIGUSR2 is being removed from the mask for the convenience of
* Purify users (Solaris, HP-UX, SGI) since Purify uses SIGUSR2
*/
#ifdef SIGUSR2
sigdelset(sig_mask, SIGUSR2);
#endif
}
status_t signal_thread(int (*signal_handler)(int signum))
{
sigset_t sig_mask;
int (*sig_func)(int signum) = (int (*)(int))signal_handler;
/* This thread will be the one responsible for handling signals */
sigfillset(&sig_mask);
/* On certain platforms, sigwait() returns EINVAL if any of various
* unblockable signals are included in the mask. This was first
* observed on AIX and Tru64.
*/
#ifdef SIGKILL
sigdelset(&sig_mask, SIGKILL);
#endif
#ifdef SIGSTOP
sigdelset(&sig_mask, SIGSTOP);
#endif
#ifdef SIGCONT
sigdelset(&sig_mask, SIGCONT);
#endif
#ifdef SIGWAITING
sigdelset(&sig_mask, SIGWAITING);
#endif
/* no synchronous signals should be in the mask passed to sigwait() */
remove_sync_sigs(&sig_mask);
/* On AIX (4.3.3, at least), sigwait() won't wake up if the high-
* order bit of the second word of flags is turned on. sigdelset()
* returns an error when trying to turn this off, so we'll turn it
* off manually.
*
* Note that the private fields differ between 32-bit and 64-bit
* and even between _ALL_SOURCE and !_ALL_SOURCE. Except that on
* AIX 4.3 32-bit builds and 64-bit builds use the same definition.
*
* Applicable AIX fixes such that this is no longer needed:
*
* APAR IY23096 for AIX 51B, fix included in AIX 51C, and
* APAR IY24162 for 43X.
*/
#if defined(_AIX)
#if defined(__64BIT__) && defined(_AIXVERSION_510)
#ifdef _ALL_SOURCE
sig_mask.ss_set[3] &= 0x7FFFFFFF;
#else /* not _ALL_SOURCE */
sig_mask.__ss_set[3] &= 0x7FFFFFFF;
#endif
#else /* not 64-bit build, or 64-bit build on 4.3 */
#ifdef _ALL_SOURCE
sig_mask.hisigs &= 0x7FFFFFFF;
#else /* not _ALL_SOURCE */
sig_mask.__hisigs &= 0x7FFFFFFF;
#endif
#endif
#endif /* _AIX */
while (1) {
#if HAVE_SIGWAIT
int signal_received;
if (sigwait(&sig_mask, &signal_received) != 0)
{
/* handle sigwait() error here */
}
if (sig_func(signal_received) == 1)
{
return CORE_OK;
}
#elif HAVE_SIGSUSPEND
sigsuspend(&sig_mask);
#else
#error No sigwait() and no sigsuspend()
#endif
}
}
status_t signal_init(void)
{
sigset_t sig_mask;
int rv;
/* All threads should mask out signals to be handled by
* the thread doing sigwait().
*
* No thread should ever block synchronous signals.
* See the Solaris man page for pthread_sigmask() for
* some information. Solaris chooses to knock out such
* processes when a blocked synchronous signal is
* delivered, skipping any registered signal handler.
* AIX doesn't call a signal handler either. At least
* one level of linux+glibc does call the handler even
* when the synchronous signal is blocked.
*/
sigfillset(&sig_mask);
remove_sync_sigs(&sig_mask);
#if defined(SIGPROCMASK_SETS_THREAD_MASK) || ! APR_HAS_THREADS
if ((rv = sigprocmask(SIG_SETMASK, &sig_mask, NULL)) != 0) {
rv = errno;
}
#else
if ((rv = pthread_sigmask(SIG_SETMASK, &sig_mask, NULL)) != 0) {
#ifdef HAVE_ZOS_PTHREADS
rv = errno;
#endif
}
#endif
return rv;
}
status_t signal_block(int signum)
{
#if HAVE_SIGACTION
sigset_t sig_mask;
int rv;
sigemptyset(&sig_mask);
sigaddset(&sig_mask, signum);
#if defined(SIGPROCMASK_SETS_THREAD_MASK)
if ((rv = sigprocmask(SIG_BLOCK, &sig_mask, NULL)) != 0) {
rv = errno;
}
#else
if ((rv = pthread_sigmask(SIG_BLOCK, &sig_mask, NULL)) != 0) {
#ifdef HAVE_ZOS_PTHREADS
rv = errno;
#endif
}
#endif
return rv;
#else
return CORE_ENOTIMPL;
#endif
}
status_t signal_unblock(int signum)
{
#if HAVE_SIGACTION
sigset_t sig_mask;
int rv;
sigemptyset(&sig_mask);
sigaddset(&sig_mask, signum);
#if defined(SIGPROCMASK_SETS_THREAD_MASK)
if ((rv = sigprocmask(SIG_UNBLOCK, &sig_mask, NULL)) != 0) {
rv = errno;
}
#else
if ((rv = pthread_sigmask(SIG_UNBLOCK, &sig_mask, NULL)) != 0) {
#ifdef HAVE_ZOS_PTHREADS
rv = errno;
#endif
}
#endif
return rv;
#else
return CORE_ENOTIMPL;
#endif
}
nextepc-0.3.10/lib/core/src/unix/sockaddr.c 0000664 0000000 0000000 00000031635 13335533574 0020472 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _sockaddr
#include "core_debug.h"
#include "core_lib.h"
#include "core_pkbuf.h"
#include "core_arch_network.h"
status_t core_getaddrinfo(c_sockaddr_t **sa_list,
int family, const char *hostname, c_uint16_t port, int flags)
{
*sa_list = NULL;
return core_addaddrinfo(sa_list, family, hostname, port, flags);
}
status_t core_freeaddrinfo(c_sockaddr_t *sa_list)
{
c_sockaddr_t *next = NULL, *addr = NULL;
addr = sa_list;
while(addr)
{
next = addr->next;
CORE_FREE(addr);
addr = next;
}
return CORE_OK;
}
status_t core_addaddrinfo(c_sockaddr_t **sa_list,
int family, const char *hostname, c_uint16_t port, int flags)
{
int rc;
char service[NI_MAXSERV];
struct addrinfo hints, *ai, *ai_list;
c_sockaddr_t *prev;
char buf[CORE_ADDRSTRLEN];
d_assert(sa_list, return CORE_ERROR,);
memset(&hints, 0, sizeof(hints));
hints.ai_family = family;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = flags;
snprintf(service, sizeof(service), "%u", port);
rc = getaddrinfo(hostname, service, &hints, &ai_list);
if (rc != 0)
{
d_error("getaddrinfo(%d:%s:%d:0x%x) failed(%d:%s)",
family, hostname, port, flags, errno, strerror(errno));
return CORE_ERROR;
}
prev = NULL;
if (*sa_list)
{
prev = *sa_list;
while(prev->next) prev = prev->next;
}
for (ai = ai_list; ai; ai = ai->ai_next)
{
c_sockaddr_t *new;
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
continue;
new = core_calloc(1, sizeof(c_sockaddr_t));
memcpy(&new->sa, ai->ai_addr, ai->ai_addrlen);
new->c_sa_port = htons(port);
d_trace(3, "addr:%s, port:%d\n", CORE_ADDR(new, buf), port);
if (!prev)
*sa_list = new;
else
prev->next = new;
prev = new;
}
freeaddrinfo(ai_list);
if (prev == NULL)
{
d_error("core_getaddrinfo(%d:%s:%d:%d) failed(%d:%s)",
family, hostname, port, flags, errno, strerror(errno));
return CORE_ERROR;
}
return CORE_OK;
}
status_t core_filteraddrinfo(c_sockaddr_t **sa_list, int family)
{
c_sockaddr_t *addr = NULL, *prev = NULL, *next = NULL;
d_assert(sa_list, return CORE_ERROR,);
prev = NULL;
addr = *sa_list;
while(addr)
{
next = addr->next;
if (addr->c_sa_family != family)
{
if (prev)
prev->next = addr->next;
else
*sa_list = addr->next;
CORE_FREE(addr);
}
else
{
prev = addr;
}
addr = next;
}
return CORE_OK;
}
status_t core_copyaddrinfo(c_sockaddr_t **dst, const c_sockaddr_t *src)
{
c_sockaddr_t *d;
const c_sockaddr_t *s;
for (*dst = d = NULL, s = src; s; s = s->next)
{
if (!d)
{
d = core_calloc(1, sizeof *s);
*dst = memcpy(d, s, sizeof *s);
}
else
{
d->next = core_calloc(1, sizeof(c_sockaddr_t));
d = memcpy(d->next, s, sizeof *s);
}
}
return CORE_OK;
}
status_t core_sortaddrinfo(c_sockaddr_t **sa_list, int family)
{
c_sockaddr_t *head = NULL, *addr = NULL, *new = NULL, *old = NULL;
d_assert(sa_list, return CORE_ERROR,);
old = *sa_list;
while(old)
{
addr = old;
old = old->next;
if (head == NULL || addr->c_sa_family == family)
{
addr->next = head;
head = addr;
}
else
{
new = head;
while(new->next != NULL && new->next->c_sa_family != family)
{
new = new->next;
}
addr->next = new->next;
new->next = addr;
}
}
*sa_list = head;
return CORE_OK;
}
c_sockaddr_t *core_link_local_addr_by_dev(const char *dev)
{
struct ifaddrs *iflist, *cur;
int rc;
d_assert(dev, return NULL,);
rc = getifaddrs(&iflist);
if (rc != 0)
{
d_error("getifaddrs failed(%d:%s)", errno, strerror(errno));
return NULL;
}
for (cur = iflist; cur != NULL; cur = cur->ifa_next)
{
c_sockaddr_t *addr = NULL;
if (cur->ifa_addr == NULL) /* may happen with ppp interfaces */
continue;
if (strcmp(dev, cur->ifa_name) != 0)
continue;
if (cur->ifa_addr->sa_family == AF_INET)
continue;
addr = (c_sockaddr_t *)cur->ifa_addr;
if (!IN6_IS_ADDR_LINKLOCAL(&addr->sin6.sin6_addr))
continue;
addr = core_calloc(1, sizeof(c_sockaddr_t));
d_assert(addr, return NULL,);
memcpy(&addr->sa, cur->ifa_addr, sockaddr_len(cur->ifa_addr));
freeifaddrs(iflist);
return addr;
}
freeifaddrs(iflist);
return NULL;
}
const char *core_inet_ntop(void *sa, char *buf, int buflen)
{
int family;
c_sockaddr_t *sockaddr = NULL;
d_assert(buf, return NULL,);
sockaddr = sa;
d_assert(sockaddr, return NULL,);
family = sockaddr->c_sa_family;
switch(family)
{
case AF_INET:
d_assert(buflen >= INET_ADDRSTRLEN, return NULL,);
return inet_ntop(family,
&sockaddr->sin.sin_addr, buf, INET_ADDRSTRLEN);
case AF_INET6:
d_assert(buflen >= CORE_ADDRSTRLEN, return NULL,);
return inet_ntop(family,
&sockaddr->sin6.sin6_addr, buf, INET6_ADDRSTRLEN);
default:
d_assert(0, return NULL, "Unknown family(%d)", family);
}
}
status_t core_inet_pton(int family, const char *src, void *sa)
{
c_sockaddr_t *dst = NULL;
d_assert(src, return CORE_ERROR,);
dst = sa;
d_assert(dst, return CORE_ERROR,);
dst->c_sa_family = family;
switch(family)
{
case AF_INET:
return inet_pton(family, src, &dst->sin.sin_addr) == 1 ?
CORE_OK : CORE_ERROR;
case AF_INET6:
return inet_pton(family, src, &dst->sin6.sin6_addr) == 1 ?
CORE_OK : CORE_ERROR;
default:
d_assert(0, return CORE_ERROR, "Unknown family(%d)", family);
}
}
socklen_t sockaddr_len(const void *sa)
{
const c_sockaddr_t *sockaddr = sa;
d_assert(sa, return 0,);
switch(sockaddr->c_sa_family)
{
case AF_INET:
return sizeof(struct sockaddr_in);
case AF_INET6:
return sizeof(struct sockaddr_in6);
default:
d_assert(0, return 0, "Unknown family(%d)", sockaddr->c_sa_family);
}
}
int sockaddr_is_equal(void *p, void *q)
{
c_sockaddr_t *a, *b;
a = p;
d_assert(a, return 0,);
b = q;
d_assert(b, return 0,);
if (a->c_sa_family != b->c_sa_family)
return 0;
if (a->c_sa_family == AF_INET && memcmp(
&a->sin.sin_addr, &b->sin.sin_addr, sizeof(struct in_addr)) == 0)
return 1;
else if (a->c_sa_family == AF_INET6 && memcmp(
&a->sin6.sin6_addr, &b->sin6.sin6_addr, sizeof(struct in6_addr)) == 0)
return 1;
else
d_assert(0, return 0, "Unknown family(%d)", a->c_sa_family);
return 0;
}
static status_t parse_network(ipsubnet_t *ipsub, const char *network)
{
/* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */
int shift;
char *s, *t;
int octet;
char buf[sizeof "255.255.255.255"];
if (strlen(network) < sizeof buf)
{
strcpy(buf, network);
}
else
{
return CORE_EBADIP;
}
/* parse components */
s = buf;
ipsub->sub[0] = 0;
ipsub->mask[0] = 0;
shift = 24;
while (*s)
{
t = s;
if (!c_isdigit(*t))
{
return CORE_EBADIP;
}
while (c_isdigit(*t))
{
++t;
}
if (*t == '.')
{
*t++ = 0;
}
else if (*t)
{
return CORE_EBADIP;
}
if (shift < 0)
{
return CORE_EBADIP;
}
octet = atoi(s);
if (octet < 0 || octet > 255)
{
return CORE_EBADIP;
}
ipsub->sub[0] |= octet << shift;
ipsub->mask[0] |= 0xFFUL << shift;
s = t;
shift -= 8;
}
ipsub->sub[0] = ntohl(ipsub->sub[0]);
ipsub->mask[0] = ntohl(ipsub->mask[0]);
ipsub->family = AF_INET;
return CORE_OK;
}
/* return values:
* CORE_EINVAL not an IP address; caller should see
* if it is something else
* CORE_BADIP IP address portion is is not valid
* CORE_BADMASK mask portion is not valid
*/
static status_t parse_ip(
ipsubnet_t *ipsub, const char *ipstr, int network_allowed)
{
/* supported flavors of IP:
*
* . IPv6 numeric address string (e.g., "fe80::1")
*
* IMPORTANT: Don't store IPv4-mapped IPv6 address as an IPv6 address.
*
* . IPv4 numeric address string (e.g., "127.0.0.1")
*
* . IPv4 network string (e.g., "9.67")
*
* IMPORTANT: This network form is only allowed if network_allowed is on.
*/
int rc;
rc = inet_pton(AF_INET6, ipstr, ipsub->sub);
if (rc == 1)
{
if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ipsub->sub))
{
/* ipsubnet_test() assumes that we don't create IPv4-mapped IPv6
* addresses; this of course forces the user to specify
* IPv4 addresses in a.b.c.d style instead of ::ffff:a.b.c.d style.
*/
d_error("Cannot support IPv4-mapped IPv6: "
"Use IPv4 address in a.b.c.d style "
"instead of ::ffff:a.b.c.d style");
return CORE_EBADIP;
}
ipsub->family = AF_INET6;
}
else
{
rc = inet_pton(AF_INET, ipstr, ipsub->sub);
if (rc == 1)
{
ipsub->family = AF_INET;
}
}
if (rc != 1)
{
if (network_allowed)
{
return parse_network(ipsub, ipstr);
}
else
{
return CORE_EBADIP;
}
}
return CORE_OK;
}
static int looks_like_ip(const char *ipstr)
{
if (strlen(ipstr) == 0)
{
return 0;
}
if (strchr(ipstr, ':'))
{
/* definitely not a hostname;
* assume it is intended to be an IPv6 address */
return 1;
}
/* simple IPv4 address string check */
while ((*ipstr == '.') || c_isdigit(*ipstr))
ipstr++;
return (*ipstr == '\0');
}
static void fix_subnet(ipsubnet_t *ipsub)
{
/* in case caller specified more bits in network address than are
* valid according to the mask, turn off the extra bits
*/
int i;
for (i = 0; i < sizeof ipsub->mask / sizeof(c_int32_t); i++)
{
ipsub->sub[i] &= ipsub->mask[i];
}
}
/* be sure not to store any IPv4 address as a v4-mapped IPv6 address */
CORE_DECLARE(status_t) core_ipsubnet(
ipsubnet_t *ipsub, const char *ipstr, const char *mask_or_numbits)
{
status_t rv;
char *endptr;
long bits, maxbits = 32;
d_assert(ipsub, return CORE_ERROR,);
d_assert(ipstr, return CORE_ERROR,);
/* filter out stuff which doesn't look remotely like an IP address;
* this helps callers like mod_access which have a syntax allowing
* hostname or IP address;
* CORE_EINVAL tells the caller that it was probably not intended
* to be an IP address
*/
if (!looks_like_ip(ipstr))
{
d_error("looks_like_ip() is failed");
return CORE_EINVAL;
}
/* assume ipstr is an individual IP address, not a subnet */
memset(ipsub->mask, 0xFF, sizeof ipsub->mask);
rv = parse_ip(ipsub, ipstr, mask_or_numbits == NULL);
if (rv != CORE_OK)
{
d_error("parse_ip() is failed");
return rv;
}
if (mask_or_numbits)
{
if (ipsub->family == AF_INET6)
{
maxbits = 128;
}
bits = strtol(mask_or_numbits, &endptr, 10);
if (*endptr == '\0' && bits > 0 && bits <= maxbits)
{
/* valid num-bits string; fill in mask appropriately */
int cur_entry = 0;
c_int32_t cur_bit_value;
memset(ipsub->mask, 0, sizeof ipsub->mask);
while (bits > 32)
{
ipsub->mask[cur_entry] = 0xFFFFFFFF; /* all 32 bits */
bits -= 32;
++cur_entry;
}
cur_bit_value = 0x80000000;
while (bits)
{
ipsub->mask[cur_entry] |= cur_bit_value;
--bits;
cur_bit_value /= 2;
}
ipsub->mask[cur_entry] = htonl(ipsub->mask[cur_entry]);
}
else if (inet_pton(AF_INET, mask_or_numbits, ipsub->mask) == 1 &&
ipsub->family == AF_INET)
{
/* valid IPv4 netmask */
}
else
{
d_error("Bad netmask");
return CORE_EBADMASK;
}
}
fix_subnet(ipsub);
return CORE_OK;
}
nextepc-0.3.10/lib/core/src/unix/socket.c 0000664 0000000 0000000 00000044345 13335533574 0020172 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _sock
#include "core_pool.h"
#include "core_debug.h"
#include "core_pkbuf.h"
#include "core_arch_network.h"
#define MAX_SOCK_POOL_SIZE 512
#define MAX_SOCK_NODE_POOL_SIZE 512
static int max_fd;
static list_t fd_list;
static fd_set read_fds;
static mutex_id mutex;
pool_declare(sock_pool, sock_t, MAX_SOCK_POOL_SIZE);
pool_declare(sock_node_pool, sock_node_t, MAX_SOCK_NODE_POOL_SIZE);
static status_t sononblock(int sd);
static status_t soblock(int sd);
static void set_fds(fd_set *fds);
static void fd_dispatch(fd_set *fds);
/*
* Init/Final
*/
status_t network_init(void)
{
mutex_create(&mutex, MUTEX_DEFAULT);
pool_init(&sock_pool, MAX_SOCK_POOL_SIZE);
pool_init(&sock_node_pool, MAX_SOCK_NODE_POOL_SIZE);
max_fd = 0;
list_init(&fd_list);
memset(&read_fds, 0, sizeof(fd_set));
return CORE_OK;
}
status_t network_final(void)
{
if (pool_size(&sock_pool) != pool_avail(&sock_pool))
d_error("%d not freed in sock_pool[%d]",
pool_size(&sock_pool) - pool_avail(&sock_pool),
pool_size(&sock_pool));
d_trace(3, "%d not freed in sock_pool[%d]\n",
pool_size(&sock_pool) - pool_avail(&sock_pool),
pool_size(&sock_pool));
if (pool_size(&sock_node_pool) != pool_avail(&sock_node_pool))
d_error("%d not freed in sock_node_pool[%d]",
pool_size(&sock_node_pool) - pool_avail(&sock_node_pool),
pool_size(&sock_node_pool));
d_trace(3, "%d not freed in sock_node_pool[%d]\n",
pool_size(&sock_node_pool) - pool_avail(&sock_node_pool),
pool_size(&sock_node_pool));
pool_final(&sock_pool);
pool_final(&sock_node_pool);
mutex_delete(mutex);
return CORE_OK;
}
/*
* Socket
*/
status_t sock_create(sock_id *new)
{
sock_t *sock = NULL;
pool_alloc_node(&sock_pool, &sock);
d_assert(sock, return CORE_ENOMEM,);
memset(sock, 0, sizeof(sock_t));
sock->fd = -1;
*new = (sock_id)sock;
return CORE_OK;
}
status_t sock_delete(sock_id id)
{
sock_t *sock = (sock_t *)id;
d_assert(id, return CORE_ERROR,);
if (sock_is_registered(id))
sock_unregister(id);
if (sock->fd >= 0)
close(sock->fd);
sock->fd = -1;
pool_free_node(&sock_pool, sock);
return CORE_OK;
}
status_t sock_delete_list(list_t *list)
{
status_t rv;
sock_node_t *snode;
d_assert(list, return CORE_ERROR,);
for (snode = list_first(list); snode; snode = list_next(snode))
{
rv = sock_delete(snode->sock);
d_assert(rv == CORE_OK, return CORE_ERROR,);
}
return CORE_OK;
}
status_t sock_socket(sock_id *new, int family, int type, int protocol)
{
status_t rv;
sock_t *sock = NULL;
rv = sock_create(new);
d_assert(rv == CORE_OK, return CORE_ERROR,);
sock = (sock_t *)(*new);
sock->family = family;
sock->fd = socket(sock->family, type, protocol);
if (sock->fd < 0)
{
d_warn("socket create(%d:%d:%d) failed(%d:%s)",
sock->family, type, protocol, errno, strerror(errno));
return CORE_ERROR;
}
d_trace(1, "socket create(%d:%d:%d)\n", sock->family, type, protocol);
return CORE_OK;
}
status_t sock_setsockopt(sock_id id, c_int32_t opt, c_int32_t on)
{
sock_t *sock = (sock_t *)id;
int one;
status_t rv;
d_assert(sock, return CORE_ERROR,);
if (on)
one = 1;
else
one = 0;
switch(opt)
{
case SOCK_O_REUSEADDR:
if (on != sock_is_option_set(sock, SOCK_O_REUSEADDR))
{
if (setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR,
(void *)&one, sizeof(int)) == -1)
{
return errno;
}
sock_set_option(sock, SOCK_O_REUSEADDR, on);
}
break;
case SOCK_O_NONBLOCK:
if (sock_is_option_set(sock, SOCK_O_NONBLOCK) != on)
{
if (on)
{
if ((rv = sononblock(sock->fd)) != CORE_OK)
return rv;
}
else
{
if ((rv = soblock(sock->fd)) != CORE_OK)
return rv;
}
sock_set_option(sock, SOCK_O_NONBLOCK, on);
}
break;
default:
d_error("Not implemented(%d)", opt);
return CORE_EINVAL;
}
return CORE_OK;
}
status_t sock_bind(sock_id id, c_sockaddr_t *addr)
{
sock_t *sock = (sock_t *)id;
char buf[CORE_ADDRSTRLEN];
socklen_t addrlen;
d_assert(sock, return CORE_ERROR,);
d_assert(addr, return CORE_ERROR,);
addrlen = sockaddr_len(addr);
d_assert(addrlen, return CORE_ERROR,);
if (bind(sock->fd, &addr->sa, addrlen) != 0)
{
d_error("socket bind(%d) [%s]:%d failed(%d:%s)",
addr->c_sa_family, CORE_ADDR(addr, buf), CORE_PORT(addr),
errno, strerror(errno));
return CORE_ERROR;
}
memcpy(&sock->local_addr, addr, sizeof(sock->local_addr));
d_trace(1, "socket bind %s:%d\n", CORE_ADDR(addr, buf), CORE_PORT(addr));
return CORE_OK;
}
status_t sock_connect(sock_id id, c_sockaddr_t *addr)
{
sock_t *sock = (sock_t *)id;
char buf[CORE_ADDRSTRLEN];
socklen_t addrlen;
d_assert(sock, return CORE_ERROR,);
d_assert(addr, return CORE_ERROR,);
addrlen = sockaddr_len(addr);
d_assert(addrlen, return CORE_ERROR,);
if (connect(sock->fd, &addr->sa, addrlen) != 0)
{
d_error("socket connect[%s]:%d failed(%d:%s)",
CORE_ADDR(addr, buf), CORE_PORT(addr), errno, strerror(errno));
return CORE_ERROR;
}
memcpy(&sock->remote_addr, addr, sizeof(sock->remote_addr));
d_trace(1, "socket connect %s:%d\n", CORE_ADDR(addr, buf), CORE_PORT(addr));
return CORE_OK;
}
status_t sock_listen(sock_id id)
{
int rc;
sock_t *sock = (sock_t *)id;
d_assert(sock, return CORE_ERROR,);
rc = listen(sock->fd, 5);
if (rc < 0)
{
d_error("listen failed(%d:%s)", errno, strerror(errno));
return CORE_ERROR;
}
return CORE_OK;
}
status_t sock_accept(sock_id *new, sock_id id)
{
sock_t *sock = (sock_t *)id;
sock_t *new_sock = NULL;
int new_fd = -1;
c_sockaddr_t addr;
socklen_t addrlen;
memset(&addr, 0, sizeof(addr));
addrlen = sizeof(addr.ss);
d_assert(id, return CORE_ERROR,);
new_fd = accept(sock->fd, &addr.sa, &addrlen);
if (new_fd < 0)
{
d_error("accept failed(%d:%s)", errno, strerror(errno));
return CORE_ERROR;
}
pool_alloc_node(&sock_pool, &new_sock);
d_assert(new_sock, return CORE_ENOMEM,);
memset(new_sock, 0, sizeof(sock_t));
new_sock->family = sock->family;
new_sock->fd = new_fd;
memcpy(&new_sock->remote_addr, &addr, sizeof(new_sock->remote_addr));
*new = (sock_id)new_sock;
return CORE_OK;
}
int sock_family(sock_id id)
{
sock_t *sock = (sock_t *)id;
d_assert(id, return -1,);
return sock->family;
}
c_sockaddr_t *sock_local_addr(sock_id id)
{
sock_t *sock = (sock_t *)id;
d_assert(id, return NULL,);
return &sock->local_addr;
}
c_sockaddr_t *sock_remote_addr(sock_id id)
{
sock_t *sock = (sock_t *)id;
d_assert(id, return NULL,);
return &sock->remote_addr;
}
/*
* Socket Node
*/
status_t sock_add_node(
list_t *list, sock_node_t **node, c_sockaddr_t *sa_list, int family)
{
status_t rv;
c_sockaddr_t *new_list = NULL;
d_assert(list, return CORE_OK,);
d_assert(node, return CORE_OK,);
d_assert(sa_list, return CORE_OK,);
rv = core_copyaddrinfo(&new_list, sa_list);
d_assert(rv == CORE_OK, return CORE_OK,);
if (family != AF_UNSPEC)
{
rv = core_filteraddrinfo(&new_list, family);
d_assert(rv == CORE_OK, return CORE_OK,);
}
if (new_list)
{
pool_alloc_node(&sock_node_pool, node);
d_assert(*node, return CORE_OK,);
memset(*node, 0, sizeof(sock_node_t));
(*node)->list = new_list;
list_append(list, *node);
}
return CORE_OK;
}
status_t sock_remove_node(list_t *list, sock_node_t *node)
{
d_assert(node, return CORE_ERROR,);
list_remove(list, node);
core_freeaddrinfo(node->list);
pool_free_node(&sock_node_pool, node);
return CORE_OK;
}
status_t sock_remove_all_nodes(list_t *list)
{
sock_node_t *node = NULL, *next_node = NULL;
node = list_first(list);
while(node)
{
next_node = list_next(node);
sock_remove_node(list, node);
node = next_node;
}
return CORE_OK;
}
status_t sock_probe_node(
list_t *list, list_t *list6, const char *dev, c_uint16_t port)
{
sock_node_t *node = NULL;
struct ifaddrs *iflist, *cur;
int rc;
rc = getifaddrs(&iflist);
if (rc != 0)
{
d_error("getifaddrs failed(%d:%s)", errno, strerror(errno));
return CORE_ERROR;
}
for (cur = iflist; cur != NULL; cur = cur->ifa_next)
{
c_sockaddr_t *addr = NULL;
if (cur->ifa_flags & IFF_LOOPBACK)
continue;
if (cur->ifa_flags & IFF_POINTOPOINT)
continue;
if (cur->ifa_addr == NULL) /* may happen with ppp interfaces */
continue;
if (dev && strcmp(dev, cur->ifa_name) != 0)
continue;
addr = (c_sockaddr_t *)cur->ifa_addr;
if (cur->ifa_addr->sa_family == AF_INET)
{
if (!list) continue;
#ifndef IN_IS_ADDR_LOOPBACK
#define IN_IS_ADDR_LOOPBACK(a) \
((((long int) (a)->s_addr) & ntohl(0xff000000)) == ntohl(0x7f000000))
#endif /* IN_IS_ADDR_LOOPBACK */
/* An IP equivalent to IN6_IS_ADDR_UNSPECIFIED */
#ifndef IN_IS_ADDR_UNSPECIFIED
#define IN_IS_ADDR_UNSPECIFIED(a) \
(((long int) (a)->s_addr) == 0x00000000)
#endif /* IN_IS_ADDR_UNSPECIFIED */
if (IN_IS_ADDR_UNSPECIFIED(&addr->sin.sin_addr) ||
IN_IS_ADDR_LOOPBACK(&addr->sin.sin_addr))
continue;
}
else if (cur->ifa_addr->sa_family == AF_INET6)
{
if (!list6) continue;
if (IN6_IS_ADDR_UNSPECIFIED(&addr->sin6.sin6_addr) ||
IN6_IS_ADDR_LOOPBACK(&addr->sin6.sin6_addr) ||
IN6_IS_ADDR_MULTICAST(&addr->sin6.sin6_addr) ||
IN6_IS_ADDR_LINKLOCAL(&addr->sin6.sin6_addr) ||
IN6_IS_ADDR_SITELOCAL(&addr->sin6.sin6_addr))
continue;
}
else
continue;
addr = core_calloc(1, sizeof(c_sockaddr_t));
d_assert(addr, return CORE_ERROR,);
memcpy(&addr->sa, cur->ifa_addr, sockaddr_len(cur->ifa_addr));
addr->c_sa_port = htons(port);
pool_alloc_node(&sock_node_pool, &node);
d_assert(node, return CORE_ERROR,);
memset(node, 0, sizeof(sock_node_t));
node->list = addr;
if (addr->c_sa_family == AF_INET)
{
d_assert(list, return CORE_ERROR,);
list_append(list, node);
}
else if (addr->c_sa_family == AF_INET6)
{
d_assert(list6, return CORE_ERROR,);
list_append(list6, node);
}
else
d_assert(0, return CORE_ERROR,);
}
freeifaddrs(iflist);
return CORE_OK;
}
status_t sock_fill_scope_id_in_local(c_sockaddr_t *sa_list)
{
struct ifaddrs *iflist = NULL, *cur;
int rc;
c_sockaddr_t *addr, *ifaddr;
for (addr = sa_list; addr != NULL; addr = addr->next)
{
if (addr->c_sa_family != AF_INET6)
continue;
if (!IN6_IS_ADDR_LINKLOCAL(&addr->sin6.sin6_addr))
continue;
if (addr->sin6.sin6_scope_id != 0)
continue;
if (iflist == NULL)
{
rc = getifaddrs(&iflist);
if (rc != 0)
{
d_error("getifaddrs failed(%d:%s)", errno, strerror(errno));
return CORE_ERROR;
}
}
for (cur = iflist; cur != NULL; cur = cur->ifa_next)
{
ifaddr = (c_sockaddr_t *)cur->ifa_addr;
if (cur->ifa_addr == NULL) /* may happen with ppp interfaces */
continue;
if (cur->ifa_addr->sa_family != AF_INET6)
continue;
if (!IN6_IS_ADDR_LINKLOCAL(&ifaddr->sin6.sin6_addr))
continue;
if (memcmp(&addr->sin6.sin6_addr,
&ifaddr->sin6.sin6_addr, sizeof(struct in6_addr)) == 0)
{
/* Fill Scope ID in localhost */
addr->sin6.sin6_scope_id = ifaddr->sin6.sin6_scope_id;
}
}
}
if (iflist)
freeifaddrs(iflist);
return CORE_OK;
}
/*
* Send/Recv
*/
ssize_t sock_write(sock_id id, const void *buf, size_t len)
{
sock_t *sock = (sock_t *)id;
ssize_t size;
d_assert(id, return -1,);
size = write(sock->fd, buf, len);
if (size < 0)
{
d_error("sock_write(len:%ld) failed(%d:%s)",
len, errno, strerror(errno));
}
return size;
}
ssize_t sock_read(sock_id id, void *buf, size_t len)
{
sock_t *sock = (sock_t *)id;
ssize_t size;
d_assert(id, return -1,);
size = read(sock->fd, buf, len);
if (size < 0)
{
d_error("sock_read(len:%ld) failed(%d:%s)",
len, errno, strerror(errno));
}
return size;
}
ssize_t core_send(sock_id id, const void *buf, size_t len, int flags)
{
sock_t *sock = (sock_t *)id;
ssize_t size;
d_assert(id, return -1,);
size = send(sock->fd, buf, len, flags);
if (size < 0)
{
d_error("core_send(len:%ld) failed(%d:%s)",
len, errno, strerror(errno));
}
return size;
}
ssize_t core_sendto(sock_id id,
const void *buf, size_t len, int flags, const c_sockaddr_t *to)
{
sock_t *sock = (sock_t *)id;
ssize_t size;
socklen_t addrlen;
d_assert(id, return -1,);
d_assert(to, return -1,);
addrlen = sockaddr_len(to);
d_assert(addrlen, return CORE_ERROR,);
size = sendto(sock->fd, buf, len, flags, &to->sa, addrlen);
if (size < 0)
{
d_error("core_sendto(len:%ld) failed(%d:%s)",
len, errno, strerror(errno));
}
return size;
}
ssize_t core_recv(sock_id id, void *buf, size_t len, int flags)
{
sock_t *sock = (sock_t *)id;
ssize_t size;
d_assert(id, return -1,);
size = recv(sock->fd, buf, len, flags);
if (size < 0)
{
d_error("core_recv(len:%ld) failed(%d:%s)",
len, errno, strerror(errno));
}
return size;
}
ssize_t core_recvfrom(sock_id id,
void *buf, size_t len, int flags, c_sockaddr_t *from)
{
sock_t *sock = (sock_t *)id;
ssize_t size;
socklen_t addrlen = sizeof(struct sockaddr_storage);
d_assert(id, return -1,);
d_assert(from, return -1,);
size = recvfrom(sock->fd, buf, len, flags, &from->sa, &addrlen);
if (size < 0)
{
d_error("corek_recvfrom(len:%ld) failed(%d:%s)",
len, errno, strerror(errno));
}
return size;
}
/*
* Select Loop
*/
status_t sock_register(sock_id id, sock_handler handler, void *data)
{
sock_t *sock = (sock_t *)id;
d_assert(id, return CORE_ERROR,);
if (sock_is_registered(id))
{
d_error("socket has already been registered");
return CORE_ERROR;
}
if (sock_setsockopt(id, SOCK_O_NONBLOCK, 1) == CORE_ERROR)
{
d_error("cannot set socket to non-block");
return CORE_ERROR;
}
if (sock->fd > max_fd)
{
max_fd = sock->fd;
}
sock->handler = handler;
sock->data = data;
list_append(&fd_list, sock);
return CORE_OK;
}
status_t sock_unregister(sock_id id)
{
d_assert(id, return CORE_ERROR,);
list_remove(&fd_list, id);
return CORE_OK;
}
int sock_is_registered(sock_id id)
{
sock_t *sock = (sock_t *)id;
sock_t *iter = NULL;
d_assert(id, return CORE_ERROR,);
for (iter = list_first(&fd_list); iter != NULL; iter = list_next(iter))
{
if (iter == sock)
{
return 1;
}
}
return 0;
}
int sock_select_loop(c_time_t timeout)
{
struct timeval tv;
int rc;
if (timeout > 0)
{
tv.tv_sec = time_sec(timeout);
tv.tv_usec = time_usec(timeout);
}
set_fds(&read_fds);
rc = select(max_fd + 1, &read_fds, NULL, NULL, timeout > 0 ? &tv : NULL);
if (rc < 0)
{
if (errno != EINTR && errno != 0)
d_error("select failed(%d:%s)", errno, strerror(errno));
return rc;
}
/* Timeout */
if (rc == 0)
{
return rc;
}
/* Dispatch Handler */
fd_dispatch(&read_fds);
return 0;
}
static status_t soblock(int sd)
{
/* BeOS uses setsockopt at present for non blocking... */
#ifndef BEOS
int fd_flags;
fd_flags = fcntl(sd, F_GETFL, 0);
#if defined(O_NONBLOCK)
fd_flags &= ~O_NONBLOCK;
#elif defined(O_NDELAY)
fd_flags &= ~O_NDELAY;
#elif defined(FNDELAY)
fd_flags &= ~FNDELAY;
#else
#error Please teach CORE how to make sockets blocking on your platform.
#endif
if (fcntl(sd, F_SETFL, fd_flags) == -1)
{
return errno;
}
#else
int on = 0;
if (setsockopt(sd, SOL_SOCKET, SO_NONBLOCK, &on, sizeof(int)) < 0)
return errno;
#endif /* BEOS */
return CORE_OK;
}
static status_t sononblock(int sd)
{
#ifndef BEOS
int fd_flags;
fd_flags = fcntl(sd, F_GETFL, 0);
#if defined(O_NONBLOCK)
fd_flags |= O_NONBLOCK;
#elif defined(O_NDELAY)
fd_flags |= O_NDELAY;
#elif defined(FNDELAY)
fd_flags |= FNDELAY;
#else
#error Please teach CORE how to make sockets non-blocking on your platform.
#endif
if (fcntl(sd, F_SETFL, fd_flags) == -1)
{
return errno;
}
#else
int on = 1;
if (setsockopt(sd, SOL_SOCKET, SO_NONBLOCK, &on, sizeof(int)) < 0)
return errno;
#endif /* BEOS */
return CORE_OK;
}
static void set_fds(fd_set *fds)
{
sock_t *sock = NULL;
FD_ZERO(fds);
for (sock = list_first(&fd_list); sock != NULL; sock = list_next(sock))
{
FD_SET(sock->fd, fds);
}
}
static void fd_dispatch(fd_set *fds)
{
sock_t *sock = NULL;
for (sock = list_first(&fd_list); sock != NULL; sock = list_next(sock))
{
if (FD_ISSET(sock->fd, fds))
{
if (sock->handler)
{
sock->handler((sock_id)sock, sock->data);
}
}
}
}
nextepc-0.3.10/lib/core/src/unix/start.c 0000664 0000000 0000000 00000003515 13335533574 0020031 0 ustar 00root root 0000000 0000000 #include "core.h"
#include "core_general.h"
#include "core_debug.h"
#include "core_pool.h"
#include "core_msgq.h"
#include "core_tlv.h"
#include "core_timer.h"
#include "core_atomic.h"
#include "core_mutex.h"
#include "core_cond.h"
#include "core_rwlock.h"
#include "core_semaphore.h"
#include "core_thread.h"
#include "core_network.h"
#include "core_file.h"
#include "core_pkbuf.h"
#include "core_signal.h"
status_t core_app_initialize(int *argc,
const char * const * *argv,
const char * const * *env)
{
/* An absolute noop. At present, only Win32 requires this stub, but it's
* required in order to move command arguments passed through the service
* control manager into the process, and it's required to fix the char*
* data passed in from win32 unicode into utf-8, win32's core internal fmt.
*/
return core_initialize();
}
static int initialized = 0;
status_t core_initialize(void)
{
if (initialized++)
{
return CORE_OK;
}
/* IMPORTANT: Mutex should be initialized firtly because node-pool
* framework uses mutex and it will be used by other xxx_init() */
mutex_init();
semaphore_init();
cond_init();
rwlock_init();
atomic_init();
thread_init();
network_init();
file_init();
pkbuf_init();
tlv_init();
tm_init();
msgq_init();
signal_init();
return CORE_OK;
}
void core_terminate(void)
{
initialized--;
if (initialized) {
return;
}
/* Reverse ordered finalization */
msgq_final();
tm_final();
tlv_final();
pkbuf_final();
file_final();
network_final();
thread_final();
atomic_final();
rwlock_final();
cond_final();
semaphore_final();
mutex_final();
return;
}
void core_terminate2(void)
{
core_terminate();
}
nextepc-0.3.10/lib/core/src/unix/tcp.c 0000664 0000000 0000000 00000004507 13335533574 0017464 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _tcp
#include "core_debug.h"
#include "core_arch_network.h"
status_t tcp_server(sock_id *new, c_sockaddr_t *sa_list)
{
status_t rv;
c_sockaddr_t *addr;
char buf[CORE_ADDRSTRLEN];
d_assert(new, return CORE_ERROR,);
d_assert(sa_list, return CORE_ERROR,);
addr = sa_list;
while(addr)
{
rv = sock_socket(new, addr->c_sa_family, SOCK_STREAM, IPPROTO_TCP);
if (rv == CORE_OK)
{
d_assert(sock_setsockopt(*new, SOCK_O_REUSEADDR, 1) == CORE_OK,
return CORE_ERROR,
"setsockopt [%s]:%d failed(%d:%s)",
CORE_ADDR(addr, buf), CORE_PORT(addr),
errno, strerror(errno));
if (sock_bind(*new, addr) == CORE_OK)
{
d_trace(1, "tcp_server() [%s]:%d\n",
CORE_ADDR(addr, buf), CORE_PORT(addr));
break;
}
rv = sock_delete(*new);
d_assert(rv == CORE_OK, return CORE_ERROR,);
}
addr = addr->next;
}
if (addr == NULL)
{
d_error("tcp_server() [%s]:%d failed(%d:%s)",
CORE_ADDR(sa_list, buf), CORE_PORT(sa_list),
errno, strerror(errno));
return CORE_ERROR;
}
rv = sock_listen(*new);
d_assert(rv == CORE_OK, return CORE_ERROR,);
return CORE_OK;
}
status_t tcp_client(sock_id *new, c_sockaddr_t *sa_list)
{
status_t rv;
c_sockaddr_t *addr;
char buf[CORE_ADDRSTRLEN];
d_assert(new, return CORE_ERROR,);
d_assert(sa_list, return CORE_ERROR,);
addr = sa_list;
while(addr)
{
rv = sock_socket(new, addr->c_sa_family, SOCK_STREAM, IPPROTO_TCP);
if (rv == CORE_OK)
{
if (sock_connect(*new, addr) == CORE_OK)
{
d_trace(1, "tcp_client() [%s]:%d\n",
CORE_ADDR(addr, buf), CORE_PORT(addr));
break;
}
rv = sock_delete(*new);
d_assert(rv == CORE_OK, return CORE_ERROR,);
}
addr = addr->next;
}
if (addr == NULL)
{
d_error("tcp_client() [%s]:%d failed(%d:%s)",
CORE_ADDR(sa_list, buf), CORE_PORT(sa_list),
errno, strerror(errno));
return CORE_ERROR;
}
return CORE_OK;
}
nextepc-0.3.10/lib/core/src/unix/thread.c 0000664 0000000 0000000 00000011332 13335533574 0020137 0 ustar 00root root 0000000 0000000 #include "core.h"
#include "core_arch_thread.h"
#include "core_portable.h"
#include "core_errno.h"
#include "core_param.h"
#include "core_general.h"
#define TRACE_MODULE _thread
#include "core_debug.h"
#include "core_pool.h"
#include "core_semaphore.h"
struct thread_stop_info {
pthread_t thread;
semaphore_id semaphore;
};
pool_declare(thread_pool, thread_t, MAX_NUM_OF_THREAD);
pool_declare(threadattr_pool, threadattr_t, MAX_NUM_OF_THREADATTR);
static struct thread_stop_info thread_stop_info;
int thread_should_stop(void)
{
return (thread_stop_info.thread == pthread_self());
}
status_t thread_init(void)
{
pool_init(&thread_pool, MAX_NUM_OF_THREAD);
pool_init(&threadattr_pool, MAX_NUM_OF_THREADATTR);
memset(&thread_stop_info, 0, sizeof(thread_stop_info));
semaphore_create(&thread_stop_info.semaphore, 0);
return CORE_OK;
}
status_t thread_final(void)
{
pool_final(&thread_pool);
pool_final(&threadattr_pool);
semaphore_delete(thread_stop_info.semaphore);
return CORE_OK;
}
status_t threadattr_create(threadattr_t **new)
{
status_t stat;
pool_alloc_node(&threadattr_pool, &(*new));
d_assert((*new), return CORE_ENOMEM, "threadattr_pool(%d) is not enough\n",
MAX_NUM_OF_THREADATTR);
stat = pthread_attr_init(&(*new)->attr);
if (stat == 0)
{
return CORE_OK;
}
return stat;
}
status_t threadattr_stacksize_set(
threadattr_t *attr, size_t stacksize)
{
int stat;
stat = pthread_attr_setstacksize(&attr->attr, stacksize);
if (stat == 0)
{
return CORE_OK;
}
return stat;
}
status_t threadattr_delete(threadattr_t *attr)
{
status_t stat;
stat = pthread_attr_destroy(&attr->attr);
pool_free_node(&threadattr_pool, attr);
if (stat == 0)
{
return CORE_OK;
}
return stat;
}
static void *dummy_worker(void *opaque)
{
void *func = NULL;
thread_t *thread = (thread_t *)opaque;
thread->thread = pthread_self();
semaphore_post(thread->semaphore);
d_trace(3, "[%d] dummy_worker post semaphore\n", thread->thread);
if (!thread_should_stop())
func = thread->func((thread_id)thread, thread->data);
d_trace(3, "[%d] thread stopped = %d\n",
thread->thread, thread_should_stop());
semaphore_post(thread_stop_info.semaphore);
d_trace(3, "[%d] post semaphore for thread_stop_info.semaphore\n",
thread->thread);
return func;
}
status_t thread_create(thread_id *id,
threadattr_t *attr, thread_start_t func, void *data)
{
status_t stat;
pthread_attr_t *temp;
thread_t *new = NULL;
pool_alloc_node(&thread_pool, &new);
d_assert(new, return CORE_ENOMEM, "thread_pool(%d) is not enough\n",
MAX_NUM_OF_THREAD);
memset(new, 0, sizeof(thread_id));
new->data = data;
new->func = func;
semaphore_create(&new->semaphore, 0);
if (attr)
temp = &attr->attr;
else
temp = NULL;
if ((stat = pthread_create(&new->thread, temp, dummy_worker, new)) != 0)
{
return stat;
}
d_trace(3, "thread_create wait\n");
semaphore_wait(new->semaphore);
d_trace(3, "thread_create done\n");
*id = (thread_id)new;
return CORE_OK;
}
status_t thread_delete(thread_id id)
{
thread_t *thread = (thread_t *)id;
thread_stop_info.thread = thread->thread;
d_trace(3, "thread_stop_info.thread for %d\n", thread_stop_info.thread);
semaphore_wait(thread_stop_info.semaphore);
d_trace(3, "semaphore_wait done\n");
thread_stop_info.thread = 0;
pthread_join(thread->thread, 0);
semaphore_delete(thread->semaphore);
pool_free_node(&thread_pool, thread);
d_trace(3, "delete thread-related memory\n");
return CORE_OK;
}
status_t thread_join(status_t *retval, thread_id id)
{
thread_t *thread = (thread_t *)id;
status_t stat;
status_t *thread_stat;
if ((stat = pthread_join(thread->thread, (void *)&thread_stat)) == 0)
{
*retval = thread->exitval;
}
semaphore_delete(thread->semaphore);
pool_free_node(&thread_pool, thread);
return stat;
}
status_t thread_exit(thread_id id, status_t retval)
{
thread_t *thread = (thread_t *)id;
thread->exitval = retval;
pthread_exit(NULL);
return CORE_OK;
}
status_t thread_detach(thread_id id)
{
thread_t *thread = (thread_t *)id;
return pthread_detach(thread->thread);
}
void thread_yield(void)
{
#ifdef HAVE_PTHREAD_YIELD
pthread_yield(NULL);
#else
#ifdef HAVE_SCHED_YIELD
sched_yield();
#endif
#endif
}
status_t os_thread_get(os_thread_t **thethd, thread_id id)
{
thread_t *thread = (thread_t *)id;
*thethd = &thread->thread;
return CORE_OK;
}
os_thread_t os_thread_current(void)
{
return pthread_self();
}
nextepc-0.3.10/lib/core/src/unix/time.c 0000664 0000000 0000000 00000014636 13335533574 0017640 0 ustar 00root root 0000000 0000000 #include "core.h"
#include "core_time.h"
static c_int32_t get_offset(struct tm *tm)
{
#if defined(HAVE_STRUCT_TM_TM_GMTOFF)
return tm->tm_gmtoff;
#elif defined(HAVE_STRUCT_TM___TM_GMTOFF)
return tm->__tm_gmtoff;
#else
#error cannot support tm->tm_gmtoff
#endif
}
status_t time_ansi_put(c_time_t *result, time_t input)
{
*result = (c_time_t)input * USEC_PER_SEC;
return CORE_OK;
}
/* NB NB NB NB This returns GMT!!!!!!!!!! */
c_time_t time_now(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec * USEC_PER_SEC + tv.tv_usec;
}
void core_sleep(c_time_t t)
{
#ifdef OS2
DosSleep(t/1000);
#elif defined(BEOS)
snooze(t);
#elif defined(NETWARE)
delay(t/1000);
#else
struct timeval tv;
tv.tv_usec = t % USEC_PER_SEC;
tv.tv_sec = t / USEC_PER_SEC;
select(0, NULL, NULL, NULL, &tv);
#endif
}
static void explode_time(time_exp_t *xt, c_time_t t,
c_int32_t offset, int use_localtime)
{
struct tm tm;
time_t tt = (t / USEC_PER_SEC) + offset;
xt->tm_usec = t % USEC_PER_SEC;
#if defined (_POSIX_THREAD_SAFE_FUNCTIONS)
if (use_localtime)
localtime_r(&tt, &tm);
else
gmtime_r(&tt, &tm);
#else
if (use_localtime)
tm = *localtime(&tt);
else
tm = *gmtime(&tt);
#endif
xt->tm_sec = tm.tm_sec;
xt->tm_min = tm.tm_min;
xt->tm_hour = tm.tm_hour;
xt->tm_mday = tm.tm_mday;
xt->tm_mon = tm.tm_mon;
xt->tm_year = tm.tm_year;
xt->tm_wday = tm.tm_wday;
xt->tm_yday = tm.tm_yday;
xt->tm_isdst = tm.tm_isdst;
xt->tm_gmtoff = get_offset(&tm);
}
status_t time_exp_tz(time_exp_t *result,
c_time_t input, c_int32_t offs)
{
explode_time(result, input, offs, 0);
result->tm_gmtoff = offs;
return CORE_OK;
}
status_t time_exp_gmt(time_exp_t *result, c_time_t input)
{
return time_exp_tz(result, input, 0);
}
status_t time_exp_lt(time_exp_t *result, c_time_t input)
{
#if defined(__EMX__)
/* EMX gcc (OS/2) has a timezone global we can use */
return time_exp_tz(result, input, -timezone);
#else
explode_time(result, input, 0, 1);
return CORE_OK;
#endif /* __EMX__ */
}
status_t time_exp_get(c_time_t *t, time_exp_t *xt)
{
time_t year = xt->tm_year;
time_t days;
static const int dayoffset[12] =
{306, 337, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275};
/* shift new year to 1st March in order to make leap year calc easy */
if (xt->tm_mon < 2)
year--;
/* Find number of days since 1st March 1900 (in the Gregorian calendar). */
days = year * 365 + year / 4 - year / 100 + (year / 100 + 3) / 4;
days += dayoffset[xt->tm_mon] + xt->tm_mday - 1;
days -= 25508; /* 1 jan 1970 is 25508 days since 1 mar 1900 */
days = ((days * 24 + xt->tm_hour) * 60 + xt->tm_min) * 60 + xt->tm_sec;
if (days < 0) {
return CORE_EBADDATE;
}
*t = days * USEC_PER_SEC + xt->tm_usec;
return CORE_OK;
}
status_t time_exp_gmt_get(c_time_t *t, time_exp_t *xt)
{
status_t status = time_exp_get(t, xt);
if (status == CORE_OK)
*t -= (time_t) xt->tm_gmtoff * USEC_PER_SEC;
return status;
}
const char month_snames[12][4] =
{
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
const char day_snames[7][4] =
{
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
status_t rfc822_date(char *date_str, c_time_t t)
{
time_exp_t xt;
const char *s;
int real_year;
time_exp_gmt(&xt, t);
/* example: "Sat, 08 Jan 2000 18:31:41 GMT" */
/* 12345678901234567890123456789 */
s = &day_snames[xt.tm_wday][0];
*date_str++ = *s++;
*date_str++ = *s++;
*date_str++ = *s++;
*date_str++ = ',';
*date_str++ = ' ';
*date_str++ = xt.tm_mday / 10 + '0';
*date_str++ = xt.tm_mday % 10 + '0';
*date_str++ = ' ';
s = &month_snames[xt.tm_mon][0];
*date_str++ = *s++;
*date_str++ = *s++;
*date_str++ = *s++;
*date_str++ = ' ';
real_year = 1900 + xt.tm_year;
/* This routine isn't y10k ready. */
*date_str++ = real_year / 1000 + '0';
*date_str++ = real_year % 1000 / 100 + '0';
*date_str++ = real_year % 100 / 10 + '0';
*date_str++ = real_year % 10 + '0';
*date_str++ = ' ';
*date_str++ = xt.tm_hour / 10 + '0';
*date_str++ = xt.tm_hour % 10 + '0';
*date_str++ = ':';
*date_str++ = xt.tm_min / 10 + '0';
*date_str++ = xt.tm_min % 10 + '0';
*date_str++ = ':';
*date_str++ = xt.tm_sec / 10 + '0';
*date_str++ = xt.tm_sec % 10 + '0';
*date_str++ = ' ';
*date_str++ = 'G';
*date_str++ = 'M';
*date_str++ = 'T';
*date_str++ = 0;
return CORE_OK;
}
status_t core_ctime(char *date_str, c_time_t t)
{
time_exp_t xt;
const char *s;
int real_year;
/* example: "Wed Jun 30 21:49:08 1993" */
/* 123456789012345678901234 */
time_exp_lt(&xt, t);
s = &day_snames[xt.tm_wday][0];
*date_str++ = *s++;
*date_str++ = *s++;
*date_str++ = *s++;
*date_str++ = ' ';
s = &month_snames[xt.tm_mon][0];
*date_str++ = *s++;
*date_str++ = *s++;
*date_str++ = *s++;
*date_str++ = ' ';
*date_str++ = xt.tm_mday / 10 + '0';
*date_str++ = xt.tm_mday % 10 + '0';
*date_str++ = ' ';
*date_str++ = xt.tm_hour / 10 + '0';
*date_str++ = xt.tm_hour % 10 + '0';
*date_str++ = ':';
*date_str++ = xt.tm_min / 10 + '0';
*date_str++ = xt.tm_min % 10 + '0';
*date_str++ = ':';
*date_str++ = xt.tm_sec / 10 + '0';
*date_str++ = xt.tm_sec % 10 + '0';
*date_str++ = ' ';
real_year = 1900 + xt.tm_year;
*date_str++ = real_year / 1000 + '0';
*date_str++ = real_year % 1000 / 100 + '0';
*date_str++ = real_year % 100 / 10 + '0';
*date_str++ = real_year % 10 + '0';
*date_str++ = 0;
return CORE_OK;
}
status_t core_strftime(char *s, size_t *retsize, size_t max,
const char *format, time_exp_t *xt)
{
struct tm tm;
memset(&tm, 0, sizeof tm);
tm.tm_sec = xt->tm_sec;
tm.tm_min = xt->tm_min;
tm.tm_hour = xt->tm_hour;
tm.tm_mday = xt->tm_mday;
tm.tm_mon = xt->tm_mon;
tm.tm_year = xt->tm_year;
tm.tm_wday = xt->tm_wday;
tm.tm_yday = xt->tm_yday;
tm.tm_isdst = xt->tm_isdst;
#if defined(HAVE_STRUCT_TM_TM_GMTOFF)
tm.tm_gmtoff = xt->tm_gmtoff;
#elif defined(HAVE_STRUCT_TM___TM_GMTOFF)
tm.__tm_gmtoff = xt->tm_gmtoff;
#endif
(*retsize) = strftime(s, max, format, &tm);
return CORE_OK;
}
nextepc-0.3.10/lib/core/src/unix/tun.c 0000664 0000000 0000000 00000023105 13335533574 0017477 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _core_tun
#include "core_debug.h"
#include "core_arch_network.h"
#if LINUX == 1
#include
#else
#include
#include
#endif
#if HAVE_NET_ROUTE_H
#include
#endif
status_t tun_open(sock_id *new, char *ifname, int is_tap)
{
status_t rv;
sock_t *sock = NULL;
int fd = -1;
#if LINUX == 1
char *dev = "/dev/net/tun";
int rc;
struct ifreq ifr;
int flags = IFF_NO_PI;
fd = open(dev, O_RDWR);
if (fd < 0)
{
d_error("open() failed(%d:%s) : dev[%s]", errno, strerror(errno), dev);
return -1;
}
#else
char name[C_PATH_MAX];
int tun = 0;
#define TUNTAP_ID_MAX 255
for (tun = 0; tun < TUNTAP_ID_MAX; tun++)
{
(void)snprintf(name, sizeof(name), "/dev/tun%i", tun);
if ((fd = open(name, O_RDWR)) > 0)
{
(void)snprintf(name, sizeof(name), "tun%i", tun);
ifname = name;
break;
}
}
#endif
rv = sock_create(new);
d_assert(rv == CORE_OK, return CORE_ERROR,);
sock = (sock_t *)(*new);
d_assert(sock, return CORE_ERROR,);
/* Save socket descriptor */
sock->fd = fd;
/* Save the interface name */
strncpy(sock->ifname, ifname, IFNAMSIZ-1);
#if LINUX == 1
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = (is_tap ? (flags | IFF_TAP) : (flags | IFF_TUN));
strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1);
rc = ioctl(sock->fd, TUNSETIFF, (void *)&ifr);
if (rc < 0)
{
d_error("ioctl() failed(%d:%s) : dev[%s] flags[0x%x]",
errno, strerror(errno), ifname, flags);
goto cleanup;
}
#endif
return CORE_OK;
#if LINUX == 1
cleanup:
sock_delete(*new);
return CORE_ERROR;
#endif
}
status_t tun_set_ipv4(sock_id id, ipsubnet_t *ipaddr, ipsubnet_t *ipsub)
{
#if LINUX != 1
sock_t *sock = NULL;
int fd;
struct ifaliasreq ifa;
struct ifreq ifr;
struct sockaddr_in addr;
struct sockaddr_in mask;
char buf[512];
int len;
struct rt_msghdr *rtm;
struct sockaddr_in dst, gw;
struct sockaddr_in *paddr;
d_assert(ipaddr, return CORE_ERROR,);
d_assert(ipsub, return CORE_ERROR,);
sock = (sock_t *)id;
d_assert(id, return CORE_ERROR,);
fd = socket(ipaddr->family, SOCK_DGRAM, 0);
(void)memset(&ifa, '\0', sizeof ifa);
(void)strlcpy(ifa.ifra_name, sock->ifname, sizeof ifa.ifra_name);
(void)memset(&ifr, '\0', sizeof ifr);
(void)strlcpy(ifr.ifr_name, sock->ifname, sizeof ifr.ifr_name);
#if 0
/* Delete previously assigned address */
(void)ioctl(fd, SIOCDIFADDR, &ifr);
#endif
(void)memset(&addr, '\0', sizeof(addr));
addr.sin_family = ipaddr->family;
addr.sin_addr.s_addr = ipaddr->sub[0];
addr.sin_len = sizeof(addr);
(void)memcpy(&ifa.ifra_addr, &addr, sizeof(addr));
(void)memcpy(&ifa.ifra_broadaddr, &addr, sizeof(addr));
(void)memset(&mask, '\0', sizeof(mask));
mask.sin_family = ipaddr->family;
mask.sin_addr.s_addr = ipaddr->mask[0];
mask.sin_len = sizeof(mask);
(void)memcpy(&ifa.ifra_mask, &mask, sizeof(ifa.ifra_mask));
if (ioctl(fd, SIOCAIFADDR, &ifa) == -1) {
d_error("Can't IP address(%d:%s) : dev[%s]",
errno, strerror(errno), sock->ifname);
return CORE_ERROR;
}
close(fd); /* SOCK_DGRAM */
fd = socket(PF_ROUTE, SOCK_RAW, 0);
if (fd < 0)
{
d_error("Can't open PF_ROUTE(%d:%s)", errno, strerror(errno));
return CORE_ERROR;
}
(void)memset(&buf, 0, sizeof(buf));
rtm = (struct rt_msghdr *)buf;
rtm->rtm_type = RTM_ADD;
rtm->rtm_version = RTM_VERSION;
rtm->rtm_pid = getpid();
rtm->rtm_seq = 0;
rtm->rtm_flags = RTF_UP | RTF_GATEWAY;
rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
paddr = (struct sockaddr_in *)(rtm + 1);
(void)memset(&dst, '\0', sizeof(dst));
dst.sin_family = ipaddr->family;
dst.sin_addr.s_addr = ipsub->sub[0];
dst.sin_len = sizeof(dst);
(void)memcpy(paddr, &dst, sizeof(dst));
paddr = (struct sockaddr_in *)((char *)paddr +
CORE_ALIGN(sizeof(*paddr), sizeof(c_uintptr_t)));
(void)memset(&gw, '\0', sizeof(gw));
gw.sin_family = ipaddr->family;
gw.sin_addr.s_addr = ipaddr->sub[0];
gw.sin_len = sizeof(gw);
(void)memcpy(paddr, &gw, sizeof(gw));
paddr = (struct sockaddr_in *)((char *)paddr +
CORE_ALIGN(sizeof(*paddr), sizeof(c_uintptr_t)));
(void)memset(&mask, '\0', sizeof(mask));
mask.sin_family = ipaddr->family;
mask.sin_addr.s_addr = ipsub->mask[0];
mask.sin_len = sizeof(mask);
(void)memcpy(paddr, &mask, sizeof(mask));
paddr = (struct sockaddr_in *)((char *)paddr +
CORE_ALIGN(sizeof(*paddr), sizeof(c_uintptr_t)));
len = (char*)paddr - buf;
rtm->rtm_msglen = len;
if (write(fd, buf, len) < 0)
{
d_error("Can't add routing(%d:%s)", errno, strerror(errno));
return CORE_ERROR;
}
close(fd); /* PF_ROUTE, SOCK_RAW */
#endif /* LINUX == 1 */
return CORE_OK;
}
status_t tun_set_ipv6(sock_id id, ipsubnet_t *ipaddr, ipsubnet_t *ipsub)
{
#if LINUX != 1
sock_t *sock = NULL;
int fd;
struct in6_aliasreq ifa;
struct in6_ifreq ifr;
struct sockaddr_in6 addr;
struct sockaddr_in6 mask;
char buf[512];
int len;
struct rt_msghdr *rtm;
#if 0
struct sockaddr_in6 dst, gw;
#else
struct sockaddr_in6 dst;
#endif
struct sockaddr_in6 *paddr;
d_assert(ipaddr, return CORE_ERROR,);
d_assert(ipsub, return CORE_ERROR,);
sock = (sock_t *)id;
d_assert(id, return CORE_ERROR,);
fd = socket(ipaddr->family, SOCK_DGRAM, 0);
(void)memset(&ifa, '\0', sizeof ifa);
(void)strlcpy(ifa.ifra_name, sock->ifname, sizeof ifa.ifra_name);
(void)memset(&ifr, '\0', sizeof ifr);
(void)strlcpy(ifr.ifr_name, sock->ifname, sizeof ifr.ifr_name);
#if 0
/* Delete previously assigned address */
(void)ioctl(fd, SIOCDIFADDR, &ifr);
#endif
(void)memset(&addr, '\0', sizeof(addr));
addr.sin6_family = ipaddr->family;
memcpy(addr.sin6_addr.s6_addr, ipaddr->sub, sizeof ipaddr->sub);
addr.sin6_len = sizeof(addr);
(void)memcpy(&ifa.ifra_addr, &addr, sizeof(addr));
(void)memcpy(&ifa.ifra_dstaddr, &addr, sizeof(addr));
(void)memset(&mask, '\0', sizeof(mask));
mask.sin6_family = ipaddr->family;
memcpy(mask.sin6_addr.s6_addr, ipaddr->mask, sizeof ipaddr->mask);
mask.sin6_len = sizeof(mask);
(void)memcpy(&ifa.ifra_prefixmask, &mask, sizeof(ifa.ifra_prefixmask));
ifa.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
ifa.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
if (ioctl(fd, SIOCAIFADDR_IN6, &ifa) == -1) {
d_error("Can't IP address(%d:%s) : dev[%s]",
errno, strerror(errno), sock->ifname);
return CORE_ERROR;
}
close(fd); /* SOCK_DGRAM */
fd = socket(PF_ROUTE, SOCK_RAW, 0);
if (fd < 0)
{
d_error("Can't open PF_ROUTE(%d:%s)", errno, strerror(errno));
return CORE_ERROR;
}
(void)memset(&buf, 0, sizeof(buf));
rtm = (struct rt_msghdr *)buf;
rtm->rtm_type = RTM_DELETE;
rtm->rtm_version = RTM_VERSION;
rtm->rtm_pid = getpid();
rtm->rtm_seq = 0;
rtm->rtm_addrs = RTA_DST;
paddr = (struct sockaddr_in6 *)(rtm + 1);
(void)memset(&dst, '\0', sizeof(dst));
dst.sin6_family = ipaddr->family;
memcpy(dst.sin6_addr.s6_addr, ipaddr->sub, sizeof ipsub->sub);
dst.sin6_len = sizeof(dst);
(void)memcpy(paddr, &dst, sizeof(dst));
paddr = (struct sockaddr_in6 *)((char *)paddr +
CORE_ALIGN(sizeof(*paddr), sizeof(c_uintptr_t)));
len = (char*)paddr - buf;
rtm->rtm_msglen = len;
if (write(fd, buf, len) < 0)
{
d_error("Can't add routing(%d:%s)", errno, strerror(errno));
return CORE_ERROR;
}
#if 0
(void)memset(&buf, 0, sizeof(buf));
rtm = (struct rt_msghdr *)buf;
rtm->rtm_type = RTM_ADD;
rtm->rtm_version = RTM_VERSION;
rtm->rtm_pid = getpid();
rtm->rtm_seq = 0;
rtm->rtm_flags = RTF_UP | RTF_GATEWAY;
rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
paddr = (struct sockaddr_in6 *)(rtm + 1);
(void)memset(&dst, '\0', sizeof(dst));
dst.sin6_family = ipaddr->family;
memcpy(dst.sin6_addr.s6_addr, ipsub->sub, sizeof ipsub->sub);
dst.sin6_len = sizeof(dst);
(void)memcpy(paddr, &dst, sizeof(dst));
paddr = (struct sockaddr_in6 *)((char *)paddr +
CORE_ALIGN(sizeof(*paddr), sizeof(c_uintptr_t)));
(void)memset(&gw, '\0', sizeof(gw));
gw.sin6_family = ipaddr->family;
memcpy(gw.sin6_addr.s6_addr, ipaddr->sub, sizeof ipaddr->sub);
gw.sin6_len = sizeof(gw);
(void)memcpy(paddr, &gw, sizeof(gw));
paddr = (struct sockaddr_in6 *)((char *)paddr +
CORE_ALIGN(sizeof(*paddr), sizeof(c_uintptr_t)));
(void)memset(&mask, '\0', sizeof(mask));
mask.sin6_family = ipaddr->family;
memcpy(mask.sin6_addr.s6_addr, ipsub->mask, sizeof ipsub->mask);
mask.sin6_len = sizeof(mask);
(void)memcpy(paddr, &mask, sizeof(mask));
paddr = (struct sockaddr_in6 *)((char *)paddr +
CORE_ALIGN(sizeof(*paddr), sizeof(c_uintptr_t)));
len = (char*)paddr - buf;
rtm->rtm_msglen = len;
if (write(fd, buf, len) < 0)
{
d_error("Can't add routing(%d:%s)", errno, strerror(errno));
return CORE_ERROR;
}
#endif
close(fd); /* PF_ROUTE, SOCK_RAW */
#endif /* LINUX == 1 */
return CORE_OK;
}
status_t tun_set_ip(sock_id id, ipsubnet_t *gw, ipsubnet_t *sub)
{
status_t rv = CORE_OK;
d_assert(id, return CORE_ERROR,);
d_assert(gw, return CORE_ERROR,);
d_assert(sub, return CORE_ERROR,);
if (gw->family == AF_INET)
rv = tun_set_ipv4(id, gw, sub);
else if (gw->family == AF_INET6)
{
#if 0
rv = tun_set_ipv6(id, gw, sub);
#endif
}
else
d_assert(0, return CORE_ERROR,);
return rv;
}
nextepc-0.3.10/lib/core/src/unix/udp.c 0000664 0000000 0000000 00000006205 13335533574 0017463 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _udp
#include "core_debug.h"
#include "core_arch_network.h"
status_t udp_socket(sock_id *new, int family)
{
status_t rv;
rv = sock_socket(new, family, SOCK_DGRAM, IPPROTO_UDP);
d_assert(rv == CORE_OK && new, return CORE_ERROR,);
d_trace(1, "udp socket(%d)\n", family);
return CORE_OK;
}
status_t udp_server(sock_id *new, c_sockaddr_t *sa_list)
{
status_t rv;
c_sockaddr_t *addr;
char buf[CORE_ADDRSTRLEN];
d_assert(new, return CORE_ERROR,);
d_assert(sa_list, return CORE_ERROR,);
addr = sa_list;
while(addr)
{
rv = udp_socket(new, addr->c_sa_family);
if (rv == CORE_OK)
{
d_assert(sock_setsockopt(*new, SOCK_O_REUSEADDR, 1) == CORE_OK,
return CORE_ERROR,
"setsockopt [%s]:%d failed(%d:%s)",
CORE_ADDR(addr, buf), CORE_PORT(addr),
errno, strerror(errno));
if (sock_bind(*new, addr) == CORE_OK)
{
d_trace(1, "udp_server() [%s]:%d\n",
CORE_ADDR(addr, buf), CORE_PORT(addr));
break;
}
rv = sock_delete(*new);
d_assert(rv == CORE_OK, return CORE_ERROR,);
}
addr = addr->next;
}
if (addr == NULL)
{
d_error("udp_server() [%s]:%d failed(%d:%s)",
CORE_ADDR(sa_list, buf), CORE_PORT(sa_list),
errno, strerror(errno));
return CORE_ERROR;
}
return CORE_OK;
}
status_t udp_client(sock_id *new, c_sockaddr_t *sa_list)
{
status_t rv;
c_sockaddr_t *addr;
char buf[CORE_ADDRSTRLEN];
d_assert(new, return CORE_ERROR,);
d_assert(sa_list, return CORE_ERROR,);
addr = sa_list;
while(addr)
{
rv = udp_socket(new, addr->c_sa_family);
if (rv == CORE_OK)
{
if (sock_connect(*new, addr) == CORE_OK)
{
d_trace(1, "udp_client() [%s]:%d\n",
CORE_ADDR(addr, buf), CORE_PORT(addr));
break;
}
rv = sock_delete(*new);
d_assert(rv == CORE_OK, return CORE_ERROR,);
}
addr = addr->next;
}
if (addr == NULL)
{
d_error("udp_client() [%s]:%d failed(%d:%s)",
CORE_ADDR(sa_list, buf), CORE_PORT(sa_list), errno,
strerror(errno));
return CORE_ERROR;
}
return CORE_OK;
}
status_t udp_connect(sock_id id, c_sockaddr_t *sa_list)
{
c_sockaddr_t *addr;
char buf[CORE_ADDRSTRLEN];
d_assert(id, return CORE_ERROR,);
d_assert(sa_list, return CORE_ERROR,);
addr = sa_list;
while(addr)
{
if (sock_connect(id, addr) == CORE_OK)
{
d_trace(1, "udp_connect() [%s]:%d\n",
CORE_ADDR(addr, buf), CORE_PORT(addr));
break;
}
addr = addr->next;
}
if (addr == NULL)
{
d_error("udp_connect() [%s]:%d failed(%d:%s)",
CORE_ADDR(sa_list, buf), CORE_PORT(sa_list),
errno, strerror(errno));
return CORE_ERROR;
}
return CORE_OK;
}
nextepc-0.3.10/lib/core/src/version.c 0000664 0000000 0000000 00000000650 13335533574 0017373 0 ustar 00root root 0000000 0000000 #include "core_version.h"
#include "core_general.h" /* for CORE_STRINGIFY */
CORE_DECLARE(void) core_version(core_version_t *pvsn)
{
pvsn->major = CORE_MAJOR_VERSION;
pvsn->minor = CORE_MINOR_VERSION;
pvsn->patch = CORE_PATCH_VERSION;
#ifdef CORE_IS_DEV_VERSION
pvsn->is_dev = 1;
#else
pvsn->is_dev = 0;
#endif
}
CORE_DECLARE(const char *) core_version_string(void)
{
return CORE_VERSION_STRING;
}
nextepc-0.3.10/lib/core/test/ 0000775 0000000 0000000 00000000000 13335533574 0015731 5 ustar 00root root 0000000 0000000 nextepc-0.3.10/lib/core/test/Makefile.am 0000664 0000000 0000000 00000001531 13335533574 0017765 0 ustar 00root root 0000000 0000000 ## Process this file with automake to produce Makefile.in.
bin_PROGRAMS = testcore
testcore_SOURCES = \
abts.c testds.c testfsm.c testsock.c testthread.c testtlv.c \
testaes.c testfile.c testlock.c testatomic.c testsha.c testtime.c \
testdir.c testfilecopy.c testmsgq.c testsleep.c testtimer.c \
testpkbuf.c testmisc.c testhash.c test3gpp.c \
abts.h abts_tests.h testutil.c testutil.h \
$(NULL)
if !USRSCTP
testcore_SOURCES += testsctp.c
endif
testcore_LDADD = \
$(top_srcdir)/lib/core/src/libcore.la \
$(NULL)
AM_CPPFLAGS = \
-I$(top_srcdir)/lib/core/include \
$(NULL)
AM_CFLAGS = \
-Wall -Werror @OSCPPFLAGS@ \
-Wno-unused-function -Wno-unused-variable -Wno-restrict \
-Wno-unknown-warning-option \
$(NULL)
TESTS = testcore
MAINTAINERCLEANFILES = Makefile.in
CLEANFILES = -R data
MOSTLYCLEANFILES = core *.stackdump
nextepc-0.3.10/lib/core/test/abts.c 0000664 0000000 0000000 00000025777 13335533574 0017050 0 ustar 00root root 0000000 0000000 /* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "abts.h"
#include "abts_tests.h"
#include "testutil.h"
#include "core_pkbuf.h"
#define ABTS_STAT_SIZE 6
static char status[ABTS_STAT_SIZE] = {'|', '/', '-', '|', '\\', '-'};
static int curr_char;
static int verbose = 1;
static int exclude = 0;
static int quiet = 0;
static int list_tests = 0;
const char **testlist = NULL;
static int find_test_name(const char *testname) {
int i;
for (i = 0; testlist[i] != NULL; i++) {
if (!strcmp(testlist[i], testname)) {
return 1;
}
}
return 0;
}
/* Determine if the test should be run at all */
static int should_test_run(const char *testname) {
int found = 0;
if (list_tests == 1) {
return 0;
}
if (testlist == NULL) {
return 1;
}
found = find_test_name(testname);
if ((found && !exclude) || (!found && exclude)) {
return 1;
}
return 0;
}
static void reset_status(void)
{
curr_char = 0;
}
static void update_status(void)
{
if (!quiet) {
curr_char = (curr_char + 1) % ABTS_STAT_SIZE;
fprintf(stdout, "\b%c", status[curr_char]);
fflush(stdout);
}
}
static void end_suite(abts_suite *suite)
{
if (suite != NULL) {
sub_suite *last = suite->tail;
if (!quiet) {
fprintf(stdout, "\b");
fflush(stdout);
}
if (last->failed == 0) {
fprintf(stdout, "SUCCESS\n");
fflush(stdout);
}
else {
fprintf(stdout, "FAILED %d of %d\n", last->failed, last->num_test);
fflush(stdout);
}
}
}
abts_suite *abts_add_suite(abts_suite *suite, const char *suite_name_full)
{
sub_suite *subsuite;
char *p;
const char *suite_name;
curr_char = 0;
/* Only end the suite if we actually ran it */
if (suite && suite->tail &&!suite->tail->not_run) {
end_suite(suite);
}
subsuite = core_malloc(sizeof(*subsuite));
subsuite->num_test = 0;
subsuite->failed = 0;
subsuite->next = NULL;
/* suite_name_full may be an absolute path depending on __FILE__
* expansion */
suite_name = strrchr(suite_name_full, '/');
if (suite_name) {
suite_name++;
} else {
suite_name = suite_name_full;
}
p = strrchr(suite_name, '.');
if (p) {
subsuite->name = memcpy(core_calloc(p - suite_name + 1, 1),
suite_name, p - suite_name);
}
else {
subsuite->name = suite_name;
}
if (list_tests) {
fprintf(stdout, "%s\n", subsuite->name);
}
subsuite->not_run = 0;
if (suite == NULL) {
suite = core_malloc(sizeof(*suite));
suite->head = subsuite;
suite->tail = subsuite;
}
else {
suite->tail->next = subsuite;
suite->tail = subsuite;
}
if (!should_test_run(subsuite->name)) {
subsuite->not_run = 1;
return suite;
}
reset_status();
fprintf(stdout, "%-20s: ", subsuite->name);
update_status();
fflush(stdout);
return suite;
}
void abts_run_test(abts_suite *ts, test_func f, void *value)
{
abts_case tc;
sub_suite *ss;
if (!should_test_run(ts->tail->name)) {
return;
}
ss = ts->tail;
tc.failed = 0;
tc.suite = ss;
ss->num_test++;
update_status();
f(&tc, value);
if (tc.failed) {
ss->failed++;
}
}
static int report(abts_suite *suite)
{
int count = 0;
sub_suite *dptr;
if (suite && suite->tail &&!suite->tail->not_run) {
end_suite(suite);
}
for (dptr = suite->head; dptr; dptr = dptr->next) {
count += dptr->failed;
}
if (list_tests) {
return 0;
}
if (count == 0) {
printf("All tests passed.\n");
return 0;
}
dptr = suite->head;
fprintf(stdout, "%-15s\t\tTotal\tFail\tFailed %%\n", "Failed Tests");
fprintf(stdout, "===================================================\n");
while (dptr != NULL) {
if (dptr->failed != 0) {
float percent = ((float)dptr->failed / (float)dptr->num_test);
fprintf(stdout, "%-15s\t\t%5d\t%4d\t%6.2f%%\n", dptr->name,
dptr->num_test, dptr->failed, percent * 100);
}
dptr = dptr->next;
}
return 1;
}
static void abts_free(abts_suite *suite)
{
sub_suite *ptr = NULL, *next_ptr = NULL;
ptr = suite->head;
while (ptr != NULL) {
next_ptr = ptr->next;
CORE_FREE((void*)ptr->name);
CORE_FREE(ptr);
ptr = next_ptr;
}
CORE_FREE(suite);
}
void abts_log_message(const char *fmt, ...)
{
va_list args;
update_status();
if (verbose) {
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fprintf(stderr, "\n");
fflush(stderr);
}
}
void abts_int_equal(abts_case *tc, const int expected, const int actual, int lineno)
{
update_status();
if (tc->failed) return;
if (expected == actual) return;
tc->failed = TRUE;
if (verbose) {
fprintf(stderr, "Line %d: expected <%d>, but saw <%d>\n", lineno, expected, actual);
fflush(stderr);
}
}
void abts_int_nequal(abts_case *tc, const int expected, const int actual, int lineno)
{
update_status();
if (tc->failed) return;
if (expected != actual) return;
tc->failed = TRUE;
if (verbose) {
fprintf(stderr, "Line %d: expected <%d>, but saw <%d>\n", lineno, expected, actual);
fflush(stderr);
}
}
void abts_size_equal(abts_case *tc, size_t expected, size_t actual, int lineno)
{
update_status();
if (tc->failed) return;
if (expected == actual) return;
tc->failed = TRUE;
if (verbose) {
/* Note that the comparison is type-exact, reporting must be a best-fit */
fprintf(stderr, "Line %d: expected %lu, but saw %lu\n", lineno,
(unsigned long)expected, (unsigned long)actual);
fflush(stderr);
}
}
void abts_str_equal(abts_case *tc, const char *expected, const char *actual, int lineno)
{
update_status();
if (tc->failed) return;
if (!expected && !actual) return;
if (expected && actual)
if (!strcmp(expected, actual)) return;
tc->failed = TRUE;
if (verbose) {
fprintf(stderr, "Line %d: expected <%s>, but saw <%s>\n", lineno, expected, actual);
fflush(stderr);
}
}
void abts_str_nequal(abts_case *tc, const char *expected, const char *actual,
size_t n, int lineno)
{
update_status();
if (tc->failed) return;
if (!strncmp(expected, actual, n)) return;
tc->failed = TRUE;
if (verbose) {
fprintf(stderr, "Line %d: expected <%s>, but saw <%s>\n", lineno, expected, actual);
fflush(stderr);
}
}
void abts_ptr_null(abts_case *tc, const void *ptr, int lineno)
{
update_status();
if (tc->failed) return;
if (ptr == NULL) return;
tc->failed = TRUE;
if (verbose) {
fprintf(stderr, "Line %d: Expected NULL, but saw <%p>\n", lineno, ptr);
fflush(stderr);
}
}
void abts_ptr_notnull(abts_case *tc, const void *ptr, int lineno)
{
update_status();
if (tc->failed) return;
if (ptr != NULL) return;
tc->failed = TRUE;
if (verbose) {
fprintf(stderr, "Line %d: Expected not NULL, but saw <%p>\n", lineno, ptr);
fflush(stderr);
}
}
void abts_ptr_equal(abts_case *tc, const void *expected, const void *actual, int lineno)
{
update_status();
if (tc->failed) return;
if (expected == actual) return;
tc->failed = TRUE;
if (verbose) {
fprintf(stderr, "Line %d: expected <%p>, but saw <%p>\n", lineno, expected, actual);
fflush(stderr);
}
}
void abts_fail(abts_case *tc, const char *message, int lineno)
{
update_status();
if (tc->failed) return;
tc->failed = TRUE;
if (verbose) {
fprintf(stderr, "Line %d: %s\n", lineno, message);
fflush(stderr);
}
}
void abts_assert(abts_case *tc, const char *message, int condition, int lineno)
{
update_status();
if (tc->failed) return;
if (condition) return;
tc->failed = TRUE;
if (verbose) {
fprintf(stderr, "Line %d: %s\n", lineno, message);
fflush(stderr);
}
}
void abts_true(abts_case *tc, int condition, int lineno)
{
update_status();
if (tc->failed) return;
if (condition) return;
tc->failed = TRUE;
if (verbose) {
fprintf(stderr, "Line %d: Condition is false, but expected true\n", lineno);
fflush(stderr);
}
}
void abts_false(abts_case *tc, int condition, int lineno)
{
update_status();
if (tc->failed) return;
if (!condition) return;
tc->failed = TRUE;
if (verbose) {
fprintf(stderr, "Line %d: Condition is true, but expected false\n", lineno);
fflush(stderr);
}
}
void abts_not_impl(abts_case *tc, const char *message, int lineno)
{
update_status();
tc->suite->not_impl++;
if (verbose) {
fprintf(stderr, "Line %d: %s\n", lineno, message);
fflush(stderr);
}
}
int main(int argc, const char *const argv[]) {
int i;
int rv;
int list_provided = 0;
abts_suite *suite = NULL;
test_initialize();
quiet = !isatty(STDOUT_FILENO);
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-v")) {
verbose = 1;
continue;
}
if (!strcmp(argv[i], "-x")) {
exclude = 1;
continue;
}
if (!strcmp(argv[i], "-l")) {
list_tests = 1;
continue;
}
if (!strcmp(argv[i], "-q")) {
quiet = 1;
continue;
}
if (argv[i][0] == '-') {
fprintf(stderr, "Invalid option: `%s'\n", argv[i]);
exit(1);
}
list_provided = 1;
}
if (list_provided) {
/* Waste a little space here, because it is easier than counting the
* number of tests listed. Besides it is at most three char *.
*/
testlist = core_calloc(argc + 1, sizeof(char *));
for (i = 1; i < argc; i++) {
testlist[i - 1] = argv[i];
}
}
for (i = 0; i < (sizeof(alltests) / sizeof(struct testlist *)); i++) {
suite = alltests[i].func(suite);
}
rv = report(suite);
abts_free(suite);
CORE_FREE(testlist);
return rv;
}
nextepc-0.3.10/lib/core/test/abts.h 0000664 0000000 0000000 00000007374 13335533574 0017046 0 ustar 00root root 0000000 0000000 /* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include
#include
#include
#include
#ifdef WIN32
#include
#else
#include
#endif
#ifndef ABTS_H
#define ABTS_H
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
struct sub_suite {
const char *name;
int num_test;
int failed;
int not_run;
int not_impl;
struct sub_suite *next;
};
typedef struct sub_suite sub_suite;
struct abts_suite {
sub_suite *head;
sub_suite *tail;
};
typedef struct abts_suite abts_suite;
struct abts_case {
int failed;
sub_suite *suite;
};
typedef struct abts_case abts_case;
typedef void (*test_func)(abts_case *tc, void *data);
#define ADD_SUITE(suite) abts_add_suite(suite, __FILE__);
abts_suite *abts_add_suite(abts_suite *suite, const char *suite_name);
void abts_run_test(abts_suite *ts, test_func f, void *value);
void abts_log_message(const char *fmt, ...);
void abts_int_equal(abts_case *tc, const int expected, const int actual, int lineno);
void abts_int_nequal(abts_case *tc, const int expected, const int actual, int lineno);
void abts_str_equal(abts_case *tc, const char *expected, const char *actual, int lineno);
void abts_str_nequal(abts_case *tc, const char *expected, const char *actual,
size_t n, int lineno);
void abts_ptr_null(abts_case *tc, const void *ptr, int lineno);
void abts_ptr_notnull(abts_case *tc, const void *ptr, int lineno);
void abts_ptr_equal(abts_case *tc, const void *expected, const void *actual, int lineno);
void abts_true(abts_case *tc, int condition, int lineno);
void abts_false(abts_case *tc, int condition, int lineno);
void abts_fail(abts_case *tc, const char *message, int lineno);
void abts_not_impl(abts_case *tc, const char *message, int lineno);
void abts_assert(abts_case *tc, const char *message, int condition, int lineno);
void abts_size_equal(abts_case *tc, size_t expected, size_t actual, int lineno);
/* Convenience macros. Ryan hates these! */
#define ABTS_INT_EQUAL(a, b, c) abts_int_equal(a, b, c, __LINE__)
#define ABTS_INT_NEQUAL(a, b, c) abts_int_nequal(a, b, c, __LINE__)
#define ABTS_STR_EQUAL(a, b, c) abts_str_equal(a, b, c, __LINE__)
#define ABTS_STR_NEQUAL(a, b, c, d) abts_str_nequal(a, b, c, d, __LINE__)
#define ABTS_PTR_NULL(a, b) abts_ptr_null(a, b, __LINE__)
#define ABTS_PTR_NOTNULL(a, b) abts_ptr_notnull(a, b, __LINE__)
#define ABTS_PTR_EQUAL(a, b, c) abts_ptr_equal(a, b, c, __LINE__)
#define ABTS_TRUE(a, b) abts_true(a, b, __LINE__);
#define ABTS_FALSE(a, b) abts_false(a, b, __LINE__);
#define ABTS_FAIL(a, b) abts_fail(a, b, __LINE__);
#define ABTS_NOT_IMPL(a, b) abts_not_impl(a, b, __LINE__);
#define ABTS_ASSERT(a, b, c) abts_assert(a, b, c, __LINE__);
#define ABTS_SIZE_EQUAL(a, b, c) abts_size_equal(a, b, c, __LINE__)
abts_suite *run_tests(abts_suite *suite);
abts_suite *run_tests1(abts_suite *suite);
#endif
#ifdef __cplusplus
}
#endif
nextepc-0.3.10/lib/core/test/abts_tests.h 0000664 0000000 0000000 00000002541 13335533574 0020257 0 ustar 00root root 0000000 0000000 /* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_TEST_INCLUDES
#define APR_TEST_INCLUDES
#include "abts.h"
#include "testutil.h"
const struct testlist {
abts_suite *(*func)(abts_suite *suite);
} alltests[] = {
{testds},
{testfsm},
{testtlv},
{testaes},
{testsha2},
{testsock},
#ifndef DARWIN
{testsctp},
#endif
{testtime},
{testtimer},
{testthread},
{testlock},
{testatomic},
{testfile},
{testfilecopy},
{testdir},
{testmsgq},
{testsleep},
{testpkbuf},
{testmisc},
{testhash},
{test3gpp},
};
#endif /* APR_TEST_INCLUDES */
nextepc-0.3.10/lib/core/test/test3gpp.c 0000664 0000000 0000000 00000001615 13335533574 0017651 0 ustar 00root root 0000000 0000000 #include "core_lib.h"
#include "core_debug.h"
#include "3gpp_types.h"
#include "testutil.h"
static void _3gpp_test1(abts_case *tc, void *data)
{
status_t rv;
plmn_id_t plmn_id;
plmn_id_build(&plmn_id, 1, 1, 2);
ABTS_TRUE(tc, memcmp(plmn_id_build(&plmn_id, 1, 1, 2), "\x00\xf1\x10",
PLMN_ID_LEN) == 0);
ABTS_INT_EQUAL(tc, 1, plmn_id_mcc(&plmn_id));
ABTS_INT_EQUAL(tc, 1, plmn_id_mnc(&plmn_id));
ABTS_INT_EQUAL(tc, 2, plmn_id_mnc_len(&plmn_id));
ABTS_TRUE(tc, memcmp(plmn_id_build(&plmn_id, 555, 10, 2), "\x55\xf5\x01",
PLMN_ID_LEN) == 0);
ABTS_INT_EQUAL(tc, 555, plmn_id_mcc(&plmn_id));
ABTS_INT_EQUAL(tc, 10, plmn_id_mnc(&plmn_id));
ABTS_INT_EQUAL(tc, 2, plmn_id_mnc_len(&plmn_id));
}
abts_suite *test3gpp(abts_suite *suite)
{
suite = ADD_SUITE(suite)
abts_run_test(suite, _3gpp_test1, NULL);
return suite;
}
nextepc-0.3.10/lib/core/test/testaes.c 0000664 0000000 0000000 00000034055 13335533574 0017554 0 ustar 00root root 0000000 0000000 #include "core_aes.h"
#include "core_aes_cmac.h"
#include "core_pkbuf.h"
#include "testutil.h"
typedef struct {
unsigned char *key;
unsigned int *rk;
int key_bits;
unsigned char input[16];
unsigned char cipher_output[16];
unsigned char decipher_output[16];
} aes_test_vector_t;
static void aes_test1(abts_case *tc, void *data)
{
const int key_bits = 128;
unsigned int rk[RKLENGTH(128)];
unsigned char key[16] =
"\x00\x01\x02\x03\x05\x06\x07\x08\x0A\x0B\x0C\x0D\x0F\x10\x11\x12";
unsigned char pt[16] = "\x50\x68\x12\xA4\x5F\x08\xC8\x89\xB9\x7F\x59\x80\x03\x8B\x83\x59";
unsigned char ct[16];
unsigned char expected[16] =
"\xD8\xF5\x32\x53\x82\x89\xEF\x7D\x06\xB5\x06\xA4\xFD\x5B\xE9\xC9";
int nrounds;
int rc;
nrounds = aes_setup_enc(rk, key, key_bits);
aes_encrypt(rk ,nrounds, pt, ct);
rc = memcmp(ct, expected, 16);
ABTS_INT_EQUAL(tc, 0, rc);
}
static void aes_test2(abts_case *tc, void *data)
{
unsigned char tmp[16];
int nrounds;
int rc;
aes_test_vector_t test_vector[3];
int i;
test_vector[0].key_bits = 128;
test_vector[0].key =
core_malloc(sizeof(char)*KEYLENGTH(test_vector[0].key_bits));
test_vector[0].rk =
core_malloc(sizeof(unsigned int)*RKLENGTH(test_vector[0].key_bits));
memcpy(test_vector[0].key,
"\x95\xA8\xEE\x8E\x89\x97\x9B\x9E"
"\xFD\xCB\xC6\xEB\x97\x97\x52\x8D",
KEYLENGTH(test_vector[0].key_bits));
memcpy(test_vector[0].input,
"\x4E\xC1\x37\xA4\x26\xDA\xBF\x8A"
"\xA0\xBE\xB8\xBC\x0C\x2B\x89\xD6",
16);
memcpy(test_vector[0].cipher_output,
"\xD9\xB6\x5D\x12\x32\xBA\x01\x99"
"\xCD\xBD\x48\x7B\x2A\x1F\xD6\x46",
16);
memcpy(test_vector[0].decipher_output,
"\x95\x70\xC3\x43\x63\x56\x5B\x39"
"\x35\x03\xA0\x01\xC0\xE2\x3B\x65",
16);
test_vector[1].key_bits = 192;
test_vector[1].key =
core_malloc(sizeof(char)*KEYLENGTH(test_vector[1].key_bits));
test_vector[1].rk =
core_malloc(sizeof(unsigned int)*RKLENGTH(test_vector[1].key_bits));
memcpy(test_vector[1].key,
"\x95\xA8\xEE\x8E\x89\x97\x9B\x9E"
"\xFD\xCB\xC6\xEB\x97\x97\x52\x8D"
"\x43\x2D\xC2\x60\x61\x55\x38\x18",
KEYLENGTH(test_vector[1].key_bits));
memcpy(test_vector[1].input ,
"\x4E\xC1\x37\xA4\x26\xDA\xBF\x8A"
"\xA0\xBE\xB8\xBC\x0C\x2B\x89\xD6",
16);
memcpy(test_vector[1].cipher_output,
"\xB1\x8B\xB3\xE7\xE1\x07\x32\xBE"
"\x13\x58\x44\x3A\x50\x4D\xBB\x49",
16);
memcpy(test_vector[1].decipher_output,
"\x29\xDF\xD7\x5B\x85\xCE\xE4\xDE"
"\x6E\x26\xA8\x08\xCD\xC2\xC9\xC3",
16);
test_vector[2].key_bits = 256;
test_vector[2].key =
core_malloc(sizeof(char)*KEYLENGTH(test_vector[2].key_bits));
test_vector[2].rk =
core_malloc(sizeof(unsigned int)*RKLENGTH(test_vector[2].key_bits));
memcpy(test_vector[2].key,
"\x95\xA8\xEE\x8E\x89\x97\x9B\x9E"
"\xFD\xCB\xC6\xEB\x97\x97\x52\x8D"
"\x43\x2D\xC2\x60\x61\x55\x38\x18"
"\xEA\x63\x5E\xC5\xD5\xA7\x72\x7E",
KEYLENGTH(test_vector[2].key_bits));
memcpy(test_vector[2].input ,
"\x4E\xC1\x37\xA4\x26\xDA\xBF\x8A"
"\xA0\xBE\xB8\xBC\x0C\x2B\x89\xD6",
16);
memcpy(test_vector[2].cipher_output,
"\x2F\x9C\xFD\xDB\xFF\xCD\xE6\xB9"
"\xF3\x7E\xF8\xE4\x0D\x51\x2C\xF4",
16);
memcpy(test_vector[2].decipher_output,
"\x11\x0A\x35\x45\xCE\x49\xB8\x4B"
"\xBB\x7B\x35\x23\x61\x08\xFA\x6E",
16);
for (i=0; i<3; i++)
{
nrounds = aes_setup_enc(test_vector[i].rk, test_vector[i].key,
test_vector[i].key_bits);
aes_encrypt(test_vector[i].rk ,nrounds, test_vector[i].input, tmp);
rc = memcmp(tmp, test_vector[i].cipher_output, 16);
ABTS_INT_EQUAL(tc, 0, rc);
nrounds = aes_setup_dec(test_vector[i].rk, test_vector[i].key,
test_vector[i].key_bits);
aes_decrypt(test_vector[i].rk ,nrounds, test_vector[i].input, tmp);
rc = memcmp(tmp, test_vector[i].decipher_output, 16);
ABTS_INT_EQUAL(tc, 0, rc);
CORE_FREE(test_vector[i].key);
CORE_FREE(test_vector[i].rk);
}
}
#if 0
Case #1: Encrypting 16 bytes (1 block) using AES-CBC with 128-bit key
Key : 0x06a9214036b8a15b512e03d534120006
IV : 0x3dafba429d9eb430b422da802c9fac41
Plaintext : "Single block msg"
Ciphertext: 0xe353779c1079aeb82708942dbe77181a
Case #2: Encrypting 32 bytes (2 blocks) using AES-CBC with 128-bit key
Key : 0xc286696d887c9aa0611bbb3e2025a45a
IV : 0x562e17996d093d28ddb3ba695a2e6f58
Plaintext : 0x000102030405060708090a0b0c0d0e0f
101112131415161718191a1b1c1d1e1f
Ciphertext: 0xd296cd94c2cccf8a3a863028b5e1dc0a
7586602d253cfff91b8266bea6d61ab1
Case #3: Encrypting 48 bytes (3 blocks) using AES-CBC with 128-bit key
Key : 0x6c3ea0477630ce21a2ce334aa746c2cd
IV : 0xc782dc4c098c66cbd9cd27d825682c81
Plaintext : "This is a 48-byte message (exactly 3 AES blocks)"
Ciphertext: 0xd0a02b3836451753d493665d33f0e886
2dea54cdb293abc7506939276772f8d5
021c19216bad525c8579695d83ba2684
Case #4: Encrypting 64 bytes (4 blocks) using AES-CBC with 128-bit key
Key : 0x56e47a38c5598974bc46903dba290349
IV : 0x8ce82eefbea0da3c44699ed7db51b7d9
Plaintext : 0xa0a1a2a3a4a5a6a7a8a9aaabacadaeaf
b0b1b2b3b4b5b6b7b8b9babbbcbdbebf
c0c1c2c3c4c5c6c7c8c9cacbcccdcecf
d0d1d2d3d4d5d6d7d8d9dadbdcdddedf
Ciphertext: 0xc30e32ffedc0774e6aff6af0869f71aa
0f3af07a9a31a9c684db207eb0ef8e4e
35907aa632c3ffdf868bb7b29d3d46ad
83ce9f9a102ee99d49a53e87f4c3da55
#endif
typedef struct {
unsigned char key[33];
int key_bits;
unsigned char ivec[33];
unsigned char plain[65];
unsigned int plainlen;
unsigned char cipher[65];
unsigned int cipherlen;
} aes_cbc_test_vector_t;
static void aes_test3(abts_case *tc, void *data)
{
aes_cbc_test_vector_t tv[5] = {
{
"\x06\xa9\x21\x40\x36\xb8\xa1\x5b\x51\x2e\x03\xd5\x34\x12\x00\x06",
128,
"\x3d\xaf\xba\x42\x9d\x9e\xb4\x30\xb4\x22\xda\x80\x2c\x9f\xac\x41",
"Single block msg",
16,
"\xe3\x53\x77\x9c\x10\x79\xae\xb8\x27\x08\x94\x2d\xbe\x77\x18\x1a",
16
}, {
"\xc2\x86\x69\x6d\x88\x7c\x9a\xa0\x61\x1b\xbb\x3e\x20\x25\xa4\x5a",
128,
"\x56\x2e\x17\x99\x6d\x09\x3d\x28\xdd\xb3\xba\x69\x5a\x2e\x6f\x58",
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
32,
"\xd2\x96\xcd\x94\xc2\xcc\xcf\x8a\x3a\x86\x30\x28\xb5\xe1\xdc\x0a"
"\x75\x86\x60\x2d\x25\x3c\xff\xf9\x1b\x82\x66\xbe\xa6\xd6\x1a\xb1",
32
}, {
"\x6c\x3e\xa0\x47\x76\x30\xce\x21\xa2\xce\x33\x4a\xa7\x46\xc2\xcd",
128,
"\xc7\x82\xdc\x4c\x09\x8c\x66\xcb\xd9\xcd\x27\xd8\x25\x68\x2c\x81",
"This is a 48-byte message (exactly 3 AES blocks)",
48,
"\xd0\xa0\x2b\x38\x36\x45\x17\x53\xd4\x93\x66\x5d\x33\xf0\xe8\x86"
"\x2d\xea\x54\xcd\xb2\x93\xab\xc7\x50\x69\x39\x27\x67\x72\xf8\xd5"
"\x02\x1c\x19\x21\x6b\xad\x52\x5c\x85\x79\x69\x5d\x83\xba\x26\x84",
48
}, {
"\x56\xe4\x7a\x38\xc5\x59\x89\x74\xbc\x46\x90\x3d\xba\x29\x03\x49",
128,
"\x8c\xe8\x2e\xef\xbe\xa0\xda\x3c\x44\x69\x9e\xd7\xdb\x51\xb7\xd9",
"\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
"\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
"\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf",
64,
"\xc3\x0e\x32\xff\xed\xc0\x77\x4e\x6a\xff\x6a\xf0\x86\x9f\x71\xaa"
"\x0f\x3a\xf0\x7a\x9a\x31\xa9\xc6\x84\xdb\x20\x7e\xb0\xef\x8e\x4e"
"\x35\x90\x7a\xa6\x32\xc3\xff\xdf\x86\x8b\xb7\xb2\x9d\x3d\x46\xad"
"\x83\xce\x9f\x9a\x10\x2e\xe9\x9d\x49\xa5\x3e\x87\xf4\xc3\xda\x55",
64
}, {
"\x56\xe4\x7a\x38\xc5\x59\x89\x74\xbc\x46\x90\x3d\xba\x29\x03\x49",
128,
"\x8c\xe8\x2e\xef\xbe\xa0\xda\x3c\x44\x69\x9e\xd7\xdb\x51\xb7\xd9",
"\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
"\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
"\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd",
62,
"\xc3\x0e\x32\xff\xed\xc0\x77\x4e\x6a\xff\x6a\xf0\x86\x9f\x71\xaa"
"\x0f\x3a\xf0\x7a\x9a\x31\xa9\xc6\x84\xdb\x20\x7e\xb0\xef\x8e\x4e"
"\x35\x90\x7a\xa6\x32\xc3\xff\xdf\x86\x8b\xb7\xb2\x9d\x3d\x46\xad"
"\x5d\x96\x74\x07\xe9\x86\x0c\x0b\x50\x80\x4a\xfb\x69\xc1\x13\xaa",
64
}
};
unsigned char out[128];
unsigned int i, rc, outlen;
c_uint8_t ivec[32];
for (i = 0; i < 5; i++)
{
outlen = sizeof(out);
memcpy(ivec, tv[i].ivec, 16);
aes_cbc_encrypt(tv[i].key, tv[i].key_bits, ivec,
tv[i].plain, tv[i].plainlen, out, &outlen);
ABTS_INT_EQUAL(tc, tv[i].cipherlen, outlen);
rc = memcmp(tv[i].cipher, out, tv[i].cipherlen);
ABTS_INT_EQUAL(tc, 0, rc);
outlen = sizeof(out);
memcpy(ivec, tv[i].ivec, 16);
aes_cbc_decrypt(tv[i].key, tv[i].key_bits, ivec,
tv[i].cipher, tv[i].cipherlen, out, &outlen);
ABTS_INT_EQUAL(tc, tv[i].cipherlen, outlen);
rc = memcmp(tv[i].plain, out, tv[i].plainlen);
ABTS_INT_EQUAL(tc, 0, rc);
}
}
/* RFC 4493
--------------------------------------------------
Subkey Generation
K 2b7e1516 28aed2a6 abf71588 09cf4f3c
AES-128(key,0) 7df76b0c 1ab899b3 3e42f047 b91b546f
K1 fbeed618 35713366 7c85e08f 7236a8de
K2 f7ddac30 6ae266cc f90bc11e e46d513b
--------------------------------------------------
--------------------------------------------------
Example 1: len = 0
M
AES-CMAC bb1d6929 e9593728 7fa37d12 9b756746
--------------------------------------------------
Example 2: len = 16
M 6bc1bee2 2e409f96 e93d7e11 7393172a
AES-CMAC 070a16b4 6b4d4144 f79bdd9d d04a287c
--------------------------------------------------
Example 3: len = 40
M 6bc1bee2 2e409f96 e93d7e11 7393172a
ae2d8a57 1e03ac9c 9eb76fac 45af8e51
30c81c46 a35ce411
AES-CMAC dfa66747 de9ae630 30ca3261 1497c827
--------------------------------------------------
Example 4: len = 64
M 6bc1bee2 2e409f96 e93d7e11 7393172a
ae2d8a57 1e03ac9c 9eb76fac 45af8e51
30c81c46 a35ce411 e5fbc119 1a0a52ef
f69f2445 df4f9b17 ad2b417b e66c3710
AES-CMAC 51f0bebf 7e3b9d92 fc497417 79363cfe
--------------------------------------------------
*/
static void cmac_test(abts_case *tc, void *data)
{
c_uint8_t key[16] = {
0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,
0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c
};
c_uint8_t msg[4][64] = {
{
/* Empty string */
},
{
0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,
0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a
}, {
0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,
0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a,
0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c,
0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51,
0x30,0xc8,0x1c,0x46,0xa3,0x5c,0xe4,0x11
}, {
0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,
0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a,
0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c,
0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51,
0x30,0xc8,0x1c,0x46,0xa3,0x5c,0xe4,0x11,
0xe5,0xfb,0xc1,0x19,0x1a,0x0a,0x52,0xef,
0xf6,0x9f,0x24,0x45,0xdf,0x4f,0x9b,0x17,
0xad,0x2b,0x41,0x7b,0xe6,0x6c,0x37,0x10
}
};
c_uint32_t msglen[4] = {0, 16, 40, 64};
c_uint8_t cmac_answer[4][16] = {
{
0xbb,0x1d,0x69,0x29,0xe9,0x59,0x37,0x28,
0x7f,0xa3,0x7d,0x12,0x9b,0x75,0x67,0x46
}, {
0x07,0x0a,0x16,0xb4,0x6b,0x4d,0x41,0x44,
0xf7,0x9b,0xdd,0x9d,0xd0,0x4a,0x28,0x7c
}, {
0xdf,0xa6,0x67,0x47,0xde,0x9a,0xe6,0x30,
0x30,0xca,0x32,0x61,0x14,0x97,0xc8,0x27
}, {
0x51,0xf0,0xbe,0xbf,0x7e,0x3b,0x9d,0x92,
0xfc,0x49,0x74,0x17,0x79,0x36,0x3c,0xfe
}
};
c_uint8_t cmac[16];
int i, rc;
status_t rv;
for (i = 0; i < 4; i++)
{
rv = aes_cmac_calculate(cmac, key, msg[i], msglen[i]);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rc = memcmp(cmac, cmac_answer[i], 16);
ABTS_INT_EQUAL(tc, 0, rc);
}
for (i = 0; i < 4; i++)
{
rv = aes_cmac_verify(cmac_answer[i], key, msg[i], msglen[i]);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
}
key[0] = 0;
for (i = 0; i < 4; i++)
{
rv = aes_cmac_verify(cmac_answer[i], key, msg[i], msglen[i]);
ABTS_INT_EQUAL(tc, ERR_INVALID_CMAC, rv);
}
}
abts_suite *testaes(abts_suite *suite)
{
suite = ADD_SUITE(suite);
abts_run_test(suite, aes_test1, NULL);
abts_run_test(suite, aes_test2, NULL);
abts_run_test(suite, aes_test3, NULL);
abts_run_test(suite, cmac_test, NULL);
return suite;
}
nextepc-0.3.10/lib/core/test/testatomic.c 0000664 0000000 0000000 00000027234 13335533574 0020261 0 ustar 00root root 0000000 0000000 #include "core_atomic.h"
#include "core_thread.h"
#include "core_mutex.h"
#include "testutil.h"
static void test_set32(abts_case *tc, void *data)
{
c_uint32_t y32;
atomic_set32(&y32, 2);
ABTS_INT_EQUAL(tc, 2, y32);
}
static void test_read32(abts_case *tc, void *data)
{
c_uint32_t y32;
atomic_set32(&y32, 2);
ABTS_INT_EQUAL(tc, 2, atomic_read32(&y32));
}
static void test_dec32(abts_case *tc, void *data)
{
c_uint32_t y32;
int rv;
atomic_set32(&y32, 2);
rv = atomic_dec32(&y32);
ABTS_INT_EQUAL(tc, 1, y32);
ABTS_ASSERT(tc, "atomic_dec returned zero when it shouldn't", rv != 0);
rv = atomic_dec32(&y32);
ABTS_INT_EQUAL(tc, 0, y32);
ABTS_ASSERT(tc, "atomic_dec didn't returned zero when it should", rv == 0);
}
static void test_xchg32(abts_case *tc, void *data)
{
c_uint32_t oldval;
c_uint32_t y32;
atomic_set32(&y32, 100);
oldval = atomic_xchg32(&y32, 50);
ABTS_INT_EQUAL(tc, 100, oldval);
ABTS_INT_EQUAL(tc, 50, y32);
}
static void test_xchgptr(abts_case *tc, void *data)
{
int a;
void *ref = "little piggy";
void *target_ptr = ref;
void *old_ptr;
old_ptr = atomic_xchgptr(&target_ptr, &a);
ABTS_PTR_EQUAL(tc, ref, old_ptr);
ABTS_PTR_EQUAL(tc, &a, (void *) target_ptr);
}
static void test_cas_equal(abts_case *tc, void *data)
{
c_uint32_t casval = 0;
c_uint32_t oldval;
oldval = atomic_cas32(&casval, 12, 0);
ABTS_INT_EQUAL(tc, 0, oldval);
ABTS_INT_EQUAL(tc, 12, casval);
}
static void test_cas_equal_nonnull(abts_case *tc, void *data)
{
c_uint32_t casval = 12;
c_uint32_t oldval;
oldval = atomic_cas32(&casval, 23, 12);
ABTS_INT_EQUAL(tc, 12, oldval);
ABTS_INT_EQUAL(tc, 23, casval);
}
static void test_cas_notequal(abts_case *tc, void *data)
{
c_uint32_t casval = 12;
c_uint32_t oldval;
oldval = atomic_cas32(&casval, 23, 2);
ABTS_INT_EQUAL(tc, 12, oldval);
ABTS_INT_EQUAL(tc, 12, casval);
}
static void test_casptr_equal(abts_case *tc, void *data)
{
int a;
void *target_ptr = NULL;
void *old_ptr;
old_ptr = atomic_casptr(&target_ptr, &a, NULL);
ABTS_PTR_EQUAL(tc, NULL, old_ptr);
ABTS_PTR_EQUAL(tc, &a, (void *) target_ptr);
}
static void test_casptr_equal_nonnull(abts_case *tc, void *data)
{
int a, b;
void *target_ptr = &a;
void *old_ptr;
old_ptr = atomic_casptr(&target_ptr, &b, &a);
ABTS_PTR_EQUAL(tc, &a, old_ptr);
ABTS_PTR_EQUAL(tc, &b, (void *) target_ptr);
}
static void test_casptr_notequal(abts_case *tc, void *data)
{
int a, b;
void *target_ptr = &a;
void *old_ptr;
old_ptr = atomic_casptr(&target_ptr, &a, &b);
ABTS_PTR_EQUAL(tc, &a, old_ptr);
ABTS_PTR_EQUAL(tc, &a, (void *) target_ptr);
}
static void test_add32(abts_case *tc, void *data)
{
c_uint32_t oldval;
c_uint32_t y32;
atomic_set32(&y32, 23);
oldval = atomic_add32(&y32, 4);
ABTS_INT_EQUAL(tc, 23, oldval);
ABTS_INT_EQUAL(tc, 27, y32);
}
static void test_add32_neg(abts_case *tc, void *data)
{
c_uint32_t oldval;
c_uint32_t y32;
atomic_set32(&y32, 23);
oldval = atomic_add32(&y32, -10);
ABTS_INT_EQUAL(tc, 23, oldval);
ABTS_INT_EQUAL(tc, 13, y32);
}
static void test_inc32(abts_case *tc, void *data)
{
c_uint32_t oldval;
c_uint32_t y32;
atomic_set32(&y32, 23);
oldval = atomic_inc32(&y32);
ABTS_INT_EQUAL(tc, 23, oldval);
ABTS_INT_EQUAL(tc, 24, y32);
}
static void test_set_add_inc_sub(abts_case *tc, void *data)
{
c_uint32_t y32;
atomic_set32(&y32, 0);
atomic_add32(&y32, 20);
atomic_inc32(&y32);
atomic_sub32(&y32, 10);
ABTS_INT_EQUAL(tc, 11, y32);
}
static void test_wrap_zero(abts_case *tc, void *data)
{
c_uint32_t y32;
c_uint32_t rv;
c_uint32_t minus1 = (c_uint32_t)-1;
char str[256];;
atomic_set32(&y32, 0);
rv = atomic_dec32(&y32);
ABTS_ASSERT(tc, "atomic_dec32 on zero returned zero.", rv != 0);
sprintf(str, "zero wrap failed: 0 - 1 = %d", y32);
ABTS_ASSERT(tc, str, y32 == minus1);
}
static void test_inc_neg1(abts_case *tc, void *data)
{
c_uint32_t y32 = (c_uint32_t)-1;
c_uint32_t minus1 = (c_uint32_t)-1;
c_uint32_t rv;
char str[256];
rv = atomic_inc32(&y32);
ABTS_ASSERT(tc, "atomic_inc32 didn't return the old value.", rv == minus1);
sprintf(str, "zero wrap failed: -1 + 1 = %d", y32);
ABTS_ASSERT(tc, str, y32 == 0);
}
void *THREAD_FUNC thread_func_mutex(thread_id id, void *data);
void *THREAD_FUNC thread_func_atomic(thread_id id, void *data);
mutex_id thread_lock;
volatile c_uint32_t mutex_locks = 0;
volatile c_uint32_t atomic_ops = 0;
status_t exit_ret_val = 123; /* just some made up number to check on later */
#define NUM_THREADS 40
#define NUM_ITERATIONS 20000
void *THREAD_FUNC thread_func_mutex(thread_id id, void *data)
{
int i;
for (i = 0; i < NUM_ITERATIONS; i++) {
mutex_lock(thread_lock);
mutex_locks++;
mutex_unlock(thread_lock);
}
thread_exit(id, exit_ret_val);
return NULL;
}
void *THREAD_FUNC thread_func_atomic(thread_id id, void *data)
{
int i;
for (i = 0; i < NUM_ITERATIONS ; i++) {
atomic_inc32(&atomic_ops);
atomic_add32(&atomic_ops, 2);
atomic_dec32(&atomic_ops);
atomic_dec32(&atomic_ops);
}
thread_exit(id, exit_ret_val);
return NULL;
}
static void test_atomics_threaded(abts_case *tc, void *data)
{
thread_id t1[NUM_THREADS];
thread_id t2[NUM_THREADS];
status_t rv;
int i;
#ifdef HAVE_PTHREAD_SETCONCURRENCY
pthread_setconcurrency(8);
#endif
rv = mutex_create(&thread_lock, MUTEX_DEFAULT);
ABTS_ASSERT(tc, "Could not create lock", rv == CORE_OK) ;
for (i = 0; i < NUM_THREADS; i++) {
status_t r1, r2;
r1 = thread_create(&t1[i], NULL, thread_func_mutex, NULL);
r2 = thread_create(&t2[i], NULL, thread_func_atomic, NULL);
ABTS_ASSERT(tc, "Failed creating threads", !r1 && !r2);
}
for (i = 0; i < NUM_THREADS; i++) {
status_t s1, s2;
thread_join(&s1, t1[i]);
thread_join(&s2, t2[i]);
ABTS_ASSERT(tc, "Invalid return value from thread_join",
s1 == exit_ret_val && s2 == exit_ret_val);
}
ABTS_INT_EQUAL(tc, NUM_THREADS * NUM_ITERATIONS, mutex_locks);
ABTS_INT_EQUAL(tc, NUM_THREADS * NUM_ITERATIONS,
atomic_read32(&atomic_ops));
rv = mutex_delete(thread_lock);
ABTS_ASSERT(tc, "Failed creating threads", rv == CORE_OK);
}
#undef NUM_THREADS
#define NUM_THREADS 7
typedef struct tbox_t tbox_t;
struct tbox_t {
abts_case *tc;
c_uint32_t *mem;
c_uint32_t preval;
c_uint32_t postval;
c_uint32_t loop;
void (*func)(tbox_t *box);
};
static CORE_INLINE void busyloop_read32(tbox_t *tbox)
{
c_uint32_t val;
do {
val = atomic_read32(tbox->mem);
if (val != tbox->preval)
thread_yield();
else
break;
} while (1);
}
static void busyloop_set32(tbox_t *tbox)
{
do {
busyloop_read32(tbox);
atomic_set32(tbox->mem, tbox->postval);
} while (--tbox->loop);
}
static void busyloop_add32(tbox_t *tbox)
{
c_uint32_t val;
do {
busyloop_read32(tbox);
val = atomic_add32(tbox->mem, tbox->postval);
mutex_lock(thread_lock);
ABTS_INT_EQUAL(tbox->tc, val, tbox->preval);
mutex_unlock(thread_lock);
} while (--tbox->loop);
}
static void busyloop_sub32(tbox_t *tbox)
{
do {
busyloop_read32(tbox);
atomic_sub32(tbox->mem, tbox->postval);
} while (--tbox->loop);
}
static void busyloop_inc32(tbox_t *tbox)
{
c_uint32_t val;
do {
busyloop_read32(tbox);
val = atomic_inc32(tbox->mem);
mutex_lock(thread_lock);
ABTS_INT_EQUAL(tbox->tc, val, tbox->preval);
mutex_unlock(thread_lock);
} while (--tbox->loop);
}
static void busyloop_dec32(tbox_t *tbox)
{
c_uint32_t val;
do {
busyloop_read32(tbox);
val = atomic_dec32(tbox->mem);
mutex_lock(thread_lock);
ABTS_INT_NEQUAL(tbox->tc, 0, val);
mutex_unlock(thread_lock);
} while (--tbox->loop);
}
static void busyloop_cas32(tbox_t *tbox)
{
c_uint32_t val;
do {
do {
val = atomic_cas32(tbox->mem, tbox->postval, tbox->preval);
if (val != tbox->preval)
thread_yield();
else
break;
} while (1);
} while (--tbox->loop);
}
static void busyloop_xchg32(tbox_t *tbox)
{
c_uint32_t val;
do {
busyloop_read32(tbox);
val = atomic_xchg32(tbox->mem, tbox->postval);
mutex_lock(thread_lock);
ABTS_INT_EQUAL(tbox->tc, val, tbox->preval);
mutex_unlock(thread_lock);
} while (--tbox->loop);
}
static void *THREAD_FUNC thread_func_busyloop(thread_id id, void *data)
{
tbox_t *tbox = data;
tbox->func(tbox);
thread_exit(id, 0);
return NULL;
}
static void test_atomics_busyloop_threaded(abts_case *tc, void *data)
{
unsigned int i;
status_t rv;
c_uint32_t count = 0;
tbox_t tbox[NUM_THREADS];
thread_id thread[NUM_THREADS];
rv = mutex_create(&thread_lock, MUTEX_DEFAULT);
ABTS_ASSERT(tc, "Could not create lock", rv == CORE_OK);
/* get ready */
for (i = 0; i < NUM_THREADS; i++) {
tbox[i].tc = tc;
tbox[i].mem = &count;
tbox[i].loop = 50;
}
tbox[0].preval = 98;
tbox[0].postval = 3891;
tbox[0].func = busyloop_add32;
tbox[1].preval = 3989;
tbox[1].postval = 1010;
tbox[1].func = busyloop_sub32;
tbox[2].preval = 2979;
tbox[2].postval = 0; /* not used */
tbox[2].func = busyloop_inc32;
tbox[3].preval = 2980;
tbox[3].postval = 16384;
tbox[3].func = busyloop_set32;
tbox[4].preval = 16384;
tbox[4].postval = 0; /* not used */
tbox[4].func = busyloop_dec32;
tbox[5].preval = 16383;
tbox[5].postval = 1048576;
tbox[5].func = busyloop_cas32;
tbox[6].preval = 1048576;
tbox[6].postval = 98; /* goto tbox[0] */
tbox[6].func = busyloop_xchg32;
/* get set */
for (i = 0; i < NUM_THREADS; i++) {
rv = thread_create(&thread[i], NULL, thread_func_busyloop,
&tbox[i]);
ABTS_ASSERT(tc, "Failed creating thread", rv == CORE_OK);
}
/* go! */
atomic_set32(tbox->mem, 98);
for (i = 0; i < NUM_THREADS; i++) {
status_t retval;
rv = thread_join(&retval, thread[i]);
ABTS_ASSERT(tc, "Thread join failed", rv == CORE_OK);
ABTS_ASSERT(tc, "Invalid return value from thread_join", retval == 0);
}
ABTS_INT_EQUAL(tbox->tc, 98, count);
rv = mutex_delete(thread_lock);
ABTS_ASSERT(tc, "Failed creating threads", rv == CORE_OK);
}
abts_suite *testatomic(abts_suite *suite)
{
suite = ADD_SUITE(suite)
abts_run_test(suite, test_set32, NULL);
abts_run_test(suite, test_read32, NULL);
abts_run_test(suite, test_dec32, NULL);
abts_run_test(suite, test_xchg32, NULL);
abts_run_test(suite, test_xchgptr, NULL);
abts_run_test(suite, test_cas_equal, NULL);
abts_run_test(suite, test_cas_equal_nonnull, NULL);
abts_run_test(suite, test_cas_notequal, NULL);
abts_run_test(suite, test_casptr_equal, NULL);
abts_run_test(suite, test_casptr_equal_nonnull, NULL);
abts_run_test(suite, test_casptr_notequal, NULL);
abts_run_test(suite, test_add32, NULL);
abts_run_test(suite, test_add32_neg, NULL);
abts_run_test(suite, test_inc32, NULL);
abts_run_test(suite, test_set_add_inc_sub, NULL);
abts_run_test(suite, test_wrap_zero, NULL);
abts_run_test(suite, test_inc_neg1, NULL);
abts_run_test(suite, test_atomics_threaded, NULL);
abts_run_test(suite, test_atomics_busyloop_threaded, NULL);
return suite;
}
nextepc-0.3.10/lib/core/test/testdir.c 0000664 0000000 0000000 00000007124 13335533574 0017557 0 ustar 00root root 0000000 0000000 /* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "core_file.h"
#include "testutil.h"
static void test_mkdir(abts_case *tc, void *data)
{
status_t rv;
file_info_t finfo;
rv = dir_make("data/testdir", FILE_UREAD | FILE_UWRITE | FILE_UEXECUTE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = file_stat(&finfo, "data/testdir", FILE_INFO_TYPE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_INT_EQUAL(tc, FILE_DIR, finfo.filetype);
}
static void test_mkdir_recurs(abts_case *tc, void *data)
{
status_t rv;
file_info_t finfo;
rv = dir_make_recursive("data/one/two/three",
FILE_UREAD | FILE_UWRITE | FILE_UEXECUTE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = file_stat(&finfo, "data/one", FILE_INFO_TYPE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_INT_EQUAL(tc, FILE_DIR, finfo.filetype);
rv = file_stat(&finfo, "data/one/two", FILE_INFO_TYPE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_INT_EQUAL(tc, FILE_DIR, finfo.filetype);
rv = file_stat(&finfo, "data/one/two/three", FILE_INFO_TYPE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_INT_EQUAL(tc, FILE_DIR, finfo.filetype);
}
static void test_remove(abts_case *tc, void *data)
{
status_t rv;
file_info_t finfo;
rv = dir_remove("data/testdir");
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = file_stat(&finfo, "data/testdir", FILE_INFO_TYPE);
ABTS_INT_EQUAL(tc, 1, STATUS_IS_ENOENT(rv));
}
static void test_removeall_fail(abts_case *tc, void *data)
{
status_t rv;
rv = dir_remove("data/one");
ABTS_INT_EQUAL(tc, 1, STATUS_IS_ENOTEMPTY(rv));
}
static void test_removeall(abts_case *tc, void *data)
{
status_t rv;
rv = dir_remove("data/one/two/three");
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = dir_remove("data/one/two");
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = dir_remove("data/one");
ABTS_INT_EQUAL(tc, CORE_OK, rv);
}
static void test_remove_notthere(abts_case *tc, void *data)
{
status_t rv;
rv = dir_remove("data/notthere");
ABTS_INT_EQUAL(tc, 1, STATUS_IS_ENOENT(rv));
}
static void test_mkdir_twice(abts_case *tc, void *data)
{
status_t rv;
rv = dir_make("data/testdir", FILE_UREAD | FILE_UWRITE | FILE_UEXECUTE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = dir_make("data/testdir", FILE_UREAD | FILE_UWRITE | FILE_UEXECUTE);
ABTS_INT_EQUAL(tc, 1, STATUS_IS_EEXIST(rv));
rv = dir_remove("data/testdir");
ABTS_INT_EQUAL(tc, CORE_OK, rv);
}
abts_suite *testdir(abts_suite *suite)
{
suite = ADD_SUITE(suite)
abts_run_test(suite, test_mkdir, NULL);
abts_run_test(suite, test_mkdir_recurs, NULL);
abts_run_test(suite, test_remove, NULL);
abts_run_test(suite, test_removeall_fail, NULL);
abts_run_test(suite, test_removeall, NULL);
abts_run_test(suite, test_remove_notthere, NULL);
abts_run_test(suite, test_mkdir_twice, NULL);
return suite;
}
nextepc-0.3.10/lib/core/test/testds.c 0000664 0000000 0000000 00000053027 13335533574 0017412 0 ustar 00root root 0000000 0000000 #include "core_pool.h"
#include "core_list.h"
#include "core_queue.h"
#include "core_ringbuf.h"
#include "testutil.h"
/*****************************************************************************
* test for core_pool.h
*/
typedef struct {
char m1;
int m2;
} pt_type1;
#define SIZE_OF_TPOOL1 5
#define SIZE_OF_TPOOL2 5
typedef char type_of_tpool1;
typedef pt_type1 type_of_tpool2;
pool_declare(tpool1, type_of_tpool1, SIZE_OF_TPOOL1);
static void pool_test_core1(abts_case *tc, void *data, int start)
{
int i, j, n;
type_of_tpool1 *org[SIZE_OF_TPOOL1+1];
type_of_tpool1 *node[SIZE_OF_TPOOL1+1];
pool_init(&tpool1, SIZE_OF_TPOOL1);
/* Check basic members */
n = pool_size(&tpool1);
ABTS_INT_EQUAL(tc, SIZE_OF_TPOOL1, n);
n = pool_avail(&tpool1);
ABTS_INT_EQUAL(tc, SIZE_OF_TPOOL1, n);
n = pool_used(&tpool1);
ABTS_INT_EQUAL(tc, 0, n);
/* Allocation up to start index */
for (i = 0; i < start; i++)
{
pool_alloc_node(&tpool1, &node[i]);
/* Check not null */
ABTS_PTR_NOTNULL(tc, node[i]);
/* Check the number of available nodes */
n = pool_avail(&tpool1);
ABTS_INT_EQUAL(tc, SIZE_OF_TPOOL1 - (i + 1), n);
}
/* Free all allocated nodes */
for (i = 0; i < start; i++)
{
pool_free_node(&tpool1, node[i]);
/* Check the number of available nodes */
n = pool_avail(&tpool1);
ABTS_INT_EQUAL(tc, SIZE_OF_TPOOL1 - start + (i + 1), n);
}
/* Allocation up to maximum pool size */
for (i = 0; i < SIZE_OF_TPOOL1; i++)
{
pool_alloc_node(&tpool1, &node[i]);
org[i] = node[i];
/* Check not null */
ABTS_PTR_NOTNULL(tc, node[i]);
/* Check the number of available nodes */
n = pool_avail(&tpool1);
ABTS_INT_EQUAL(tc, SIZE_OF_TPOOL1 - (i + 1), n);
}
/* Free all allocated */
for (i = 0; i < SIZE_OF_TPOOL1; i++)
{
pool_free_node(&tpool1, node[i]);
/* Check the number of available nodes */
n = pool_avail(&tpool1);
ABTS_INT_EQUAL(tc, i + 1, n);
}
/* Check that addresses of nodes are same with original ones */
n = 0;
for (i = 0; i < SIZE_OF_TPOOL1; i++)
{
pool_alloc_node(&tpool1, &node[i]);
for (j = 0; j < SIZE_OF_TPOOL1; j++)
{
if (node[i] == org[j])
n++;
}
}
/* Free all allocated */
for (i = 0; i < SIZE_OF_TPOOL1; i++)
{
pool_free_node(&tpool1, node[i]);
/* Check the number of available nodes */
n = pool_avail(&tpool1);
ABTS_INT_EQUAL(tc, i + 1, n);
}
pool_final(&tpool1);
}
static void pool_test_core2(abts_case *tc, void *data, int start)
{
int i, j, n;
type_of_tpool2 *org[SIZE_OF_TPOOL2+1];
type_of_tpool2 *node[SIZE_OF_TPOOL2+1];
pool_init(&tpool1, SIZE_OF_TPOOL2);
/* Check basic members */
n = pool_size(&tpool1);
ABTS_INT_EQUAL(tc, SIZE_OF_TPOOL2, n);
n = pool_avail(&tpool1);
ABTS_INT_EQUAL(tc, SIZE_OF_TPOOL2, n);
n = pool_used(&tpool1);
ABTS_INT_EQUAL(tc, 0, n);
/* Allocation up to start index */
for (i = 0; i < start; i++)
{
pool_alloc_node(&tpool1, &node[i]);
/* Check not null */
ABTS_PTR_NOTNULL(tc, node[i]);
/* Check the number of available nodes */
n = pool_avail(&tpool1);
ABTS_INT_EQUAL(tc, SIZE_OF_TPOOL2 - (i + 1), n);
}
/* Free all allocated nodes */
for (i = 0; i < start; i++)
{
pool_free_node(&tpool1, node[i]);
/* Check the number of available nodes */
n = pool_avail(&tpool1);
ABTS_INT_EQUAL(tc, SIZE_OF_TPOOL2 - start + (i + 1), n);
}
/* Allocation up to maximum pool size */
for (i = 0; i < SIZE_OF_TPOOL2; i++)
{
pool_alloc_node(&tpool1, &node[i]);
org[i] = node[i];
/* Check not null */
ABTS_PTR_NOTNULL(tc, node[i]);
/* Check the number of available nodes */
n = pool_avail(&tpool1);
ABTS_INT_EQUAL(tc, SIZE_OF_TPOOL2 - (i + 1), n);
}
/* Free all allocated */
for (i = 0; i < SIZE_OF_TPOOL2; i++)
{
pool_free_node(&tpool1, node[i]);
/* Check the number of available nodes */
n = pool_avail(&tpool1);
ABTS_INT_EQUAL(tc, i + 1, n);
}
/* Check that addresses of nodes are same with original ones */
n = 0;
for (i = 0; i < SIZE_OF_TPOOL2; i++)
{
pool_alloc_node(&tpool1, &node[i]);
for (j = 0; j < SIZE_OF_TPOOL2; j++)
{
if (node[i] == org[j])
n++;
}
}
/* Free all allocated */
for (i = 0; i < SIZE_OF_TPOOL2; i++)
{
pool_free_node(&tpool1, node[i]);
/* Check the number of available nodes */
n = pool_avail(&tpool1);
ABTS_INT_EQUAL(tc, i + 1, n);
}
pool_final(&tpool1);
}
static void pool_test1(abts_case *tc, void *data)
{
int i;
for (i = 0; i < SIZE_OF_TPOOL1; i++)
pool_test_core1(tc, data, i);
}
static void pool_test2(abts_case *tc, void *data)
{
int i;
for (i = 0; i < SIZE_OF_TPOOL2; i++)
pool_test_core2(tc, data, i);
}
/*****************************************************************************
* test for core_list.h
*/
typedef struct {
lnode_t node;
int m1;
} lt_type1;
list_t tlist1;
int lttype1_compare(lt_type1 *pnode1, lt_type1 *pnode2)
{
if (pnode1->m1 == pnode2->m1)
return 0;
else if (pnode1->m1 < pnode2->m1)
return -1;
else
return 1;
}
#define SIZE_OF_lt_type1 16
static void list_test1(abts_case *tc, void *data)
{
int i;
lt_type1 *iter, node[SIZE_OF_lt_type1];
for (i = 0; i < SIZE_OF_lt_type1; i++)
node[i].m1 = i;
/* Initialize head of list */
list_init(&tlist1);
/* Check list is empty */
ABTS_TRUE(tc, list_is_empty(&tlist1));
/* Confirm that any node can't be get */
iter = list_first(&tlist1);
ABTS_PTR_NULL(tc, iter);
/* Add a node */
list_append(&tlist1, &node[0]);
/* Iterate from the first. And check the pointers */
iter = list_first(&tlist1);
ABTS_PTR_EQUAL(tc, &node[0], iter);
iter = list_next(iter);
ABTS_PTR_NULL(tc, iter);
/* Iterate from the last. And check the pointers */
iter = list_last(&tlist1);
ABTS_PTR_EQUAL(tc, &node[0], iter);
iter = list_prev(iter);
ABTS_PTR_NULL(tc, iter);
/* Add two nodes */
list_append(&tlist1, &node[1]);
list_append(&tlist1, &node[2]);
/* Iterate from the first. And check the pointers */
iter = list_first(&tlist1);
ABTS_PTR_EQUAL(tc, &node[0], iter);
iter = list_next(iter);
ABTS_PTR_EQUAL(tc, &node[1], iter);
iter = list_next(iter);
ABTS_PTR_EQUAL(tc, &node[2], iter);
iter = list_next(iter);
ABTS_PTR_NULL(tc, iter);
/* Iterate from the last. And check the pointers */
iter = list_last(&tlist1);
ABTS_PTR_EQUAL(tc, &node[2], iter);
iter = list_prev(iter);
ABTS_PTR_EQUAL(tc, &node[1], iter);
iter = list_prev(iter);
ABTS_PTR_EQUAL(tc, &node[0], iter);
iter = list_prev(iter);
ABTS_PTR_NULL(tc, iter);
/* Remove all nodes */
list_remove(&tlist1, &node[0]);
list_remove(&tlist1, &node[1]);
list_remove(&tlist1, &node[2]);
/* Check list is empty */
ABTS_TRUE(tc, list_is_empty(&tlist1));
}
static void list_test2(abts_case *tc, void *data)
{
int i;
lt_type1 *iter, node[SIZE_OF_lt_type1];
for (i = 0; i < SIZE_OF_lt_type1; i++)
node[i].m1 = i;
/* Initialize head of list */
list_init(&tlist1);
/* Check list is empty */
ABTS_TRUE(tc, list_is_empty(&tlist1));
/* Confirm that any node can't be get */
iter = list_first(&tlist1);
ABTS_PTR_NULL(tc, iter);
/* Add a node */
list_prepend(&tlist1, &node[0]);
/* Iterate from the first. And check the pointers */
iter = list_first(&tlist1);
ABTS_PTR_EQUAL(tc, &node[0], iter);
iter = list_next(iter);
ABTS_PTR_NULL(tc, iter);
/* Iterate from the last. And check the pointers */
iter = list_last(&tlist1);
ABTS_PTR_EQUAL(tc, &node[0], iter);
iter = list_prev(iter);
ABTS_PTR_NULL(tc, iter);
/* Add two nodes */
list_prepend(&tlist1, &node[1]);
list_prepend(&tlist1, &node[2]);
/* Iterate from the first. And check the pointers */
iter = list_first(&tlist1);
ABTS_PTR_EQUAL(tc, &node[2], iter);
iter = list_next(iter);
ABTS_PTR_EQUAL(tc, &node[1], iter);
iter = list_next(iter);
ABTS_PTR_EQUAL(tc, &node[0], iter);
iter = list_next(iter);
ABTS_PTR_NULL(tc, iter);
/* Iterate from the last. And check the pointers */
iter = list_last(&tlist1);
ABTS_PTR_EQUAL(tc, &node[0], iter);
iter = list_prev(iter);
ABTS_PTR_EQUAL(tc, &node[1], iter);
iter = list_prev(iter);
ABTS_PTR_EQUAL(tc, &node[2], iter);
iter = list_prev(iter);
ABTS_PTR_NULL(tc, iter);
/* Remove all nodes */
list_remove(&tlist1, &node[2]);
list_remove(&tlist1, &node[1]);
list_remove(&tlist1, &node[0]);
/* Check list is empty */
ABTS_TRUE(tc, list_is_empty(&tlist1));
}
static void list_test3(abts_case *tc, void *data)
{
int i;
lt_type1 *iter, node[SIZE_OF_lt_type1];
for (i = 0; i < SIZE_OF_lt_type1; i++)
node[i].m1 = i;
/* Initialize head of list */
list_init(&tlist1);
/* Add three nodes */
for (i = 0; i < 3; i++)
list_append(&tlist1, &node[i]);
/* Iterate from the first. And check the pointers */
i = 0; iter = list_first(&tlist1);
while (iter)
{
ABTS_PTR_EQUAL(tc, &node[i++], iter);
iter = list_next(iter);
}
ABTS_INT_EQUAL(tc, 3, i);
/* Iterate from the last. And check the pointers */
i = 0; iter = list_last(&tlist1);
while (iter)
{
ABTS_PTR_EQUAL(tc, &node[3 - (++i)], iter);
iter = list_prev(iter);
}
ABTS_INT_EQUAL(tc, 3, i);
/* Insert three nodes by list_insert_prev() */
list_insert_prev(&tlist1, &node[0], &node[3]);
list_insert_prev(&tlist1, &node[1], &node[4]);
list_insert_prev(&tlist1, &node[2], &node[5]);
/* Iterate from the first. And check the pointers */
iter = list_first(&tlist1);
ABTS_PTR_EQUAL(tc, &node[3], iter);
iter = list_next(iter);
ABTS_PTR_EQUAL(tc, &node[0], iter);
iter = list_next(iter);
ABTS_PTR_EQUAL(tc, &node[4], iter);
iter = list_next(iter);
ABTS_PTR_EQUAL(tc, &node[1], iter);
iter = list_next(iter);
ABTS_PTR_EQUAL(tc, &node[5], iter);
iter = list_next(iter);
ABTS_PTR_EQUAL(tc, &node[2], iter);
iter = list_next(iter);
ABTS_PTR_NULL(tc, iter);
/* Remove three nodes inserted by list_insert_prev() */
list_remove(&tlist1, &node[3]);
list_remove(&tlist1, &node[4]);
list_remove(&tlist1, &node[5]);
/* Iterate from the first. And check the pointers */
iter = list_first(&tlist1);
ABTS_PTR_EQUAL(tc, &node[0], iter);
iter = list_next(iter);
ABTS_PTR_EQUAL(tc, &node[1], iter);
iter = list_next(iter);
ABTS_PTR_EQUAL(tc, &node[2], iter);
iter = list_next(iter);
ABTS_PTR_NULL(tc, iter);
}
static void list_test4(abts_case *tc, void *data)
{
int i;
lt_type1 *iter, node[SIZE_OF_lt_type1];
for (i = 0; i < SIZE_OF_lt_type1; i++)
node[i].m1 = i;
/* Initialize head of list */
list_init(&tlist1);
/* Add three nodes */
for (i = 0; i < 3; i++)
list_append(&tlist1, &node[i]);
/* Iterate from the first. And check the pointers */
i = 0; iter = list_first(&tlist1);
while (iter)
{
ABTS_PTR_EQUAL(tc, &node[i++], iter);
iter = list_next(iter);
}
ABTS_INT_EQUAL(tc, 3, i);
/* Iterate from the last. And check the pointers */
i = 0; iter = list_last(&tlist1);
while (iter)
{
ABTS_PTR_EQUAL(tc, &node[3 - (++i)], iter);
iter = list_prev(iter);
}
ABTS_INT_EQUAL(tc, 3, i);
/* Insert three nodes by list_insert_next() */
list_insert_next(&tlist1, &node[0], &node[3]);
list_insert_next(&tlist1, &node[1], &node[4]);
list_insert_next(&tlist1, &node[2], &node[5]);
/* Iterate from the first. And check the pointers */
iter = list_first(&tlist1);
ABTS_PTR_EQUAL(tc, &node[0], iter);
iter = list_next(iter);
ABTS_PTR_EQUAL(tc, &node[3], iter);
iter = list_next(iter);
ABTS_PTR_EQUAL(tc, &node[1], iter);
iter = list_next(iter);
ABTS_PTR_EQUAL(tc, &node[4], iter);
iter = list_next(iter);
ABTS_PTR_EQUAL(tc, &node[2], iter);
iter = list_next(iter);
ABTS_PTR_EQUAL(tc, &node[5], iter);
iter = list_next(iter);
ABTS_PTR_NULL(tc, iter);
/* Remove three nodes inserted by list_insert_next() */
list_remove(&tlist1, &node[3]);
list_remove(&tlist1, &node[4]);
list_remove(&tlist1, &node[5]);
/* Iterate from the first. And check the pointers */
iter = list_first(&tlist1);
ABTS_PTR_EQUAL(tc, &node[0], iter);
iter = list_next(iter);
ABTS_PTR_EQUAL(tc, &node[1], iter);
iter = list_next(iter);
ABTS_PTR_EQUAL(tc, &node[2], iter);
iter = list_next(iter);
ABTS_PTR_NULL(tc, iter);
}
static void list_test5(abts_case *tc, void *data)
{
int i, j;
/* List up posssible oders with four nodes */
int od[24][4] = {
{0,1,2,3}, {0,1,3,2}, {0,2,1,3}, {0,2,3,1}, {0,3,1,2}, {0,3,2,1},
{1,0,2,3}, {1,0,3,2}, {1,2,0,3}, {1,2,3,0}, {1,3,0,2}, {1,3,2,0},
{2,1,0,3}, {2,1,3,0}, {2,0,1,3}, {2,0,3,1}, {2,3,1,0}, {2,3,0,1},
{3,1,2,0}, {3,1,0,2}, {3,2,1,0}, {3,2,0,1}, {3,0,1,2}, {3,0,2,1}
};
lt_type1 *iter, node[SIZE_OF_lt_type1];
for (i = 0; i < SIZE_OF_lt_type1; i++)
node[i].m1 = i;
for (i = 0; i < 24; i++)
{
/* Initialize head of list */
list_init(&tlist1);
/* Add four nodes using predefined orders */
for (j = 0; j < 4; j++)
list_insert_sorted(&tlist1, &node[od[i][j]], <type1_compare);
/* Iterate from the first. And check the SORTED */
j = 0; iter = list_first(&tlist1);
while (iter)
{
ABTS_INT_EQUAL(tc, iter->m1, j++);
iter = list_next(iter);
}
}
}
/*****************************************************************************
* test for core_queue.h
*/
typedef struct {
int m1;
} qt_type1;
#define SIZE_OF_TQUE1 4
#define SIZE_OF_TQUE2 3
typedef int type_of_tque1;
typedef qt_type1 type_of_tque2;
que_declare(tque1, type_of_tque1, SIZE_OF_TQUE1);
que_declare(tque2, type_of_tque2, SIZE_OF_TQUE2);
que_declare(tque3, type_of_tque2 *, SIZE_OF_TQUE2);
static void que_test1(abts_case *tc, void *data)
{
int i, r;
type_of_tque1 n, node[SIZE_OF_TQUE1+1];
n = 0;
for (i = 0; i < SIZE_OF_TQUE1; i++)
node[i] = i;
/* Initialize queue */
que_init(&tque1, SIZE_OF_TQUE1);
/* Check basic members */
ABTS_TRUE(tc, que_is_empty(&tque1));
ABTS_FALSE(tc, que_is_full(&tque1));
ABTS_INT_EQUAL(tc, SIZE_OF_TQUE1, que_avail(&tque1));
ABTS_INT_EQUAL(tc, 0, que_used(&tque1));
/* Push a node */
r = que_push(&tque1, &node[0]);
ABTS_INT_EQUAL(tc, 1, r);
/* Check queue status */
ABTS_FALSE(tc, que_is_empty(&tque1));
ABTS_FALSE(tc, que_is_full(&tque1));
ABTS_INT_EQUAL(tc, SIZE_OF_TQUE1 - 1, que_avail(&tque1));
ABTS_INT_EQUAL(tc, 1, que_used(&tque1));
/* Pop a node */
r = que_pop(&tque1, &n);
ABTS_INT_EQUAL(tc, 0, r);
/* Check queue status */
ABTS_TRUE(tc, que_is_empty(&tque1));
ABTS_FALSE(tc, que_is_full(&tque1));
ABTS_INT_EQUAL(tc, SIZE_OF_TQUE1, que_avail(&tque1));
ABTS_INT_EQUAL(tc, 0, que_used(&tque1));
/* Push nodes up to queue size */
for (i = 0; i < SIZE_OF_TQUE1; i++)
{
r = que_push(&tque1, &node[i]);
ABTS_INT_EQUAL(tc, i + 1, r);
}
/* Check queue status */
ABTS_FALSE(tc, que_is_empty(&tque1));
ABTS_TRUE(tc, que_is_full(&tque1));
ABTS_INT_EQUAL(tc, 0, que_avail(&tque1));
ABTS_INT_EQUAL(tc, SIZE_OF_TQUE1, que_used(&tque1));
/* Push a node to full queue */
r = que_push(&tque1, &node[0]);
ABTS_INT_EQUAL(tc, -1, r);
/* Pop all pushed nodes and check pop order */
for (i = 0; i < SIZE_OF_TQUE1; i++)
{
r = que_pop(&tque1, &n);
ABTS_INT_EQUAL(tc, node[i], n);
ABTS_INT_EQUAL(tc, SIZE_OF_TQUE1 - (i + 1), r);
}
/* Check queue status */
ABTS_TRUE(tc, que_is_empty(&tque1));
ABTS_FALSE(tc, que_is_full(&tque1));
ABTS_INT_EQUAL(tc, SIZE_OF_TQUE1, que_avail(&tque1));
ABTS_INT_EQUAL(tc, 0, que_used(&tque1));
/* Pop a node from empty queue */
r = que_pop(&tque1, &n);
ABTS_INT_EQUAL(tc, -1, r);
}
/*****************************************************************************
* test for core_ringbuf.h
*/
#define SIZE_OF_TRBUF1 7
rbuf_declare(trbuf1, SIZE_OF_TRBUF1);
#define SIZE_OF_TRBUF2 7
rbuf_declare_ext(trbuf2);
char trbuf2_ext_buf[SIZE_OF_TRBUF2];
static void rbuf_test1(abts_case *tc, void *data)
{
int i, n;
char wbuf[32];
char rbuf[32];
for (i = 0; i < 26; i++)
wbuf[i] = 'a' + i;
rbuf_init(&trbuf1, SIZE_OF_TRBUF1);
/* Check basic members */
ABTS_TRUE(tc, rbuf_is_empty(&trbuf1));
ABTS_FALSE(tc, rbuf_is_full(&trbuf1));
ABTS_INT_EQUAL(tc, SIZE_OF_TRBUF1, rbuf_free_bytes(&trbuf1));
ABTS_INT_EQUAL(tc, 0, rbuf_bytes(&trbuf1));
/* Write 3 bytes */
n = rbuf_write(&trbuf1, wbuf, 3);
ABTS_INT_EQUAL(tc, 3, n);
/* Check basic members */
ABTS_FALSE(tc, rbuf_is_empty(&trbuf1));
ABTS_FALSE(tc, rbuf_is_full(&trbuf1));
ABTS_INT_EQUAL(tc, SIZE_OF_TRBUF1 - 3, rbuf_free_bytes(&trbuf1));
ABTS_INT_EQUAL(tc, 3, rbuf_bytes(&trbuf1));
/* Read 3 bytes */
n = rbuf_read(&trbuf1, rbuf, 3); rbuf[3] = 0;
ABTS_INT_EQUAL(tc, 3, n);
ABTS_STR_EQUAL(tc, "abc", rbuf);
/* Check basic members */
ABTS_TRUE(tc, rbuf_is_empty(&trbuf1));
ABTS_FALSE(tc, rbuf_is_full(&trbuf1));
ABTS_INT_EQUAL(tc, SIZE_OF_TRBUF1, rbuf_free_bytes(&trbuf1));
ABTS_INT_EQUAL(tc, 0, rbuf_bytes(&trbuf1));
/* Write 3 bytes */
n = rbuf_write(&trbuf1, wbuf, 3);
ABTS_INT_EQUAL(tc, 3, n);
/* Write 5 bytes, but only 4 bytes shall be written */
n = rbuf_write(&trbuf1, wbuf + 3, 5);
ABTS_INT_EQUAL(tc, 4, n);
/* Write 1 bytes to full buffer */
n = rbuf_write(&trbuf1, wbuf, 1);
ABTS_INT_EQUAL(tc, -1, n);
/* Read 2 bytes */
n = rbuf_read(&trbuf1, rbuf, 2); rbuf[2] = 0;
ABTS_INT_EQUAL(tc, 2, n);
ABTS_STR_EQUAL(tc, "ab", rbuf);
/* Read 5 bytes */
n = rbuf_read(&trbuf1, rbuf, 5); rbuf[5] = 0;
ABTS_INT_EQUAL(tc, 5, n);
ABTS_STR_EQUAL(tc, "cdefg", rbuf);
/* Check basic members */
ABTS_TRUE(tc, rbuf_is_empty(&trbuf1));
ABTS_FALSE(tc, rbuf_is_full(&trbuf1));
ABTS_INT_EQUAL(tc, SIZE_OF_TRBUF1, rbuf_free_bytes(&trbuf1));
ABTS_INT_EQUAL(tc, 0, rbuf_bytes(&trbuf1));
/* Read 1 bytes from empty buffer */
n = rbuf_read(&trbuf1, rbuf, 1);
ABTS_INT_EQUAL(tc, -1, n);
}
static void rbuf_test2(abts_case *tc, void *data)
{
int i, n;
char wbuf[32];
char rbuf[32];
for (i = 0; i < 26; i++)
wbuf[i] = 'a' + i;
rbuf_init_ext(&trbuf2, SIZE_OF_TRBUF1, trbuf2_ext_buf);
/* Check basic members */
ABTS_TRUE(tc, rbuf_is_empty(&trbuf2));
ABTS_FALSE(tc, rbuf_is_full(&trbuf2));
ABTS_INT_EQUAL(tc, SIZE_OF_TRBUF2, rbuf_free_bytes(&trbuf2));
ABTS_INT_EQUAL(tc, 0, rbuf_bytes(&trbuf2));
/* Write 3 bytes */
n = rbuf_write(&trbuf2, wbuf, 3);
ABTS_INT_EQUAL(tc, 3, n);
/* Check basic members */
ABTS_FALSE(tc, rbuf_is_empty(&trbuf2));
ABTS_FALSE(tc, rbuf_is_full(&trbuf2));
ABTS_INT_EQUAL(tc, SIZE_OF_TRBUF2 - 3, rbuf_free_bytes(&trbuf2));
ABTS_INT_EQUAL(tc, 3, rbuf_bytes(&trbuf2));
/* Read 3 bytes */
n = rbuf_read(&trbuf2, rbuf, 3); rbuf[3] = 0;
ABTS_INT_EQUAL(tc, 3, n);
ABTS_STR_EQUAL(tc, "abc", rbuf);
/* Check basic members */
ABTS_TRUE(tc, rbuf_is_empty(&trbuf2));
ABTS_FALSE(tc, rbuf_is_full(&trbuf2));
ABTS_INT_EQUAL(tc, SIZE_OF_TRBUF2, rbuf_free_bytes(&trbuf2));
ABTS_INT_EQUAL(tc, 0, rbuf_bytes(&trbuf2));
/* Write 3 bytes */
n = rbuf_write(&trbuf2, wbuf, 3);
ABTS_INT_EQUAL(tc, 3, n);
/* Write 5 bytes, but only 4 bytes shall be written */
n = rbuf_write(&trbuf2, wbuf + 3, 5);
ABTS_INT_EQUAL(tc, 4, n);
/* Write 1 bytes to full buffer */
n = rbuf_write(&trbuf2, wbuf, 1);
ABTS_INT_EQUAL(tc, -1, n);
/* Read 2 bytes */
n = rbuf_read(&trbuf2, rbuf, 2); rbuf[2] = 0;
ABTS_INT_EQUAL(tc, 2, n);
ABTS_STR_EQUAL(tc, "ab", rbuf);
/* Read 5 bytes */
n = rbuf_read(&trbuf2, rbuf, 5); rbuf[5] = 0;
ABTS_INT_EQUAL(tc, 5, n);
ABTS_STR_EQUAL(tc, "cdefg", rbuf);
/* Check basic members */
ABTS_TRUE(tc, rbuf_is_empty(&trbuf2));
ABTS_FALSE(tc, rbuf_is_full(&trbuf2));
ABTS_INT_EQUAL(tc, SIZE_OF_TRBUF2, rbuf_free_bytes(&trbuf2));
ABTS_INT_EQUAL(tc, 0, rbuf_bytes(&trbuf2));
/* Read 1 bytes from empty buffer */
n = rbuf_read(&trbuf2, rbuf, 1);
ABTS_INT_EQUAL(tc, -1, n);
n = rbuf_skip_write_pos(&trbuf2, 5);
ABTS_INT_EQUAL(tc, 5, n);
n = rbuf_skip_read_pos(&trbuf2, 5);
ABTS_INT_EQUAL(tc, 5, n);
}
abts_suite *testds(abts_suite *suite)
{
suite = ADD_SUITE(suite)
abts_run_test(suite, pool_test1, NULL);
abts_run_test(suite, pool_test2, NULL);
abts_run_test(suite, list_test1, NULL);
abts_run_test(suite, list_test2, NULL);
abts_run_test(suite, list_test3, NULL);
abts_run_test(suite, list_test4, NULL);
abts_run_test(suite, list_test5, NULL);
abts_run_test(suite, que_test1, NULL);
abts_run_test(suite, rbuf_test1, NULL);
abts_run_test(suite, rbuf_test2, NULL);
return suite;
}
nextepc-0.3.10/lib/core/test/testfile.c 0000664 0000000 0000000 00000046062 13335533574 0017724 0 ustar 00root root 0000000 0000000 #include "core_file.h"
#include "core_pkbuf.h"
#include "testutil.h"
#define DIRNAME "data"
#define FILENAME DIRNAME "/file_datafile.txt"
#define TESTSTR "This is the file data file."
#define TESTREAD_BLKSIZE 1024
#define FILE_BUFFERSIZE 4096 /* This should match FILE's buffer size. */
static void test_file_init(abts_case *tc, void *data)
{
status_t rv;
file_info_t finfo;
size_t bytes;
file_t *filetest = NULL;
rv = dir_make("data", FILE_UREAD | FILE_UWRITE | FILE_UEXECUTE);
rv = file_stat(&finfo, "data", FILE_INFO_TYPE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_INT_EQUAL(tc, FILE_DIR, finfo.filetype);
rv = file_open(&filetest, FILENAME,
FILE_WRITE | FILE_CREATE,
FILE_UREAD | FILE_UWRITE | FILE_GREAD);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
bytes = strlen(TESTSTR);
rv = file_write(filetest, TESTSTR, &bytes);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
file_close(filetest);
}
static void test_open_noreadwrite(abts_case *tc, void *data)
{
status_t rv;
file_t *thefile = NULL;
rv = file_open(&thefile, FILENAME,
FILE_CREATE | FILE_EXCL,
FILE_UREAD | FILE_UWRITE | FILE_GREAD);
ABTS_TRUE(tc, rv != CORE_OK);
ABTS_INT_EQUAL(tc, 1, STATUS_IS_EACCES(rv));
ABTS_PTR_EQUAL(tc, NULL, thefile);
}
static void test_open_excl(abts_case *tc, void *data)
{
status_t rv;
file_t *thefile = NULL;
rv = file_open(&thefile, FILENAME,
FILE_CREATE | FILE_EXCL | FILE_WRITE,
FILE_UREAD | FILE_UWRITE | FILE_GREAD);
ABTS_TRUE(tc, rv != CORE_OK);
ABTS_INT_EQUAL(tc, 1, STATUS_IS_EEXIST(rv));
ABTS_PTR_EQUAL(tc, NULL, thefile);
}
static void test_open_read(abts_case *tc, void *data)
{
status_t rv;
file_t *filetest = NULL;
rv = file_open(&filetest, FILENAME,
FILE_READ,
FILE_UREAD | FILE_UWRITE | FILE_GREAD);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_PTR_NOTNULL(tc, filetest);
file_close(filetest);
}
static void link_existing(abts_case *tc, void *data)
{
status_t rv;
rv = file_link("data/file_datafile.txt", "data/file_datafile2.txt");
file_remove("data/file_datafile2.txt");
ABTS_ASSERT(tc, "Couldn't create hardlink to file", rv == CORE_OK);
}
static void link_nonexisting(abts_case *tc, void *data)
{
status_t rv;
rv = file_link("data/does_not_exist.txt", "data/fake.txt");
ABTS_ASSERT(tc, "", rv != CORE_OK);
}
static void test_read(abts_case *tc, void *data)
{
status_t rv;
size_t nbytes = 256;
char *str = core_malloc(nbytes + 1);
file_t *filetest = NULL;
rv = file_open(&filetest, FILENAME,
FILE_READ,
FILE_UREAD | FILE_UWRITE | FILE_GREAD);
CORE_ASSERT_OK(tc, "Opening test file " FILENAME, rv);
rv = file_read(filetest, str, &nbytes);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_SIZE_EQUAL(tc, strlen(TESTSTR), nbytes);
ABTS_STR_EQUAL(tc, TESTSTR, str);
CORE_FREE(str);
file_close(filetest);
}
static void test_readzero(abts_case *tc, void *data)
{
status_t rv;
size_t nbytes = 0;
char *str = NULL;
file_t *filetest;
rv = file_open(&filetest, FILENAME, FILE_READ, FILE_OS_DEFAULT);
CORE_ASSERT_OK(tc, "Opening test file " FILENAME, rv);
rv = file_read(filetest, str, &nbytes);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_SIZE_EQUAL(tc, 0, nbytes);
file_close(filetest);
}
static void test_filename(abts_case *tc, void *data)
{
const char *str;
status_t rv;
file_t *filetest = NULL;
rv = file_open(&filetest, FILENAME,
FILE_READ,
FILE_UREAD | FILE_UWRITE | FILE_GREAD);
CORE_ASSERT_OK(tc, "Opening test file " FILENAME, rv);
rv = file_name_get(&str, filetest);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_STR_EQUAL(tc, FILENAME, str);
file_close(filetest);
}
static void test_fileclose(abts_case *tc, void *data)
{
char str;
status_t rv;
size_t one = 1;
file_t *filetest = NULL;
rv = file_open(&filetest, FILENAME,
FILE_READ,
FILE_UREAD | FILE_UWRITE | FILE_GREAD);
CORE_ASSERT_OK(tc, "Opening test file " FILENAME, rv);
rv = file_close(filetest);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
/* We just closed the file, so this should fail */
rv = file_read(filetest, &str, &one);
ABTS_INT_EQUAL(tc, 1, STATUS_IS_EBADF(rv));
}
static void test_file_remove(abts_case *tc, void *data)
{
status_t rv;
file_t *filetest = NULL;
rv = file_remove(FILENAME);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = file_open(&filetest, FILENAME, FILE_READ,
FILE_UREAD | FILE_UWRITE | FILE_GREAD);
ABTS_INT_EQUAL(tc, 1, STATUS_IS_ENOENT(rv));
}
static void test_open_write(abts_case *tc, void *data)
{
status_t rv;
file_t *filetest = NULL;
filetest = NULL;
rv = file_open(&filetest, FILENAME,
FILE_WRITE,
FILE_UREAD | FILE_UWRITE | FILE_GREAD);
ABTS_INT_EQUAL(tc, 1, STATUS_IS_ENOENT(rv));
ABTS_PTR_EQUAL(tc, NULL, filetest);
}
static void test_open_writecreate(abts_case *tc, void *data)
{
status_t rv;
file_t *filetest = NULL;
filetest = NULL;
rv = file_open(&filetest, FILENAME,
FILE_WRITE | FILE_CREATE,
FILE_UREAD | FILE_UWRITE | FILE_GREAD);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
file_close(filetest);
}
static void test_write(abts_case *tc, void *data)
{
status_t rv;
size_t bytes = strlen(TESTSTR);
file_t *filetest = NULL;
rv = file_open(&filetest, FILENAME,
FILE_WRITE | FILE_CREATE,
FILE_UREAD | FILE_UWRITE | FILE_GREAD);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = file_write(filetest, TESTSTR, &bytes);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
file_close(filetest);
}
static void test_open_readwrite(abts_case *tc, void *data)
{
status_t rv;
file_t *filetest = NULL;
filetest = NULL;
rv = file_open(&filetest, FILENAME,
FILE_READ | FILE_WRITE,
FILE_UREAD | FILE_UWRITE | FILE_GREAD);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_PTR_NOTNULL(tc, filetest);
file_close(filetest);
}
static void test_seek(abts_case *tc, void *data)
{
status_t rv;
off_t offset = 5;
size_t nbytes = 256;
char *str = core_malloc(nbytes + 1);
file_t *filetest = NULL;
rv = file_open(&filetest, FILENAME,
FILE_READ,
FILE_UREAD | FILE_UWRITE | FILE_GREAD);
CORE_ASSERT_OK(tc, "Open test file " FILENAME, rv);
rv = file_read(filetest, str, &nbytes);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_SIZE_EQUAL(tc, strlen(TESTSTR), nbytes);
ABTS_STR_EQUAL(tc, TESTSTR, str);
memset(str, 0, nbytes + 1);
rv = file_seek(filetest, SEEK_SET, &offset);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = file_read(filetest, str, &nbytes);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_SIZE_EQUAL(tc, strlen(TESTSTR) - 5, nbytes);
ABTS_STR_EQUAL(tc, TESTSTR + 5, str);
file_close(filetest);
/* Test for regression of sign error bug with SEEK_END and
buffered files. */
rv = file_open(&filetest, FILENAME,
FILE_READ,
FILE_UREAD | FILE_UWRITE | FILE_GREAD);
CORE_ASSERT_OK(tc, "Open test file " FILENAME, rv);
offset = -5;
rv = file_seek(filetest, SEEK_END, &offset);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_SIZE_EQUAL(tc, strlen(TESTSTR) - 5, nbytes);
memset(str, 0, nbytes + 1);
nbytes = 256;
rv = file_read(filetest, str, &nbytes);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_SIZE_EQUAL(tc, 5, nbytes);
ABTS_STR_EQUAL(tc, TESTSTR + strlen(TESTSTR) - 5, str);
CORE_FREE(str);
file_close(filetest);
}
static void test_getc(abts_case *tc, void *data)
{
file_t *f = NULL;
status_t rv;
char ch;
rv = file_open(&f, FILENAME, FILE_READ, 0);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
file_getc(&ch, f);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_INT_EQUAL(tc, (int)TESTSTR[0], (int)ch);
file_close(f);
}
static void test_gets(abts_case *tc, void *data)
{
file_t *f = NULL;
status_t rv;
char *str = core_malloc(256);
rv = file_open(&f, FILENAME, FILE_READ, 0);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = file_gets(str, 256, f);
/* Only one line in the test file, so FILE will encounter EOF on the first
* call to gets, but we should get CORE_OK on this call and
* CORE_EOF on the next.
*/
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_STR_EQUAL(tc, TESTSTR, str);
rv = file_gets(str, 256, f);
ABTS_INT_EQUAL(tc, CORE_EOF, rv);
ABTS_STR_EQUAL(tc, "", str);
CORE_FREE(str);
file_close(f);
}
static void test_bigread(abts_case *tc, void *data)
{
file_t *f = NULL;
status_t rv;
char buf[FILE_BUFFERSIZE * 2];
size_t nbytes;
/* Create a test file with known content.
*/
rv = file_open(&f, "data/created_file",
FILE_CREATE | FILE_WRITE | FILE_TRUNCATE,
FILE_UREAD | FILE_UWRITE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
nbytes = FILE_BUFFERSIZE;
memset(buf, 0xFE, nbytes);
rv = file_write(f, buf, &nbytes);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_SIZE_EQUAL(tc, FILE_BUFFERSIZE, nbytes);
rv = file_close(f);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
f = NULL;
rv = file_open(&f, "data/created_file", FILE_READ, 0);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
nbytes = sizeof buf;
rv = file_read(f, buf, &nbytes);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_SIZE_EQUAL(tc, FILE_BUFFERSIZE, nbytes);
rv = file_close(f);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = file_remove("data/created_file");
ABTS_INT_EQUAL(tc, CORE_OK, rv);
}
/* This is a horrible name for this function. We are testing FILE, not how
* Apache uses FILE. And, this function tests _way_ too much stuff.
*/
static void test_mod_neg(abts_case *tc, void *data)
{
status_t rv;
file_t *f;
const char *s;
int i;
size_t nbytes;
char buf[8192];
off_t cur;
const char *fname = "data/modneg.dat";
rv = file_open(&f, fname,
FILE_CREATE | FILE_WRITE, FILE_UREAD | FILE_UWRITE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
s = "body56789\n";
nbytes = strlen(s);
rv = file_write(f, s, &nbytes);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_SIZE_EQUAL(tc, strlen(s), nbytes);
for (i = 0; i < 7980; i++) {
s = "0";
nbytes = strlen(s);
rv = file_write(f, s, &nbytes);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_SIZE_EQUAL(tc, strlen(s), nbytes);
}
s = "end456789\n";
nbytes = strlen(s);
rv = file_write(f, s, &nbytes);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_SIZE_EQUAL(tc, strlen(s), nbytes);
for (i = 0; i < 10000; i++) {
s = "1";
nbytes = strlen(s);
rv = file_write(f, s, &nbytes);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_SIZE_EQUAL(tc, strlen(s), nbytes);
}
rv = file_close(f);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = file_open(&f, fname, FILE_READ, 0);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = file_gets(buf, 11, f);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_STR_EQUAL(tc, "body56789\n", buf);
cur = 0;
rv = file_seek(f, FILE_CUR, &cur);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_ASSERT(tc, "File Pointer Mismatch, expected 10", cur == 10);
nbytes = sizeof(buf);
rv = file_read(f, buf, &nbytes);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_SIZE_EQUAL(tc, nbytes, sizeof(buf));
cur = -((off_t)nbytes - 7980);
rv = file_seek(f, FILE_CUR, &cur);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_ASSERT(tc, "File Pointer Mismatch, expected 7990", cur == 7990);
rv = file_gets(buf, 11, f);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_STR_EQUAL(tc, "end456789\n", buf);
rv = file_close(f);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = file_remove(fname);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
}
/* Test that the contents of file FNAME are equal to data EXPECT of
* length EXPECTLEN. */
static void file_contents_equal(abts_case *tc,
const char *fname,
const void *expect,
size_t expectlen)
{
void *actual = core_malloc(expectlen);
file_t *f;
CORE_ASSERT_OK(tc, "open file",
file_open(&f, fname, FILE_READ,
0));
CORE_ASSERT_OK(tc, "read from file",
file_read_full(f, actual, expectlen, NULL));
ABTS_ASSERT(tc, "matched expected file contents",
memcmp(expect, actual, expectlen) == 0);
CORE_ASSERT_OK(tc, "close file", file_close(f));
CORE_FREE(actual);
}
#define LINE1 "this is a line of text\n"
#define LINE2 "this is a second line of text\n"
static void test_puts(abts_case *tc, void *data)
{
file_t *f;
const char *fname = "data/testputs.txt";
CORE_ASSERT_OK(tc, "open file for writing",
file_open(&f, fname,
FILE_WRITE|FILE_CREATE|FILE_TRUNCATE,
FILE_OS_DEFAULT));
CORE_ASSERT_OK(tc, "write line to file",
file_puts(LINE1, f));
CORE_ASSERT_OK(tc, "write second line to file",
file_puts(LINE2, f));
CORE_ASSERT_OK(tc, "close for writing",
file_close(f));
file_contents_equal(tc, fname, LINE1 LINE2, strlen(LINE1 LINE2));
}
static void test_writev(abts_case *tc, void *data)
{
file_t *f;
size_t nbytes;
struct iovec vec[5];
const char *fname = "data/testwritev.txt";
CORE_ASSERT_OK(tc, "open file for writing",
file_open(&f, fname,
FILE_WRITE|FILE_CREATE|FILE_TRUNCATE,
FILE_OS_DEFAULT));
vec[0].iov_base = LINE1;
vec[0].iov_len = strlen(LINE1);
CORE_ASSERT_OK(tc, "writev of size 1 to file",
file_writev(f, vec, 1, &nbytes));
file_contents_equal(tc, fname, LINE1, strlen(LINE1));
vec[0].iov_base = LINE1;
vec[0].iov_len = strlen(LINE1);
vec[1].iov_base = LINE2;
vec[1].iov_len = strlen(LINE2);
vec[2].iov_base = LINE1;
vec[2].iov_len = strlen(LINE1);
vec[3].iov_base = LINE1;
vec[3].iov_len = strlen(LINE1);
vec[4].iov_base = LINE2;
vec[4].iov_len = strlen(LINE2);
CORE_ASSERT_OK(tc, "writev of size 5 to file",
file_writev(f, vec, 5, &nbytes));
CORE_ASSERT_OK(tc, "close for writing",
file_close(f));
file_contents_equal(tc, fname, LINE1 LINE1 LINE2 LINE1 LINE1 LINE2,
strlen(LINE1)*4 + strlen(LINE2)*2);
}
static void test_writev_full(abts_case *tc, void *data)
{
file_t *f;
size_t nbytes;
struct iovec vec[5];
const char *fname = "data/testwritev_full.txt";
CORE_ASSERT_OK(tc, "open file for writing",
file_open(&f, fname,
FILE_WRITE|FILE_CREATE|FILE_TRUNCATE,
FILE_OS_DEFAULT));
vec[0].iov_base = LINE1;
vec[0].iov_len = strlen(LINE1);
vec[1].iov_base = LINE2;
vec[1].iov_len = strlen(LINE2);
vec[2].iov_base = LINE1;
vec[2].iov_len = strlen(LINE1);
vec[3].iov_base = LINE1;
vec[3].iov_len = strlen(LINE1);
vec[4].iov_base = LINE2;
vec[4].iov_len = strlen(LINE2);
CORE_ASSERT_OK(tc, "writev_full of size 5 to file",
file_writev_full(f, vec, 5, &nbytes));
ABTS_SIZE_EQUAL(tc, strlen(LINE1)*3 + strlen(LINE2)*2, nbytes);
CORE_ASSERT_OK(tc, "close for writing",
file_close(f));
file_contents_equal(tc, fname, LINE1 LINE2 LINE1 LINE1 LINE2,
strlen(LINE1)*3 + strlen(LINE2)*2);
}
static void test_truncate(abts_case *tc, void *data)
{
status_t rv;
file_t *f;
const char *fname = "data/testtruncate.dat";
const char *s;
size_t nbytes;
file_info_t finfo;
file_remove(fname);
rv = file_open(&f, fname,
FILE_CREATE | FILE_WRITE, FILE_UREAD | FILE_UWRITE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
s = "some data";
nbytes = strlen(s);
rv = file_write(f, s, &nbytes);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_SIZE_EQUAL(tc, strlen(s), nbytes);
rv = file_close(f);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = file_open(&f, fname,
FILE_TRUNCATE | FILE_WRITE, FILE_UREAD | FILE_UWRITE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = file_close(f);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = file_stat(&finfo, fname, FILE_INFO_SIZE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_ASSERT(tc, "File size mismatch, expected 0 (empty)", finfo.size == 0);
rv = file_remove(fname);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
}
static void test_fail_write_flush(abts_case *tc, void *data)
{
file_t *f;
const char *fname = "data/testflush.dat";
status_t rv;
char buf[FILE_BUFFERSIZE];
int n;
file_remove(fname);
CORE_ASSERT_OK(tc, "open test file",
file_open(&f, fname,
FILE_CREATE|FILE_READ,
FILE_UREAD|FILE_UWRITE));
memset(buf, 'A', sizeof buf);
/* Try three writes. One of these should fail when it exceeds the
* internal buffer and actually tries to write to the file, which
* was opened read-only and hence should be unwritable. */
for (n = 0, rv = CORE_OK; n < 4 && rv == CORE_OK; n++) {
size_t bytes = sizeof buf;
rv = file_write(f, buf, &bytes);
}
ABTS_ASSERT(tc, "failed to write to read-only buffered fd",
rv != CORE_OK);
file_close(f);
}
abts_suite *testfile(abts_suite *suite)
{
suite = ADD_SUITE(suite)
abts_run_test(suite, test_file_init, NULL);
abts_run_test(suite, test_open_noreadwrite, NULL);
abts_run_test(suite, test_open_excl, NULL);
abts_run_test(suite, test_open_read, NULL);
abts_run_test(suite, test_open_readwrite, NULL);
abts_run_test(suite, link_existing, NULL);
abts_run_test(suite, link_nonexisting, NULL);
abts_run_test(suite, test_read, NULL);
abts_run_test(suite, test_readzero, NULL);
abts_run_test(suite, test_seek, NULL);
abts_run_test(suite, test_filename, NULL);
abts_run_test(suite, test_fileclose, NULL);
abts_run_test(suite, test_file_remove, NULL);
abts_run_test(suite, test_open_write, NULL);
abts_run_test(suite, test_open_writecreate, NULL);
abts_run_test(suite, test_write, NULL);
abts_run_test(suite, test_getc, NULL);
abts_run_test(suite, test_gets, NULL);
abts_run_test(suite, test_puts, NULL);
abts_run_test(suite, test_writev, NULL);
abts_run_test(suite, test_writev_full, NULL);
abts_run_test(suite, test_bigread, NULL);
abts_run_test(suite, test_mod_neg, NULL);
abts_run_test(suite, test_truncate, NULL);
abts_run_test(suite, test_fail_write_flush, NULL);
return suite;
}
nextepc-0.3.10/lib/core/test/testfilecopy.c 0000664 0000000 0000000 00000011166 13335533574 0020614 0 ustar 00root root 0000000 0000000 #include "core_file.h"
#include "testutil.h"
#define DIRNAME "data"
#define FILENAME1 DIRNAME "/file_datafile.txt"
#define TESTSTR1 "This is the file data file."
#define FILENAME2 DIRNAME "/mmap_datafile.txt"
#define TESTSTR2 "This is the MMAP data file."
static void test_filecopy_init(abts_case *tc, void *data)
{
status_t rv;
file_info_t finfo;
size_t bytes;
file_t *filetest = NULL;
rv = dir_make("data", FILE_UREAD | FILE_UWRITE | FILE_UEXECUTE);
rv = file_stat(&finfo, "data", FILE_INFO_TYPE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_INT_EQUAL(tc, FILE_DIR, finfo.filetype);
rv = file_open(&filetest, FILENAME1,
FILE_WRITE | FILE_CREATE,
FILE_UREAD | FILE_UWRITE | FILE_GREAD);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
bytes = strlen(TESTSTR1);
rv = file_write(filetest, TESTSTR1, &bytes);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
file_close(filetest);
rv = file_open(&filetest, FILENAME2,
FILE_WRITE | FILE_CREATE,
FILE_UREAD | FILE_UWRITE | FILE_GREAD);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
bytes = strlen(TESTSTR2);
rv = file_write(filetest, TESTSTR2, &bytes);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
file_close(filetest);
}
static void copy_helper(abts_case *tc, const char *from, const char * to,
file_perms_t perms, int append)
{
status_t rv;
status_t dest_rv;
file_info_t copy;
file_info_t orig;
file_info_t dest;
dest_rv = file_stat(&dest, to, FILE_INFO_SIZE);
if (!append) {
rv = file_copy(from, to, perms);
}
else {
rv = file_append(from, to, perms);
}
CORE_ASSERT_OK(tc, "Error copying file", rv);
rv = file_stat(&orig, from, FILE_INFO_SIZE);
CORE_ASSERT_OK(tc, "Couldn't stat original file", rv);
rv = file_stat(©, to, FILE_INFO_SIZE);
CORE_ASSERT_OK(tc, "Couldn't stat copy file", rv);
if (!append) {
ABTS_ASSERT(tc, "File size differs", orig.size == copy.size);
}
else {
ABTS_ASSERT(tc, "File size differs",
((dest_rv == CORE_OK)
? dest.size : 0) + orig.size == copy.size);
}
}
static void copy_short_file(abts_case *tc, void *data)
{
status_t rv;
/* make absolutely sure that the dest file doesn't exist. */
file_remove("data/file_copy.txt");
copy_helper(tc, "data/file_datafile.txt", "data/file_copy.txt",
FILE_SOURCE_PERMS, 0);
rv = file_remove("data/file_copy.txt");
CORE_ASSERT_OK(tc, "Couldn't remove copy file", rv);
}
static void copy_over_existing(abts_case *tc, void *data)
{
status_t rv;
/* make absolutely sure that the dest file doesn't exist. */
file_remove("data/file_copy.txt");
/* This is a cheat. I don't want to create a new file, so I just copy
* one file, then I copy another. If the second copy succeeds, then
* this works.
*/
copy_helper(tc, "data/file_datafile.txt", "data/file_copy.txt",
FILE_SOURCE_PERMS, 0);
copy_helper(tc, "data/mmap_datafile.txt", "data/file_copy.txt",
FILE_SOURCE_PERMS, 0);
rv = file_remove("data/file_copy.txt");
CORE_ASSERT_OK(tc, "Couldn't remove copy file", rv);
}
static void append_nonexist(abts_case *tc, void *data)
{
status_t rv;
/* make absolutely sure that the dest file doesn't exist. */
file_remove("data/file_copy.txt");
copy_helper(tc, "data/file_datafile.txt", "data/file_copy.txt",
FILE_SOURCE_PERMS, 0);
rv = file_remove("data/file_copy.txt");
CORE_ASSERT_OK(tc, "Couldn't remove copy file", rv);
}
static void append_exist(abts_case *tc, void *data)
{
status_t rv;
/* make absolutely sure that the dest file doesn't exist. */
file_remove("data/file_copy.txt");
/* This is a cheat. I don't want to create a new file, so I just copy
* one file, then I copy another. If the second copy succeeds, then
* this works.
*/
copy_helper(tc, "data/file_datafile.txt", "data/file_copy.txt",
FILE_SOURCE_PERMS, 0);
copy_helper(tc, "data/mmap_datafile.txt", "data/file_copy.txt",
FILE_SOURCE_PERMS, 1);
rv = file_remove("data/file_copy.txt");
CORE_ASSERT_OK(tc, "Couldn't remove copy file", rv);
}
abts_suite *testfilecopy(abts_suite *suite)
{
suite = ADD_SUITE(suite)
abts_run_test(suite, test_filecopy_init, NULL);
abts_run_test(suite, copy_short_file, NULL);
abts_run_test(suite, copy_over_existing, NULL);
abts_run_test(suite, append_nonexist, NULL);
abts_run_test(suite, append_exist, NULL);
return suite;
}
nextepc-0.3.10/lib/core/test/testfsm.c 0000664 0000000 0000000 00000015456 13335533574 0017575 0 ustar 00root root 0000000 0000000 #include "core_fsm.h"
#include "testutil.h"
enum bomb_signal_t {
UP_SIG = FSM_USER_SIG,
DOWN_SIG,
ARM_SIG
};
typedef struct _tick_event_t {
fsm_event_t event;
} tick_event_t;
typedef struct _bomb_t {
fsm_t fsm;
c_uint8_t timeout;
c_uint8_t code;
c_uint8_t defuse;
} bomb_t;
void bomb_initial(bomb_t *s, tick_event_t *e);
void bomb_setting(bomb_t *s, tick_event_t *e);
void bomb_timing(bomb_t *s, tick_event_t *e);
void bomb_create(bomb_t *s, uint8_t defuse)
{
fsm_create(&s->fsm, &bomb_initial, 0);
s->defuse = defuse;
}
void bomb_initial(bomb_t *s, tick_event_t *e)
{
s->timeout = 10;
FSM_TRAN(s, &bomb_setting);
}
void bomb_setting(bomb_t *s, tick_event_t *e)
{
switch (e->event)
{
case UP_SIG:
{
if (s->timeout < 12)
{
++s->timeout;
}
break;
}
case DOWN_SIG: {
if (s->timeout > 8)
{
--s->timeout;
}
break;
}
case ARM_SIG:
{
FSM_TRAN(s, &bomb_timing);
break;
}
}
}
void bomb_timing(bomb_t *s, tick_event_t *e)
{
switch (e->event)
{
case FSM_ENTRY_SIG:
{
s->code = 0;
break;
}
case UP_SIG:
{
s->code <<= 1;
s->code |= 1;
break;
}
case DOWN_SIG:
{
s->code <<= 1;
break;
}
case ARM_SIG:
{
if (s->code == s->defuse)
{
FSM_TRAN(s, &bomb_setting);
break;
}
}
}
}
static void fsm_test1(abts_case *tc, void *data)
{
bomb_t bomb;
tick_event_t tick_event;
bomb_create(&bomb, 14);
fsm_init(&bomb, 0);
ABTS_PTR_EQUAL(tc, &bomb_setting, FSM_STATE(&bomb));
ABTS_INT_EQUAL(tc, 10, bomb.timeout);
tick_event.event = UP_SIG;
fsm_dispatch(&bomb, &tick_event);
ABTS_PTR_EQUAL(tc, &bomb_setting, FSM_STATE(&bomb));
ABTS_INT_EQUAL(tc, 11, bomb.timeout);
fsm_dispatch(&bomb, &tick_event);
ABTS_PTR_EQUAL(tc, &bomb_setting, FSM_STATE(&bomb));
ABTS_INT_EQUAL(tc, 12, bomb.timeout);
fsm_dispatch(&bomb, &tick_event);
ABTS_PTR_EQUAL(tc, &bomb_setting, FSM_STATE(&bomb));
ABTS_INT_EQUAL(tc, 12, bomb.timeout);
tick_event.event = DOWN_SIG;
fsm_dispatch(&bomb, &tick_event);
ABTS_PTR_EQUAL(tc, &bomb_setting, FSM_STATE(&bomb));
ABTS_INT_EQUAL(tc, 11, bomb.timeout);
fsm_dispatch(&bomb, &tick_event);
ABTS_PTR_EQUAL(tc, &bomb_setting, FSM_STATE(&bomb));
ABTS_INT_EQUAL(tc, 10, bomb.timeout);
fsm_dispatch(&bomb, &tick_event);
ABTS_PTR_EQUAL(tc, &bomb_setting, FSM_STATE(&bomb));
ABTS_INT_EQUAL(tc, 9, bomb.timeout);
fsm_dispatch(&bomb, &tick_event);
ABTS_PTR_EQUAL(tc, &bomb_setting, FSM_STATE(&bomb));
ABTS_INT_EQUAL(tc, 8, bomb.timeout);
fsm_dispatch(&bomb, &tick_event);
ABTS_PTR_EQUAL(tc, &bomb_setting, FSM_STATE(&bomb));
ABTS_INT_EQUAL(tc, 8, bomb.timeout);
tick_event.event = ARM_SIG;
fsm_dispatch((fsm_t *)&bomb, &tick_event);
ABTS_PTR_EQUAL(tc, &bomb_timing, FSM_STATE(&bomb));
ABTS_INT_EQUAL(tc, 0, bomb.code);
tick_event.event = UP_SIG;
fsm_dispatch((fsm_t *)&bomb, &tick_event);
ABTS_PTR_EQUAL(tc, &bomb_timing, FSM_STATE(&bomb));
ABTS_INT_EQUAL(tc, 1, bomb.code);
tick_event.event = UP_SIG;
fsm_dispatch((fsm_t *)&bomb, &tick_event);
ABTS_PTR_EQUAL(tc, &bomb_timing, FSM_STATE(&bomb));
ABTS_INT_EQUAL(tc, 3, bomb.code);
tick_event.event = UP_SIG;
fsm_dispatch((fsm_t *)&bomb, &tick_event);
ABTS_PTR_EQUAL(tc, &bomb_timing, FSM_STATE(&bomb));
ABTS_INT_EQUAL(tc, 7, bomb.code);
tick_event.event = DOWN_SIG;
fsm_dispatch((fsm_t *)&bomb, &tick_event);
ABTS_PTR_EQUAL(tc, &bomb_timing, FSM_STATE(&bomb));
ABTS_INT_EQUAL(tc, 14, bomb.code);
tick_event.event = ARM_SIG;
fsm_dispatch((fsm_t *)&bomb, &tick_event);
ABTS_PTR_EQUAL(tc, &bomb_setting, FSM_STATE(&bomb));
}
enum alarm_signal_t {
TICK_SIG = FSM_USER_SIG,
ALARM_SET_SIG,
ALARM_ON_SIG,
ALARM_OFF_SIG,
ALARM_SIG,
CLOCK_12H_SIG,
CLOCK_24H_SIG,
TIME_SIG,
TERMINATE_SIG
};
typedef struct _alarm_t {
fsm_t fsm;
c_uint32_t time;
} alarm_t;
typedef struct _set_event_t {
fsm_event_t event;
c_uint8_t digit;
} set_event_t;
typedef struct _time_event_t {
fsm_event_t event;
c_uint8_t current_time;
} time_event_t;
void alarm_initial(alarm_t *s, set_event_t *e);
void alarm_off(alarm_t *s, set_event_t *e);
void alarm_on(alarm_t *s, time_event_t *e);
void alarm_initial(alarm_t *s, set_event_t *e)
{
s->time = 12*60;
FSM_TRAN(s, &alarm_off);
}
void alarm_off(alarm_t *s, set_event_t *e)
{
switch (e->event)
{
case FSM_ENTRY_SIG:
{
s->time = (s->time/60)*100 + s->time%60;
break;
}
case FSM_EXIT_SIG:
{
s->time = (s->time/100)*60 + s->time%100;
break;
}
case ALARM_ON_SIG:
{
FSM_TRAN(s, &alarm_on);
break;
}
case ALARM_SET_SIG:
{
c_uint32_t alarm = (10 * s->time
+ e->digit) % 10000;
if ((alarm / 100 < 24) && (alarm % 100 < 60))
{
s->time = alarm;
}
else
{
s->time = 0;
}
break;
}
}
}
void alarm_on(alarm_t *s, time_event_t *e)
{
switch (e->event)
{
case FSM_ENTRY_SIG:
{
break;
}
case ALARM_SET_SIG:
{
break;
}
case ALARM_OFF_SIG:
{
FSM_TRAN(s, &alarm_off);
break;
}
}
}
static void fsm_test2(abts_case *tc, void *data)
{
alarm_t alarm;
set_event_t set_event;
time_event_t time_event;
fsm_create(&alarm.fsm, &alarm_initial, 0);
fsm_init(&alarm, 0);
ABTS_PTR_EQUAL(tc, &alarm_off, FSM_STATE(&alarm));
ABTS_INT_EQUAL(tc, 1200, alarm.time);
set_event.event = ALARM_ON_SIG;
fsm_dispatch(&alarm, &set_event);
ABTS_PTR_EQUAL(tc, &alarm_on, FSM_STATE(&alarm));
ABTS_INT_EQUAL(tc, 720, alarm.time);
time_event.event = ALARM_OFF_SIG;
fsm_dispatch(&alarm, &time_event);
ABTS_PTR_EQUAL(tc, &alarm_off, FSM_STATE(&alarm));
ABTS_INT_EQUAL(tc, 1200, alarm.time);
set_event.event = ALARM_SET_SIG;
set_event.digit = 0;
fsm_dispatch(&alarm, &set_event);
ABTS_PTR_EQUAL(tc, &alarm_off, FSM_STATE(&alarm));
ABTS_INT_EQUAL(tc, 2000, alarm.time);
}
abts_suite *testfsm(abts_suite *suite)
{
suite = ADD_SUITE(suite)
abts_run_test(suite, fsm_test1, NULL);
abts_run_test(suite, fsm_test2, NULL);
return suite;
}
nextepc-0.3.10/lib/core/test/testhash.c 0000664 0000000 0000000 00000023160 13335533574 0017722 0 ustar 00root root 0000000 0000000 #include "testutil.h"
#include "core_hash.h"
#define MAX_LTH 256
#define MAX_DEPTH 11
static int comp_string(const void *str1, const void *str2)
{
return strcmp(str1,str2);
}
static void dump_hash(hash_t *h, char str[][MAX_LTH])
{
hash_index_t *hi;
int i = 0;
for (hi = hash_first(h); hi; hi = hash_next(hi)) {
const char *key = hash_this_key(hi);
int len = hash_this_key_len(hi);
char *val = hash_this_val(hi);
str[i][0]='\0';
sprintf(str[i], "%sKey %s (%d) Value %s\n",
str[i], key, len, val);
i++;
}
str[i][0]='\0';
sprintf(str[i], "%s#entries %d\n", str[i], i);
/* Sort the result strings so that they can be checked for expected results easily,
* without having to worry about platform quirks
*/
qsort(
str, /* Pointer to elements */
i, /* number of elements */
MAX_LTH, /* size of one element */
comp_string /* Pointer to comparison routine */
);
}
static void sum_hash(hash_t *h, int *pcount, int *keySum, int *valSum)
{
hash_index_t *hi;
void *val, *key;
int count = 0;
*keySum = 0;
*valSum = 0;
*pcount = 0;
for (hi = hash_first(h); hi; hi = hash_next(hi)) {
hash_this(hi, (void*)&key, NULL, &val);
*valSum += *(int *)val;
*keySum += *(int *)key;
count++;
}
*pcount=count;
}
static void hash_make_test(abts_case *tc, void *data)
{
hash_t *h = NULL;
h = hash_make();
ABTS_PTR_NOTNULL(tc, h);
hash_destroy(h);
}
static void hash_set_test(abts_case *tc, void *data)
{
hash_t *h = NULL;
char *result = NULL;
h = hash_make();
ABTS_PTR_NOTNULL(tc, h);
hash_set(h, "key", HASH_KEY_STRING, "value");
result = hash_get(h, "key", HASH_KEY_STRING);
ABTS_STR_EQUAL(tc, "value", result);
hash_destroy(h);
}
static void hash_get_or_set_test(abts_case *tc, void *data)
{
hash_t *h = NULL;
char *result = NULL;
h = hash_make();
ABTS_PTR_NOTNULL(tc, h);
result = hash_get_or_set(h, "key", HASH_KEY_STRING, "value");
ABTS_STR_EQUAL(tc, "value", result);
result = hash_get_or_set(h, "key", HASH_KEY_STRING, "other");
ABTS_STR_EQUAL(tc, "value", result);
result = hash_get_or_set(h, "key", HASH_KEY_STRING, NULL);
ABTS_STR_EQUAL(tc, "value", result);
hash_set(h, "key", HASH_KEY_STRING, NULL);
result = hash_get(h, "key", HASH_KEY_STRING);
ABTS_PTR_EQUAL(tc, NULL, result);
result = hash_get_or_set(h, "key", HASH_KEY_STRING, NULL);
ABTS_PTR_EQUAL(tc, NULL, result);
result = hash_get_or_set(h, "key", HASH_KEY_STRING, "other");
ABTS_STR_EQUAL(tc, "other", result);
hash_destroy(h);
}
static void hash_reset(abts_case *tc, void *data)
{
hash_t *h = NULL;
char *result = NULL;
h = hash_make();
ABTS_PTR_NOTNULL(tc, h);
hash_set(h, "key", HASH_KEY_STRING, "value");
result = hash_get(h, "key", HASH_KEY_STRING);
ABTS_STR_EQUAL(tc, "value", result);
hash_set(h, "key", HASH_KEY_STRING, "new");
result = hash_get(h, "key", HASH_KEY_STRING);
ABTS_STR_EQUAL(tc, "new", result);
hash_destroy(h);
}
static void same_value(abts_case *tc, void *data)
{
hash_t *h = NULL;
char *result = NULL;
h = hash_make();
ABTS_PTR_NOTNULL(tc, h);
hash_set(h, "same1", HASH_KEY_STRING, "same");
result = hash_get(h, "same1", HASH_KEY_STRING);
ABTS_STR_EQUAL(tc, "same", result);
hash_set(h, "same2", HASH_KEY_STRING, "same");
result = hash_get(h, "same2", HASH_KEY_STRING);
ABTS_STR_EQUAL(tc, "same", result);
hash_destroy(h);
}
static unsigned int hash_custom( const char *key, int *klen)
{
unsigned int hash = 0;
unsigned int len = *klen;
while( len ) {
(len) --;
hash = hash * 33 + key[ len ];
}
return hash;
}
static void same_value_custom(abts_case *tc, void *data)
{
hash_t *h = NULL;
char *result = NULL;
h = hash_make_custom(hash_custom);
ABTS_PTR_NOTNULL(tc, h);
hash_set(h, "same1", 5, "same");
result = hash_get(h, "same1", 5);
ABTS_STR_EQUAL(tc, "same", result);
hash_set(h, "same2", 5, "same");
result = hash_get(h, "same2", 5);
ABTS_STR_EQUAL(tc, "same", result);
hash_destroy(h);
}
static void key_space(abts_case *tc, void *data)
{
hash_t *h = NULL;
char *result = NULL;
h = hash_make();
ABTS_PTR_NOTNULL(tc, h);
hash_set(h, "key with space", HASH_KEY_STRING, "value");
result = hash_get(h, "key with space", HASH_KEY_STRING);
ABTS_STR_EQUAL(tc, "value", result);
hash_destroy(h);
}
static void hash_clear_test(abts_case *tc, void *data)
{
hash_t *h;
int num[10], i;
int c;
h = hash_make();
ABTS_PTR_NOTNULL(tc, h);
for (i = 0; i < 10; i++)
{
num[i] = i;
hash_set(h, &num[i], sizeof(num[i]), &num[i]);
}
c = hash_count(h);
ABTS_INT_EQUAL(tc, 10, c);
hash_clear(h);
c = hash_count(h);
ABTS_INT_EQUAL(tc, 0, c);
hash_destroy(h);
}
/* This is kind of a hack, but I am just keeping an existing test. This is
* really testing hash_first, hash_next, and hash_this which
* should be tested in three separate tests, but this will do for now.
*/
static void hash_traverse(abts_case *tc, void *data)
{
hash_t *h;
char StrArray[MAX_DEPTH][MAX_LTH];
h = hash_make();
ABTS_PTR_NOTNULL(tc, h);
hash_set(h, "OVERWRITE", HASH_KEY_STRING, "should not see this");
hash_set(h, "FOO3", HASH_KEY_STRING, "bar3");
hash_set(h, "FOO3", HASH_KEY_STRING, "bar3");
hash_set(h, "FOO1", HASH_KEY_STRING, "bar1");
hash_set(h, "FOO2", HASH_KEY_STRING, "bar2");
hash_set(h, "FOO4", HASH_KEY_STRING, "bar4");
hash_set(h, "SAME1", HASH_KEY_STRING, "same");
hash_set(h, "SAME2", HASH_KEY_STRING, "same");
hash_set(h, "OVERWRITE", HASH_KEY_STRING, "Overwrite key");
dump_hash(h, StrArray);
ABTS_STR_EQUAL(tc, "Key FOO1 (4) Value bar1\n", StrArray[0]);
ABTS_STR_EQUAL(tc, "Key FOO2 (4) Value bar2\n", StrArray[1]);
ABTS_STR_EQUAL(tc, "Key FOO3 (4) Value bar3\n", StrArray[2]);
ABTS_STR_EQUAL(tc, "Key FOO4 (4) Value bar4\n", StrArray[3]);
ABTS_STR_EQUAL(tc, "Key OVERWRITE (9) Value Overwrite key\n", StrArray[4]);
ABTS_STR_EQUAL(tc, "Key SAME1 (5) Value same\n", StrArray[5]);
ABTS_STR_EQUAL(tc, "Key SAME2 (5) Value same\n", StrArray[6]);
ABTS_STR_EQUAL(tc, "#entries 7\n", StrArray[7]);
hash_destroy(h);
}
/* This is kind of a hack, but I am just keeping an existing test. This is
* really testing hash_first, hash_next, and hash_this which
* should be tested in three separate tests, but this will do for now.
*/
static void summation_test(abts_case *tc, void *data)
{
hash_t *h;
int sumKeys, sumVal, trySumKey, trySumVal;
int i, j, val[100], key[100];
h = hash_make();
ABTS_PTR_NOTNULL(tc, h);
sumKeys = 0;
sumVal = 0;
trySumKey = 0;
trySumVal = 0;
for (i = 0; i < 100; i++) {
j = i * 10 + 1;
sumKeys += j;
sumVal += i;
key[i] = j;
val[i] = i;
hash_set(h, &key[i], sizeof(int), &val[i]);
}
sum_hash(h, &i, &trySumKey, &trySumVal);
ABTS_INT_EQUAL(tc, 100, i);
ABTS_INT_EQUAL(tc, sumVal, trySumVal);
ABTS_INT_EQUAL(tc, sumKeys, trySumKey);
hash_destroy(h);
}
static void delete_key(abts_case *tc, void *data)
{
hash_t *h = NULL;
char *result = NULL;
h = hash_make();
ABTS_PTR_NOTNULL(tc, h);
hash_set(h, "key", HASH_KEY_STRING, "value");
hash_set(h, "key2", HASH_KEY_STRING, "value2");
result = hash_get(h, "key", HASH_KEY_STRING);
ABTS_STR_EQUAL(tc, "value", result);
result = hash_get(h, "key2", HASH_KEY_STRING);
ABTS_STR_EQUAL(tc, "value2", result);
hash_set(h, "key", HASH_KEY_STRING, NULL);
result = hash_get(h, "key", HASH_KEY_STRING);
ABTS_PTR_EQUAL(tc, NULL, result);
result = hash_get(h, "key2", HASH_KEY_STRING);
ABTS_STR_EQUAL(tc, "value2", result);
hash_destroy(h);
}
static void hash_count_0(abts_case *tc, void *data)
{
hash_t *h = NULL;
int count;
h = hash_make();
ABTS_PTR_NOTNULL(tc, h);
count = hash_count(h);
ABTS_INT_EQUAL(tc, 0, count);
hash_destroy(h);
}
static void hash_count_1(abts_case *tc, void *data)
{
hash_t *h = NULL;
int count;
h = hash_make();
ABTS_PTR_NOTNULL(tc, h);
hash_set(h, "key", HASH_KEY_STRING, "value");
count = hash_count(h);
ABTS_INT_EQUAL(tc, 1, count);
hash_destroy(h);
}
static void hash_count_5(abts_case *tc, void *data)
{
hash_t *h = NULL;
int count;
h = hash_make();
ABTS_PTR_NOTNULL(tc, h);
hash_set(h, "key1", HASH_KEY_STRING, "value1");
hash_set(h, "key2", HASH_KEY_STRING, "value2");
hash_set(h, "key3", HASH_KEY_STRING, "value3");
hash_set(h, "key4", HASH_KEY_STRING, "value4");
hash_set(h, "key5", HASH_KEY_STRING, "value5");
count = hash_count(h);
ABTS_INT_EQUAL(tc, 5, count);
hash_destroy(h);
}
abts_suite *testhash(abts_suite *suite)
{
suite = ADD_SUITE(suite)
abts_run_test(suite, hash_make_test, NULL);
abts_run_test(suite, hash_set_test, NULL);
abts_run_test(suite, hash_get_or_set_test, NULL);
abts_run_test(suite, hash_reset, NULL);
abts_run_test(suite, same_value, NULL);
abts_run_test(suite, same_value_custom, NULL);
abts_run_test(suite, key_space, NULL);
abts_run_test(suite, delete_key, NULL);
abts_run_test(suite, hash_count_0, NULL);
abts_run_test(suite, hash_count_1, NULL);
abts_run_test(suite, hash_count_5, NULL);
abts_run_test(suite, hash_clear_test, NULL);
abts_run_test(suite, hash_traverse, NULL);
abts_run_test(suite, summation_test, NULL);
return suite;
}
nextepc-0.3.10/lib/core/test/testlock.c 0000664 0000000 0000000 00000024136 13335533574 0017733 0 ustar 00root root 0000000 0000000 #include "core_thread.h"
#include "core_mutex.h"
#include "core_cond.h"
#include "core_rwlock.h"
#include "core_semaphore.h"
#include "core_time.h"
#include "testutil.h"
#define MAX_ITER 40000
#define MAX_COUNTER 10000
#define MAX_RETRY 3
static void *THREAD_FUNC thread_rwlock_func(thread_id id, void *data);
static void *THREAD_FUNC thread_mutex_function(thread_id id, void *data);
static void *THREAD_FUNC thread_cond_producer(thread_id id, void *data);
static void *THREAD_FUNC thread_cond_consumer(thread_id id, void *data);
static mutex_id mutex;
static rwlock_id rwlock;
static semaphore_id semaphore;
static int i = 0, x = 0;
static int buff[MAX_COUNTER];
struct {
mutex_id mutex;
int nput;
int nval;
} put;
struct {
mutex_id mutex;
cond_id cond;
int nready;
} nready;
static mutex_id timeout_mutex;
static cond_id timeout_cond;
static void *THREAD_FUNC thread_rwlock_func(thread_id id, void *data)
{
int exitLoop = 1;
while (1)
{
rwlock_rdlock(rwlock);
if (i == MAX_ITER)
exitLoop = 0;
rwlock_unlock(rwlock);
if (!exitLoop)
break;
rwlock_wrlock(rwlock);
if (i != MAX_ITER)
{
i++;
x++;
}
rwlock_unlock(rwlock);
}
return NULL;
}
static void *THREAD_FUNC thread_mutex_function(thread_id id, void *data)
{
int exitLoop = 1;
/* slight delay to allow things to settle */
core_sleep (1);
while (1)
{
mutex_lock(mutex);
if (i == MAX_ITER)
exitLoop = 0;
else
{
i++;
x++;
}
mutex_unlock(mutex);
if (!exitLoop)
break;
}
return NULL;
}
static void *THREAD_FUNC thread_cond_producer(thread_id id, void *data)
{
for (;;)
{
mutex_lock(put.mutex);
if (put.nput >= MAX_COUNTER)
{
mutex_unlock(put.mutex);
return NULL;
}
buff[put.nput] = put.nval;
put.nput++;
put.nval++;
mutex_unlock(put.mutex);
mutex_lock(nready.mutex);
if (nready.nready == 0)
cond_signal(nready.cond);
nready.nready++;
mutex_unlock(nready.mutex);
*((int *) data) += 1;
}
return NULL;
}
static void *THREAD_FUNC thread_cond_consumer(thread_id id, void *data)
{
int i;
for (i = 0; i < MAX_COUNTER; i++)
{
mutex_lock(nready.mutex);
while (nready.nready == 0)
cond_wait(nready.cond, nready.mutex);
nready.nready--;
mutex_unlock(nready.mutex);
if (buff[i] != i)
printf("buff[%d] = %d\n", i, buff[i]);
}
return NULL;
}
static void *THREAD_FUNC thread_semaphore_function(thread_id id, void *data)
{
int exitLoop = 1;
/* slight delay to allow things to settle */
core_sleep (1);
while (1)
{
semaphore_wait(semaphore);
if (i == MAX_ITER)
exitLoop = 0;
else
{
i++;
x++;
}
semaphore_post(semaphore);
if (!exitLoop)
break;
}
return NULL;
}
static void test_mutex(abts_case *tc, void *data)
{
thread_id t1, t2, t3, t4;
status_t s1, s2, s3, s4;
s1 = mutex_create(&mutex, MUTEX_DEFAULT);
ABTS_INT_EQUAL(tc, CORE_OK, s1);
i = 0;
x = 0;
s1 = thread_create(&t1, NULL, thread_mutex_function, NULL);
ABTS_INT_EQUAL(tc, CORE_OK, s1);
s2 = thread_create(&t2, NULL, thread_mutex_function, NULL);
ABTS_INT_EQUAL(tc, CORE_OK, s2);
s3 = thread_create(&t3, NULL, thread_mutex_function, NULL);
ABTS_INT_EQUAL(tc, CORE_OK, s3);
s4 = thread_create(&t4, NULL, thread_mutex_function, NULL);
ABTS_INT_EQUAL(tc, CORE_OK, s4);
ABTS_INT_EQUAL(tc, CORE_OK, thread_delete(t1));
ABTS_INT_EQUAL(tc, CORE_OK, thread_delete(t2));
ABTS_INT_EQUAL(tc, CORE_OK, thread_delete(t3));
ABTS_INT_EQUAL(tc, CORE_OK, thread_delete(t4));
ABTS_INT_EQUAL(tc, MAX_ITER, x);
CORE_ASSERT_OK(tc, "delete mutex", mutex_delete(mutex));
}
static void test_thread_rwlock(abts_case *tc, void *data)
{
thread_id t1, t2, t3, t4;
status_t s1, s2, s3, s4;
s1 = rwlock_create(&rwlock);
if (s1 == CORE_ENOTIMPL)
{
ABTS_NOT_IMPL(tc, "rwlocks not implemented");
return;
}
CORE_ASSERT_OK(tc, "rwlock_create", s1);
i = 0;
x = 0;
s1 = thread_create(&t1, NULL, thread_rwlock_func, NULL);
CORE_ASSERT_OK(tc, "create thread 1", s1);
s2 = thread_create(&t2, NULL, thread_rwlock_func, NULL);
CORE_ASSERT_OK(tc, "create thread 2", s2);
s3 = thread_create(&t3, NULL, thread_rwlock_func, NULL);
CORE_ASSERT_OK(tc, "create thread 3", s3);
s4 = thread_create(&t4, NULL, thread_rwlock_func, NULL);
CORE_ASSERT_OK(tc, "create thread 4", s4);
ABTS_INT_EQUAL(tc, CORE_OK, thread_delete(t1));
ABTS_INT_EQUAL(tc, CORE_OK, thread_delete(t2));
ABTS_INT_EQUAL(tc, CORE_OK, thread_delete(t3));
ABTS_INT_EQUAL(tc, CORE_OK, thread_delete(t4));
ABTS_INT_EQUAL(tc, MAX_ITER, x);
CORE_ASSERT_OK(tc, "delete rwlock", rwlock_delete(rwlock));
}
static void test_cond(abts_case *tc, void *data)
{
thread_id p1, p2, p3, p4, c1;
status_t s0, s1, s2, s3, s4;
int count1, count2, count3, count4;
int sum;
CORE_ASSERT_OK(tc, "create put mutex",
mutex_create(&put.mutex, MUTEX_DEFAULT));
CORE_ASSERT_OK(tc, "create nready mutex",
mutex_create(&nready.mutex, MUTEX_DEFAULT));
CORE_ASSERT_OK(tc, "create condvar",
cond_create(&nready.cond));
count1 = count2 = count3 = count4 = 0;
put.nput = put.nval = 0;
nready.nready = 0;
i = 0;
x = 0;
s0 = thread_create(&p1, NULL, thread_cond_producer, &count1);
ABTS_INT_EQUAL(tc, CORE_OK, s0);
s1 = thread_create(&p2, NULL, thread_cond_producer, &count2);
ABTS_INT_EQUAL(tc, CORE_OK, s1);
s2 = thread_create(&p3, NULL, thread_cond_producer, &count3);
ABTS_INT_EQUAL(tc, CORE_OK, s2);
s3 = thread_create(&p4, NULL, thread_cond_producer, &count4);
ABTS_INT_EQUAL(tc, CORE_OK, s3);
s4 = thread_create(&c1, NULL, thread_cond_consumer, NULL);
ABTS_INT_EQUAL(tc, CORE_OK, s4);
ABTS_INT_EQUAL(tc, CORE_OK, thread_delete(p1));
ABTS_INT_EQUAL(tc, CORE_OK, thread_delete(p2));
ABTS_INT_EQUAL(tc, CORE_OK, thread_delete(p3));
ABTS_INT_EQUAL(tc, CORE_OK, thread_delete(p4));
ABTS_INT_EQUAL(tc, CORE_OK, thread_delete(c1));
CORE_ASSERT_OK(tc, "delete condvar",
cond_delete(nready.cond));
CORE_ASSERT_OK(tc, "delete ready mutex", mutex_delete(nready.mutex));
CORE_ASSERT_OK(tc, "delete put mutex", mutex_delete(put.mutex));
sum = count1 + count2 + count3 + count4;
ABTS_INT_EQUAL(tc, MAX_COUNTER, sum);
}
static void test_timeoutcond(abts_case *tc, void *data)
{
status_t s;
c_time_t timeout;
c_time_t begin, end;
int i;
s = mutex_create(&timeout_mutex, MUTEX_DEFAULT);
ABTS_INT_EQUAL(tc, CORE_OK, s);
s = cond_create(&timeout_cond);
ABTS_INT_EQUAL(tc, CORE_OK, s);
timeout = time_from_sec(1);
for (i = 0; i < MAX_RETRY; i++)
{
mutex_lock(timeout_mutex);
begin = time_now();
s = cond_timedwait(timeout_cond, timeout_mutex, timeout);
end = time_now();
mutex_unlock(timeout_mutex);
if (s != CORE_OK && !STATUS_IS_TIMEUP(s))
{
continue;
}
ABTS_INT_EQUAL(tc, 1, STATUS_IS_TIMEUP(s));
ABTS_ASSERT(tc,
"Timer returned too late", end - begin - timeout < 100000);
break;
}
ABTS_ASSERT(tc, "Too many retries", i < MAX_RETRY);
CORE_ASSERT_OK(tc, "Unable to delete the conditional",
cond_delete(timeout_cond));
CORE_ASSERT_OK(tc, "Unable to delete the mutex",
mutex_delete(timeout_mutex));
}
static void test_semaphore(abts_case *tc, void *data)
{
thread_id t1, t2, t3, t4;
status_t s1, s2, s3, s4;
s1 = semaphore_create(&semaphore, 1);
ABTS_INT_EQUAL(tc, CORE_OK, s1);
i = 0;
x = 0;
s1 = thread_create(&t1, NULL, thread_semaphore_function, NULL);
ABTS_INT_EQUAL(tc, CORE_OK, s1);
s2 = thread_create(&t2, NULL, thread_semaphore_function, NULL);
ABTS_INT_EQUAL(tc, CORE_OK, s2);
s3 = thread_create(&t3, NULL, thread_semaphore_function, NULL);
ABTS_INT_EQUAL(tc, CORE_OK, s3);
s4 = thread_create(&t4, NULL, thread_semaphore_function, NULL);
ABTS_INT_EQUAL(tc, CORE_OK, s4);
ABTS_INT_EQUAL(tc, CORE_OK, thread_delete(t1));
ABTS_INT_EQUAL(tc, CORE_OK, thread_delete(t2));
ABTS_INT_EQUAL(tc, CORE_OK, thread_delete(t3));
ABTS_INT_EQUAL(tc, CORE_OK, thread_delete(t4));
ABTS_INT_EQUAL(tc, MAX_ITER, x);
CORE_ASSERT_OK(tc, "delete semaphore", semaphore_delete(semaphore));
}
#if HAVE_SEM_TIMEDWAIT
static semaphore_id timeout_semaphore;
static void test_timeoutsemaphore(abts_case *tc, void *data)
{
status_t s;
c_time_t timeout;
c_time_t begin, end;
int i;
s = semaphore_create(&timeout_semaphore, 0);
ABTS_INT_EQUAL(tc, CORE_OK, s);
timeout = time_from_sec(1);
for (i = 0; i < MAX_RETRY; i++)
{
begin = time_now();
s = semaphore_timedwait(timeout_semaphore, timeout);
end = time_now();
if (s != CORE_OK && !STATUS_IS_TIMEUP(s))
{
continue;
}
ABTS_INT_EQUAL(tc, 1, STATUS_IS_TIMEUP(s));
ABTS_ASSERT(tc,
"Timer returned too late", end - begin - timeout < 100000);
break;
}
ABTS_ASSERT(tc, "Too many retries", i < MAX_RETRY);
CORE_ASSERT_OK(tc, "Unable to delete the semaphore",
semaphore_delete(timeout_semaphore));
}
#endif
abts_suite *testlock(abts_suite *suite)
{
suite = ADD_SUITE(suite)
abts_run_test(suite, test_mutex, NULL);
abts_run_test(suite, test_thread_rwlock, NULL);
abts_run_test(suite, test_cond, NULL);
abts_run_test(suite, test_timeoutcond, NULL);
abts_run_test(suite, test_semaphore, NULL);
#if HAVE_SEM_TIMEDWAIT
abts_run_test(suite, test_timeoutsemaphore, NULL);
#endif
return suite;
}
nextepc-0.3.10/lib/core/test/testmisc.c 0000664 0000000 0000000 00000016260 13335533574 0017735 0 ustar 00root root 0000000 0000000 #include "core_lib.h"
#include "core_debug.h"
#include "testutil.h"
static void misc_test1(abts_case *tc, void *data)
{
unsigned char c[42];
ABTS_INT_EQUAL(tc, CORE_OK, core_generate_random_bytes(c, sizeof c));
}
static void misc_test2(abts_case *tc, void *data)
{
#define K "4 6 5B5 CE8 B199B49FAA5F0A2EE238A6BC "
#define OP "5F1D289C 5D354D0A 140C2548 F5F3E3BA"
#define OPc "E8ED2 89D EBA9 52E4 283B 54E8 8E61 83CA"
#define AMF "8000"
c_uint8_t k[16] = "\x46\x5B\x5C\xE8\xB1\x99\xB4\x9F\xAA\x5F\x0A\x2E\xE2\x38\xA6\xBC";
c_uint8_t op[16] = "\x5F\x1D\x28\x9C\x5D\x35\x4D\x0A\x14\x0C\x25\x48\xF5\xF3\xE3\xBA";
c_uint8_t opc[16] = "\xE8\xED\x28\x9D\xEB\xA9\x52\xE4\x28\x3B\x54\xE8\x8E\x61\x83\xCA";
c_uint8_t amf[2] = { 0x80, 0x00 };
#define LOWER " 12abcdE F"
c_uint8_t lower[4] = "\x12\xab\xcd\xef";
char buffer[16];
ABTS_TRUE(tc, memcmp(k, CORE_HEX(K, strlen(K), buffer), 16) == 0);
ABTS_TRUE(tc, memcmp(op, CORE_HEX(OP, strlen(OP), buffer), 16) == 0);
ABTS_TRUE(tc, memcmp(opc, CORE_HEX(OPc, strlen(OPc), buffer), 16) == 0);
ABTS_TRUE(tc, memcmp(amf, CORE_HEX(AMF, strlen(AMF), buffer), 2) == 0);
ABTS_TRUE(tc, memcmp(lower,
CORE_HEX(LOWER, strlen(LOWER), buffer), 4) == 0);
}
static void misc_test3(abts_case *tc, void *data)
{
c_uint8_t k[16] = "\x46\x5B\x5C\xE8\xB1\x99\xB4\x9F\xAA\x5F\x0A\x2E\xE2\x38\xA6\xBC";
c_uint8_t op[16] = "\x5F\x1D\x28\x9C\x5D\x35\x4D\x0A\x14\x0C\x25\x48\xF5\xF3\xE3\xBA";
c_uint8_t opc[16] = "\xE8\xED\x28\x9D\xEB\xA9\x52\xE4\x28\x3B\x54\xE8\x8E\x61\x83\xCA";
c_uint8_t amf[2] = { 0x80, 0x00 };
c_uint8_t lower[4] = "\x12\xab\xcd\xef";
c_uint8_t buffer[128];
ABTS_TRUE(tc, strcmp("465B5CE8 B199B49F AA5F0A2E E238A6BC",
core_hex_to_ascii(k, sizeof(k), buffer, sizeof(buffer))) == 0);
ABTS_TRUE(tc, strcmp("5F1D289C 5D354D0A 140C2548 F5F3E3BA",
core_hex_to_ascii(op, sizeof(op), buffer, sizeof(buffer))) == 0);
ABTS_TRUE(tc, strcmp("E8ED289D EBA952E4 283B54E8 8E6183CA",
core_hex_to_ascii(opc, sizeof(opc), buffer, sizeof(buffer))) == 0);
ABTS_TRUE(tc, strcmp("8000",
core_hex_to_ascii(amf, sizeof(amf), buffer, sizeof(buffer))) == 0);
ABTS_TRUE(tc, strcmp("12ABCDEF",
core_hex_to_ascii(lower, sizeof(lower), buffer, sizeof(buffer))) == 0);
}
static void misc_test4(abts_case *tc, void *data)
{
#define MAX_SIZE 8
c_uint8_t tmp[MAX_SIZE] = "\x01\x23\x45\x67\x89\xab\xcd\xef";
c_uint8_t buf[MAX_SIZE];
c_uint64_t num;
num = 0x0123456789abcdef;
ABTS_TRUE(tc, memcmp(tmp, core_uint64_to_buffer(num, 8, buf), 8) == 0);
num = 0x0123456789abcd;
ABTS_TRUE(tc, memcmp(tmp, core_uint64_to_buffer(num, 7, buf), 7) == 0);
num = 0x0123456789ab;
ABTS_TRUE(tc, memcmp(tmp, core_uint64_to_buffer(num, 6, buf), 6) == 0);
num = 0x0123456789;
ABTS_TRUE(tc, memcmp(tmp, core_uint64_to_buffer(num, 5, buf), 5) == 0);
num = 0x01234567;
ABTS_TRUE(tc, memcmp(tmp, core_uint64_to_buffer(num, 4, buf), 4) == 0);
num = 0x012345;
ABTS_TRUE(tc, memcmp(tmp, core_uint64_to_buffer(num, 3, buf), 3) == 0);
num = 0x0123;
ABTS_TRUE(tc, memcmp(tmp, core_uint64_to_buffer(num, 2, buf), 2) == 0);
num = 0x01;
ABTS_TRUE(tc, memcmp(tmp, core_uint64_to_buffer(num, 1, buf), 1) == 0);
}
static void misc_test5(abts_case *tc, void *data)
{
ABTS_TRUE(tc, 0x0123456789abcdef ==
core_buffer_to_uint64("\x01\x23\x45\x67\x89\xab\xcd\xef", 8));
ABTS_TRUE(tc, 0x0123456789abcd ==
core_buffer_to_uint64("\x01\x23\x45\x67\x89\xab\xcd", 7));
ABTS_TRUE(tc, 0x0123456789ab ==
core_buffer_to_uint64("\x01\x23\x45\x67\x89\xab", 6));
ABTS_TRUE(tc, 0x0123456789 ==
core_buffer_to_uint64("\x01\x23\x45\x67\x89", 5));
ABTS_TRUE(tc, 0x01234567 ==
core_buffer_to_uint64("\x01\x23\x45\x67", 4));
ABTS_TRUE(tc, 0x012345 ==
core_buffer_to_uint64("\x01\x23\x45", 3));
ABTS_TRUE(tc, 0x0123 ==
core_buffer_to_uint64("\x01\x23", 2));
ABTS_TRUE(tc, 0x01 ==
core_buffer_to_uint64("\x01", 1));
}
static void misc_test6(abts_case *tc, void *data)
{
char out[16];
int out_len;
#define MSISDN "491725670014"
core_bcd_to_buffer(MSISDN, out, &out_len);
ABTS_TRUE(tc, memcmp("\x94\x71\x52\x76\x00\x41", out, out_len) == 0);
#define MEI "3516020019874800"
core_bcd_to_buffer(MEI, out, &out_len);
ABTS_TRUE(tc,
memcmp("\x53\x61\x20\x00\x91\x78\x84\x00", out, out_len) == 0);
#define IMSI "001010123456819"
core_bcd_to_buffer(IMSI, out, &out_len);
ABTS_TRUE(tc,
memcmp("\x00\x01\x01\x21\x43\x65\x18\xf9", out, out_len) == 0);
}
static void misc_test7(abts_case *tc, void *data)
{
char out[32];
c_uint8_t buf1[6] = "\x94\x71\x52\x76\x00\x41";
int buf1_len = 6;
c_uint8_t buf2[8] = "\x53\x61\x20\x00\x91\x78\x84\x00";
int buf2_len = 8;
c_uint8_t buf3[8] = "\x00\x01\x01\x21\x43\x65\x18\xf9";
int buf3_len = 8;
core_buffer_to_bcd(buf1, buf1_len, out);
ABTS_TRUE(tc, strcmp("491725670014", out) == 0);
core_buffer_to_bcd(buf2, buf2_len, out);
ABTS_TRUE(tc, strcmp("3516020019874800", out) == 0);
core_buffer_to_bcd(buf3, buf3_len, out);
ABTS_TRUE(tc, strcmp("001010123456819", out) == 0);
}
#define TEST_ENVVAR_NAME "core_test_envvar"
#define TEST_ENVVAR2_NAME "core_test_envvar2"
#define TEST_ENVVAR_VALUE "Just a value that we'll check"
static void misc_test8(abts_case *tc, void *data)
{
char *value;
status_t rv;
rv = core_env_set(TEST_ENVVAR_NAME, TEST_ENVVAR_VALUE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
value = core_env_get(TEST_ENVVAR_NAME);
ABTS_PTR_NOTNULL(tc, value);
ABTS_STR_EQUAL(tc, TEST_ENVVAR_VALUE, value);
rv = core_env_delete(TEST_ENVVAR_NAME);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
value = core_env_get(TEST_ENVVAR_NAME);
ABTS_PTR_NULL(tc, value);
rv = core_env_set(TEST_ENVVAR_NAME, "");
ABTS_INT_EQUAL(tc, CORE_OK, rv);
value = core_env_get(TEST_ENVVAR_NAME);
ABTS_PTR_NOTNULL(tc, value);
ABTS_STR_EQUAL(tc, "", value);
rv = core_env_delete(TEST_ENVVAR_NAME);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
value = core_env_get(TEST_ENVVAR_NAME);
ABTS_PTR_NULL(tc, value);
rv = core_env_set(TEST_ENVVAR2_NAME, TEST_ENVVAR_VALUE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
value = core_env_get(TEST_ENVVAR2_NAME);
ABTS_PTR_NOTNULL(tc, value);
ABTS_STR_EQUAL(tc, TEST_ENVVAR_VALUE, value);
value = core_env_get(TEST_ENVVAR_NAME);
ABTS_PTR_NULL(tc, value);
value = core_env_get(TEST_ENVVAR2_NAME);
ABTS_PTR_NOTNULL(tc, value);
ABTS_STR_EQUAL(tc, TEST_ENVVAR_VALUE, value);
rv = core_env_delete(TEST_ENVVAR2_NAME);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
value = core_env_get(TEST_ENVVAR2_NAME);
ABTS_PTR_NULL(tc, value);
}
abts_suite *testmisc(abts_suite *suite)
{
suite = ADD_SUITE(suite)
abts_run_test(suite, misc_test1, NULL);
abts_run_test(suite, misc_test2, NULL);
abts_run_test(suite, misc_test3, NULL);
abts_run_test(suite, misc_test4, NULL);
abts_run_test(suite, misc_test5, NULL);
abts_run_test(suite, misc_test6, NULL);
abts_run_test(suite, misc_test7, NULL);
abts_run_test(suite, misc_test8, NULL);
return suite;
}
nextepc-0.3.10/lib/core/test/testmsgq.c 0000664 0000000 0000000 00000016645 13335533574 0017760 0 ustar 00root root 0000000 0000000 #include "core_msgq.h"
#include "core_thread.h"
#include "core_portable.h"
#include "testutil.h"
static char msg[16][24] = {
{0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18},
{0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28},
{0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38},
{0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48},
{0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58},
{0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68},
{0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78},
{0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88},
{0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98},
{0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8},
{0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8},
{0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8},
{0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8},
{0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8},
{0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8},
{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}
};
static char rmsg[16][24];
static int msglen[16] = {3, 4, 5, 6, 7, 8, 1, 2, 11, 12, 13, 14, 15, 16, 17, 18};
static msgq_id md;
static void msgq_test1(abts_case *tc, void *data)
{
int i, n;
/* Basic test */
md = msgq_create(5, 8, 0);
ABTS_INT_NEQUAL(tc, 0, md);
n = msgq_send(md, msg[0], msglen[0]);
ABTS_INT_EQUAL(tc, msglen[0], n);
n = msgq_recv(md, rmsg[0], 8);
ABTS_INT_EQUAL(tc, msglen[0], n);
n = memcmp(msg[0], rmsg[0], msglen[0]);
ABTS_INT_EQUAL(tc, 0, n);
msgq_delete(md);
/* Test with send() and recv() function up to queue size */
md = msgq_create(5, 8, 0);
ABTS_INT_NEQUAL(tc, 0, md);
for (i = 0; i < 5; i++)
{
n = msgq_send(md, msg[i], msglen[i]);
ABTS_INT_EQUAL(tc, msglen[i], n);
}
for (i = 0; i < 5; i++)
{
n = msgq_recv(md, rmsg[i], 8);
ABTS_INT_EQUAL(tc, msglen[i], n);
n = memcmp(msg[i], rmsg[i], msglen[i]);
ABTS_INT_EQUAL(tc, 0, n);
}
msgq_delete(md);
/* Test with send() and timedrecv() function up to queue size */
md = msgq_create(5, 8, 0);
ABTS_INT_NEQUAL(tc, 0, md);
for (i = 0; i < 5; i++)
{
n = msgq_send(md, msg[i], msglen[i]);
ABTS_INT_EQUAL(tc, msglen[i], n);
}
for (i = 0; i < 5; i++)
{
n = msgq_timedrecv(md, rmsg[i], 8, 0);
ABTS_INT_EQUAL(tc, msglen[i], n);
n = memcmp(msg[i], rmsg[i], msglen[i]);
ABTS_INT_EQUAL(tc, 0, n);
}
msgq_delete(md);
}
static void msgq_test2(abts_case *tc, void *data)
{
int i, n;
md = msgq_create(5, 8, MSGQ_O_NONBLOCK);
ABTS_INT_NEQUAL(tc, 0, md);
/* fill up the queue */
for (i = 0; i < 5; i++)
{
n = msgq_send(md, msg[i], msglen[i]);
ABTS_INT_EQUAL(tc, msglen[i], n);
}
/* Now, there is no room to send.
* Confirm that send() returns CORE_EGAIN */
n = msgq_send(md, msg[0], msglen[0]);
ABTS_INT_EQUAL(tc, CORE_EAGAIN, n);
/* empty queue */
for (i = 0; i < 5; i++)
{
n = msgq_recv(md, rmsg[i], 8);
ABTS_INT_EQUAL(tc, msglen[i], n);
n = memcmp(msg[i], rmsg[i], msglen[i]);
ABTS_INT_EQUAL(tc, 0, n);
}
/* Now, there is no sent buffer to be read.
* Confirm that recv() return CORE_EGAIN */
n = msgq_recv(md, rmsg[i], 8);
ABTS_INT_EQUAL(tc, CORE_EAGAIN, n);
msgq_delete(md);
}
static void msgq_test3(abts_case *tc, void *data)
{
int i, j, n;
md = msgq_create(16, 24, MSGQ_O_BLOCK);
ABTS_INT_NEQUAL(tc, 0, md);
/* Repeat 10 times */
for (j = 0; j < 10; j++)
{
/* Cycle repeatedly by queue depth */
for (i = 0; i < 16; i++)
{
n = msgq_send(md, msg[i], 24);
ABTS_INT_EQUAL(tc, CORE_OK, n);
n = msgq_recv(md, rmsg[i], 24);
ABTS_INT_EQUAL(tc, CORE_OK, n);
n = memcmp(msg[i], rmsg[i], 24);
ABTS_INT_EQUAL(tc, 0, n);
}
}
msgq_delete(md);
}
#define TEST_QUEUE_SIZE 128
#define TEST_EVT_SIZE (sizeof(test_event_t))
typedef struct {
int a;
int b;
char c[30];
} test_event_t;
typedef struct {
abts_case *tc;
int opt;
int cancelled;
int timed;
} test_param_t;
static thread_id thr_producer;
static thread_id thr_consumer;
static int max = 100000;
static int exit_ret_val = 123;
static void *THREAD_FUNC producer_main(thread_id id, void *data)
{
test_param_t *param = (test_param_t *)data;
abts_case *tc = param->tc;
status_t rv;
int i = 0;
unsigned int full = 0;
while (i++ < max)
{
test_event_t te;
te.a = i;
te.b = i+2;
te.c[28] = 'X';
te.c[29] = 'Y';
rv = msgq_send(md, (char*)&te, TEST_EVT_SIZE);
if (rv == CORE_EAGAIN)
{
full++;
thread_yield();
continue;
}
ABTS_ASSERT(tc, "producer error", rv == CORE_OK);
}
thread_exit(id, exit_ret_val);
return NULL;
}
static void *THREAD_FUNC consumer_main(thread_id id, void *data)
{
test_param_t *param = (test_param_t *)data;
abts_case *tc = param->tc;
status_t rv;
int i = 0;
while (!thread_should_stop())
{
test_event_t te;
if (param->cancelled)
pthread_testcancel();
if (param->timed)
rv = msgq_timedrecv(md, (char*)&te, TEST_EVT_SIZE, 10000);
else
rv = msgq_recv(md, (char*)&te, TEST_EVT_SIZE);
if (rv == CORE_EAGAIN || rv == CORE_TIMEUP)
{
thread_yield();
continue;
}
ABTS_ASSERT(tc, "consumer error", rv == CORE_OK);
ABTS_ASSERT(tc, "consumer error", te.c[28] == 'X' && te.c[29] == 'Y');
i++;
}
return NULL;
}
static void msgq_test4(abts_case *tc, void *data)
{
status_t rv;
test_param_t *param = (test_param_t *)data;
param->tc = tc;
md = msgq_create(TEST_QUEUE_SIZE, TEST_EVT_SIZE, param->opt);
ABTS_INT_NEQUAL(tc, 0, md);
rv = thread_create(&thr_producer, NULL, producer_main, param);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = thread_create(&thr_consumer, NULL, consumer_main, param);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
thread_join(&rv, thr_producer);
ABTS_INT_EQUAL(tc, exit_ret_val, rv);
if (param->cancelled)
{
os_thread_t *thread;
os_thread_get(&thread, thr_consumer);
pthread_cancel(*thread);
thread_join(&rv, thr_consumer);
}
else
{
thread_delete(thr_consumer);
}
msgq_delete(md);
}
#define STRESS_TEST 0
abts_suite *testmsgq(abts_suite *suite)
{
suite = ADD_SUITE(suite)
#if 0 /* Deprecated */
abts_run_test(suite, msgq_test1, NULL);
abts_run_test(suite, msgq_test2, NULL);
#endif
abts_run_test(suite, msgq_test3, NULL);
#if STRESS_TEST == 1
while(1)
{
#endif
test_param_t param;
memset(¶m, 0, sizeof(test_param_t));
param.opt = MSGQ_O_NONBLOCK;
abts_run_test(suite, msgq_test4, (void *)¶m);
#if HAVE_PTHREAD_H == 1
param.opt = MSGQ_O_BLOCK;
param.cancelled = 1;
abts_run_test(suite, msgq_test4, (void *)¶m);
#endif
param.opt = MSGQ_O_NONBLOCK;
param.timed = 1;
abts_run_test(suite, msgq_test4, (void *)¶m);
param.opt = MSGQ_O_BLOCK;
param.timed = 1;
abts_run_test(suite, msgq_test4, (void *)¶m);
#if STRESS_TEST == 1
printf("Test again = %"C_UINT64_T_FMT "\n", time_now());
sleep(3);
}
#endif
return suite;
}
nextepc-0.3.10/lib/core/test/testnetlib.c 0000664 0000000 0000000 00000032713 13335533574 0020260 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _testnetlib
#include "core_debug.h"
#include "core_net.h"
#include "testutil.h"
#define TEST_SERVER_PORT 5121
#define TEST_BUFFER_SIZE 1024
#define TEST_MAX_NUM 4
#define DISABLE_FTPTEST 1
#define DISABLE_LINKTEST 1
static char buffer[TEST_BUFFER_SIZE];
static int tcp_server_started = 0;
static int udp_server_started = 0;
pthread_t tserver_tid,userver_tid;
net_sock_t *tserver_sock,*userver_sock;
static void *tcp_session_main(void *param)
{
int rc;
net_sock_t *net_sock = (net_sock_t *)param;
while (1)
{
rc = net_read(net_sock, buffer, TEST_BUFFER_SIZE, 1);
if (rc > 0)
{
if (!strncmp(buffer, "QUIT",4))
{
break;
}
else
{
/* Send received data */
rc = net_send(net_sock, buffer, rc);
}
}
else if (rc == 0)
{
/* Timeout */
}
else
{
printf("error = %d\n", net_sock->sndrcv_errno);
break;
}
}
net_close(net_sock);
return NULL;
}
static void start_tcp_session(net_sock_t *net_sock)
{
pthread_t tid;
pthread_create(&tid, NULL, tcp_session_main, (void *)net_sock);
pthread_detach(tid);
return;
}
static void *tcp_server_main(void *param)
{
int rc;
net_sock_t *new_sock;
rc = net_listen(&tserver_sock, SOCK_STREAM, IPPROTO_TCP, TEST_SERVER_PORT);
if (rc != 0)
{
d_error("net_tcp_listen Error(rc = %d)\n",rc);
return NULL;
}
tcp_server_started = 1;
while (1)
{
rc = net_accept(&new_sock, tserver_sock, 1);
if (rc >0)
{
/* New connection arrived. Start session */
start_tcp_session(new_sock);
}
else if (rc == 0)
{
/* Timeout */
}
else
{
/* Error occured */
break;
}
}
return NULL;
}
static void start_tcp_server()
{
pthread_create(&tserver_tid, NULL, tcp_server_main, NULL);
while (tcp_server_started == 0)
{
sleep(1);
}
sleep(1);
return;
}
static void stop_tcp_server()
{
net_close(tserver_sock);
pthread_join(tserver_tid, NULL);
}
static void *udp_server_main(void *param)
{
int rc;
rc = net_listen(&userver_sock,
SOCK_DGRAM, IPPROTO_UDP, TEST_SERVER_PORT);
if (rc != 0)
{
d_error("net_udp Error(rc = %d)\n",rc);
return NULL;
}
udp_server_started = 1;
while (1)
{
d_trace(1,"Wait for data....\n");
rc = net_read(userver_sock, buffer, TEST_BUFFER_SIZE, 2);
if (rc >0)
{
d_trace(1,"RECV %d bytes\n", rc);
if (!strncmp(buffer, "QUIT",4))
{
break;
}
else
{
/* Send received data */
rc = net_send(userver_sock, buffer, rc);
d_trace(1,"SEND %d bytes\n", rc);
if (rc == -1)
{
printf("error = %d\n", userver_sock->sndrcv_errno);
}
}
}
else if (rc == 0)
{
/* Timeout */
}
else
{
/* Error occured */
break;
}
}
return NULL;
}
static void start_udp_server()
{
pthread_create(&userver_tid, NULL, udp_server_main, NULL);
while (udp_server_started == 0)
{
sleep(1);
}
return;
}
static void stop_udp_server()
{
net_close(userver_sock);
pthread_join(userver_tid, NULL);
}
static void netlib1(abts_case *tc, void *data)
{
int rc = 0;
net_sock_t *net_sock;
char inputbuf[TEST_MAX_NUM][20];
char outputbuf[TEST_MAX_NUM][20];
int i;
/* Start TCP server */
start_tcp_server();
rc = net_open(&net_sock, "127.0.0.1", 0,
TEST_SERVER_PORT, SOCK_STREAM, IPPROTO_TCP);
ABTS_INT_EQUAL(tc, 0, rc);
for (i=0; i< TEST_MAX_NUM; i++)
{
sprintf(inputbuf[i],"asdf%d",i);
rc = net_send(net_sock, inputbuf[i], strlen(inputbuf[i])+1);
ABTS_INT_EQUAL(tc, strlen(inputbuf[i])+1, rc);
}
for (i=0; i< TEST_MAX_NUM; i++)
{
memset(outputbuf[i], 0, sizeof(outputbuf[i]));
rc = 0;
while (1)
{
int n;
n = net_read(net_sock, outputbuf[i], 6, 1);
rc += n;
if (n == 0 || n == 6)
break;
}
ABTS_INT_EQUAL(tc, 6, rc);
ABTS_INT_EQUAL(tc, 6, strlen(outputbuf[i])+1);
ABTS_STR_EQUAL(tc, inputbuf[i], outputbuf[i]);
}
/* Send QUIT */
rc = net_send(net_sock, "QUIT", 4);
ABTS_INT_EQUAL(tc, 4, rc);
/* Close */
rc = net_close(net_sock);
ABTS_INT_EQUAL(tc, 0, rc);
/* Stop TCP server */
stop_tcp_server();
}
static void netlib2(abts_case *tc, void *data)
{
int rc = 0;
net_sock_t *net_sock[TEST_MAX_NUM];
char inputbuf[TEST_MAX_NUM][20];
char outputbuf[TEST_MAX_NUM][20];
int i;
/* Start TCP server */
start_tcp_server();
/* Connect to invalid port */
d_log_set_level(D_MSG_TO_STDOUT, D_LOG_LEVEL_FATAL);
for (i =0 ; ih_proto) == proto)
{
d_print_hex(buf, len);
}
}
static void netlib5(abts_case *tc, void *data)
{
net_link_t *net_link = NULL;
int promisc = 1;
int rc;
int max_count = 10;
char buf[1024];
#if DISABLE_LINKTEST
return;
#endif
rc = net_link_open(&net_link, "eth0", ETH_P_ALL);
ABTS_INT_EQUAL(tc, 0, rc);
ABTS_PTR_NOTNULL(tc, net_link);
rc = net_link_promisc(net_link, promisc);
ABTS_INT_EQUAL(tc, 0, rc);
#if 0
d_print("HW addr of %s : ",net_link->ifname);
d_print_hex(net_link->hwaddr.sa_data, 6);
#endif
while (max_count-- > 0)
{
rc = net_link_read(net_link, buf, 1024, 1);
ABTS_TRUE(tc, rc > 0);
filter_updu(buf, rc);
}
rc = net_link_close(net_link);
ABTS_INT_EQUAL(tc, 0, rc);
}
static int make_test_updu(char *src_addr, char *dst_addr, char *buf, int len)
{
unsigned short proto = 0x88B6;
struct ethhdr *eth_hdr = NULL;
int rc = sizeof(struct ethhdr);
char *ptr = buf;
eth_hdr = (struct ethhdr *)buf;
memcpy(eth_hdr->h_source, src_addr, 6);
memcpy(eth_hdr->h_dest, dst_addr, 6);
eth_hdr->h_proto = htons(proto);
/* Fill the data */
rc += sprintf(ptr+rc,"Hellow World");
d_print_hex(buf, rc);
return rc;
}
static void netlib6(abts_case *tc, void *data)
{
net_link_t *net_link = NULL;
int promisc = 1;
int rc;
int max_count = 1;
char buf[1024];
#if 0
char dst_addr[6] = {'\x00','\x00','\x00','\x11','\x22','\x33'};
#else
char dst_addr[6] = {'\xff','\xff','\xff','\xff','\xff','\xff'};
#endif
#if DISABLE_LINKTEST
return;
#endif
rc = net_link_open(&net_link, "eth0", ETH_P_ALL);
ABTS_INT_EQUAL(tc, 0, rc);
ABTS_PTR_NOTNULL(tc, net_link);
rc = net_link_promisc(net_link, promisc);
ABTS_INT_EQUAL(tc, 0, rc);
while (max_count-- > 0)
{
rc = make_test_updu(net_link->hwaddr.sa_data, dst_addr,buf,1024);
rc = net_link_write(net_link, buf, rc);
ABTS_TRUE(tc, rc > 0);
}
rc = net_link_close(net_link);
ABTS_INT_EQUAL(tc, 0, rc);
}
#endif
abts_suite *testnetlib(abts_suite *suite)
{
suite = ADD_SUITE(suite);
abts_run_test(suite, netlib1, NULL);
/*
* OpenSUSE OBS
* - Ubuntu 17.04 i586 failed
* - Jinyoung Fixed
*
[ 542s] testnetlib : Line 262: expected <0>, but saw <-1>
[ 542s] [10/30 07:48:38.730] ERRR: connect error(111:Connection refused)(proto:6 remote:127.0.0.1 dport:5121 lport:0) (net_lib.c:353)
[ 542s] [10/30 07:48:38.730] ERRR: connect error(111:Connection refused)(proto:6 remote:127.0.0.1 dport:5121 lport:0) (net_lib.c:353)
[ 542s] [10/30 07:48:38.730] ERRR: connect error(111:Connection refused)(proto:6 remote:127.0.0.1 dport:5121 lport:0) (net_lib.c:353)
[ 542s] [10/30 07:48:38.730] ERRR: connect error(111:Connection refused)(proto:6 remote:127.0.0.1 dport:5121 lport:0) (net_lib.c:353)
[ 542s] [10/30 07:48:38.730] ASSERT: !(net_sock && buffer). Invalid params
[ 542s] (net_lib.c:590)
[ 542s] [10/30 07:48:38.730] ASSERT: !(net_sock). net_sock is NULL
[ 542s] (net_lib.c:408)
[ 542s] [10/30 07:48:38.730] ASSERT: !(net_sock). net_sock is NULL
*/
abts_run_test(suite, netlib2, NULL);
abts_run_test(suite, netlib3, NULL);
abts_run_test(suite, netlib4, NULL);
#if LINUX == 1
abts_run_test(suite, netlib5, NULL);
abts_run_test(suite, netlib6, NULL);
#endif
return suite;
}
nextepc-0.3.10/lib/core/test/testpkbuf.c 0000664 0000000 0000000 00000002634 13335533574 0020111 0 ustar 00root root 0000000 0000000 #include "core_pkbuf.h"
#include "testutil.h"
static void pkbuf_test1(abts_case *tc, void *data)
{
char *ptr = core_malloc(256);
ABTS_PTR_NOTNULL(tc, ptr);
CORE_FREE(ptr);
}
static void pkbuf_test2(abts_case *tc, void *data)
{
char *ptr = core_calloc(2, 10);
int i;
for (i = 0; i < 2*10; i++)
{
ABTS_INT_EQUAL(tc, 0, ptr[i]);
}
ABTS_PTR_NOTNULL(tc, ptr);
CORE_FREE(ptr);
}
static void pkbuf_test3(abts_case *tc, void *data)
{
char *ptr = core_realloc(0, 10);
ABTS_PTR_NOTNULL(tc, ptr);
CORE_FREE(ptr);
ptr = core_malloc(20);
ABTS_PTR_NOTNULL(tc, ptr);
ptr = core_realloc(ptr, 0);
}
static void pkbuf_test4(abts_case *tc, void *data)
{
char *p, *q;
p = core_malloc(10);
ABTS_PTR_NOTNULL(tc, p);
memset(p, 1, 10);
q = core_realloc(p,
CORE_ALIGN(128+MAX_SIZEOF_HEADROOM, SIZEOF_VOIDP) -
SIZEOF_VOIDP-1);
ABTS_TRUE(tc, p == q);
p = core_realloc(q,
CORE_ALIGN(128+MAX_SIZEOF_HEADROOM, SIZEOF_VOIDP) -
SIZEOF_VOIDP);
ABTS_TRUE(tc, p != q);
ABTS_TRUE(tc, memcmp(p, q, 10) == 0);
CORE_FREE(p);
}
abts_suite *testpkbuf(abts_suite *suite)
{
suite = ADD_SUITE(suite)
abts_run_test(suite, pkbuf_test1, NULL);
abts_run_test(suite, pkbuf_test2, NULL);
abts_run_test(suite, pkbuf_test3, NULL);
abts_run_test(suite, pkbuf_test4, NULL);
return suite;
}
nextepc-0.3.10/lib/core/test/testsctp.c 0000664 0000000 0000000 00000022123 13335533574 0017746 0 ustar 00root root 0000000 0000000 #include "core_debug.h"
#include "core_thread.h"
#include "core_network.h"
#include "testutil.h"
#define DATASTR "This is a test"
#define STRLEN 8092
#define PORT 7777
#define PORT2 7778
#define PPID 12345
#ifndef AI_PASSIVE
#define AI_PASSIVE 1
#endif
static void sctp_test1(abts_case *tc, void *data)
{
sock_id sctp;
c_sockaddr_t *addr;
status_t rv;
rv = sctp_socket(&sctp, AF_INET6, SOCK_SEQPACKET);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = sock_delete(sctp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_getaddrinfo(&addr, AF_INET, NULL, PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = sctp_server(&sctp, SOCK_STREAM, addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = sock_delete(sctp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_getaddrinfo(&addr, AF_UNSPEC, NULL, PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = sctp_server(&sctp, SOCK_SEQPACKET, addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = sock_delete(sctp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
}
static thread_id test2_thread;
static void *THREAD_FUNC test2_main(thread_id id, void *data)
{
abts_case *tc = data;
status_t rv;
sock_id sctp;
char str[STRLEN];
ssize_t size;
c_uint32_t ppid;
sctp_info_t sinfo;
c_sockaddr_t *addr;
c_sockaddr_t from;
rv = core_getaddrinfo(&addr, AF_UNSPEC, NULL, PORT, 0);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = sctp_client(&sctp, SOCK_SEQPACKET, addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
size = core_sctp_recvdata(sctp, str, STRLEN, &from, &sinfo);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ABTS_INT_EQUAL(tc, PPID, sinfo.ppid);
rv = sock_delete(sctp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
thread_exit(id, size);
return NULL;
}
static void sctp_test2(abts_case *tc, void *data)
{
status_t rv;
sock_id sctp, sctp2;
ssize_t size;
c_sockaddr_t *addr;
rv = core_getaddrinfo(&addr, AF_INET6, NULL, PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = sctp_server(&sctp, SOCK_STREAM, addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = thread_create(&test2_thread, NULL, test2_main, tc);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = sock_accept(&sctp2, sctp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
size = core_sctp_sendmsg(sctp2, DATASTR, strlen(DATASTR), NULL, PPID, 0);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
thread_join(&rv, test2_thread);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
rv = sock_delete(sctp2);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = sock_delete(sctp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
}
static thread_id test3_thread;
static void *THREAD_FUNC test3_main(thread_id id, void *data)
{
abts_case *tc = data;
status_t rv;
sock_id sctp;
c_sockaddr_t *addr;
c_sockaddr_t *to;
char str[STRLEN];
ssize_t size;
int rc;
rv = sctp_socket(&sctp, AF_INET, SOCK_SEQPACKET);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_getaddrinfo(&to, AF_INET, NULL, PORT, 0);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
size = core_sctp_sendmsg(sctp, DATASTR, strlen(DATASTR), to, PPID, 0);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
rv = core_freeaddrinfo(to);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = sock_delete(sctp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
thread_exit(id, size);
return NULL;
}
static void sctp_test3(abts_case *tc, void *data)
{
sock_id sctp;
status_t rv;
ssize_t size;
c_sockaddr_t from, *addr;
char str[STRLEN];
char buf[CORE_ADDRSTRLEN];
sctp_info_t sinfo;
rv = core_getaddrinfo(&addr, AF_INET, NULL, PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = sctp_server(&sctp, SOCK_SEQPACKET, addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = thread_create(&test3_thread, NULL, test3_main, tc);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
size = core_sctp_recvdata(sctp, str, STRLEN, &from, &sinfo);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ABTS_INT_EQUAL(tc, PPID, sinfo.ppid);
thread_join(&rv, test3_thread);
ABTS_INT_EQUAL(tc, strlen(DATASTR), rv);
rv = sock_delete(sctp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
}
static thread_id test4_thread;
static void *THREAD_FUNC test4_main(thread_id id, void *data)
{
abts_case *tc = data;
status_t rv;
sock_id sctp;
c_sockaddr_t *addr;
char str[STRLEN];
ssize_t size;
sctp_info_t sinfo;
rv = core_getaddrinfo(&addr, AF_UNSPEC, NULL, PORT, 0);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = sctp_client(&sctp, SOCK_STREAM, addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
size = core_sctp_sendmsg(sctp, DATASTR, strlen(DATASTR), NULL, PPID, 0);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
size = core_sctp_recvdata(sctp, str, STRLEN, NULL, &sinfo);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ABTS_INT_EQUAL(tc, PPID, sinfo.ppid);
rv = sock_delete(sctp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
thread_exit(id, size);
return NULL;
}
static void sctp_test4(abts_case *tc, void *data)
{
sock_id sctp;
status_t rv;
ssize_t size;
c_sockaddr_t from, *addr;
char str[STRLEN];
sctp_info_t sinfo;
char buf[CORE_ADDRSTRLEN];
rv = core_getaddrinfo(&addr, AF_INET6, NULL, PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = sctp_server(&sctp, SOCK_SEQPACKET, addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = thread_create(&test4_thread, NULL, test4_main, tc);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
size = core_sctp_recvdata(sctp, str, STRLEN, &from, &sinfo);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ABTS_STR_EQUAL(tc, "::1", CORE_ADDR(&from, buf));
ABTS_INT_EQUAL(tc, PPID, sinfo.ppid);
size = core_sctp_sendmsg(sctp, DATASTR, strlen(DATASTR), &from, PPID, 0);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
thread_join(&rv, test4_thread);
ABTS_INT_EQUAL(tc, strlen(DATASTR), rv);
rv = sock_delete(sctp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
}
static thread_id test5_thread;
static void *THREAD_FUNC test5_main(thread_id id, void *data)
{
abts_case *tc = data;
status_t rv;
sock_id sctp;
char str[STRLEN];
c_sockaddr_t from, *remote_addr, *addr;
sctp_info_t sinfo;
ssize_t size;
char buf[CORE_ADDRSTRLEN];
rv = core_getaddrinfo(&addr, AF_INET6, NULL, PORT2, AI_PASSIVE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = sctp_server(&sctp, SOCK_SEQPACKET, addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_getaddrinfo(&addr, AF_INET6, NULL, PORT, 0);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = sctp_connect(sctp, addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
remote_addr = sock_remote_addr(sctp);
ABTS_STR_EQUAL(tc, "::1", CORE_ADDR(remote_addr, buf));
size = core_sctp_sendmsg(sctp, DATASTR, strlen(DATASTR),
remote_addr, PPID, 0);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
size = core_sctp_recvdata(sctp, str, STRLEN, &from, &sinfo);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ABTS_STR_EQUAL(tc, "::1", CORE_ADDR(&from, buf));
ABTS_INT_EQUAL(tc, PPID, sinfo.ppid);
rv = sock_delete(sctp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
thread_exit(id, size);
return NULL;
}
static void sctp_test5(abts_case *tc, void *data)
{
sock_id sctp;
status_t rv;
ssize_t size;
c_sockaddr_t from, *addr;
socklen_t addrlen;
char str[STRLEN];
sctp_info_t sinfo;
char buf[CORE_ADDRSTRLEN];
rv = core_getaddrinfo(&addr, AF_INET6, NULL, PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = sctp_server(&sctp, SOCK_SEQPACKET, addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = thread_create(&test5_thread, NULL, test5_main, tc);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
size = core_sctp_recvdata(sctp, str, STRLEN, &from, &sinfo);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ABTS_STR_EQUAL(tc, "::1", CORE_ADDR(&from, buf));
ABTS_INT_EQUAL(tc, PPID, sinfo.ppid);
size = core_sctp_sendmsg(sctp, DATASTR, strlen(DATASTR), &from,
sinfo.ppid, 0);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
thread_join(&rv, test5_thread);
ABTS_INT_EQUAL(tc, strlen(DATASTR), rv);
rv = sock_delete(sctp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
}
abts_suite *testsctp(abts_suite *suite)
{
suite = ADD_SUITE(suite);
abts_run_test(suite, sctp_test1, NULL);
abts_run_test(suite, sctp_test2, NULL);
abts_run_test(suite, sctp_test3, NULL);
abts_run_test(suite, sctp_test4, NULL);
abts_run_test(suite, sctp_test5, NULL);
return suite;
}
nextepc-0.3.10/lib/core/test/testsha.c 0000664 0000000 0000000 00000015215 13335533574 0017554 0 ustar 00root root 0000000 0000000 #include "core_debug.h"
#include "core_sha1.h"
#include "core_sha2.h"
#include "core_pkbuf.h"
#include "testutil.h"
static void sha1_test1(abts_case *tc, void *data)
{
c_uint8_t msg1[] = "abc";
c_uint8_t msg2[] = "abcdbcdecdefdefgefghfghighij"
"hijkijkljklmklmnlmnomnopnopq";
c_uint8_t digest1[] = {
0xa9,0x99,0x3e,0x36,0x47,0x06,0x81,0x6a,
0xba,0x3e,0x25,0x71,0x78,0x50,0xc2,0x6c,
0x9c,0xd0,0xd8,0x9d
};
c_uint8_t digest2[] = {
0x84,0x98,0x3e,0x44,0x1c,0x3b,0xd2,0x6e,
0xba,0xae,0x4a,0xa1,0xf9,0x51,0x29,0xe5,
0xe5,0x46,0x70,0xf1
};
c_uint8_t digest3[] = {
0x34,0xaa,0x97,0x3c,0xd4,0xc4,0xda,0xa4,
0xf6,0x1e,0xeb,0x2b,0xdb,0xad,0x27,0x31,
0x65,0x34,0x01,0x6f,
};
c_uint8_t digest[20];
int i;
sha1_ctx ctx;
sha1_init(&ctx);
sha1_update(&ctx, msg1, sizeof(msg1) - 1);
sha1_final(&ctx, digest);
ABTS_INT_EQUAL(tc, 0, memcmp(digest1, digest, 20));
sha1_init(&ctx);
sha1_update(&ctx, msg2, sizeof(msg2) - 1);
sha1_final(&ctx, digest);
ABTS_INT_EQUAL(tc, 0, memcmp(digest2, digest, 20));
sha1_init(&ctx);
for (i = 0; i < 1000000; i++)
sha1_update(&ctx, (c_uint8_t*)"a", 1);
sha1_final(&ctx, digest);
ABTS_INT_EQUAL(tc, 0, memcmp(digest3, digest, 20));
}
static void sha2_test1(abts_case *tc, void *data)
{
char *vectors[4][3] =
{ /* SHA-224 */
{
"\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2\x55\xb3\x2a\xad\xbc\xe4\xbd\xa0\xb3\xf7\xe3\x6c\x9d\xa7",
"\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01\x50\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25",
"\x20\x79\x46\x55\x98\x0c\x91\xd8\xbb\xb4\xc1\xea\x97\x61\x8a\x4b\xf0\x3f\x42\x58\x19\x48\xb2\xee\x4e\xe7\xad\x67",
},
/* SHA-\x25\x6 */
{
"\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad",
"\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1",
"\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0",
},
/* SHA-\x38\x4 */
{
"\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed"
"\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34\xc8\x25\xa7",
"\x09\x33\x0c\x33\xf7\x11\x47\xe8\x3d\x19\x2f\xc7\x82\xcd\x1b\x47\x53\x11\x1b\x17\x3b\x3b\x05\xd2\x2f\xa0\x80\x86\xe3\xb0\xf7\x12"
"\xfc\xc7\xc7\x1a\x55\x7e\x2d\xb9\x66\xc3\xe9\xfa\x91\x74\x60\x39",
"\x9d\x0e\x18\x09\x71\x64\x74\xcb\x08\x6e\x83\x4e\x31\x0a\x4a\x1c\xed\x14\x9e\x9c\x00\xf2\x48\x52\x79\x72\xce\xc5\x70\x4c\x2a\x5b"
"\x07\xb8\xb3\xdc\x38\xec\xc4\xeb\xae\x97\xdd\xd8\x7f\x3d\x89\x85",
},
/* SHA-\x51\x2 */
{
"\xdd\xaf\x35\xa1\x93\x61\x7a\xba\xcc\x41\x73\x49\xae\x20\x41\x31\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2\x0a\x9e\xee\xe6\x4b\x55\xd3\x9a"
"\x21\x92\x99\x2a\x27\x4f\xc1\xa8\x36\xba\x3c\x23\xa3\xfe\xeb\xbd\x45\x4d\x44\x23\x64\x3c\xe8\x0e\x2a\x9a\xc9\x4f\xa5\x4c\xa4\x9f",
"\x8e\x95\x9b\x75\xda\xe3\x13\xda\x8c\xf4\xf7\x28\x14\xfc\x14\x3f\x8f\x77\x79\xc6\xeb\x9f\x7f\xa1\x72\x99\xae\xad\xb6\x88\x90\x18"
"\x50\x1d\x28\x9e\x49\x00\xf7\xe4\x33\x1b\x99\xde\xc4\xb5\x43\x3a\xc7\xd3\x29\xee\xb6\xdd\x26\x54\x5e\x96\xe5\x5b\x87\x4b\xe9\x09",
"\xe7\x18\x48\x3d\x0c\xe7\x69\x64\x4e\x2e\x42\xc7\xbc\x15\xb4\x63\x8e\x1f\x98\xb1\x3b\x20\x44\x28\x56\x32\xa8\x03\xaf\xa9\x73\xeb"
"\xde\x0f\xf2\x44\x87\x7e\xa6\x0a\x4c\xb0\x43\x2c\xe5\x77\xc3\x1b\xeb\x00\x9c\x5c\x2c\x49\xaa\x2e\x4e\xad\xb2\x17\xad\x8c\xc0\x9b"
}
};
char message1[] = "abc";
char message2a[] = "abcdbcdecdefdefgefghfghighijhi"
"jkijkljklmklmnlmnomnopnopq";
char message2b[] = "abcdefghbcdefghicdefghijdefghijkefghij"
"klfghijklmghijklmnhijklmnoijklmnopjklm"
"nopqklmnopqrlmnopqrsmnopqrstnopqrstu";
unsigned char *message3;
unsigned int message3_len = 1000000;
unsigned char digest[SHA512_DIGEST_SIZE];
int rc;
message3 = malloc(message3_len);
if (message3 == NULL) {
fprintf(stderr, "Can't allocate memory\n");
return;
}
memset(message3, 'a', message3_len);
/* SHA-2 FIPS 180-2 Validation tests.
* SHA-224 Test vector */
sha224((c_uint8_t *)message1, strlen((char *) message1), digest);
rc = memcmp(vectors[0][0], digest, SHA224_DIGEST_SIZE);
ABTS_INT_EQUAL(tc, 0, rc);
sha224((c_uint8_t *)message2a, strlen((char *) message2a), digest);
rc = memcmp(vectors[0][1], digest, SHA224_DIGEST_SIZE);
ABTS_INT_EQUAL(tc, 0, rc);
sha224((c_uint8_t *)message3, message3_len, digest);
rc = memcmp(vectors[0][2], digest, SHA224_DIGEST_SIZE);
ABTS_INT_EQUAL(tc, 0, rc);
/* SHA-256 Test vector */
sha256((c_uint8_t *)message1, strlen((char *) message1), digest);
rc = memcmp(vectors[1][0], digest, SHA256_DIGEST_SIZE);
ABTS_INT_EQUAL(tc, 0, rc);
sha256((c_uint8_t *)message2a, strlen((char *) message2a), digest);
rc = memcmp(vectors[1][1], digest, SHA256_DIGEST_SIZE);
ABTS_INT_EQUAL(tc, 0, rc);
sha256((c_uint8_t *)message3, message3_len, digest);
rc = memcmp(vectors[1][2], digest, SHA256_DIGEST_SIZE);
ABTS_INT_EQUAL(tc, 0, rc);
/* SHA-384 Test vector */
sha384((c_uint8_t *)message1, strlen((char *) message1), digest);
rc = memcmp(vectors[2][0], digest, SHA384_DIGEST_SIZE);
ABTS_INT_EQUAL(tc, 0, rc);
sha384((c_uint8_t *)message2b, strlen((char *) message2b), digest);
rc = memcmp(vectors[2][1], digest, SHA384_DIGEST_SIZE);
ABTS_INT_EQUAL(tc, 0, rc);
sha384((c_uint8_t *)message3, message3_len, digest);
rc = memcmp(vectors[2][2], digest, SHA384_DIGEST_SIZE);
ABTS_INT_EQUAL(tc, 0, rc);
/* SHA-512 Test vector */
sha512((c_uint8_t *)message1, strlen((char *) message1), digest);
rc = memcmp(vectors[3][0], digest, SHA512_DIGEST_SIZE);
ABTS_INT_EQUAL(tc, 0, rc);
sha512((c_uint8_t *)message2b, strlen((char *) message2b), digest);
rc = memcmp(vectors[3][1], digest, SHA512_DIGEST_SIZE);
ABTS_INT_EQUAL(tc, 0, rc);
sha512((c_uint8_t *)message3, message3_len, digest);
rc = memcmp(vectors[3][2], digest, SHA512_DIGEST_SIZE);
ABTS_INT_EQUAL(tc, 0, rc);
free(message3);
}
abts_suite *testsha2(abts_suite *suite)
{
suite = ADD_SUITE(suite);
abts_run_test(suite, sha1_test1, NULL);
abts_run_test(suite, sha2_test1, NULL);
return suite;
}
nextepc-0.3.10/lib/core/test/testsleep.c 0000664 0000000 0000000 00000002664 13335533574 0020115 0 ustar 00root root 0000000 0000000 /* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "core_time.h"
#include "testutil.h"
#define SLEEP_INTERVAL 3
static void sleep_one(abts_case *tc, void *data)
{
time_t pretime = time(NULL);
time_t posttime;
time_t timediff;
core_sleep(time_from_sec(SLEEP_INTERVAL));
posttime = time(NULL);
/* normalize the timediff. We should have slept for SLEEP_INTERVAL, so
* we should just subtract that out.
*/
timediff = posttime - pretime - SLEEP_INTERVAL;
ABTS_TRUE(tc, timediff >= 0);
ABTS_TRUE(tc, timediff <= 1);
}
abts_suite *testsleep(abts_suite *suite)
{
suite = ADD_SUITE(suite)
abts_run_test(suite, sleep_one, NULL);
return suite;
}
nextepc-0.3.10/lib/core/test/testsock.c 0000664 0000000 0000000 00000030432 13335533574 0017736 0 ustar 00root root 0000000 0000000 #include "core_debug.h"
#include "core_thread.h"
#include "core_pkbuf.h"
#include "core_network.h"
#include "testutil.h"
#define DATASTR "This is a test"
#define STRLEN 8092
#define PORT 7777
#define PORT2 7778
#ifndef AI_PASSIVE
#define AI_PASSIVE 1
#endif
static void sock_test1(abts_case *tc, void *data)
{
sock_id udp;
c_sockaddr_t *addr;
status_t rv;
rv = core_getaddrinfo(&addr, AF_UNSPEC, NULL, PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = udp_server(&udp, addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = sock_delete(udp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_getaddrinfo(&addr, AF_UNSPEC, "127.0.0.1", PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = udp_server(&udp, addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = sock_delete(udp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_getaddrinfo(&addr, AF_UNSPEC, "::1", PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = udp_server(&udp, addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = sock_delete(udp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
}
static thread_id test2_thread;
static void *THREAD_FUNC test2_main(thread_id id, void *data)
{
abts_case *tc = data;
status_t rv;
sock_id tcp;
c_sockaddr_t *addr;
char str[STRLEN];
ssize_t size;
rv = core_getaddrinfo(&addr, AF_UNSPEC, "::1", PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = tcp_client(&tcp, addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
size = core_recv(tcp, str, STRLEN, 0);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
rv = sock_delete(tcp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
thread_exit(id, size);
return NULL;
}
static void sock_test2(abts_case *tc, void *data)
{
status_t rv;
sock_id tcp, tcp2;
c_sockaddr_t *addr;
ssize_t size;
rv = core_getaddrinfo(&addr, AF_INET6, NULL, PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = tcp_server(&tcp, addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = thread_create(&test2_thread, NULL, test2_main, tc);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = sock_accept(&tcp2, tcp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
size = core_send(tcp2, DATASTR, strlen(DATASTR), 0);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
thread_join(&rv, test2_thread);
ABTS_INT_EQUAL(tc, strlen(DATASTR), rv);
rv = sock_delete(tcp2);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = sock_delete(tcp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
}
static thread_id test3_thread;
static void *THREAD_FUNC test3_main(thread_id id, void *data)
{
abts_case *tc = data;
status_t rv;
sock_id udp;
c_sockaddr_t *sa;
char str[STRLEN];
ssize_t size;
int rc;
char buf[CORE_ADDRSTRLEN];
rv = udp_socket(&udp, AF_INET);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_getaddrinfo(&sa, AF_INET, NULL, PORT, 0);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
size = core_sendto(udp, DATASTR, strlen(DATASTR), 0, sa);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
rv = core_freeaddrinfo(sa);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = sock_delete(udp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
thread_exit(id, size);
return NULL;
}
static void sock_test3(abts_case *tc, void *data)
{
sock_id udp;
status_t rv;
ssize_t size;
c_sockaddr_t sa, *addr;
socklen_t addrlen;
char str[STRLEN];
char buf[CORE_ADDRSTRLEN];
rv = core_getaddrinfo(&addr, AF_INET, NULL, PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = udp_server(&udp, addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = thread_create(&test3_thread, NULL, test3_main, tc);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
size = core_recvfrom(udp, str, STRLEN, 0, &sa);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ABTS_STR_EQUAL(tc, "127.0.0.1", CORE_ADDR(&sa, buf));
thread_join(&rv, test3_thread);
ABTS_INT_EQUAL(tc, strlen(DATASTR), rv);
rv = sock_delete(udp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
}
static thread_id test4_thread;
static void *THREAD_FUNC test4_main(thread_id id, void *data)
{
abts_case *tc = data;
status_t rv;
sock_id udp;
c_sockaddr_t *addr;
char str[STRLEN];
ssize_t size;
rv = core_getaddrinfo(&addr, AF_INET, NULL, PORT, 0);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = udp_client(&udp, addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
size = core_send(udp, DATASTR, strlen(DATASTR), 0);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
size = core_recv(udp, str, STRLEN, 0);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
rv = sock_delete(udp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
thread_exit(id, size);
return NULL;
}
static void sock_test4(abts_case *tc, void *data)
{
sock_id udp;
status_t rv;
ssize_t size;
c_sockaddr_t sa, *addr;
socklen_t addrlen;
char str[STRLEN];
char buf[CORE_ADDRSTRLEN];
rv = core_getaddrinfo(&addr, AF_INET, NULL, PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = udp_server(&udp, addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = thread_create(&test4_thread, NULL, test4_main, tc);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
size = core_recvfrom(udp, str, STRLEN, 0, &sa);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ABTS_STR_EQUAL(tc, "127.0.0.1", CORE_ADDR(&sa, buf));
size = core_sendto(udp, DATASTR, strlen(DATASTR), 0, &sa);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
thread_join(&rv, test4_thread);
ABTS_INT_EQUAL(tc, strlen(DATASTR), rv);
rv = sock_delete(udp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
}
static thread_id test5_thread;
static void *THREAD_FUNC test5_main(thread_id id, void *data)
{
abts_case *tc = data;
status_t rv;
sock_id udp;
c_sockaddr_t *addr;
char str[STRLEN];
ssize_t size;
rv = core_getaddrinfo(&addr, AF_INET6, NULL, PORT2, AI_PASSIVE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = udp_server(&udp, addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_getaddrinfo(&addr, AF_INET6, NULL, PORT, 0);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = udp_connect(udp, addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
size = core_send(udp, DATASTR, strlen(DATASTR), 0);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
size = core_recv(udp, str, STRLEN, 0);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
rv = sock_delete(udp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
thread_exit(id, size);
return NULL;
}
static void sock_test5(abts_case *tc, void *data)
{
sock_id udp;
status_t rv;
ssize_t size;
c_sockaddr_t sa, *addr;
socklen_t addrlen;
char str[STRLEN];
char buf[CORE_ADDRSTRLEN];
rv = core_getaddrinfo(&addr, AF_INET6, NULL, PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = udp_server(&udp, addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_getaddrinfo(&addr, AF_INET6, NULL, PORT2, 0);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = udp_connect(udp, addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = thread_create(&test5_thread, NULL, test5_main, tc);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
size = core_recvfrom(udp, str, STRLEN, 0, &sa);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ABTS_STR_EQUAL(tc, "::1", CORE_ADDR(&sa, buf));
size = core_send(udp, DATASTR, strlen(DATASTR), 0);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
thread_join(&rv, test5_thread);
ABTS_INT_EQUAL(tc, strlen(DATASTR), rv);
rv = sock_delete(udp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
}
static void sock_test6(abts_case *tc, void *data)
{
c_sockaddr_t addr, *paddr, *dst;
char buf[CORE_ADDRSTRLEN];
status_t rv;
rv = core_inet_pton(AF_INET, "127.0.0.1", &addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_STR_EQUAL(tc, "127.0.0.1", CORE_ADDR(&addr, buf));
rv = core_inet_pton(AF_INET6, "::1", &addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_STR_EQUAL(tc, "::1", CORE_ADDR(&addr, buf));
paddr = NULL;
rv = core_addaddrinfo(&paddr, AF_UNSPEC, NULL, PORT, 0);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_sortaddrinfo(&paddr, AF_INET6);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_STR_EQUAL(tc, "::1", CORE_ADDR(paddr, buf));
ABTS_PTR_NOTNULL(tc, paddr->next);
ABTS_STR_EQUAL(tc, "127.0.0.1", CORE_ADDR(paddr->next, buf));
rv = core_copyaddrinfo(&dst, paddr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_STR_EQUAL(tc, "::1", CORE_ADDR(dst, buf));
ABTS_PTR_NOTNULL(tc, paddr->next);
ABTS_STR_EQUAL(tc, "127.0.0.1", CORE_ADDR(dst->next, buf));
rv = core_freeaddrinfo(dst);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_sortaddrinfo(&paddr, AF_INET);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_STR_EQUAL(tc, "127.0.0.1", CORE_ADDR(paddr, buf));
ABTS_PTR_NOTNULL(tc, paddr->next);
ABTS_STR_EQUAL(tc, "::1", CORE_ADDR(paddr->next, buf));
rv = core_filteraddrinfo(&paddr, AF_INET);
ABTS_PTR_NOTNULL(tc, paddr);
ABTS_STR_EQUAL(tc, "127.0.0.1", CORE_ADDR(paddr, buf));
rv = core_copyaddrinfo(&dst, paddr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_STR_EQUAL(tc, "127.0.0.1", CORE_ADDR(dst, buf));
rv = core_addaddrinfo(&dst, AF_UNSPEC, NULL, PORT, 0);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_STR_EQUAL(tc, "127.0.0.1", CORE_ADDR(dst, buf));
rv = core_freeaddrinfo(dst);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_filteraddrinfo(&paddr, AF_INET6);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_PTR_NULL(tc, paddr);
rv = core_copyaddrinfo(&dst, paddr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
ABTS_PTR_NULL(tc, dst);
paddr = NULL;
rv = core_addaddrinfo(&paddr, AF_INET, "127.0.0.1", PORT, 0);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_addaddrinfo(&paddr, AF_INET, "127.0.0.2", PORT, 0);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_addaddrinfo(&paddr, AF_INET, "127.0.0.3", PORT, 0);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_filteraddrinfo(&paddr, AF_INET6);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
}
static void sock_test7(abts_case *tc, void *data)
{
status_t rv;
sock_node_t *node;
c_sockaddr_t *addr;
list_t list, list6;
list_init(&list);
list_init(&list6);
rv = core_getaddrinfo(&addr, AF_UNSPEC, "localhost", PORT, 0);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = sock_add_node(&list, &node, addr, AF_INET);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
core_freeaddrinfo(addr);
sock_remove_all_nodes(&list);
rv = sock_probe_node(&list, &list6, NULL, PORT);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
sock_remove_all_nodes(&list);
sock_remove_all_nodes(&list6);
}
static void sock_test8(abts_case *tc, void *data)
{
status_t rv;
ipsubnet_t ipsub;
rv = core_ipsubnet(&ipsub, "127.0.0.1", "8");
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_ipsubnet(&ipsub, "fe80::1", "64");
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_ipsubnet(&ipsub, "172.16.0.1", "16");
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_ipsubnet(&ipsub, "cafe::1", "64");
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_ipsubnet(&ipsub, "172.16.0.1", NULL);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = core_ipsubnet(&ipsub, "cafe::1", NULL);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
}
abts_suite *testsock(abts_suite *suite)
{
suite = ADD_SUITE(suite)
abts_run_test(suite, sock_test1, NULL);
abts_run_test(suite, sock_test2, NULL);
abts_run_test(suite, sock_test3, NULL);
abts_run_test(suite, sock_test4, NULL);
abts_run_test(suite, sock_test5, NULL);
abts_run_test(suite, sock_test6, NULL);
abts_run_test(suite, sock_test7, NULL);
abts_run_test(suite, sock_test8, NULL);
return suite;
}
nextepc-0.3.10/lib/core/test/testthread.c 0000664 0000000 0000000 00000003667 13335533574 0020260 0 ustar 00root root 0000000 0000000 #include "core_mutex.h"
#include "core_thread.h"
#include "testutil.h"
static mutex_id lock;
static int x = 0;
static status_t exit_ret_val = 123;
static thread_id t1;
static thread_id t2;
static thread_id t3;
static thread_id t4;
static void *THREAD_FUNC thread_func1(thread_id id, void *data)
{
int i;
for (i = 0; i < 10000; i++)
{
mutex_lock(lock);
x++;
mutex_unlock(lock);
}
thread_exit(id, exit_ret_val);
return NULL;
}
static void init_thread(abts_case *tc, void *data)
{
status_t rv;
rv = mutex_create(&lock, MUTEX_DEFAULT);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
}
static void create_threads(abts_case *tc, void *data)
{
status_t rv;
rv = thread_create(&t1, NULL, thread_func1, NULL);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = thread_create(&t2, NULL, thread_func1, NULL);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = thread_create(&t3, NULL, thread_func1, NULL);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = thread_create(&t4, NULL, thread_func1, NULL);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
}
static void join_threads(abts_case *tc, void *data)
{
status_t s;
thread_join(&s, t1);
ABTS_INT_EQUAL(tc, exit_ret_val, s);
thread_join(&s, t2);
ABTS_INT_EQUAL(tc, exit_ret_val, s);
thread_join(&s, t3);
ABTS_INT_EQUAL(tc, exit_ret_val, s);
thread_join(&s, t4);
ABTS_INT_EQUAL(tc, exit_ret_val, s);
}
static void check_locks(abts_case *tc, void *data)
{
ABTS_INT_EQUAL(tc, 40000, x);
}
static void final_thread(abts_case *tc, void *data)
{
status_t rv;
rv = mutex_delete(lock);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
}
abts_suite *testthread(abts_suite *suite)
{
suite = ADD_SUITE(suite)
abts_run_test(suite, init_thread, NULL);
abts_run_test(suite, create_threads, NULL);
abts_run_test(suite, join_threads, NULL);
abts_run_test(suite, check_locks, NULL);
abts_run_test(suite, final_thread, NULL);
return suite;
}
nextepc-0.3.10/lib/core/test/testtime.c 0000664 0000000 0000000 00000016436 13335533574 0017745 0 ustar 00root root 0000000 0000000 #include "core_time.h"
#include "testutil.h"
#define STR_SIZE 100
/* The time value is used throughout the tests, so just make this a global.
* Also, we need a single value that we can test for the positive tests, so
* I chose the number below, it corresponds to:
* 2002-08-14 12:05:36.186711 -25200 [257 Sat].
* Which happens to be when I wrote the new tests.
*/
static c_time_t now = C_INT64_C(1032030336186711);
static void test_now(abts_case *tc, void *data)
{
c_time_t timediff;
c_time_t current;
time_t os_now;
current = time_now();
time(&os_now);
timediff = os_now - (current / USEC_PER_SEC);
/* Even though these are called so close together, there is the chance
* that the time will be slightly off, so accept anything between -1 and
* 1 second.
*/
ABTS_ASSERT(tc, "core_time and OS time do not agree",
(timediff > -2) && (timediff < 2));
}
static void test_gmtstr(abts_case *tc, void *data)
{
status_t rv;
time_exp_t xt;
char str[STR_SIZE+1];
rv = time_exp_gmt(&xt, now);
if (rv == CORE_ENOTIMPL)
{
ABTS_NOT_IMPL(tc, "time_exp_gmt");
}
ABTS_TRUE(tc, rv == CORE_OK);
sprintf(str, "%04d-%02d-%02d %02d:%02d:%02d.%06d %+05d [%d %s]%s",
xt.tm_year + 1900,
xt.tm_mon,
xt.tm_mday,
xt.tm_hour,
xt.tm_min,
xt.tm_sec,
xt.tm_usec,
xt.tm_gmtoff,
xt.tm_yday + 1,
day_snames[xt.tm_wday],
(xt.tm_isdst ? " DST" : ""));
ABTS_STR_EQUAL(tc, "2002-08-14 19:05:36.186711 +0000 [257 Sat]", str);
}
static void test_exp_lt(abts_case *tc, void *data)
{
status_t rv;
time_exp_t xt;
time_t posix_secs = (time_t)time_sec(now);
struct tm *posix_exp = localtime(&posix_secs);
rv = time_exp_lt(&xt, now);
if (rv == CORE_ENOTIMPL)
{
ABTS_NOT_IMPL(tc, "time_exp_lt");
}
ABTS_TRUE(tc, rv == CORE_OK);
#define CHK_FIELD(f) \
ABTS_ASSERT(tc, "Mismatch in " #f, posix_exp->f == xt.f)
CHK_FIELD(tm_sec);
CHK_FIELD(tm_min);
CHK_FIELD(tm_hour);
CHK_FIELD(tm_mday);
CHK_FIELD(tm_mon);
CHK_FIELD(tm_year);
CHK_FIELD(tm_wday);
CHK_FIELD(tm_yday);
CHK_FIELD(tm_isdst);
#undef CHK_FIELD
}
static void test_exp_get_gmt(abts_case *tc, void *data)
{
status_t rv;
time_exp_t xt;
c_time_t imp;
c_int64_t hr_off_64;
rv = time_exp_gmt(&xt, now);
ABTS_TRUE(tc, rv == CORE_OK);
rv = time_exp_get(&imp, &xt);
if (rv == CORE_ENOTIMPL)
{
ABTS_NOT_IMPL(tc, "time_exp_get");
}
ABTS_TRUE(tc, rv == CORE_OK);
hr_off_64 = (c_int64_t) xt.tm_gmtoff * USEC_PER_SEC;
ABTS_TRUE(tc, now + hr_off_64 == imp);
}
static void test_exp_get_lt(abts_case *tc, void *data)
{
status_t rv;
time_exp_t xt;
c_time_t imp;
c_int64_t hr_off_64;
rv = time_exp_lt(&xt, now);
ABTS_TRUE(tc, rv == CORE_OK);
rv = time_exp_get(&imp, &xt);
if (rv == CORE_ENOTIMPL)
{
ABTS_NOT_IMPL(tc, "time_exp_get");
}
ABTS_TRUE(tc, rv == CORE_OK);
hr_off_64 = (c_int64_t) xt.tm_gmtoff * USEC_PER_SEC;
ABTS_TRUE(tc, now + hr_off_64 == imp);
}
static void test_imp_gmt(abts_case *tc, void *data)
{
status_t rv;
time_exp_t xt;
c_time_t imp;
rv = time_exp_gmt(&xt, now);
ABTS_TRUE(tc, rv == CORE_OK);
rv = time_exp_gmt_get(&imp, &xt);
if (rv == CORE_ENOTIMPL)
{
ABTS_NOT_IMPL(tc, "time_exp_gmt_get");
}
ABTS_TRUE(tc, rv == CORE_OK);
ABTS_TRUE(tc, now == imp);
}
static void test_rfcstr(abts_case *tc, void *data)
{
status_t rv;
char str[STR_SIZE];
rv = rfc822_date(str, now);
if (rv == CORE_ENOTIMPL)
{
ABTS_NOT_IMPL(tc, "rfc822_date");
}
ABTS_TRUE(tc, rv == CORE_OK);
ABTS_STR_EQUAL(tc, "Sat, 14 Sep 2002 19:05:36 GMT", str);
}
static void test_ctime(abts_case *tc, void *data)
{
status_t rv;
char core_str[STR_SIZE];
char libc_str[STR_SIZE];
c_time_t now_sec = time_sec(now);
time_t posix_sec = (time_t) now_sec;
rv = core_ctime(core_str, now);
if (rv == CORE_ENOTIMPL)
{
ABTS_NOT_IMPL(tc, "core_ctime");
}
ABTS_TRUE(tc, rv == CORE_OK);
strcpy(libc_str, ctime(&posix_sec));
*strchr(libc_str, '\n') = '\0';
ABTS_STR_EQUAL(tc, libc_str, core_str);
}
static void test_strftime(abts_case *tc, void *data)
{
status_t rv;
time_exp_t xt;
char str[STR_SIZE+1];
size_t sz;
rv = time_exp_gmt(&xt, now);
rv = core_strftime(str, &sz, STR_SIZE, "%R %A %d %B %Y", &xt);
if (rv == CORE_ENOTIMPL)
{
ABTS_NOT_IMPL(tc, "core_strftime");
}
ABTS_TRUE(tc, rv == CORE_OK);
ABTS_STR_EQUAL(tc, "19:05 Saturday 14 September 2002", str);
}
static void test_strftimesmall(abts_case *tc, void *data)
{
status_t rv;
time_exp_t xt;
char str[STR_SIZE];
size_t sz;
rv = time_exp_gmt(&xt, now);
rv = core_strftime(str, &sz, STR_SIZE, "%T", &xt);
if (rv == CORE_ENOTIMPL)
{
ABTS_NOT_IMPL(tc, "core_strftime");
}
ABTS_TRUE(tc, rv == CORE_OK);
ABTS_STR_EQUAL(tc, "19:05:36", str);
}
static void test_exp_tz(abts_case *tc, void *data)
{
status_t rv;
time_exp_t xt;
c_int32_t hr_off = -5 * 3600; /* 5 hours in seconds */
rv = time_exp_tz(&xt, now, hr_off);
if (rv == CORE_ENOTIMPL)
{
ABTS_NOT_IMPL(tc, "time_exp_tz");
}
ABTS_TRUE(tc, rv == CORE_OK);
ABTS_TRUE(tc, (xt.tm_usec == 186711) &&
(xt.tm_sec == 36) &&
(xt.tm_min == 5) &&
(xt.tm_hour == 14) &&
(xt.tm_mday == 14) &&
(xt.tm_mon == 8) &&
(xt.tm_year == 102) &&
(xt.tm_wday == 6) &&
(xt.tm_yday == 256));
}
static void test_strftimeoffset(abts_case *tc, void *data)
{
status_t rv;
time_exp_t xt;
char str[STR_SIZE];
size_t sz;
c_int32_t hr_off = -5 * 3600; /* 5 hours in seconds */
time_exp_tz(&xt, now, hr_off);
rv = core_strftime(str, &sz, STR_SIZE, "%T", &xt);
if (rv == CORE_ENOTIMPL)
{
ABTS_NOT_IMPL(tc, "core_strftime");
}
ABTS_TRUE(tc, rv == CORE_OK);
}
/* 0.9.4 and earlier rejected valid dates in 2038 */
static void test_2038(abts_case *tc, void *data)
{
time_exp_t xt;
c_time_t t;
/* 2038-01-19T03:14:07.000000Z */
xt.tm_year = 138;
xt.tm_mon = 0;
xt.tm_mday = 19;
xt.tm_hour = 3;
xt.tm_min = 14;
xt.tm_sec = 7;
CORE_ASSERT_OK(tc, "explode January 19th, 2038",
time_exp_get(&t, &xt));
}
abts_suite *testtime(abts_suite *suite)
{
suite = ADD_SUITE(suite)
abts_run_test(suite, test_now, NULL);
abts_run_test(suite, test_gmtstr, NULL);
abts_run_test(suite, test_exp_lt, NULL);
abts_run_test(suite, test_exp_get_gmt, NULL);
abts_run_test(suite, test_exp_get_lt, NULL);
abts_run_test(suite, test_imp_gmt, NULL);
abts_run_test(suite, test_rfcstr, NULL);
abts_run_test(suite, test_ctime, NULL);
abts_run_test(suite, test_strftime, NULL);
abts_run_test(suite, test_strftimesmall, NULL);
abts_run_test(suite, test_exp_tz, NULL);
abts_run_test(suite, test_strftimeoffset, NULL);
abts_run_test(suite, test_2038, NULL);
return suite;
}
nextepc-0.3.10/lib/core/test/testtimer.c 0000664 0000000 0000000 00000027474 13335533574 0020133 0 ustar 00root root 0000000 0000000 #include "core_time.h"
#include "core_timer.h"
#include "core_param.h"
#include "testutil.h"
#define TEST_TIMER_NUM 200
#define TEST_TIMER_PRECISION 20 /* 2ms precision */
#define TEST_DURATION 400
c_uint8_t expire_check[TEST_DURATION/TEST_TIMER_PRECISION];
typedef struct _test_timer_eliment
{
c_uint8_t type;
c_uint32_t duration;
} test_timer_eliment;
test_timer_eliment timer_eliment[] ={
{TIMER_TYPE_ONE_SHOT, 500},
{TIMER_TYPE_ONE_SHOT, 50},
{TIMER_TYPE_ONE_SHOT, 200},
{TIMER_TYPE_ONE_SHOT, 90},
{TIMER_TYPE_ONE_SHOT, 800}
};
void test_expire_func_1(c_uintptr_t data,
c_uintptr_t param1, c_uintptr_t param2, c_uintptr_t param3,
c_uintptr_t param4, c_uintptr_t param5, c_uintptr_t param6)
{
c_uint32_t index = param2;
expire_check[index] = TRUE;
}
void test_expire_func_2(c_uintptr_t data,
c_uintptr_t param1, c_uintptr_t param2, c_uintptr_t param3,
c_uintptr_t param4, c_uintptr_t param5, c_uintptr_t param6)
{
c_uint32_t index = param2;
expire_check[index]++;
}
static void test_now(abts_case *tc, void *data)
{
c_time_t timediff;
c_time_t current;
time_t os_now;
current = time_now();
time(&os_now);
timediff = os_now - (current / USEC_PER_SEC);
/* Even though these are called so close together, there is the chance
* that the time will be slightly off, so accept anything between -1 and
* 1 second.
*/
ABTS_ASSERT(tc, "core_time and OS time do not agree",
(timediff > -2) && (timediff < 2));
}
/* basic timer Test */
static void timer_test_1(abts_case *tc, void *data)
{
int n = 0;
tm_block_id id_array[100];
tm_block_id id;
tm_service_t tm_service;
memset((char*)id_array, 0x00, sizeof(tm_service));
memset(expire_check, 0x00, sizeof(expire_check));
/* init tm_service */
tm_service_init(&tm_service);
for(n = 0; n < sizeof(timer_eliment) / sizeof(test_timer_eliment); n++)
{
id_array[n] = tm_create(&tm_service, TIMER_TYPE_ONE_SHOT,
timer_eliment[n].duration, test_expire_func_1);
tm_set_param1(id_array[n], (c_uintptr_t)id_array[n]);
tm_set_param2(id_array[n], n);
}
for(n = 0; n < sizeof(timer_eliment) / sizeof(test_timer_eliment); n++)
{
tm_start(id_array[n]);
}
id = (tm_block_id)list_first(&tm_service.idle_list);
ABTS_INT_EQUAL(tc, id, 0);
id = (tm_block_id)list_first(&tm_service.active_list);
ABTS_INT_NEQUAL(tc, id, 0);
ABTS_INT_EQUAL(tc, id, id_array[1]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, id_array[3]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, id_array[2]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, id_array[0]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, id_array[4]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, 0);
core_sleep(70000);
tm_execute_tm_service(&tm_service, 0);
id = (tm_block_id)list_first(&tm_service.idle_list);
ABTS_INT_EQUAL(tc, id, id_array[1]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, 0);
id = (tm_block_id)list_first(&tm_service.active_list);
ABTS_INT_NEQUAL(tc, id, 0);
ABTS_INT_EQUAL(tc, id, id_array[3]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, id_array[2]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, id_array[0]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, id_array[4]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, 0);
ABTS_INT_EQUAL(tc, expire_check[0], 0);
ABTS_INT_EQUAL(tc, expire_check[1], 1);
ABTS_INT_EQUAL(tc, expire_check[2], 0);
ABTS_INT_EQUAL(tc, expire_check[3], 0);
ABTS_INT_EQUAL(tc, expire_check[4], 0);
core_sleep(40000);
tm_execute_tm_service(&tm_service, 0);
id = (tm_block_id)list_first(&tm_service.idle_list);
ABTS_INT_EQUAL(tc, id, id_array[1]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, id_array[3]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, 0);
id = (tm_block_id)list_first(&tm_service.active_list);
ABTS_INT_NEQUAL(tc, id, 0);
ABTS_INT_EQUAL(tc, id, id_array[2]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, id_array[0]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, id_array[4]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, 0);
ABTS_INT_EQUAL(tc, expire_check[0], 0);
ABTS_INT_EQUAL(tc, expire_check[1], 1);
ABTS_INT_EQUAL(tc, expire_check[2], 0);
ABTS_INT_EQUAL(tc, expire_check[3], 1);
ABTS_INT_EQUAL(tc, expire_check[4], 0);
core_sleep(140000);
tm_execute_tm_service(&tm_service, 0);
id = (tm_block_id)list_first(&tm_service.idle_list);
ABTS_INT_EQUAL(tc, id, id_array[1]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, id_array[3]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, id_array[2]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, 0);
id = (tm_block_id)list_first(&tm_service.active_list);
ABTS_INT_NEQUAL(tc, id, 0);
ABTS_INT_EQUAL(tc, id, id_array[0]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, id_array[4]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, 0);
ABTS_INT_EQUAL(tc, expire_check[0], 0);
ABTS_INT_EQUAL(tc, expire_check[1], 1);
ABTS_INT_EQUAL(tc, expire_check[2], 1);
ABTS_INT_EQUAL(tc, expire_check[3], 1);
ABTS_INT_EQUAL(tc, expire_check[4], 0);
core_sleep(300000);
tm_execute_tm_service(&tm_service, 0);
id = (tm_block_id)list_first(&tm_service.idle_list);
ABTS_INT_EQUAL(tc, id, id_array[1]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, id_array[3]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, id_array[2]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, id_array[0]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, 0);
id = (tm_block_id)list_first(&tm_service.active_list);
ABTS_INT_NEQUAL(tc, id, 0);
ABTS_INT_EQUAL(tc, id, id_array[4]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, 0);
ABTS_INT_EQUAL(tc, expire_check[0], 1);
ABTS_INT_EQUAL(tc, expire_check[1], 1);
ABTS_INT_EQUAL(tc, expire_check[2], 1);
ABTS_INT_EQUAL(tc, expire_check[3], 1);
ABTS_INT_EQUAL(tc, expire_check[4], 0);
core_sleep(300000);
tm_execute_tm_service(&tm_service, 0);
id = (tm_block_id)list_first(&tm_service.idle_list);
ABTS_INT_EQUAL(tc, id, id_array[1]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, id_array[3]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, id_array[2]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, id_array[0]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, id_array[4]); if(tc->failed) return;
id = (tm_block_id)list_next(id);
ABTS_INT_EQUAL(tc, id, 0);
id = (tm_block_id)list_first(&tm_service.active_list);
ABTS_INT_EQUAL(tc, id, 0);
ABTS_INT_EQUAL(tc, expire_check[0], 1);
ABTS_INT_EQUAL(tc, expire_check[1], 1);
ABTS_INT_EQUAL(tc, expire_check[2], 1);
ABTS_INT_EQUAL(tc, expire_check[3], 1);
ABTS_INT_EQUAL(tc, expire_check[4], 1);
for( n = 0; n < sizeof(timer_eliment) / sizeof(test_timer_eliment); n++)
{
tm_delete(id_array[n]);
}
ABTS_INT_EQUAL(tc, tm_pool_avail(), MAX_NUM_OF_TIMER);
return;
}
static void timer_test_2(abts_case *tc, void *data)
{
int n = 0;
tm_block_id id_array[TEST_TIMER_NUM];
tm_service_t tm_service;
int duration;
int tm_num[TEST_DURATION/TEST_TIMER_PRECISION];
int tm_idx;
memset((char*)id_array, 0x00, sizeof(tm_service));
memset(expire_check, 0x00, sizeof(expire_check));
memset(tm_num, 0x00, sizeof(tm_num));
/* init tm_service */
tm_service_init(&tm_service);
for(n = 0; n < TEST_TIMER_NUM; n++)
{
duration = (rand() % (TEST_DURATION/TEST_TIMER_PRECISION))
* TEST_TIMER_PRECISION;
tm_idx = duration/TEST_TIMER_PRECISION;
tm_num[tm_idx]++;
duration += (TEST_TIMER_PRECISION >> 1);
id_array[n] = tm_create(&tm_service,
TIMER_TYPE_ONE_SHOT, duration, test_expire_func_2);
tm_set_param1(id_array[n], (c_uintptr_t)id_array[n]);
tm_set_param2(id_array[n], tm_idx);
}
for(n = 0; n < TEST_TIMER_NUM; n++)
{
tm_start(id_array[n]);
}
for(n = 0; n < TEST_DURATION/TEST_TIMER_PRECISION; n++)
{
core_sleep(TEST_TIMER_PRECISION * 1000);
tm_execute_tm_service(&tm_service, 0);
ABTS_INT_EQUAL(tc, tm_num[n], expire_check[n]);
}
for(n = 0; n < TEST_TIMER_NUM; n++)
{
tm_delete(id_array[n]);
}
ABTS_INT_EQUAL(tc, tm_pool_avail(), MAX_NUM_OF_TIMER);
return;
}
static void timer_test_3(abts_case *tc, void *data)
{
c_uint32_t n = 0;
tm_block_id id_array[TEST_TIMER_NUM];
tm_service_t tm_service;
int id_duration[TEST_TIMER_NUM];
int duration;
int tm_num[TEST_DURATION/TEST_TIMER_PRECISION];
int tm_idx, tm_check_id;
memset((char*)id_array, 0x00, sizeof(tm_service));
memset(expire_check, 0x00, sizeof(expire_check));
memset(tm_num, 0x00, sizeof(tm_num));
/* init tm_service */
tm_service_init(&tm_service);
for(n = 0; n < TEST_TIMER_NUM; n++)
{
duration = (rand() % (TEST_DURATION/TEST_TIMER_PRECISION))
* TEST_TIMER_PRECISION;
tm_idx = duration/TEST_TIMER_PRECISION;
tm_num[tm_idx]++;
id_duration[n] = duration;
duration += (TEST_TIMER_PRECISION >> 1);
id_array[n] = tm_create(&tm_service,
TIMER_TYPE_ONE_SHOT, duration, test_expire_func_2);
tm_set_param1(id_array[n], (c_uintptr_t)id_array[n]);
tm_set_param2(id_array[n], tm_idx);
}
for(n = 0; n < TEST_TIMER_NUM; n++)
{
tm_start(id_array[n]);
}
for(n = 0; n < TEST_TIMER_NUM / 10; n++)
{
tm_idx = n*10 + rand()%10;
tm_check_id = id_duration[tm_idx]/TEST_TIMER_PRECISION;
tm_num[tm_check_id]--;
tm_delete(id_array[tm_idx]);
id_array[tm_idx] = 0;
}
for(n = 0; n < TEST_DURATION/TEST_TIMER_PRECISION; n++)
{
core_sleep(TEST_TIMER_PRECISION * 1000);
tm_execute_tm_service(&tm_service, 0);
ABTS_INT_EQUAL(tc, tm_num[n], expire_check[n]);
}
for(n = 0; n < TEST_TIMER_NUM; n++)
{
if(id_array[n] != 0)
{
tm_delete(id_array[n]);
}
}
ABTS_INT_EQUAL(tc, tm_pool_avail(), MAX_NUM_OF_TIMER);
return;
}
abts_suite *testtimer(abts_suite *suite)
{
suite = ADD_SUITE(suite)
/*
* OpenSUSE OBS
* - Ubuntu 16.10 i586 failed
* - It is probably VM issue
* [ 661s] testtimer : Line 176: expected <1449351760>, but saw <0>
* [ 661s] Line 305: expected <1019>, but saw <1024>
* [ 661s] Line 372: expected <1019>, but saw <1024>
* [ 661s] FAILED 3 of 4
*/
abts_run_test(suite, test_now, NULL);
abts_run_test(suite, timer_test_1, NULL);
abts_run_test(suite, timer_test_2, NULL);
abts_run_test(suite, timer_test_3, NULL);
return suite;
}
nextepc-0.3.10/lib/core/test/testtlv.c 0000664 0000000 0000000 00000073073 13335533574 0017614 0 ustar 00root root 0000000 0000000 #include "core_tlv.h"
#include "core_tlv_msg.h"
#include "core_lib.h"
#include "core_debug.h"
#include "testutil.h"
#define TLV_0_LEN 10
#define TLV_1_LEN 20
#define TLV_2_LEN 100
#define TLV_3_LEN 200
#define TLV_4_LEN 2
#define TLV_5_LEN 2000
#define TLV_0_INSTANCE 0
#define TLV_1_INSTANCE 1
#define TLV_2_INSTANCE 2
#define TLV_3_INSTANCE 3
#define TLV_4_INSTANCE 4
#define TLV_5_INSTANCE 5
#define TLV_VALUE_ARRAY_SIZE 3000
#define EMBED_TLV_TYPE 20
#define EMBED_TLV_INSTANCE 7
typedef struct _test_tlv_element
{
c_uint8_t type;
c_uint32_t length;
c_uint8_t instance;
c_uint8_t *value;
c_uint8_t val_char;
} test_tlv_element;
c_uint8_t test_tlv_value[TLV_VALUE_ARRAY_SIZE];
test_tlv_element tlv_element[] ={
{1, TLV_0_LEN, TLV_0_INSTANCE, 0, 0x0a},
{50, TLV_1_LEN, TLV_1_INSTANCE, 0, 0x0b},
{255, TLV_2_LEN, TLV_2_INSTANCE, 0, 0x0c},
{254, TLV_3_LEN, TLV_3_INSTANCE, 0, 0x0d},
{5, TLV_4_LEN, TLV_4_INSTANCE, 0, 0x0e},
{30, TLV_5_LEN, TLV_5_INSTANCE, 0, 0x0f}
};
void tlv_test_set_tlv_value(void)
{
c_uint32_t inc = 0;
/* set test tlv value */
tlv_element[0].value = test_tlv_value;
memset(tlv_element[0].value, tlv_element[0].val_char, tlv_element[0].length);
inc += tlv_element[0].length;
tlv_element[1].value = test_tlv_value + inc;
memset(tlv_element[1].value, tlv_element[1].val_char, tlv_element[1].length);
inc += tlv_element[1].length;
tlv_element[2].value = test_tlv_value + inc;
memset(tlv_element[2].value, tlv_element[2].val_char, tlv_element[2].length);
inc += tlv_element[2].length;
tlv_element[3].value = test_tlv_value + inc;
memset(tlv_element[3].value, tlv_element[3].val_char, tlv_element[3].length);
inc += tlv_element[3].length;
tlv_element[4].value = test_tlv_value + inc;
memset(tlv_element[4].value, tlv_element[4].val_char, tlv_element[4].length);
inc += tlv_element[4].length;
return;
}
void tlv_test_check_embed_tlv_test(abts_case *tc, tlv_t *root_tlv, int mode)
{
c_uint32_t m;
c_uint32_t parent_block_len;
tlv_t *pTlv;
tlv_t *embed_tlv = NULL, *parent_tlv = NULL, *parsed_tlv = NULL;
c_uint8_t parent_block[4000];
c_uint8_t *pos = NULL;
int result;
memset(parent_block, 0x00, sizeof(parent_block));
parent_block_len = tlv_render(root_tlv, parent_block,
sizeof(parent_block), mode);
tlv_free_all(root_tlv);
ABTS_INT_EQUAL(tc, tlv_pool_avail(), NUM_OF_TLV_NODE);
pos = parent_block;
switch(mode)
{
case TLV_MODE_T2_L2:
{
ABTS_INT_EQUAL(tc, 332, parent_block_len);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[0].type >> 8);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[0].type & 0xFF);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[0].length >> 8);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[0].length & 0xFF);
for(m = 0; m < tlv_element[0].length; m++)
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[0].val_char);
ABTS_INT_EQUAL(tc, *(pos++), EMBED_TLV_TYPE >> 8);
ABTS_INT_EQUAL(tc, *(pos++), EMBED_TLV_TYPE & 0xFF);
ABTS_INT_EQUAL(tc, *(pos++), (308 >> 8));
ABTS_INT_EQUAL(tc, *(pos++), 308 & 0xFF);
/* embedded tlv_t */
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[2].type >> 8);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[2].type & 0xFF);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[2].length >> 8);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[2].length & 0xFF);
for(m = 0; m < tlv_element[2].length; m++)
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[2].val_char);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[3].type >> 8);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[3].type & 0xFF);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[3].length >> 8);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[3].length & 0xFF);
for(m = 0; m < tlv_element[3].length; m++)
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[3].val_char);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[4].type >> 8);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[4].type & 0xFF);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[4].length >> 8);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[4].length & 0xFF);
for(m = 0; m < tlv_element[4].length; m++)
ABTS_INT_EQUAL(tc, *(pos++), 0x0e);
break;
}
case TLV_MODE_T1_L2:
{
ABTS_INT_EQUAL(tc, 327, parent_block_len);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[0].type & 0xFF);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[0].length >> 8);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[0].length & 0xFF);
for(m = 0; m < tlv_element[0].length; m++)
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[0].val_char);
ABTS_INT_EQUAL(tc, *(pos++), EMBED_TLV_TYPE & 0xFF);
ABTS_INT_EQUAL(tc, *(pos++), (306 >> 8));
ABTS_INT_EQUAL(tc, *(pos++), 306 & 0xFF);
/* embedded tlv_t */
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[2].type & 0xFF);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[2].length >> 8);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[2].length & 0xFF);
for(m = 0; m < tlv_element[2].length; m++)
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[2].val_char);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[3].type & 0xFF);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[3].length >> 8);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[3].length & 0xFF);
for(m = 0; m < tlv_element[3].length; m++)
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[3].val_char);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[4].type & 0xFF);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[4].length >> 8);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[4].length & 0xFF);
for(m = 0; m < tlv_element[4].length; m++)
ABTS_INT_EQUAL(tc, *(pos++), 0x0e);
break;
}
case TLV_MODE_T1_L2_I1:
{
ABTS_INT_EQUAL(tc, 332, parent_block_len);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[0].type & 0xFF);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[0].length >> 8);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[0].length & 0xFF);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[0].instance & 0xFF);
for(m = 0; m < tlv_element[0].length; m++)
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[0].val_char);
ABTS_INT_EQUAL(tc, *(pos++), EMBED_TLV_TYPE & 0xFF);
ABTS_INT_EQUAL(tc, *(pos++), (308 >> 8));
ABTS_INT_EQUAL(tc, *(pos++), 308 & 0xFF);
ABTS_INT_EQUAL(tc, *(pos++), EMBED_TLV_INSTANCE);
/* embedded tlv_t */
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[2].type & 0xFF);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[2].length >> 8);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[2].length & 0xFF);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[2].instance & 0xFF);
for(m = 0; m < tlv_element[2].length; m++)
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[2].val_char);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[3].type & 0xFF);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[3].length >> 8);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[3].length & 0xFF);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[3].instance & 0xFF);
for(m = 0; m < tlv_element[3].length; m++)
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[3].val_char);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[4].type & 0xFF);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[4].length >> 8);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[4].length & 0xFF);
ABTS_INT_EQUAL(tc, *(pos++), tlv_element[4].instance & 0xFF);
for(m = 0; m < tlv_element[4].length; m++)
ABTS_INT_EQUAL(tc, *(pos++), 0x0e);
break;
}
default:
{
ABTS_TRUE(tc, 0);
break;
}
}
parsed_tlv = tlv_parse_block(parent_block_len,
parent_block, mode);
ABTS_PTR_NOTNULL(tc, parsed_tlv);
pTlv = parsed_tlv;
ABTS_INT_EQUAL(tc, pTlv->type, tlv_element[0].type);
ABTS_INT_EQUAL(tc, pTlv->length, tlv_element[0].length);
ABTS_INT_EQUAL(tc, pTlv->instance, tlv_element[0].instance);
result = memcmp(pTlv->value, tlv_element[0].value, tlv_element[0].length);
ABTS_INT_EQUAL(tc, result, 0);
pTlv = pTlv->next;
ABTS_INT_EQUAL(tc, pTlv->type, 20);
switch(mode)
{
case TLV_MODE_T2_L2:
case TLV_MODE_T1_L2_I1:
ABTS_INT_EQUAL(tc, pTlv->length, 308);
break;
case TLV_MODE_T1_L2:
ABTS_INT_EQUAL(tc, pTlv->length, 306);
break;
default:
ABTS_TRUE(tc, 0);
break;
}
pTlv = pTlv->next;
ABTS_INT_EQUAL(tc, pTlv->type, tlv_element[4].type);
ABTS_INT_EQUAL(tc, pTlv->length, tlv_element[4].length);
if (mode == TLV_MODE_T1_L2_I1)
ABTS_INT_EQUAL(tc, pTlv->instance, tlv_element[4].instance);
else
ABTS_INT_EQUAL(tc, pTlv->instance, 0);
result = memcmp(pTlv->value, tlv_element[4].value, tlv_element[4].length);
ABTS_INT_EQUAL(tc, result, 0);
pTlv = pTlv->next;
ABTS_PTR_NULL(tc, pTlv);
parent_tlv = tlv_find(parsed_tlv,20);
ABTS_PTR_NOTNULL(tc, parent_tlv);
tlv_parse_embedded_block(parent_tlv, mode);
embed_tlv = parent_tlv->embedded;
ABTS_PTR_NOTNULL(tc, embed_tlv);
ABTS_INT_EQUAL(tc, embed_tlv->type, tlv_element[2].type);
ABTS_INT_EQUAL(tc, embed_tlv->length, tlv_element[2].length);
if (mode == TLV_MODE_T1_L2_I1)
ABTS_INT_EQUAL(tc, embed_tlv->instance, tlv_element[2].instance);
else
ABTS_INT_EQUAL(tc, embed_tlv->instance, 0);
for(m = 0; m < tlv_element[2].length; m++)
{
ABTS_INT_EQUAL(tc, *((c_uint8_t*)(embed_tlv->value+m)),
tlv_element[2].val_char);
}
embed_tlv = embed_tlv->next;
ABTS_INT_EQUAL(tc, embed_tlv->type, tlv_element[3].type);
ABTS_INT_EQUAL(tc, embed_tlv->length, tlv_element[3].length);
if (mode == TLV_MODE_T1_L2_I1)
ABTS_INT_EQUAL(tc, embed_tlv->instance, tlv_element[3].instance);
else
ABTS_INT_EQUAL(tc, embed_tlv->instance, 0);
for(m = 0; m < tlv_element[3].length; m++)
{
ABTS_INT_EQUAL(tc, *((c_uint8_t*)(embed_tlv->value+m)),
tlv_element[3].val_char);
}
embed_tlv = embed_tlv->next;
ABTS_PTR_NULL(tc, embed_tlv);
embed_tlv = tlv_find(parsed_tlv,254);
ABTS_PTR_NOTNULL(tc, embed_tlv);
embed_tlv = tlv_find(parsed_tlv,253);
ABTS_PTR_NULL(tc, embed_tlv);
tlv_free_all(parsed_tlv);
ABTS_INT_EQUAL(tc, tlv_pool_avail(), NUM_OF_TLV_NODE);
return;
}
/* basic encoding/decoding/finding Test */
static void tlv_test_1(abts_case *tc, void *data)
{
c_uint32_t idx, m, parent_block_len;
tlv_t *root_tlv = NULL, *parsed_tlv = NULL, *pTlv;
c_uint8_t parent_block[4000];
c_uint8_t *pos = NULL;
c_uint8_t mode = (c_uintptr_t)data;
tlv_test_set_tlv_value();
/* tlv encoding for test */
root_tlv = tlv_add(NULL,tlv_element[0].type,
tlv_element[0].length, tlv_element[0].instance, tlv_element[0].value);
for(idx = 1; idx < 4; idx++)
{
tlv_add(root_tlv, tlv_element[idx].type,
tlv_element[idx].length, tlv_element[idx].instance,
tlv_element[idx].value);
}
memset(parent_block, 0x00, sizeof(parent_block));
parent_block_len = tlv_render(root_tlv, parent_block,
sizeof(parent_block), mode);
switch(mode)
{
case TLV_MODE_T2_L2:
case TLV_MODE_T1_L2_I1:
ABTS_INT_EQUAL(tc, 346, parent_block_len);
break;
case TLV_MODE_T1_L2:
ABTS_INT_EQUAL(tc, 342, parent_block_len);
break;
case TLV_MODE_T1_L1:
ABTS_INT_EQUAL(tc, 338, parent_block_len);
break;
default:
ABTS_TRUE(tc, 0);
break;
}
tlv_free_all(root_tlv);
ABTS_INT_EQUAL(tc, tlv_pool_avail(), NUM_OF_TLV_NODE);
pos = parent_block;
for(idx = 0; idx < 4; idx++)
{
switch(mode)
{
case TLV_MODE_T2_L2:
ABTS_INT_EQUAL(tc, (tlv_element[idx].type >> 8), *(pos++));
ABTS_INT_EQUAL(tc, tlv_element[idx].type & 0xFF, *(pos++));
ABTS_INT_EQUAL(tc, (tlv_element[idx].length >> 8), *(pos++));
ABTS_INT_EQUAL(tc, tlv_element[idx].length & 0xFF, *(pos++));
break;
case TLV_MODE_T1_L2:
ABTS_INT_EQUAL(tc, tlv_element[idx].type & 0xFF, *(pos++));
ABTS_INT_EQUAL(tc, (tlv_element[idx].length >> 8), *(pos++));
ABTS_INT_EQUAL(tc, tlv_element[idx].length & 0xFF, *(pos++));
break;
case TLV_MODE_T1_L1:
ABTS_INT_EQUAL(tc, tlv_element[idx].type & 0xFF, *(pos++));
ABTS_INT_EQUAL(tc, tlv_element[idx].length & 0xFF, *(pos++));
break;
case TLV_MODE_T1_L2_I1:
ABTS_INT_EQUAL(tc, tlv_element[idx].type & 0xFF, *(pos++));
ABTS_INT_EQUAL(tc, (tlv_element[idx].length >> 8), *(pos++));
ABTS_INT_EQUAL(tc, tlv_element[idx].length & 0xFF, *(pos++));
ABTS_INT_EQUAL(tc, tlv_element[idx].instance & 0xFF, *(pos++));
break;
default:
ABTS_TRUE(tc, 0);
break;
}
for(m = 0; m < tlv_element[idx].length; m++)
ABTS_INT_EQUAL(tc, tlv_element[idx].val_char, *(pos++));
}
parsed_tlv = tlv_parse_block(parent_block_len,parent_block, mode);
ABTS_PTR_NOTNULL(tc, parsed_tlv);
pTlv = parsed_tlv;
idx = 0;
while(pTlv)
{
int result;
ABTS_INT_EQUAL(tc, pTlv->type, tlv_element[idx].type);
ABTS_INT_EQUAL(tc, pTlv->length, tlv_element[idx].length);
if (mode == TLV_MODE_T1_L2_I1)
ABTS_INT_EQUAL(tc, pTlv->instance, tlv_element[idx].instance);
else
ABTS_INT_EQUAL(tc, pTlv->instance, 0);
result = memcmp(pTlv->value, tlv_element[idx].value, tlv_element[idx].length);
ABTS_INT_EQUAL(tc, result, 0);
pTlv = pTlv->next;
idx++;
}
ABTS_INT_EQUAL(tc, idx, 4);
pTlv = tlv_find(parsed_tlv, 255);
ABTS_PTR_NOTNULL(tc, pTlv);
pTlv = tlv_find(parsed_tlv, 253);
ABTS_PTR_NULL(tc, pTlv);
tlv_free_all(parsed_tlv);
ABTS_INT_EQUAL(tc, tlv_pool_avail(), NUM_OF_TLV_NODE);
return;
}
/* embedded tlv_t test : first, make embedded tlv block for embeded tlv
and then make whole tlv block using embedded tlv block previously made*/
static void tlv_test_2(abts_case *tc, void *data)
{
c_uint32_t embed_block_len;
tlv_t *root_tlv = NULL;
tlv_t *embed_tlv = NULL;
c_uint8_t embed_block[1000];;
c_uint8_t mode = (c_uintptr_t)data;
tlv_test_set_tlv_value();
/* Tlv Encoding for embeded tlv_t */
embed_tlv = tlv_add(NULL, tlv_element[2].type,
tlv_element[2].length, tlv_element[2].instance, tlv_element[2].value);
tlv_add(embed_tlv,tlv_element[3].type,
tlv_element[3].length, tlv_element[3].instance, tlv_element[3].value);
embed_block_len = tlv_render(embed_tlv, embed_block,
sizeof(embed_block), mode);
switch(mode)
{
case TLV_MODE_T2_L2:
case TLV_MODE_T1_L2_I1:
ABTS_INT_EQUAL(tc, embed_block_len, 308);
break;
case TLV_MODE_T1_L2:
ABTS_INT_EQUAL(tc, embed_block_len, 306);
break;
default:
ABTS_TRUE(tc, 0);
break;
}
tlv_free_all(embed_tlv);
ABTS_INT_EQUAL(tc, tlv_pool_avail(), NUM_OF_TLV_NODE);
root_tlv = tlv_add(NULL,tlv_element[0].type,
tlv_element[0].length, tlv_element[0].instance, tlv_element[0].value);
tlv_add(root_tlv, EMBED_TLV_TYPE, embed_block_len,
EMBED_TLV_INSTANCE, embed_block);
tlv_add(root_tlv,tlv_element[4].type,
tlv_element[4].length, tlv_element[4].instance, tlv_element[4].value);
tlv_test_check_embed_tlv_test(tc, root_tlv, mode);
return;
}
/* embedded tlv_t test : make parent and embedded tlv and then tlv_render
functions makes whole tlv block. the value member of each tlv must
point to vaild address at the time using tlv_rendering function */
static void tlv_test_3(abts_case *tc, void *data)
{
tlv_t *root_tlv = NULL, *parent_tlv = NULL;
c_uint8_t mode = (c_uintptr_t)data;
tlv_test_set_tlv_value();
/* Tlv Encoding for embeded tlv_t */
root_tlv = tlv_add(NULL,tlv_element[0].type,
tlv_element[0].length, tlv_element[0].instance, tlv_element[0].value);
parent_tlv= tlv_add(root_tlv, EMBED_TLV_TYPE, 0, EMBED_TLV_INSTANCE, NULL);
tlv_add(root_tlv,tlv_element[4].type,
tlv_element[4].length, tlv_element[4].instance, tlv_element[4].value);
tlv_embed(parent_tlv,tlv_element[2].type,
tlv_element[2].length, tlv_element[2].instance, tlv_element[2].value);
tlv_embed(parent_tlv,tlv_element[3].type,
tlv_element[3].length, tlv_element[3].instance, tlv_element[3].value);
tlv_test_check_embed_tlv_test(tc, root_tlv, mode);
return;
}
/* embedded tlv_t test : make parent and embedded tlv and then tlv_render
functions makes whole tlv block. The value member of each tlv is copied
to the buff of the root tlv_t, so the allocated resource for the value
member of each tlv can be deallocated after executing tlv_add or tlv embed
function*/
static void tlv_test_4(abts_case *tc, void *data)
{
tlv_t *root_tlv = NULL, *parent_tlv = NULL;
c_uint8_t tlv_buff[2000];
c_uint8_t mode = (c_uintptr_t)data;
tlv_test_set_tlv_value();
root_tlv = tlv_copy(tlv_buff, sizeof(tlv_buff),
tlv_element[0].type, tlv_element[0].length,
tlv_element[0].instance, tlv_element[0].value);
parent_tlv = tlv_add(root_tlv, EMBED_TLV_TYPE, 0, EMBED_TLV_INSTANCE, NULL);
tlv_add(root_tlv, tlv_element[4].type, tlv_element[4].length,
tlv_element[4].instance, tlv_element[4].value);
tlv_embed(parent_tlv,tlv_element[2].type,
tlv_element[2].length, tlv_element[2].instance, tlv_element[2].value);
tlv_embed(parent_tlv,tlv_element[3].type,
tlv_element[3].length, tlv_element[3].instance, tlv_element[3].value);
memset(tlv_element[2].value, 0x00, tlv_element[2].length);
memset(tlv_element[3].value, 0xf0, tlv_element[3].length);
tlv_test_check_embed_tlv_test(tc, root_tlv, mode);
return;
}
/* endian check test */
static void tlv_test_5(abts_case *tc, void *data)
{
c_uint32_t parent_block_len;
tlv_t *root_tlv = NULL, *parsed_tlv = NULL, *p_tlv;
c_uint8_t parent_block[4000];
c_uint8_t *pos = NULL;
c_uint16_t c_16 = 0x1122;
c_uint32_t c_32 = 0x11223344;
c_uint8_t mode = (c_uintptr_t)data;
/* tlv encoding for test */
c_16 = htons(c_16);
root_tlv = tlv_add(NULL, 10, 2, 0, (c_uint8_t*)&c_16);
c_32 = htonl(c_32);
tlv_add(root_tlv, 20, 4, 0, (c_uint8_t*)&c_32);
memset(parent_block, 0x00, sizeof(parent_block));
parent_block_len = tlv_render(root_tlv, parent_block,
sizeof(parent_block), mode);
tlv_free_all(root_tlv);
ABTS_INT_EQUAL(tc, tlv_pool_avail(), NUM_OF_TLV_NODE);
pos = parent_block;
switch(mode)
{
case TLV_MODE_T2_L2:
ABTS_INT_EQUAL(tc, *(pos++), 0);
ABTS_INT_EQUAL(tc, *(pos++), 10);
ABTS_INT_EQUAL(tc, *(pos++), 0);
ABTS_INT_EQUAL(tc, *(pos++), 2);
ABTS_INT_EQUAL(tc, *(pos++), 0x11);
ABTS_INT_EQUAL(tc, *(pos++), 0x22);
ABTS_INT_EQUAL(tc, *(pos++), 0);
ABTS_INT_EQUAL(tc, *(pos++), 20);
ABTS_INT_EQUAL(tc, *(pos++), 0);
ABTS_INT_EQUAL(tc, *(pos++), 4);
ABTS_INT_EQUAL(tc, *(pos++), 0x11);
ABTS_INT_EQUAL(tc, *(pos++), 0x22);
ABTS_INT_EQUAL(tc, *(pos++), 0x33);
ABTS_INT_EQUAL(tc, *(pos++), 0x44);
break;
case TLV_MODE_T1_L2:
ABTS_INT_EQUAL(tc, *(pos++), 10);
ABTS_INT_EQUAL(tc, *(pos++), 0);
ABTS_INT_EQUAL(tc, *(pos++), 2);
ABTS_INT_EQUAL(tc, *(pos++), 0x11);
ABTS_INT_EQUAL(tc, *(pos++), 0x22);
ABTS_INT_EQUAL(tc, *(pos++), 20);
ABTS_INT_EQUAL(tc, *(pos++), 0);
ABTS_INT_EQUAL(tc, *(pos++), 4);
ABTS_INT_EQUAL(tc, *(pos++), 0x11);
ABTS_INT_EQUAL(tc, *(pos++), 0x22);
ABTS_INT_EQUAL(tc, *(pos++), 0x33);
ABTS_INT_EQUAL(tc, *(pos++), 0x44);
break;
case TLV_MODE_T1_L2_I1:
ABTS_INT_EQUAL(tc, *(pos++), 10);
ABTS_INT_EQUAL(tc, *(pos++), 0);
ABTS_INT_EQUAL(tc, *(pos++), 2);
ABTS_INT_EQUAL(tc, *(pos++), 0);
ABTS_INT_EQUAL(tc, *(pos++), 0x11);
ABTS_INT_EQUAL(tc, *(pos++), 0x22);
ABTS_INT_EQUAL(tc, *(pos++), 20);
ABTS_INT_EQUAL(tc, *(pos++), 0);
ABTS_INT_EQUAL(tc, *(pos++), 4);
ABTS_INT_EQUAL(tc, *(pos++), 0);
ABTS_INT_EQUAL(tc, *(pos++), 0x11);
ABTS_INT_EQUAL(tc, *(pos++), 0x22);
ABTS_INT_EQUAL(tc, *(pos++), 0x33);
ABTS_INT_EQUAL(tc, *(pos++), 0x44);
break;
case TLV_MODE_T1_L1:
ABTS_INT_EQUAL(tc, *(pos++), 10);
ABTS_INT_EQUAL(tc, *(pos++), 2);
ABTS_INT_EQUAL(tc, *(pos++), 0x11);
ABTS_INT_EQUAL(tc, *(pos++), 0x22);
ABTS_INT_EQUAL(tc, *(pos++), 20);
ABTS_INT_EQUAL(tc, *(pos++), 4);
ABTS_INT_EQUAL(tc, *(pos++), 0x11);
ABTS_INT_EQUAL(tc, *(pos++), 0x22);
ABTS_INT_EQUAL(tc, *(pos++), 0x33);
ABTS_INT_EQUAL(tc, *(pos++), 0x44);
break;
default:
ABTS_TRUE(tc, 0);
break;
}
p_tlv = parsed_tlv = tlv_parse_block(parent_block_len,parent_block,
mode);
ABTS_INT_EQUAL(tc, tlv_value_16(p_tlv), 0x1122);
p_tlv = parsed_tlv->next;
ABTS_INT_EQUAL(tc, tlv_value_32(p_tlv), 0x11223344);
tlv_free_all(parsed_tlv);
ABTS_INT_EQUAL(tc, tlv_pool_avail(), NUM_OF_TLV_NODE);
return;
}
/* Sample header for tlv_msg */
#define TLV_AUTHORIZATION_POLICY_SUPPORT_TYPE 21
#define TLV_AUTHORIZATION_POLICY_SUPPORT_LEN 1
typedef tlv_uint8_t tlv_authorization_policy_support_t;
extern tlv_desc_t tlv_desc_authorization_policy_support;
#define TLV_CLIENT_SECURITY_HISTORY_TYPE 108
#define TLV_CLIENT_SECURITY_HISTORY_LEN TLV_VARIABLE_LEN
typedef struct _tlv_client_security_history_t {
tlv_presence_t presence;
tlv_authorization_policy_support_t authorization_policy_support0;
tlv_authorization_policy_support_t authorization_policy_support2;
} tlv_client_security_history_t;
extern tlv_desc_t tlv_desc_client_security_history;
#define TLV_CLIENT_INFO_TYPE 103
#define TLV_CLIENT_INFO_LEN TLV_VARIABLE_LEN
typedef struct _tlv_client_info_t {
tlv_presence_t presence;
tlv_client_security_history_t client_security_history;
} tlv_client_info_t;
extern tlv_desc_t tlv_desc_client_info;
#define TLV_SERVER_NAME_TYPE 25
#define TLV_SERVER_NAME_LEN TLV_VARIABLE_LEN
typedef tlv_octet_t tlv_server_name_t;
extern tlv_desc_t tlv_desc_server_name;
#define TLV_SERVER_INFO_TYPE 26
#define TLV_SERVER_INFO_LEN TLV_VARIABLE_LEN
typedef struct _tlv_server_info_t {
tlv_presence_t presence;
tlv_server_name_t TLV_1_OR_MORE(server_name);
} tlv_server_info_t;
extern tlv_desc_t tlv_desc_server_info;
typedef struct _tlv_attach_req {
tlv_client_info_t client_info;
tlv_server_info_t server_info;
} tlv_attach_req;
extern tlv_desc_t tlv_desc_attach_req;
/* Sample source for tlv_msg */
tlv_desc_t tlv_desc_authorization_policy_support0 =
{
TLV_UINT8,
"Auth Policy0",
TLV_AUTHORIZATION_POLICY_SUPPORT_TYPE,
TLV_AUTHORIZATION_POLICY_SUPPORT_LEN,
0,
sizeof(tlv_authorization_policy_support_t),
{ NULL }
};
tlv_desc_t tlv_desc_authorization_policy_support2 =
{
TLV_UINT8,
"Auth Policy2",
TLV_AUTHORIZATION_POLICY_SUPPORT_TYPE,
TLV_AUTHORIZATION_POLICY_SUPPORT_LEN,
2,
sizeof(tlv_authorization_policy_support_t),
{ NULL }
};
tlv_desc_t tlv_desc_client_security_history =
{
TLV_COMPOUND,
"Sec History",
TLV_CLIENT_SECURITY_HISTORY_TYPE,
TLV_CLIENT_SECURITY_HISTORY_LEN,
0,
sizeof(tlv_client_security_history_t),
{
&tlv_desc_authorization_policy_support0,
&tlv_desc_authorization_policy_support2,
NULL,
}
};
tlv_desc_t tlv_desc_client_info =
{
TLV_COMPOUND,
"Client Info",
TLV_CLIENT_INFO_TYPE,
TLV_CLIENT_INFO_LEN,
0,
sizeof(tlv_client_info_t),
{
&tlv_desc_client_security_history,
NULL,
}
};
tlv_desc_t tlv_desc_server_name =
{
TLV_VAR_STR,
"Server Name",
TLV_SERVER_NAME_TYPE,
TLV_SERVER_NAME_LEN,
0,
sizeof(tlv_server_name_t),
{ NULL }
};
tlv_desc_t tlv_desc_server_info =
{
TLV_COMPOUND,
"Server Info",
TLV_SERVER_INFO_TYPE,
TLV_SERVER_INFO_LEN,
0,
sizeof(tlv_server_info_t),
{
&tlv_desc_server_name, &tlv_desc_more2,
NULL,
}
};
tlv_desc_t tlv_desc_attach_req = {
TLV_MESSAGE, "Attach Req", 0, 0, 0, 0, {
&tlv_desc_client_info,
&tlv_desc_server_info,
NULL,
}};
static void tlv_test_6(abts_case *tc, void *data)
{
tlv_attach_req reqv;
tlv_attach_req reqv2;
pkbuf_t *req = NULL;
char testbuf[1024];
/* Initialize message value structure */
memset(&reqv, 0, sizeof(tlv_attach_req));
/* Set nessary members of message */
reqv.client_info.presence = 1;
reqv.client_info.client_security_history.presence = 1;
reqv.client_info.client_security_history.
authorization_policy_support0.presence = 1;
reqv.client_info.client_security_history.
authorization_policy_support0.u8 = 0x3;
reqv.client_info.client_security_history.
authorization_policy_support2.presence = 1;
reqv.client_info.client_security_history.
authorization_policy_support2.u8 = 0x9;
reqv.server_info.presence = 1;
reqv.server_info.server_name[0].presence = 1;
reqv.server_info.server_name[0].data =
(c_uint8_t*)"\x11\x22\x33\x44\x55\x66";
reqv.server_info.server_name[0].len = 6;
reqv.server_info.presence = 1;
reqv.server_info.server_name[1].presence = 1;
reqv.server_info.server_name[1].data =
(c_uint8_t*)"\xaa\xbb\xcc\xdd\xee\xff";
reqv.server_info.server_name[1].len = 6;
/* Build message */
tlv_build_msg(&req, &tlv_desc_attach_req, &reqv, TLV_MODE_T1_L2_I1);
#define TEST_TLV_BUILD_MSG \
"67000e00 6c000a00 15000100 03150001" \
"02091a00 14001900 06001122 33445566" \
"19000600 aabbccdd eeff"
ABTS_INT_EQUAL(tc, 42, req->len);
ABTS_TRUE(tc, memcmp(req->payload,
CORE_HEX(TEST_TLV_BUILD_MSG, strlen(TEST_TLV_BUILD_MSG), testbuf),
req->len) == 0);
/* Initialize message value structure */
memset(&reqv2, 0, sizeof(tlv_attach_req));
/* Parse message */
tlv_parse_msg(&reqv2, &tlv_desc_attach_req, req,
TLV_MODE_T1_L2_I1);
ABTS_INT_EQUAL(tc, 1, reqv2.client_info.presence);
ABTS_INT_EQUAL(tc, 1,
reqv2.client_info.client_security_history.presence);
ABTS_INT_EQUAL(tc, 1,
reqv2.client_info.client_security_history.
authorization_policy_support0.presence);
ABTS_INT_EQUAL(tc, 0x3, reqv2.client_info.
client_security_history.authorization_policy_support0.u8);
ABTS_INT_EQUAL(tc, 1,
reqv2.client_info.client_security_history.
authorization_policy_support2.presence);
ABTS_INT_EQUAL(tc, 0x9, reqv2.client_info.
client_security_history.authorization_policy_support2.u8);
ABTS_INT_EQUAL(tc, 1, reqv2.server_info.presence);
ABTS_INT_EQUAL(tc, 1, reqv2.server_info.server_name[0].presence);
ABTS_INT_EQUAL(tc, 1, reqv2.server_info.server_name[1].presence);
ABTS_INT_EQUAL(tc, 6, reqv2.server_info.server_name[0].len);
ABTS_TRUE(tc, memcmp(reqv2.server_info.server_name[0].data,
(c_uint8_t*)"\x11\x22\x33\x44\x55\x66", 6) == 0);
ABTS_INT_EQUAL(tc, 6, reqv2.server_info.server_name[1].len);
ABTS_TRUE(tc, memcmp(reqv2.server_info.server_name[1].data,
(c_uint8_t*)"\xaa\xbb\xcc\xdd\xee\xff", 6) == 0);
pkbuf_free(req);
}
abts_suite *testtlv(abts_suite *suite)
{
suite = ADD_SUITE(suite)
abts_run_test(suite, tlv_test_1, (void*)TLV_MODE_T2_L2);
abts_run_test(suite, tlv_test_2, (void*)TLV_MODE_T2_L2);
abts_run_test(suite, tlv_test_3, (void*)TLV_MODE_T2_L2);
abts_run_test(suite, tlv_test_4, (void*)TLV_MODE_T2_L2);
abts_run_test(suite, tlv_test_5, (void*)TLV_MODE_T2_L2);
abts_run_test(suite, tlv_test_1, (void*)TLV_MODE_T1_L1);
abts_run_test(suite, tlv_test_5, (void*)TLV_MODE_T1_L1);
abts_run_test(suite, tlv_test_1, (void*)TLV_MODE_T1_L2);
abts_run_test(suite, tlv_test_2, (void*)TLV_MODE_T1_L2);
abts_run_test(suite, tlv_test_3, (void*)TLV_MODE_T1_L2);
abts_run_test(suite, tlv_test_4, (void*)TLV_MODE_T1_L2);
abts_run_test(suite, tlv_test_5, (void*)TLV_MODE_T1_L2);
abts_run_test(suite, tlv_test_1, (void*)TLV_MODE_T1_L2_I1);
abts_run_test(suite, tlv_test_2, (void*)TLV_MODE_T1_L2_I1);
abts_run_test(suite, tlv_test_3, (void*)TLV_MODE_T1_L2_I1);
abts_run_test(suite, tlv_test_4, (void*)TLV_MODE_T1_L2_I1);
abts_run_test(suite, tlv_test_5, (void*)TLV_MODE_T1_L2_I1);
abts_run_test(suite, tlv_test_6, NULL);
return suite;
}
nextepc-0.3.10/lib/core/test/testutil.c 0000664 0000000 0000000 00000002514 13335533574 0017754 0 ustar 00root root 0000000 0000000 /* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "core.h"
#include "abts.h"
#include "testutil.h"
void core_assert_ok(abts_case* tc, const char* context, status_t rv,
int lineno)
{
if (rv == CORE_ENOTIMPL)
{
abts_not_impl(tc, context, lineno);
} else if (rv != CORE_OK)
{
char buf[STRING_MAX], ebuf[128];
sprintf(buf, "%s (%d): %s\n", context, rv,
core_strerror(rv, ebuf, sizeof ebuf));
abts_fail(tc, buf, lineno);
}
}
void test_initialize(void)
{
core_initialize();
atexit(core_terminate);
}
nextepc-0.3.10/lib/core/test/testutil.h 0000664 0000000 0000000 00000005052 13335533574 0017761 0 ustar 00root root 0000000 0000000 /* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "core_general.h"
#include "abts.h"
#ifndef __APR_TEST_UTIL__
#define __APR_TEST_UTIL__
/* XXX: FIXME - these all should become much more utilitarian
* and part of core, itself
*/
#ifdef WIN32
#ifdef BINPATH
#define TESTBINPATH APR_STRINGIFY(BINPATH) "/"
#else
#define TESTBINPATH ""
#endif
#else
#define TESTBINPATH "./"
#endif
#ifdef WIN32
#define EXTENSION ".exe"
#elif NETWARE
#define EXTENSION ".nlm"
#else
#define EXTENSION
#endif
#define STRING_MAX 8096
/* Some simple functions to make the test apps easier to write and
* a bit more consistent...
*/
/* Assert that RV is an CORE_OK value; else fail giving strerror
* for RV and CONTEXT message. */
void core_assert_ok(abts_case* tc, const char *context,
status_t rv, int lineno);
#define CORE_ASSERT_OK(tc, ctxt, rv) \
core_assert_ok(tc, ctxt, rv, __LINE__)
void test_initialize(void);
abts_suite *testds(abts_suite *suite);
abts_suite *testfsm(abts_suite *suite);
abts_suite *testtlv(abts_suite *suite);
abts_suite *testaes(abts_suite *suite);
abts_suite *testsha2(abts_suite *suite);
abts_suite *testsock(abts_suite *suite);
abts_suite *testsctp(abts_suite *suite);
abts_suite *testtime(abts_suite *suite);
abts_suite *testtimer(abts_suite *suite);
abts_suite *testthread(abts_suite *suite);
abts_suite *testlock(abts_suite *suite);
abts_suite *testatomic(abts_suite *suite);
abts_suite *testfile(abts_suite *suite);
abts_suite *testfilecopy(abts_suite *suite);
abts_suite *testdir(abts_suite *suite);
abts_suite *testmsgq(abts_suite *suite);
abts_suite *testsleep(abts_suite *suite);
abts_suite *testpkbuf(abts_suite *suite);
abts_suite *testmisc(abts_suite *suite);
abts_suite *testhash(abts_suite *suite);
abts_suite *test3gpp(abts_suite *suite);
#endif /* CORE_TEST_INCLUDES */
nextepc-0.3.10/lib/fd/ 0000775 0000000 0000000 00000000000 13335533574 0014413 5 ustar 00root root 0000000 0000000 nextepc-0.3.10/lib/fd/Makefile.am 0000664 0000000 0000000 00000002135 13335533574 0016450 0 ustar 00root root 0000000 0000000 ## Process this file with automake to produce Makefile.in
pkglib_LTLIBRARIES = libfd.la
libfd_la_SOURCES = \
fd_message.h fd_logger.h fd_lib.h \
libapp_sip.c fd_message.c fd_logger.c fd_config.c fd_init.c \
\
s6a/s6a_dict.h s6a/s6a_message.h \
s6a/dict_init.c \
\
gx/gx_dict.h gx/gx_message.h \
gx/dict_init.c gx/gx_message.c \
\
rx/rx_dict.h rx/rx_message.h \
rx/dict_init.c rx/rx_message.c \
$(NULL)
libfd_la_DEPENDENCIES = \
$(top_srcdir)/lib/core/src/libcore.la \
$(top_srcdir)/lib/@FREEDIAMETER_DIR@/libfdcore/libfdcore.la \
$(top_srcdir)/lib/@FREEDIAMETER_DIR@/libfdproto/libfdproto.la \
$(NULL)
libfd_la_LIBADD = \
$(top_srcdir)/lib/core/src/libcore.la \
$(top_srcdir)/lib/@FREEDIAMETER_DIR@/libfdcore/libfdcore.la \
$(top_srcdir)/lib/@FREEDIAMETER_DIR@/libfdproto/libfdproto.la \
$(NULL)
AM_LDFLAGS = \
-version-info @LIBVERSION@ \
$(NULL)
AM_CPPFLAGS = \
-I$(top_srcdir)/lib/core/include \
-I$(top_srcdir)/lib/@FREEDIAMETER_DIR@/include \
$(NULL)
AM_CFLAGS = \
-Wall -Werror \
$(NULL)
MAINTAINERCLEANFILES = Makefile.in
MOSTLYCLEANFILES = *.stackdump
nextepc-0.3.10/lib/fd/fd_config.c 0000664 0000000 0000000 00000013157 13335533574 0016504 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _fd_config
#include "core_debug.h"
#include "core_lib.h"
#include "core_file.h"
#include "fd_lib.h"
static status_t fd_config_apply(fd_config_t *fd_config)
{
struct addrinfo hints, *ai;
int ret;
int i;
d_assert(fd_config->cnf_diamid, return CORE_ERROR,);
d_assert(fd_config->cnf_diamrlm, return CORE_ERROR,);
d_assert(fd_config->cnf_addr, return CORE_ERROR,);
/********************************************************************
* Diameter Server
*/
fd_g_config->cnf_diamid = (DiamId_t)fd_config->cnf_diamid;
fd_os_validate_DiameterIdentity(
&fd_g_config->cnf_diamid, &fd_g_config->cnf_diamid_len, 1);
fd_g_config->cnf_diamrlm = (DiamId_t)fd_config->cnf_diamrlm;
fd_os_validate_DiameterIdentity(
&fd_g_config->cnf_diamrlm, &fd_g_config->cnf_diamrlm_len, 1);
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
ret = getaddrinfo(fd_config->cnf_addr, NULL, &hints, &ai);
if (ret)
{
d_error("getaddrinfo() [%s] failed(%d:%s)",
fd_config->cnf_addr, errno, strerror(errno));
return CORE_ERROR;
}
CHECK_FCT_DO( fd_ep_add_merge( &fd_g_config->cnf_endpoints,
ai->ai_addr, ai->ai_addrlen, EP_FL_CONF), return CORE_ERROR );
freeaddrinfo(ai);
if (fd_config->cnf_port)
fd_g_config->cnf_port = fd_config->cnf_port;
if (fd_config->cnf_port_tls)
fd_g_config->cnf_port_tls = fd_config->cnf_port_tls;
if (fd_config->cnf_flags.no_sctp)
fd_g_config->cnf_flags.no_sctp = fd_config->cnf_flags.no_sctp;
/********************************************************************
* Diameter Client
*/
for (i = 0; i < fd_config->num_of_conn; i++)
{
int disc = 0;
struct peer_info fddpi;
d_assert(fd_config->conn[i].addr, return CORE_ERROR,);
memset(&fddpi, 0, sizeof(fddpi));
fddpi.config.pic_flags.persist = PI_PRST_ALWAYS;
fddpi.config.pic_flags.pro3 = PI_P3_IP;
fddpi.config.pic_flags.pro4 = PI_P4_TCP;
fddpi.config.pic_flags.alg = PI_ALGPREF_TCP;
fddpi.config.pic_flags.sec |= PI_SEC_NONE;
fddpi.config.pic_port = fd_config->conn[i].port;
fddpi.pi_diamid = (DiamId_t)fd_config->conn[i].identity;
fd_list_init( &fddpi.pi_endpoints, NULL );
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICHOST;
ret = getaddrinfo(fd_config->conn[i].addr, NULL, &hints, &ai);
if (ret)
{
d_error("getaddrinfo() [%s] failed(%d:%s)",
fd_config->conn[i].addr, errno, strerror(errno));
return CORE_ERROR;
}
CHECK_FCT_DO( fd_ep_add_merge(
&fddpi.pi_endpoints, ai->ai_addr, ai->ai_addrlen,
EP_FL_CONF | (disc ?: EP_ACCEPTALL) ), return CORE_ERROR);
CHECK_FCT_DO( fd_peer_add ( &fddpi, NULL, NULL, NULL ),
return CORE_ERROR);
freeaddrinfo(ai);
}
/********************************************************************
* Load Extension
*/
for (i = 0; i < fd_config->num_of_ext; i++)
{
char *fname = NULL;
char *cfname = NULL;
FILE *fd;
fname = strdup(fd_config->ext[i].module);
d_assert(fname, return CORE_ERROR,);
fd = fopen(fname, "r");
if ((fd == NULL) && (*fname != '/'))
{
char *bkp = fname;
fname = malloc(strlen(bkp) + strlen(DEFAULT_EXTENSIONS_PATH) + 2);
d_assert(fname, return CORE_ERROR,);
sprintf(fname, DEFAULT_EXTENSIONS_PATH "/%s", bkp);
fd = fopen(fname, "r");
if (fd == NULL)
{
free(fname);
fname = bkp;
}
else
{
free(bkp);
}
}
if (fd)
fclose(fd);
cfname = (char *)fd_config->ext[i].conf;
if (cfname)
{
cfname = strdup(fd_config->ext[i].conf);
d_assert(cfname, return CORE_ERROR,);
fd = fopen(cfname, "r");
if ((fd == NULL) && (*cfname != '/'))
{
char *test = NULL;
test = malloc( strlen(cfname) + strlen(DEFAULT_CONF_PATH) + 2);
d_assert(test, return CORE_ERROR,);
sprintf(test, DEFAULT_CONF_PATH "/%s", cfname);
fd = fopen(test, "r");
if (fd)
{
free(cfname);
cfname=test;
}
else
{
free(test);
}
}
if (fd)
fclose(fd);
}
extern int fd_ext_add( char * filename, char * conffile );
CHECK_FCT_DO( fd_ext_add( fname, cfname ), return CORE_ERROR );
}
return CORE_OK;
}
status_t fd_config_init(fd_config_t *fd_config)
{
char * buf = NULL, *b;
size_t len = 0;
CHECK_FCT( fd_config_apply(fd_config) );
/* The following module use data from the configuration */
int fd_rtdisp_init(void);
CHECK_FCT( fd_rtdisp_init() );
/* Now, load all dynamic extensions */
int fd_ext_load();
CHECK_FCT( fd_ext_load() );
/* Display configuration */
b = fd_conf_dump(&buf, &len, NULL);
LOG_SPLIT(FD_LOG_NOTICE, NULL,
b ?: "", NULL);
free(buf);
/* Since some extensions might have modified the definitions from the dict_base_protocol, we only load the objects now */
int fd_msg_init(void);
CHECK_FCT( fd_msg_init() );
return CORE_OK;
}
nextepc-0.3.10/lib/fd/fd_init.c 0000664 0000000 0000000 00000007133 13335533574 0016177 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _fd_init
#include "core_debug.h"
#include "core_param.h"
#include "core_signal.h"
#include "core_semaphore.h"
#include "fd_logger.h"
#include "fd_lib.h"
static void fd_gnutls_log_func(int level, const char *str);
static void fd_log_func(int printlevel, const char *format, va_list ap);
int fd_init(int mode, const char *conffile, fd_config_t *fd_config)
{
int ret;
fd_g_debug_lvl = FD_LOG_ERROR;
if (g_trace_mask)
{
if (TRACE_MODULE >= 25)
gnutls_global_set_log_level(TRACE_MODULE-24);
if (TRACE_MODULE >= 25 && TRACE_MODULE < 27)
fd_g_debug_lvl = FD_LOG_NOTICE;
else if (TRACE_MODULE >= 27 && TRACE_MODULE < 29)
fd_g_debug_lvl = FD_LOG_DEBUG;
else if (TRACE_MODULE >= 29)
fd_g_debug_lvl = FD_LOG_ANNOYING;
}
gnutls_global_set_log_function(fd_gnutls_log_func);
ret = fd_log_handler_register(fd_log_func);
if (ret != 0)
{
d_error("fd_log_handler_register() failed");
return ret;
}
ret = fd_core_initialize();
if (ret != 0)
{
d_error("fd_core_initialize() failed");
return ret;
}
/* Parse the configuration file */
if (conffile)
{
CHECK_FCT_DO( fd_core_parseconf(conffile), goto error );
}
else
{
CHECK_FCT_DO( fd_config_init(fd_config), goto error );
}
/* Initialize FD Message */
CHECK_FCT( fd_message_init() );
/* Initialize FD logger */
CHECK_FCT_DO( fd_logger_init(mode), goto error );
/* Start the servers */
CHECK_FCT_DO( fd_core_start(), goto error );
CHECK_FCT_DO( fd_core_waitstartcomplete(), goto error );
CHECK_FCT( fd_logger_stats_start() );
return 0;
error:
CHECK_FCT_DO( fd_core_shutdown(), );
CHECK_FCT_DO( fd_core_wait_shutdown_complete(), );
return -1;
}
void fd_final()
{
fd_logger_final();
CHECK_FCT_DO( fd_core_shutdown(), d_error("fd_core_shutdown() failed") );
CHECK_FCT_DO( fd_core_wait_shutdown_complete(),
d_error("fd_core_wait_shutdown_complete() failed"));
}
static void fd_gnutls_log_func(int level, const char *str)
{
d_trace(25-level, "gnutls[%d]: %s", level, str);
}
static void fd_log_func(int printlevel, const char *format, va_list ap)
{
char buffer[HUGE_STRING_LEN];
int ret = 0;
ret = vsnprintf(buffer, HUGE_STRING_LEN, format, ap);
if (ret < 0 || ret > HUGE_STRING_LEN)
{
d_error("vsnprintf() failed");
return;
}
switch(printlevel)
{
case FD_LOG_ANNOYING:
d_trace(29, "freeDiameter[%d]: %s\n", printlevel, buffer);
break;
case FD_LOG_DEBUG:
d_trace(27, "freeDiameter[%d]: %s\n", printlevel, buffer);
break;
case FD_LOG_NOTICE:
d_trace(25, "freeDiameter[%d]: %s\n", printlevel, buffer);
break;
case FD_LOG_ERROR:
d_error("%s", buffer);
if (!strcmp(buffer, " - The certificate is expired."))
{
d_error("You can renew CERT as follows:");
d_error("./support/freeDiameter/make_certs.sh "
"./install/etc/nextepc/freeDiameter");
}
break;
case FD_LOG_FATAL:
{
char *except = "Initiating freeDiameter shutdown sequence";
if (strncmp(buffer, except, strlen(except)) == 0)
d_trace(1, "freeDiameter[%d]: %s\n", printlevel, buffer);
else
d_fatal("%s", buffer);
}
break;
default:
d_warn("%s", buffer);
break;
}
}
nextepc-0.3.10/lib/fd/fd_lib.h 0000664 0000000 0000000 00000003466 13335533574 0016014 0 ustar 00root root 0000000 0000000 #ifndef __FD_LIB_H__
#define __FD_LIB_H__
#include "core_errno.h"
#include "freeDiameter/freeDiameter-host.h"
#include "freeDiameter/libfdcore.h"
#include "fd_message.h"
#include "fd_logger.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* This is default diameter configuration if there is no config file
* The Configuration : No TLS, Only TCP */
typedef struct _fd_config_t {
/* Diameter Identity of the local peer (FQDN -- ASCII) */
const char *cnf_diamid;
/* Diameter realm of the local peer, default to realm part of cnf_diamid */
const char *cnf_diamrlm;
/* IP address of the local peer */
const char *cnf_addr;
/* the local port for legacy Diameter (default: 3868) in host byte order */
c_uint16_t cnf_port;
/* the local port for Diameter/TLS (default: 5658) in host byte order */
c_uint16_t cnf_port_tls;
struct {
unsigned no_sctp: 1; /* disable the use of SCTP */
} cnf_flags;
#define MAX_NUM_OF_FD_EXTENSION 32
struct {
const char *module;
const char *conf;
} ext[MAX_NUM_OF_FD_EXTENSION];
int num_of_ext;
#define MAX_NUM_OF_FD_CONN 16
/* (supposedly) UTF-8, \0 terminated.
* The Diameter Identity of the remote peer. */
struct {
const char *identity;
const char *addr; /* IP address of the remote peer */
c_uint16_t port; /* port to connect to. 0: default. */
} conn[MAX_NUM_OF_FD_CONN];
int num_of_conn;
} fd_config_t;
CORE_DECLARE(int) fd_init(
int mode, const char *conffile, fd_config_t *fd_config);
CORE_DECLARE(void) fd_final(void);
CORE_DECLARE(int) fd_config_init(fd_config_t *fd_config);
int fd_avp_search_avp ( struct avp * groupedavp,
struct dict_object * what, struct avp ** avp );
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ! __FD_LIB_H__ */
nextepc-0.3.10/lib/fd/fd_logger.c 0000664 0000000 0000000 00000010511 13335533574 0016505 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _fd_logger
#include "core_debug.h"
#include "fd_logger.h"
static struct fd_logger_t self;
static struct fd_hook_hdl *logger_hdl = NULL;
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_t fd_stats_th = (pthread_t)NULL;
static fd_logger_user_handler user_handler = NULL;
static void fd_logger_cb(enum fd_hook_type type, struct msg * msg,
struct peer_hdr * peer, void * other, struct fd_hook_permsgdata *pmd,
void * regdata);
static void * fd_stats_worker(void * arg);
int fd_logger_init(int mode)
{
uint32_t mask_peers = HOOK_MASK( HOOK_PEER_CONNECT_SUCCESS );
memset(&self, 0, sizeof(struct fd_logger_t));
self.mode = mode;
self.duration = 60; /* 60 seconds */
CHECK_FCT( fd_hook_register(
mask_peers, fd_logger_cb, NULL, NULL, &logger_hdl) );
CHECK_POSIX( pthread_mutex_init(&self.stats_lock, NULL) );
return 0;
}
void fd_logger_final()
{
CHECK_FCT_DO( fd_thr_term(&fd_stats_th), );
CHECK_POSIX_DO( pthread_mutex_destroy(&self.stats_lock), );
if (logger_hdl) { CHECK_FCT_DO( fd_hook_unregister( logger_hdl ), ); }
}
struct fd_logger_t* fd_logger_self()
{
return &self;
}
int fd_logger_stats_start()
{
/* Start the statistics thread */
CHECK_POSIX( pthread_create(&fd_stats_th, NULL, fd_stats_worker, NULL) );
return 0;
}
void fd_logger_register(fd_logger_user_handler instance)
{
user_handler = instance;
}
void fd_logger_unregister(void)
{
user_handler = NULL;
}
/* The callback called when messages are received and sent */
static void fd_logger_cb(enum fd_hook_type type, struct msg * msg,
struct peer_hdr * peer, void * other, struct fd_hook_permsgdata *pmd,
void * regdata)
{
char * peer_name = peer ? peer->info.pi_diamid : "";
CHECK_POSIX_DO( pthread_mutex_lock(&mtx), );
if (user_handler)
{
user_handler(type, msg, peer, other, pmd, regdata);
}
switch (type) {
/* peers */
case HOOK_PEER_CONNECT_SUCCESS:
{
char protobuf[40];
if (peer) {
CHECK_FCT_DO(fd_peer_cnx_proto_info(peer, protobuf, sizeof(protobuf)), break );
} else {
protobuf[0] = '-';
protobuf[1] = '\0';
}
d_info("CONNECTED TO '%s' (%s):", peer_name, protobuf);
}
break;
default:
d_warn("Unknown type(%d)", type);
break;
}
CHECK_POSIX_DO( pthread_mutex_unlock(&mtx), );
}
/* Function to display statistics periodically */
static void * fd_stats_worker(void * arg)
{
struct timespec start, now;
struct fd_stats copy;
/* Get the start time */
CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &start), );
/* Now, loop until canceled */
while (1) {
/* Display statistics every XX seconds */
sleep(self.duration);
/* Now, get the current stats */
CHECK_POSIX_DO( pthread_mutex_lock(&self.stats_lock), );
memcpy(©, &self.stats, sizeof(struct fd_stats));
CHECK_POSIX_DO( pthread_mutex_unlock(&self.stats_lock), );
/* Get the current execution time */
CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &now), );
/* Now, display everything */
d_trace(15, "------- fd statistics ---------\n");
if (now.tv_nsec >= start.tv_nsec)
{
d_trace(15, " Executing for: %d.%06ld sec\n",
(int)(now.tv_sec - start.tv_sec),
(long)(now.tv_nsec - start.tv_nsec) / 1000);
}
else
{
d_trace(15, " Executing for: %d.%06ld sec\n",
(int)(now.tv_sec - 1 - start.tv_sec),
(long)(now.tv_nsec + 1000000000 - start.tv_nsec) / 1000);
}
if (self.mode & FD_MODE_SERVER) {
d_trace(15, " Server: %llu message(s) echoed\n",
copy.nb_echoed);
}
if (self.mode & FD_MODE_CLIENT) {
d_trace(15, " Client:\n");
d_trace(15, " %llu message(s) sent\n", copy.nb_sent);
d_trace(15, " %llu error(s) received\n", copy.nb_errs);
d_trace(15, " %llu answer(s) received\n", copy.nb_recv);
d_trace(15, " fastest: %ld.%06ld sec.\n",
copy.shortest / 1000000, copy.shortest % 1000000);
d_trace(15, " slowest: %ld.%06ld sec.\n",
copy.longest / 1000000, copy.longest % 1000000);
d_trace(15, " Average: %ld.%06ld sec.\n",
copy.avg / 1000000, copy.avg % 1000000);
}
d_trace(15, "-------------------------------------\n");
}
return NULL; /* never called */
}
nextepc-0.3.10/lib/fd/fd_logger.h 0000664 0000000 0000000 00000002643 13335533574 0016521 0 ustar 00root root 0000000 0000000 #ifndef __FD_LOGGER_H__
#define __FD_LOGGER_H__
#include "core_errno.h"
#include "freeDiameter/freeDiameter-host.h"
#include "freeDiameter/libfdcore.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
struct fd_logger_t {
#define FD_MODE_SERVER 0x1
#define FD_MODE_CLIENT 0x2
int mode; /* default FD_MODE_SERVER | FD_MODE_CLIENT */
int duration; /* default 10 */
struct fd_stats {
unsigned long long nb_echoed; /* server */
unsigned long long nb_sent; /* client */
unsigned long long nb_recv; /* client */
unsigned long long nb_errs; /* client */
unsigned long shortest; /* fastest answer, in microseconds */
unsigned long longest; /* slowest answer, in microseconds */
unsigned long avg; /* average answer time, in microseconds */
} stats;
pthread_mutex_t stats_lock;
};
CORE_DECLARE(int) fd_logger_init(int mode);
CORE_DECLARE(void) fd_logger_final();
CORE_DECLARE(struct fd_logger_t*) fd_logger_self();
CORE_DECLARE(int) fd_logger_stats_start();
typedef void (*fd_logger_user_handler)(
enum fd_hook_type type, struct msg *msg, struct peer_hdr *peer,
void *other, struct fd_hook_permsgdata *pmd, void *regdata);
CORE_DECLARE(void) fd_logger_register(fd_logger_user_handler instance);
CORE_DECLARE(void) fd_logger_unregister();
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ! __FD_LOGGER_H__ */
nextepc-0.3.10/lib/fd/fd_message.c 0000664 0000000 0000000 00000012071 13335533574 0016655 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _fd_message
#include "fd_message.h"
#define CHECK_dict_search( _type, _criteria, _what, _result ) \
CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
#define FD_3GPP_VENDOR_ID 10415
struct dict_object *fd_session_id = NULL;
struct dict_object *fd_origin_host = NULL;
struct dict_object *fd_origin_realm = NULL;
struct dict_object *fd_destination_host = NULL;
struct dict_object *fd_destination_realm = NULL;
struct dict_object *fd_user_name = NULL;
struct dict_object *fd_auth_session_state = NULL;
struct dict_object *fd_auth_application_id = NULL;
struct dict_object *fd_auth_request_type = NULL;
struct dict_object *fd_re_auth_request_type = NULL;
struct dict_object *fd_result_code = NULL;
struct dict_object *fd_experimental_result = NULL;
struct dict_object *fd_experimental_result_code = NULL;
struct dict_object *fd_vendor_specific_application_id = NULL;
struct dict_object *fd_mip6_agent_info = NULL;
struct dict_object *fd_mip_home_agent_address = NULL;
struct dict_object *fd_vendor = NULL;
struct dict_object *fd_vendor_id = NULL;
int fd_message_init()
{
vendor_id_t id = FD_3GPP_VENDOR_ID;
CHECK_dict_search( DICT_VENDOR, VENDOR_BY_ID, (void *)&id, &fd_vendor);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Vendor-Id", &fd_vendor_id);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Session-Id", &fd_session_id);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Origin-Host", &fd_origin_host);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Origin-Realm", &fd_origin_realm);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Destination-Host", &fd_destination_host);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Destination-Realm", &fd_destination_realm);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "User-Name", &fd_user_name);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Auth-Session-State", &fd_auth_session_state);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Auth-Application-Id", &fd_auth_application_id);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Auth-Request-Type", &fd_auth_request_type);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Re-Auth-Request-Type", &fd_re_auth_request_type);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Result-Code", &fd_result_code);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Experimental-Result", &fd_experimental_result);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Experimental-Result-Code", &fd_experimental_result_code);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Vendor-Specific-Application-Id", &fd_vendor_specific_application_id);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "MIP6-Agent-Info", &fd_mip6_agent_info);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "MIP-Home-Agent-Address", &fd_mip_home_agent_address);
return 0;
}
int fd_message_session_id_set(
struct msg *msg, c_uint8_t *sid, size_t sidlen)
{
struct avp *avp;
union avp_value val;
/* Create an AVP to hold it */
CHECK_FCT( fd_msg_avp_new( fd_session_id, 0, &avp ) );
/* Set its value */
memset(&val, 0, sizeof(val));
val.os.data = sid;
val.os.len = sidlen;
CHECK_FCT( fd_msg_avp_setvalue( avp, &val ) );
/* Add it to the message */
CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_FIRST_CHILD, avp ) );
return 0;
}
int fd_message_experimental_rescode_set(
struct msg *msg, c_uint32_t result_code)
{
struct avp *avp;
struct avp *avp_vendor;
struct avp *avp_experimental_result_code;
union avp_value value;
CHECK_FCT( fd_msg_avp_new(fd_experimental_result, 0, &avp) );
CHECK_FCT( fd_msg_avp_new(fd_vendor_id, 0, &avp_vendor) );
value.u32 = FD_3GPP_VENDOR_ID;
CHECK_FCT( fd_msg_avp_setvalue(avp_vendor, &value) );
CHECK_FCT( fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avp_vendor) );
CHECK_FCT( fd_msg_avp_new(
fd_experimental_result_code, 0, &avp_experimental_result_code) );
value.u32 = result_code;
CHECK_FCT( fd_msg_avp_setvalue(avp_experimental_result_code, &value) );
CHECK_FCT( fd_msg_avp_add(
avp, MSG_BRW_LAST_CHILD, avp_experimental_result_code) );
CHECK_FCT( fd_msg_avp_add(msg, MSG_BRW_LAST_CHILD, avp) );
CHECK_FCT( fd_msg_add_origin(msg, 0) );
return 0;
}
int fd_message_vendor_specific_appid_set(struct msg *msg, c_uint32_t app_id)
{
struct avp *avp;
struct avp *avp_vendor;
struct avp *avp_vendor_specific_application_id;
union avp_value value;
CHECK_FCT( fd_msg_avp_new(fd_vendor_specific_application_id, 0, &avp) );
CHECK_FCT( fd_msg_avp_new(fd_vendor_id, 0, &avp_vendor) );
value.u32 = FD_3GPP_VENDOR_ID;
CHECK_FCT( fd_msg_avp_setvalue(avp_vendor, &value) );
CHECK_FCT( fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avp_vendor) );
CHECK_FCT( fd_msg_avp_new(
fd_auth_application_id, 0, &avp_vendor_specific_application_id) );
value.u32 = app_id;
CHECK_FCT(
fd_msg_avp_setvalue(avp_vendor_specific_application_id, &value) );
CHECK_FCT( fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD,
avp_vendor_specific_application_id) );
CHECK_FCT( fd_msg_avp_add(msg, MSG_BRW_LAST_CHILD, avp) );
return 0;
}
nextepc-0.3.10/lib/fd/fd_message.h 0000664 0000000 0000000 00000004565 13335533574 0016673 0 ustar 00root root 0000000 0000000 #ifndef __FD_MESSAGE_H__
#define __FD_MESSAGE_H__
#include "core_errno.h"
#include "freeDiameter/freeDiameter-host.h"
#include "freeDiameter/libfdcore.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define FD_AVP_CODE_FRAME_IP_ADDRESS 8
#define FD_AVP_CODE_FRAME_IPV6_PREFIX 97
/* Result-Code AVP */
#define FD_DIAMETER_UNKNOWN_PEER 3010
#define FD_DIAMETER_AVP_UNSUPPORTED 5001
#define FD_DIAMETER_UNKNOWN_SESSION_ID 5002
#define FD_DIAMETER_AUTHORIZATION_REJECTED 5003
#define FD_DIAMETER_MISSING_AVP 5004
#define FD_DIAMETER_INVALID_AVP_VALUE 5005
extern struct dict_object *fd_session_id;
extern struct dict_object *fd_origin_host;
extern struct dict_object *fd_origin_realm;
extern struct dict_object *fd_destination_host;
extern struct dict_object *fd_destination_realm;
extern struct dict_object *fd_user_name;
#define FD_AUTH_SESSION_STATE_MAINTAINED 0
#define FD_AUTH_SESSION_NO_STATE_MAINTAINED 1
extern struct dict_object *fd_auth_session_state;
extern struct dict_object *fd_auth_application_id;
#define FD_AUTH_REQUEST_TYPE_AUTHENTICATE_ONLY 1
#define FD_AUTH_REQUEST_TYPE_AUTHORIZE_ONLY 2
#define FD_AUTH_REQUEST_TYPE_AUTHORIZE_AUTHENTICATE 3
extern struct dict_object *fd_auth_request_type;
#define FD_RE_AUTH_REQUEST_TYPE_AUTHORIZE_ONLY 0
#define FD_RE_AUTH_REQUEST_TYPE_AUTHORIZE_AUTHENTICATE 1
extern struct dict_object *fd_re_auth_request_type;
extern struct dict_object *fd_result_code;
extern struct dict_object *fd_experimental_result;
extern struct dict_object *fd_experimental_result_code;
extern struct dict_object *fd_vendor_specific_application_id;
extern struct dict_object *fd_mip6_agent_info;
extern struct dict_object *fd_mip_home_agent_address;
extern struct dict_object *fd_vendor;
extern struct dict_object *fd_vendor_id;
CORE_DECLARE(int) fd_message_init(void);
CORE_DECLARE(int) fd_message_session_id_set(
struct msg *msg, c_uint8_t *sid, size_t sidlen);
CORE_DECLARE(int) fd_message_experimental_rescode_set(
struct msg *msg, c_uint32_t result_code);
CORE_DECLARE(int) fd_message_vendor_specific_appid_set(
struct msg *msg, c_uint32_t app_id);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ! __FD_MESSAGE_H__ */
nextepc-0.3.10/lib/fd/gx/ 0000775 0000000 0000000 00000000000 13335533574 0015031 5 ustar 00root root 0000000 0000000 nextepc-0.3.10/lib/fd/gx/dict_init.c 0000664 0000000 0000000 00000021607 13335533574 0017151 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _gx_dict
#include "gx_dict.h"
#define CHECK_dict_search( _type, _criteria, _what, _result ) \
CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
struct dict_object *gx_application = NULL;
struct dict_object *gx_cmd_ccr = NULL;
struct dict_object *gx_cmd_cca = NULL;
struct dict_object *gx_cmd_rar = NULL;
struct dict_object *gx_cmd_raa = NULL;
struct dict_object *gx_cc_request_type = NULL;
struct dict_object *gx_cc_request_number = NULL;
struct dict_object *gx_network_request_support = NULL;
struct dict_object *gx_subscription_id = NULL;
struct dict_object *gx_subscription_id_type = NULL;
struct dict_object *gx_subscription_id_data = NULL;
struct dict_object *gx_supported_features = NULL;
struct dict_object *gx_feature_list_id = NULL;
struct dict_object *gx_feature_list = NULL;
struct dict_object *gx_framed_ip_address = NULL;
struct dict_object *gx_framed_ipv6_prefix = NULL;
struct dict_object *gx_ip_can_type = NULL;
struct dict_object *gx_rat_type = NULL;
struct dict_object *gx_qos_information = NULL;
struct dict_object *gx_qos_class_identifier = NULL;
struct dict_object *gx_max_requested_bandwidth_ul = NULL;
struct dict_object *gx_max_requested_bandwidth_dl = NULL;
struct dict_object *gx_min_requested_bandwidth_ul = NULL;
struct dict_object *gx_min_requested_bandwidth_dl = NULL;
struct dict_object *gx_guaranteed_bitrate_ul = NULL;
struct dict_object *gx_guaranteed_bitrate_dl = NULL;
struct dict_object *gx_allocation_retention_priority = NULL;
struct dict_object *gx_priority_level = NULL;
struct dict_object *gx_pre_emption_capability = NULL;
struct dict_object *gx_pre_emption_vulnerability = NULL;
struct dict_object *gx_apn_aggregate_max_bitrate_ul = NULL;
struct dict_object *gx_apn_aggregate_max_bitrate_dl = NULL;
struct dict_object *gx_3gpp_user_location_info = NULL;
struct dict_object *gx_called_station_id = NULL;
struct dict_object *gx_default_eps_bearer_qos = NULL;
struct dict_object *gx_3gpp_ms_timezone = NULL;
struct dict_object *gx_event_trigger = NULL;
struct dict_object *gx_bearer_control_mode = NULL;
struct dict_object *gx_charging_rule_install = NULL;
struct dict_object *gx_charging_rule_remove = NULL;
struct dict_object *gx_charging_rule_definition = NULL;
struct dict_object *gx_charging_rule_base_name = NULL;
struct dict_object *gx_charging_rule_name = NULL;
struct dict_object *gx_flow_information = NULL;
struct dict_object *gx_flow_direction = NULL;
struct dict_object *gx_flow_description = NULL;
struct dict_object *gx_flow_status = NULL;
struct dict_object *gx_precedence = NULL;
struct dict_object *gx_flows = NULL;
struct dict_object *gx_media_component_description = NULL;
struct dict_object *gx_media_component_number = NULL;
struct dict_object *gx_media_type = NULL;
struct dict_object *gx_rr_bandwidth = NULL;
struct dict_object *gx_rs_bandwidth = NULL;
struct dict_object *gx_codec_data = NULL;
struct dict_object *gx_media_sub_component = NULL;
struct dict_object *gx_flow_number = NULL;
struct dict_object *gx_flow_usage = NULL;
int gx_dict_init(void)
{
application_id_t id = GX_APPLICATION_ID;
CHECK_dict_search(DICT_APPLICATION, APPLICATION_BY_ID, (void *)&id, &gx_application);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Credit-Control-Request", &gx_cmd_ccr);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Credit-Control-Answer", &gx_cmd_cca);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Re-Auth-Request", &gx_cmd_rar);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Re-Auth-Answer", &gx_cmd_raa);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "CC-Request-Type", &gx_cc_request_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "CC-Request-Number", &gx_cc_request_number);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Network-Request-Support", &gx_network_request_support);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Subscription-Id", &gx_subscription_id);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Subscription-Id-Type", &gx_subscription_id_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Subscription-Id-Data", &gx_subscription_id_data);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Supported-Features", &gx_supported_features);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Feature-List-ID", &gx_feature_list_id);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Feature-List", &gx_feature_list);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Framed-IP-Address", &gx_framed_ip_address);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Framed-IPv6-Prefix", &gx_framed_ipv6_prefix);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "IP-CAN-Type", &gx_ip_can_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "RAT-Type", &gx_rat_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "QoS-Information", &gx_qos_information);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "QoS-Class-Identifier" , &gx_qos_class_identifier);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Max-Requested-Bandwidth-UL" , &gx_max_requested_bandwidth_ul);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Max-Requested-Bandwidth-DL" , &gx_max_requested_bandwidth_dl);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Min-Requested-Bandwidth-UL" , &gx_min_requested_bandwidth_ul);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Min-Requested-Bandwidth-DL" , &gx_min_requested_bandwidth_dl);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Guaranteed-Bitrate-UL" , &gx_guaranteed_bitrate_ul);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Guaranteed-Bitrate-DL" , &gx_guaranteed_bitrate_dl);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Allocation-Retention-Priority" , &gx_allocation_retention_priority);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Priority-Level", &gx_priority_level);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Pre-emption-Capability", &gx_pre_emption_capability);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Pre-emption-Vulnerability", &gx_pre_emption_vulnerability);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "APN-Aggregate-Max-Bitrate-UL" , &gx_apn_aggregate_max_bitrate_ul);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "APN-Aggregate-Max-Bitrate-DL" , &gx_apn_aggregate_max_bitrate_dl);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "3GPP-User-Location-Info", &gx_3gpp_user_location_info);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Called-Station-Id", &gx_called_station_id);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Default-EPS-Bearer-QoS", &gx_default_eps_bearer_qos);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "3GPP-MS-TimeZone", &gx_3gpp_ms_timezone);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Event-Trigger", &gx_event_trigger);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Bearer-Control-Mode", &gx_bearer_control_mode);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Charging-Rule-Install", &gx_charging_rule_install);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Charging-Rule-Remove", &gx_charging_rule_remove);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Charging-Rule-Definition", &gx_charging_rule_definition);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Charging-Rule-Base-Name", &gx_charging_rule_base_name);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Charging-Rule-Name", &gx_charging_rule_name);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Flow-Information", &gx_flow_information);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Flow-Direction", &gx_flow_direction);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Flow-Description", &gx_flow_description);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Flow-Status", &gx_flow_status);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Precedence", &gx_precedence);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Flows", &gx_flows);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Media-Component-Description", &gx_media_component_description);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Media-Component-Number", &gx_media_component_number);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Media-Type", &gx_media_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "RR-Bandwidth" , &gx_rr_bandwidth);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "RS-Bandwidth" , &gx_rs_bandwidth);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Codec-Data", &gx_codec_data);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Media-Sub-Component", &gx_media_sub_component);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Flow-Number", &gx_flow_number);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Flow-Usage", &gx_flow_usage);
return 0;
}
nextepc-0.3.10/lib/fd/gx/gx_dict.h 0000664 0000000 0000000 00000011477 13335533574 0016635 0 ustar 00root root 0000000 0000000 #ifndef __GX_DICT_H__
#define __GX_DICT_H__
#include "freeDiameter/freeDiameter-host.h"
#include "freeDiameter/libfdcore.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GX_APPLICATION_ID 16777238
#define GX_AVP_CODE_RE_AUTH_REQUEST_TYPE (285)
#define GX_AVP_CODE_CC_REQUEST_NUMBER (415)
#define GX_AVP_CODE_CC_REQUEST_TYPE (416)
#define GX_AVP_CODE_DEFAULT_EPS_BEARER_QOS (1049)
#define GX_AVP_CODE_SUPPORTED_FEATURES (628)
#define GX_AVP_CODE_CHARGING_RULE_INSTALL (1001)
#define GX_AVP_CODE_CHARGING_RULE_REMOVE (1002)
#define GX_AVP_CODE_CHARGING_RULE_DEFINITION (1003)
#define GX_AVP_CODE_CHARGING_RULE_NAME (1005)
#define GX_AVP_CODE_FLOW_INFORMATION (1058)
#define GX_AVP_CODE_FLOW_STATUS (511)
#define GX_AVP_CODE_QOS_INFORMATION (1016)
#define GX_AVP_CODE_PRECEDENCE (1010)
extern struct dict_object *gx_application;
extern struct dict_object *gx_cmd_ccr;
extern struct dict_object *gx_cmd_cca;
extern struct dict_object *gx_cmd_rar;
extern struct dict_object *gx_cmd_raa;
extern struct dict_object *gx_cc_request_type;
extern struct dict_object *gx_cc_request_number;
extern struct dict_object *gx_network_request_support;
extern struct dict_object *gx_subscription_id;
#define GX_SUBSCRIPTION_ID_TYPE_END_USER_E164 0
#define GX_SUBSCRIPTION_ID_TYPE_END_USER_IMSI 1
#define GX_SUBSCRIPTION_ID_TYPE_END_USER_SIP_URI 2
#define GX_SUBSCRIPTION_ID_TYPE_END_USER_NAI 3
extern struct dict_object *gx_subscription_id_type;
extern struct dict_object *gx_subscription_id_data;
extern struct dict_object *gx_supported_features;
extern struct dict_object *gx_feature_list_id;
extern struct dict_object *gx_feature_list;
extern struct dict_object *gx_framed_ip_address;
extern struct dict_object *gx_framed_ipv6_prefix;
#define GX_IP_CAN_TYPE_3GPP_GPRS 0
#define GX_IP_CAN_TYPE_DOCSIS 1
#define GX_IP_CAN_TYPE_xDSL 2
#define GX_IP_CAN_TYPE_WiMAX 3
#define GX_IP_CAN_TYPE_3GPP2 4
#define GX_IP_CAN_TYPE_3GPP_EPS 5
#define GX_IP_CAN_TYPE_Non_3GPP_EPS 6
extern struct dict_object *gx_ip_can_type;
#define GX_RAT_TYPE_WLAN 0
#define GX_RAT_TYPE_VIRTUAL 1
#define GX_RAT_TYPE_UTRAN 1000
#define GX_RAT_TYPE_GERAN 1001
#define GX_RAT_TYPE_GAN 1002
#define GX_RAT_TYPE_HSPA_EVOLUTION 1003
#define GX_RAT_TYPE_EUTRAN 1004
#define GX_RAT_TYPE_EUTRAN_NB_IoT 1005
#define GX_RAT_TYPE_CDMA2000_1X 2000
#define GX_RAT_TYPE_HRPD 2001
#define GX_RAT_TYPE_UMB 2002
#define GX_RAT_TYPE_EHRPD 2003
extern struct dict_object *gx_rat_type;
extern struct dict_object *gx_qos_information;
extern struct dict_object *gx_qos_class_identifier;
extern struct dict_object *gx_max_requested_bandwidth_ul;
extern struct dict_object *gx_max_requested_bandwidth_dl;
extern struct dict_object *gx_guaranteed_bitrate_ul;
extern struct dict_object *gx_guaranteed_bitrate_dl;
extern struct dict_object *gx_allocation_retention_priority;
extern struct dict_object *gx_priority_level;
extern struct dict_object *gx_pre_emption_capability;
extern struct dict_object *gx_pre_emption_vulnerability;
extern struct dict_object *gx_apn_aggregate_max_bitrate_ul;
extern struct dict_object *gx_apn_aggregate_max_bitrate_dl;
#define GX_3GPP_USER_LOCATION_INFO_TYPE_TAI_AND_ECGI 130
extern struct dict_object *gx_3gpp_user_location_info;
extern struct dict_object *gx_called_station_id;
extern struct dict_object *gx_default_eps_bearer_qos;
extern struct dict_object *gx_3gpp_ms_timezone;
extern struct dict_object *gx_event_trigger;
extern struct dict_object *gx_bearer_control_mode;
extern struct dict_object *gx_charging_rule_install;
extern struct dict_object *gx_charging_rule_remove;
extern struct dict_object *gx_charging_rule_definition;
extern struct dict_object *gx_charging_rule_base_name;
extern struct dict_object *gx_charging_rule_name;
extern struct dict_object *gx_flow_information;
extern struct dict_object *gx_flow_direction;
extern struct dict_object *gx_flow_description;
extern struct dict_object *gx_flow_status;
extern struct dict_object *gx_precedence;
extern struct dict_object *gx_flows;
extern struct dict_object *gx_media_component_description;
extern struct dict_object *gx_media_component_number;
extern struct dict_object *gx_media_type;
extern struct dict_object *gx_rr_bandwidth;
extern struct dict_object *gx_rs_bandwidth;
extern struct dict_object *gx_codec_data;
extern struct dict_object *gx_media_sub_component;
extern struct dict_object *gx_flow_number;
extern struct dict_object *gx_flow_usage;
int gx_dict_init(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GX_DICT_H__ */
nextepc-0.3.10/lib/fd/gx/gx_message.c 0000664 0000000 0000000 00000000502 13335533574 0017314 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _gx_message
#include "core_debug.h"
#include "core_pkbuf.h"
#include "gx_message.h"
void gx_message_free(gx_message_t *gx_message)
{
int i;
d_assert(gx_message, return,);
for (i = 0; i < gx_message->num_of_pcc_rule; i++)
{
PCC_RULE_FREE(&gx_message->pcc_rule[i]);
}
}
nextepc-0.3.10/lib/fd/gx/gx_message.h 0000664 0000000 0000000 00000003024 13335533574 0017323 0 ustar 00root root 0000000 0000000 #ifndef __GX_MESSAGE_H__
#define __GX_MESSAGE_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include "3gpp_types.h"
typedef struct _gx_message_t {
#define GX_CMD_CODE_CREDIT_CONTROL 272
#define GX_CMD_RE_AUTH 258
c_uint16_t cmd_code;
/* Experimental-Result-Codes */
#define GX_DIAMETER_ERROR_LATE_OVERLAPPING_REQUEST 5453
#define GX_DIAMETER_ERROR_TIMED_OUT_REQUEST 5454
#define GX_DIAMETER_ERROR_INITIAL_PARAMETERS 5140
#define GX_DIAMETER_ERROR_TRIGGER_EVENT 5141
#define GX_DIAMETER_PCC_RULE_EVENT 5142
#define GX_DIAMETER_ERROR_BEARER_NOT_AUTHORIZED 5143
#define GX_DIAMETER_ERROR_TRAFFIC_MAPPING_INFO_REJECTED 5144
#define GX_DIAMETER_ERROR_CONFLICTING_REQUEST 5147
#define GX_DIAMETER_ADC_RULE_EVENT 5148
#define GX_DIAMETER_ERROR_NBIFOM_NOT_AUTHORIZED 5149
c_uint32_t result_code;
#define GX_CC_REQUEST_TYPE_INITIAL_REQUEST 1
#define GX_CC_REQUEST_TYPE_UPDATE_REQUEST 2
#define GX_CC_REQUEST_TYPE_TERMINATION_REQUEST 3
#define GX_CC_REQUEST_TYPE_EVENT_REQUEST 4
c_uint32_t cc_request_type;
pdn_t pdn;
pcc_rule_t pcc_rule[MAX_NUM_OF_PCC_RULE];
int num_of_pcc_rule;
} gx_message_t;
CORE_DECLARE(void) gx_message_free(gx_message_t *gx_message);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GX_MESSAGE_H__ */
nextepc-0.3.10/lib/fd/libapp_sip.c 0000664 0000000 0000000 00000007111 13335533574 0016701 0 ustar 00root root 0000000 0000000 /*********************************************************************************************************
* Software License Agreement (BSD License) *
* Author: Alexandre Westfahl *
* *
* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (Keio University), and the WIDE Project. *
* *
* All rights reserved. *
* *
* Redistribution and use of this software in source and binary forms, with or without modification, are *
* permitted provided that the following conditions are met: *
* *
* * Redistributions of source code must retain the above *
* copyright notice, this list of conditions and the *
* following disclaimer. *
* *
* * Redistributions in binary form must reproduce the above *
* copyright notice, this list of conditions and the *
* following disclaimer in the documentation and/or other *
* materials provided with the distribution. *
* *
* * Neither the name of the Teraoka Laboratory nor the *
* names of its contributors may be used to endorse or *
* promote products derived from this software without *
* specific prior written permission of Teraoka Laboratory *
* *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
*********************************************************************************************************/
#include "freeDiameter/freeDiameter-host.h"
#include "freeDiameter/libfdcore.h"
/* Search a given AVP model in an AVP (extracted from libfreediameter/message.c ) */
int fd_avp_search_avp ( struct avp * groupedavp, struct dict_object * what, struct avp ** avp )
{
struct avp * nextavp;
struct avp_hdr * nextavphdr;
struct dict_avp_data dictdata;
TRACE_ENTRY("%p %p %p", groupedavp, what, avp);
CHECK_FCT( fd_dict_getval(what, &dictdata) );
// Loop only in the group AVP
CHECK_FCT( fd_msg_browse(groupedavp, MSG_BRW_FIRST_CHILD, (void *)&nextavp, NULL) );
CHECK_FCT( fd_msg_avp_hdr( nextavp, &nextavphdr ) );
while (nextavphdr) {
if ( (nextavphdr->avp_code == dictdata.avp_code) && (nextavphdr->avp_vendor == dictdata.avp_vendor) ) // always 0 if no Vendor flag
{
break;
}
// Otherwise move to next AVP in the grouped AVP
CHECK_FCT( fd_msg_browse(nextavp, MSG_BRW_NEXT, (void *)&nextavp, NULL) );
if(nextavp!=NULL)
{
CHECK_FCT( fd_msg_avp_hdr( nextavp, &nextavphdr ) );
}
else
nextavphdr=NULL;
}
if (avp)
*avp = nextavp;
if (avp && nextavp) {
struct dictionary * dict;
CHECK_FCT( fd_dict_getdict( what, &dict) );
CHECK_FCT_DO( fd_msg_parse_dict( nextavp, dict, NULL ), );
}
if (avp || nextavp)
return 0;
else
return ENOENT;
}
nextepc-0.3.10/lib/fd/rx/ 0000775 0000000 0000000 00000000000 13335533574 0015044 5 ustar 00root root 0000000 0000000 nextepc-0.3.10/lib/fd/rx/dict_init.c 0000664 0000000 0000000 00000011506 13335533574 0017161 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _rx_dict
#include "rx_dict.h"
#define CHECK_dict_search( _type, _criteria, _what, _result ) \
CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
struct dict_object *rx_application = NULL;
struct dict_object *rx_cmd_aar = NULL;
struct dict_object *rx_cmd_aaa = NULL;
struct dict_object *rx_cmd_asr = NULL;
struct dict_object *rx_cmd_asa = NULL;
struct dict_object *rx_cmd_str = NULL;
struct dict_object *rx_cmd_sta = NULL;
struct dict_object *rx_media_component_description = NULL;
struct dict_object *rx_media_component_number = NULL;
struct dict_object *rx_media_type = NULL;
struct dict_object *rx_max_requested_bandwidth_ul = NULL;
struct dict_object *rx_max_requested_bandwidth_dl = NULL;
struct dict_object *rx_min_requested_bandwidth_ul = NULL;
struct dict_object *rx_min_requested_bandwidth_dl = NULL;
struct dict_object *rx_rr_bandwidth = NULL;
struct dict_object *rx_rs_bandwidth = NULL;
struct dict_object *rx_flow_status = NULL;
struct dict_object *rx_codec_data = NULL;
struct dict_object *rx_media_sub_component = NULL;
struct dict_object *rx_flow_number = NULL;
struct dict_object *rx_flow_usage = NULL;
struct dict_object *rx_flow_description = NULL;
struct dict_object *rx_subscription_id = NULL;
struct dict_object *rx_subscription_id_type = NULL;
struct dict_object *rx_subscription_id_data = NULL;
struct dict_object *rx_specific_action = NULL;
struct dict_object *rx_framed_ip_address = NULL;
struct dict_object *rx_framed_ipv6_prefix = NULL;
struct dict_object *rx_ip_can_type = NULL;
struct dict_object *rx_rat_type = NULL;
struct dict_object *rx_abort_cause = NULL;
struct dict_object *rx_termination_cause = NULL;
int rx_dict_init(void)
{
application_id_t id = RX_APPLICATION_ID;
CHECK_dict_search(DICT_APPLICATION, APPLICATION_BY_ID, (void *)&id, &rx_application);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "AA-Request", &rx_cmd_aar);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "AA-Answer", &rx_cmd_aaa);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Abort-Session-Request", &rx_cmd_asr);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Abort-Session-Answer", &rx_cmd_asa);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Session-Termination-Request", &rx_cmd_str);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Session-Termination-Answer", &rx_cmd_sta);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Media-Component-Description", &rx_media_component_description);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Media-Component-Number", &rx_media_component_number);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Media-Type", &rx_media_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Max-Requested-Bandwidth-UL" , &rx_max_requested_bandwidth_ul);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Max-Requested-Bandwidth-DL" , &rx_max_requested_bandwidth_dl);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Min-Requested-Bandwidth-UL" , &rx_min_requested_bandwidth_ul);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Min-Requested-Bandwidth-DL" , &rx_min_requested_bandwidth_dl);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "RR-Bandwidth" , &rx_rr_bandwidth);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "RS-Bandwidth" , &rx_rs_bandwidth);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Flow-Status", &rx_flow_status);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Codec-Data", &rx_codec_data);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Media-Sub-Component", &rx_media_sub_component);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Flow-Number", &rx_flow_number);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Flow-Usage", &rx_flow_usage);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Flow-Description", &rx_flow_description);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Subscription-Id", &rx_subscription_id);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Subscription-Id-Type", &rx_subscription_id_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Subscription-Id-Data", &rx_subscription_id_data);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Specific-Action", &rx_specific_action);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Framed-IP-Address", &rx_framed_ip_address);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Framed-IPv6-Prefix", &rx_framed_ipv6_prefix);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "IP-CAN-Type", &rx_ip_can_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "RAT-Type", &rx_rat_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Abort-Cause", &rx_abort_cause);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Termination-Cause", &rx_termination_cause);
return 0;
}
nextepc-0.3.10/lib/fd/rx/rx_dict.h 0000664 0000000 0000000 00000011254 13335533574 0016654 0 ustar 00root root 0000000 0000000 #ifndef __RX_DICT_H__
#define __RX_DICT_H__
#include "freeDiameter/freeDiameter-host.h"
#include "freeDiameter/libfdcore.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define RX_APPLICATION_ID 16777236
#define RX_AVP_CODE_SUBSCRIPTION_ID (443)
#define RX_AVP_CODE_SPECIFIC_ACTION (513)
#define RX_AVP_CODE_MEDIA_COMPONENT_DESCRIPTION (517)
#define RX_AVP_CODE_MEDIA_TYPE (520)
#define RX_AVP_CODE_MAX_REQUESTED_BANDWIDTH_DL (515)
#define RX_AVP_CODE_MAX_REQUESTED_BANDWIDTH_UL (516)
#define RX_AVP_CODE_RR_BANDWIDTH (521)
#define RX_AVP_CODE_RS_BANDWIDTH (522)
#define RX_AVP_CODE_MIN_REQUESTED_BANDWIDTH_DL (534)
#define RX_AVP_CODE_MIN_REQUESTED_BANDWIDTH_UL (535)
#define RX_AVP_CODE_MEDIA_COMPONENT_NUMBER (518)
#define RX_AVP_CODE_MEDIA_SUB_COMPONENT (519)
#define RX_AVP_CODE_FLOW_DESCRIPTION (507)
#define RX_AVP_CODE_FLOW_NUMBER (509)
#define RX_AVP_CODE_FLOW_USAGE (512)
extern struct dict_object *rx_application;
extern struct dict_object *rx_cmd_aar;
extern struct dict_object *rx_cmd_aaa;
extern struct dict_object *rx_cmd_asr;
extern struct dict_object *rx_cmd_asa;
extern struct dict_object *rx_cmd_str;
extern struct dict_object *rx_cmd_sta;
extern struct dict_object *rx_media_component_description;
extern struct dict_object *rx_media_component_number;
extern struct dict_object *rx_media_type;
extern struct dict_object *rx_max_requested_bandwidth_ul;
extern struct dict_object *rx_max_requested_bandwidth_dl;
extern struct dict_object *rx_min_requested_bandwidth_ul;
extern struct dict_object *rx_min_requested_bandwidth_dl;
extern struct dict_object *rx_rr_bandwidth;
extern struct dict_object *rx_rs_bandwidth;
#define RX_FLOW_STATUS_ENABLED_UPLINK 0
#define RX_FLOW_STATUS_ENABLED_DOWNLINK 1
#define RX_FLOW_STATUS_ENABLED 2
#define RX_FLOW_STATUS_DISABLED 3
extern struct dict_object *rx_flow_status;
extern struct dict_object *rx_codec_data;
extern struct dict_object *rx_media_sub_component;
extern struct dict_object *rx_flow_number;
extern struct dict_object *rx_flow_usage;
extern struct dict_object *rx_flow_description;
extern struct dict_object *rx_subscription_id;
#define RX_SUBSCRIPTION_ID_TYPE_END_USER_E164 0
#define RX_SUBSCRIPTION_ID_TYPE_END_USER_IMSI 1
#define RX_SUBSCRIPTION_ID_TYPE_END_USER_SIP_URI 2
#define RX_SUBSCRIPTION_ID_TYPE_END_USER_NAI 3
extern struct dict_object *rx_subscription_id_type;
extern struct dict_object *rx_subscription_id_data;
extern struct dict_object *rx_specific_action;
extern struct dict_object *rx_framed_ip_address;
extern struct dict_object *rx_framed_ipv6_prefix;
#define RX_IP_CAN_TYPE_3GPP_GPRS 0
#define RX_IP_CAN_TYPE_DOCSIS 1
#define RX_IP_CAN_TYPE_xDSL 2
#define RX_IP_CAN_TYPE_WiMAX 3
#define RX_IP_CAN_TYPE_3GPP2 4
#define RX_IP_CAN_TYPE_3GPP_EPS 5
#define RX_IP_CAN_TYPE_Non_3GPP_EPS 6
extern struct dict_object *rx_ip_can_type;
#define RX_RAT_TYPE_WLAN 0
#define RX_RAT_TYPE_VIRTUAL 1
#define RX_RAT_TYPE_UTRAN 1000
#define RX_RAT_TYPE_GERAN 1001
#define RX_RAT_TYPE_GAN 1002
#define RX_RAT_TYPE_HSPA_EVOLUTION 1003
#define RX_RAT_TYPE_EUTRAN 1004
#define RX_RAT_TYPE_EUTRAN_NB_IoT 1005
#define RX_RAT_TYPE_CDMA2000_1X 2000
#define RX_RAT_TYPE_HRPD 2001
#define RX_RAT_TYPE_UMB 2002
#define RX_RAT_TYPE_EHRPD 2003
extern struct dict_object *rx_rat_type;
#define RX_ABORT_CAUSE_BEARER_RELEASED 0
#define RX_ABORT_CAUSE_INSUFFICIENT_SERVER_RESOURCES 1
#define RX_ABORT_CAUSE_INSUFFICIENT_BEARER_RESOURCES 2
#define RX_ABORT_CAUSE_PS_TO_CS_HANDOVER 3
#define RX_ABORT_CAUSE_SPONSORED_DATA_CONNECTIVITY_ DISALLOWED 4
extern struct dict_object *rx_abort_cause;
#define RX_TERMINATION_CAUSE_DIAMETER_LOGOUT 1
#define RX_TERMINATION_CAUSE_DIAMETER_SERVICE_NOT_PROVIDED 2
#define RX_TERMINATION_CAUSE_DIAMETER_BAD_ANSWER 3
#define RX_TERMINATION_CAUSE_DIAMETER_DIAMETER_ADMINISTRATIVE 4
#define RX_TERMINATION_CAUSE_DIAMETER_LINK_BROKEN 5
#define RX_TERMINATION_CAUSE_DIAMETER_AUTH_EXPIRED 6
#define RX_TERMINATION_CAUSE_DIAMETER_USER_MOVED 7
#define RX_TERMINATION_CAUSE_DIAMETER_SESSION_TIMEOUT 8
extern struct dict_object *rx_termination_cause;
int rx_dict_init(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __RX_DICT_H__ */
nextepc-0.3.10/lib/fd/rx/rx_message.c 0000664 0000000 0000000 00000001536 13335533574 0017352 0 ustar 00root root 0000000 0000000 #define TRACE_MODULE _rx_message
#include "core_debug.h"
#include "core_pkbuf.h"
#include "rx_message.h"
void rx_message_free(rx_message_t *rx_message)
{
int i, j, k;
d_assert(rx_message, return, "Null param");
for (i = 0; i < rx_message->num_of_media_component; i++)
{
rx_media_component_t *media_component =
&rx_message->media_component[i];
for (j = 0; j < media_component->num_of_sub; j++)
{
rx_media_sub_component_t *sub = &media_component->sub[j];
for (k = 0; k < sub->num_of_flow; k++)
{
flow_t *flow = &sub->flow[k];
if (flow->description)
{
CORE_FREE(flow->description);
}
else
d_assert(0,, "Null param");
}
}
}
}
nextepc-0.3.10/lib/fd/rx/rx_message.h 0000664 0000000 0000000 00000005045 13335533574 0017356 0 ustar 00root root 0000000 0000000 #ifndef __RX_MESSAGE_H__
#define __RX_MESSAGE_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include "3gpp_types.h"
typedef struct _rx_media_sub_component_t {
c_uint32_t flow_number;
#define RX_FLOW_USAGE_NO_INFORMATION 0
#define RX_FLOW_USAGE_RTCP 1
#define RX_FLOW_USAGE_AF_SIGNALLING 2
c_uint32_t flow_usage;
flow_t flow[MAX_NUM_OF_FLOW];
int num_of_flow;
} rx_media_sub_component_t;
typedef struct _rx_media_component_t {
c_uint32_t media_component_number;
#define RX_MEDIA_TYPE_AUDIO 0
#define RX_MEDIA_TYPE_VIDEO 1
#define RX_MEDIA_TYPE_DATA 2
#define RX_MEDIA_TYPE_APPLICATION 3
#define RX_MEDIA_TYPE_CONTROL 4
#define RX_MEDIA_TYPE_TEXT 5
#define RX_MEDIA_TYPE_MESSAGE 6
#define RX_MEDIA_TYPE_OTHER 0xFFFFFFFF
c_uint32_t media_type;
c_uint64_t max_requested_bandwidth_dl;
c_uint64_t max_requested_bandwidth_ul;
c_uint64_t min_requested_bandwidth_dl;
c_uint64_t min_requested_bandwidth_ul;
c_uint64_t rr_bandwidth;
c_uint64_t rs_bandwidth;
#define MAX_NUM_OF_MEDIA_SUB_COMPONENT 8
rx_media_sub_component_t sub[MAX_NUM_OF_MEDIA_SUB_COMPONENT];
int num_of_sub;
} rx_media_component_t;
typedef struct _rx_message_t {
#define RX_CMD_CODE_AA 265
#define RX_CMD_CODE_SESSION_TERMINATION 275
c_uint16_t cmd_code;
/* Experimental-Result-Codes */
#define RX_DIAMETER_INVALID_SERVICE_INFORMATION 5061
#define RX_DIAMETER_FILTER_RESTRICTIONS 5062
#define RX_DIAMETER_REQUESTED_SERVICE_NOT_AUTHORIZED 5063
#define RX_DIAMETER_DUPLICATED_AF_SESSION 5064
#define RX_DIAMETER_IP_CAN_SESSION_NOT_AVAILABLE 5065
#define RX_DIAMETER_UNAUTHORIZED_NON_EMERGENCY_SESSION 5066
#define RX_DIAMETER_UNAUTHORIZED_SPONSORED_DATA_CONNECTIVITY 5067
#define RX_DIAMETER_TEMPORARY_NETWORK_FAILURE 5068
c_uint32_t result_code;
#define MAX_NUM_OF_MEDIA_COMPONENT 16
rx_media_component_t media_component[MAX_NUM_OF_MEDIA_COMPONENT];
int num_of_media_component;
} rx_message_t;
CORE_DECLARE(void) rx_message_free(rx_message_t *rx_message);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __RX_MESSAGE_H__ */
nextepc-0.3.10/lib/fd/s6a/ 0000775 0000000 0000000 00000000000 13335533574 0015104 5 ustar 00root root 0000000 0000000 nextepc-0.3.10/lib/fd/s6a/dict_init.c 0000664 0000000 0000000 00000014767 13335533574 0017235 0 ustar 00root root 0000000 0000000 #include "s6a_dict.h"
#define CHECK_dict_search( _type, _criteria, _what, _result ) \
CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
struct dict_object *s6a_application = NULL;
struct dict_object *s6a_cmd_air = NULL;
struct dict_object *s6a_cmd_aia = NULL;
struct dict_object *s6a_cmd_ulr = NULL;
struct dict_object *s6a_cmd_ula = NULL;
struct dict_object *s6a_cmd_pur = NULL;
struct dict_object *s6a_cmd_pua = NULL;
struct dict_object *s6a_visited_plmn_id = NULL;
struct dict_object *s6a_rat_type = NULL;
struct dict_object *s6a_ulr_flags = NULL;
struct dict_object *s6a_ula_flags = NULL;
struct dict_object *s6a_subscription_data = NULL;
struct dict_object *s6a_req_eutran_auth_info = NULL;
struct dict_object *s6a_number_of_requested_vectors = NULL;
struct dict_object *s6a_immediate_response_preferred = NULL;
struct dict_object *s6a_authentication_info = NULL;
struct dict_object *s6a_re_synchronization_info = NULL;
struct dict_object *s6a_service_selection = NULL;
struct dict_object *s6a_ue_srvcc_capability = NULL;
struct dict_object *s6a_e_utran_vector = NULL;
struct dict_object *s6a_rand = NULL;
struct dict_object *s6a_xres = NULL;
struct dict_object *s6a_autn = NULL;
struct dict_object *s6a_kasme = NULL;
struct dict_object *s6a_subscriber_status = NULL;
struct dict_object *s6a_ambr = NULL;
struct dict_object *s6a_network_access_mode = NULL;
struct dict_object *s6a_access_restriction_data = NULL;
struct dict_object *s6a_apn_configuration_profile = NULL;
struct dict_object *s6a_subscribed_rau_tau_timer = NULL;
struct dict_object *s6a_context_identifier = NULL;
struct dict_object *s6a_all_apn_configuration_included_indicator = NULL;
struct dict_object *s6a_apn_configuration = NULL;
struct dict_object *s6a_max_bandwidth_ul = NULL;
struct dict_object *s6a_max_bandwidth_dl = NULL;
struct dict_object *s6a_pdn_type = NULL;
struct dict_object *s6a_eps_subscribed_qos_profile = NULL;
struct dict_object *s6a_qos_class_identifier = NULL;
struct dict_object *s6a_allocation_retention_priority = NULL;
struct dict_object *s6a_priority_level = NULL;
struct dict_object *s6a_pre_emption_capability = NULL;
struct dict_object *s6a_pre_emption_vulnerability = NULL;
int s6a_dict_init(void)
{
application_id_t id = S6A_APPLICATION_ID;
CHECK_dict_search(DICT_APPLICATION, APPLICATION_BY_ID, (void *)&id, &s6a_application);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Authentication-Information-Request", &s6a_cmd_air);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Authentication-Information-Answer", &s6a_cmd_aia);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Update-Location-Request", &s6a_cmd_ulr);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Update-Location-Answer", &s6a_cmd_ula);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Purge-UE-Request", &s6a_cmd_pur);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Purge-UE-Answer", &s6a_cmd_pua);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Visited-PLMN-Id", &s6a_visited_plmn_id);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "RAT-Type", &s6a_rat_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "ULR-Flags", &s6a_ulr_flags);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "ULA-Flags", &s6a_ula_flags);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "UE-SRVCC-Capability", &s6a_ue_srvcc_capability);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Requested-EUTRAN-Authentication-Info", &s6a_req_eutran_auth_info);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Number-Of-Requested-Vectors", &s6a_number_of_requested_vectors);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Immediate-Response-Preferred", &s6a_immediate_response_preferred);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Re-Synchronization-Info", &s6a_re_synchronization_info);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Authentication-Info", &s6a_authentication_info);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "E-UTRAN-Vector", &s6a_e_utran_vector);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "RAND", &s6a_rand);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "XRES", &s6a_xres);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "AUTN", &s6a_autn);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "KASME", &s6a_kasme);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "EPS-Subscribed-QoS-Profile", &s6a_eps_subscribed_qos_profile);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "QoS-Class-Identifier", &s6a_qos_class_identifier);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Allocation-Retention-Priority", &s6a_allocation_retention_priority);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Priority-Level", &s6a_priority_level);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Pre-emption-Capability", &s6a_pre_emption_capability);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Pre-emption-Vulnerability", &s6a_pre_emption_vulnerability);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "AMBR", &s6a_ambr);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Max-Requested-Bandwidth-UL", &s6a_max_bandwidth_ul);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Max-Requested-Bandwidth-DL", &s6a_max_bandwidth_dl);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "APN-Configuration-Profile", &s6a_apn_configuration_profile);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Context-Identifier", &s6a_context_identifier);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "All-APN-Configurations-Included-Indicator", &s6a_all_apn_configuration_included_indicator);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "APN-Configuration", &s6a_apn_configuration);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Service-Selection", &s6a_service_selection);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "PDN-Type", &s6a_pdn_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Subscription-Data", &s6a_subscription_data);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Subscriber-Status", &s6a_subscriber_status);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Network-Access-Mode", &s6a_network_access_mode);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Access-Restriction-Data", &s6a_access_restriction_data);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Subscribed-Periodic-RAU-TAU-Timer", &s6a_subscribed_rau_tau_timer);
return 0;
}
nextepc-0.3.10/lib/fd/s6a/s6a_dict.h 0000664 0000000 0000000 00000007066 13335533574 0016762 0 ustar 00root root 0000000 0000000 #ifndef __S6A_LIB_H__
#define __S6A_LIB_H__
#include "freeDiameter/freeDiameter-host.h"
#include "freeDiameter/libfdcore.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define S6A_APPLICATION_ID 16777251
#define S6A_AVP_CODE_CONTEXT_IDENTIFIER (1423)
#define S6A_AVP_CODE_ALL_APN_CONFIG_INC_IND (1428)
#define S6A_AVP_CODE_APN_CONFIGURATION (1430)
#define S6A_AVP_CODE_MIP_HOME_AGENT_ADDRESS (334)
#define S6A_RAT_TYPE_WLAN 0
#define S6A_RAT_TYPE_VIRTUAL 1
#define S6A_RAT_TYPE_UTRAN 1000
#define S6A_RAT_TYPE_GERAN 1001
#define S6A_RAT_TYPE_GAN 1002
#define S6A_RAT_TYPE_HSPA_EVOLUTION 1003
#define S6A_RAT_TYPE_EUTRAN 1004
#define S6A_RAT_TYPE_EUTRAN_NB_IOT 1005
#define S6A_RAT_TYPE_CDMA2000_1X 2000
#define S6A_RAT_TYPE_HRPD 2001
#define S6A_RAT_TYPE_UMB 2002
#define S6A_RAT_TYPE_EHRPD 2003
#define S6A_ULR_SINGLE_REGISTRATION_IND (1)
#define S6A_ULR_S6A_S6D_INDICATOR (1 << 1)
#define S6A_ULR_SKIP_SUBSCRIBER_DATA (1 << 2)
#define S6A_ULR_GPRS_SUBSCRIPTION_DATA_IND (1 << 3)
#define S6A_ULR_NODE_TYPE_IND (1 << 4)
#define S6A_ULR_INITIAL_ATTACH_IND (1 << 5)
#define S6A_ULR_PS_LCS_SUPPORTED_BY_UE (1 << 6)
#define S6A_UE_SRVCC_NOT_SUPPORTED (0)
#define S6A_UE_SRVCC_SUPPORTED (1)
extern struct dict_object *s6a_application;
extern struct dict_object *s6a_cmd_air;
extern struct dict_object *s6a_cmd_aia;
extern struct dict_object *s6a_cmd_ulr;
extern struct dict_object *s6a_cmd_ula;
extern struct dict_object *s6a_cmd_pur;
extern struct dict_object *s6a_cmd_pua;
extern struct dict_object *s6a_visited_plmn_id;
extern struct dict_object *s6a_rat_type;
extern struct dict_object *s6a_ulr_flags;
extern struct dict_object *s6a_ula_flags;
extern struct dict_object *s6a_subscription_data;
extern struct dict_object *s6a_req_eutran_auth_info;
extern struct dict_object *s6a_number_of_requested_vectors;
extern struct dict_object *s6a_immediate_response_preferred;
extern struct dict_object *s6a_authentication_info;
extern struct dict_object *s6a_re_synchronization_info;
extern struct dict_object *s6a_service_selection;
extern struct dict_object *s6a_ue_srvcc_capability;
extern struct dict_object *s6a_e_utran_vector;
extern struct dict_object *s6a_rand;
extern struct dict_object *s6a_xres;
extern struct dict_object *s6a_autn;
extern struct dict_object *s6a_kasme;
extern struct dict_object *s6a_subscriber_status;
extern struct dict_object *s6a_ambr;
extern struct dict_object *s6a_network_access_mode;
extern struct dict_object *s6a_access_restriction_data;
extern struct dict_object *s6a_apn_configuration_profile;
extern struct dict_object *s6a_subscribed_rau_tau_timer;
extern struct dict_object *s6a_context_identifier;
extern struct dict_object *s6a_all_apn_configuration_included_indicator;
extern struct dict_object *s6a_apn_configuration;
extern struct dict_object *s6a_max_bandwidth_ul;
extern struct dict_object *s6a_max_bandwidth_dl;
extern struct dict_object *s6a_pdn_type;
extern struct dict_object *s6a_eps_subscribed_qos_profile;
extern struct dict_object *s6a_qos_class_identifier;
extern struct dict_object *s6a_allocation_retention_priority;
extern struct dict_object *s6a_priority_level;
extern struct dict_object *s6a_pre_emption_capability;
extern struct dict_object *s6a_pre_emption_vulnerability;
int s6a_dict_init(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ! __S6A_LIB_H__ */
nextepc-0.3.10/lib/fd/s6a/s6a_message.h 0000664 0000000 0000000 00000005734 13335533574 0017463 0 ustar 00root root 0000000 0000000 #ifndef __S6A_MESSAGE_H__
#define __S6A_MESSAGE_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include "core_sha2.h"
#include "3gpp_types.h"
typedef struct _e_utran_vector_t {
c_uint8_t xres[MAX_RES_LEN];
c_uint8_t xres_len;
c_uint8_t kasme[SHA256_DIGEST_SIZE];
c_uint8_t rand[RAND_LEN];
c_uint8_t autn[AUTN_LEN];
} e_utran_vector_t;
typedef struct _s6a_aia_message_t {
e_utran_vector_t e_utran_vector;
} s6a_aia_message_t;
typedef struct _s6a_subscription_data_t {
#define HSS_ACCESS_RESTRICTION_UTRAN_NOT_ALLOWED (1)
#define HSS_ACCESS_RESTRICTION_GERAN_NOT_ALLOWED (1<<1)
#define HSS_ACCESS_RESTRICTION_GAN_NOT_ALLOWED (1<<2)
#define HSS_ACCESS_RESTRICTION_I_HSPA_EVOLUTION_NOT_ALLOWED (1<<3)
#define HSS_ACCESS_RESTRICTION_WB_E_UTRAN_NOT_ALLOWED (1<<4)
#define HSS_ACCESS_RESTRICTION_HO_TO_NON_3GPP_ACCESS_NOT_ALLOWED (1<<5)
#define HSS_ACCESS_RESTRICTION_NB_IOT_NOT_ALLOWED (1<<6)
c_uint32_t access_restriction_data;
#define HSS_SUBSCRIBER_STATUS_SERVICE_GRANTED 0
#define HSS_SUBSCRIBER_STATUS_OPERATOR_DETERMINED_BARRING 1
c_uint32_t subscriber_status;
#define HSS_NETWORK_ACCESS_MODE_PACKET_AND_CIRCUIT 0
#define HSS_NETWORK_ACCESS_MODE_RESERVED 1
#define HSS_NETWORK_ACCESS_MODE_ONLY_PACKET 2
c_uint32_t network_access_mode;
bitrate_t ambr; /* UE-AMBR */
c_uint32_t subscribed_rau_tau_timer; /* unit : minutes */
c_uint32_t context_identifier; /* default APN */
pdn_t pdn[MAX_NUM_OF_SESS];
int num_of_pdn;
} s6a_subscription_data_t;
typedef struct _s6a_ula_message_t {
#define S6A_ULA_FLAGS_SEPARATION_INDICATION (0)
#define S6A_ULA_FLAGS_MME_REGISTERED_FOR_SMS (1)
c_uint32_t ula_flags;
s6a_subscription_data_t subscription_data;
} s6a_ula_message_t;
typedef struct _s6a_message_t {
#define S6A_CMD_CODE_UPDATE_LOCATION 316
#define S6A_CMD_CODE_AUTHENTICATION_INFORMATION 318
c_uint16_t cmd_code;
/* Experimental Result Code */
#define S6A_DIAMETER_AUTHENTICATION_DATA_UNAVAILABLE 4181
#define S6A_DIAMETER_ERROR_USER_UNKNOWN 5001
#define S6A_DIAMETER_ERROR_ROAMING_NOT_ALLOWED 5004
#define S6A_DIAMETER_ERROR_UNKNOWN_EPS_SUBSCRIPTION 5420
#define S6A_DIAMETER_ERROR_RAT_NOT_ALLOWED 5421
#define S6A_DIAMETER_ERROR_EQUIPMENT_UNKNOWN 5422
#define S6A_DIAMETER_ERROR_UNKOWN_SERVING_NODE 5423
c_uint32_t result_code;
s6a_aia_message_t aia_message;
s6a_ula_message_t ula_message;
} s6a_message_t;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __S6A_MESSAGE_H__ */
nextepc-0.3.10/lib/freeDiameter-1.2.1/ 0000775 0000000 0000000 00000000000 13335533574 0017053 5 ustar 00root root 0000000 0000000 nextepc-0.3.10/lib/freeDiameter-1.2.1/.hg_archival.txt 0000664 0000000 0000000 00000000171 13335533574 0022140 0 ustar 00root root 0000000 0000000 repo: 13530e1f02e3d918eaec5cf9ad027d752c1cf2ab
node: 2cb8d71a405df19cf385e49e237f649589513e8d
branch: default
tag: 1.2.1
nextepc-0.3.10/lib/freeDiameter-1.2.1/.hgignore 0000664 0000000 0000000 00000000116 13335533574 0020654 0 ustar 00root root 0000000 0000000 syntax: glob
*.orig
*.rej
*~
*.log
*.sum
.hg
build*
test.*
GPATH
GRTAGS
GTAGS
nextepc-0.3.10/lib/freeDiameter-1.2.1/.hgtags 0000664 0000000 0000000 00000007740 13335533574 0020341 0 ustar 00root root 0000000 0000000 195096819152dcceb181b01f05e3e22594e33bbd 1.0.0-rc1
478173cb832ac426090c8ef4c37783303fe7931d 1.0.0
478173cb832ac426090c8ef4c37783303fe7931d 1.0.0
e9ab851f6dca2d4b0c3ca11821d0efda78d9c3c5 1.0.0
25440e53a48e96c1cff0e29569a4a8ec32019cf9 1.0.1-rc1
62ad61238af2b83dcdb8848c2fedb1f3e482010d 1.0.1
144eeab1e3a45288e79321e5783b4f02e10851ca 1.0.2-rc1
f27b40a9dd82152f4587679f397e6ff571a70efb 1.0.2
7ae66129fd7341846df8b6c51ddc2d525707bc3b 1.0.3-rc1
18c4a738e3e910e4e6863aebe5ecb8a61948f5f5 1.0.3-rc2
69d3579f6c6cd3b16daeedc60ca94ca6056a3748 1.0.3-rc3
f065e3cb846ee557b13279b99272032a4ad913a9 1.0.3
5b05d85682f1a23fcd0ecfc87649a65b841e7ca8 1.0.x-last
2e94ef0515d71fb7e932e48894feb84487939c3f 1.1.0-rc1
ff23fecac0b2214818e19f1d4b74b2d4b97f1142 1.1.0-rc2
b2bc31410425527e4c0930580d185c4f15b1cb56 1.1.0-rc3
5d529eb0ad331e9a381de9100a9670e1148b7a98 1.1.0
36caa2c02d1e25309bc9cc6a1f0bb3333ddf7e80 1.1.1
36caa2c02d1e25309bc9cc6a1f0bb3333ddf7e80 1.1.1
0925471e2a88d4d7e2993214e83d925b37908991 1.1.1
69ef21d4a7fea3a812bf19b909df8e56c43adce8 1.1.2
066e1ad7e9fa1eccd6e1d2174d5b57eb6bd33507 1.1.3
7541554029bfbca3370a2ae58a09e91946c6bd78 1.1.4-rc1
4ae6da028be7582a0b3fe98054d5fa0940f8985b 1.1.4
4ae6da028be7582a0b3fe98054d5fa0940f8985b 1.1.4
0000000000000000000000000000000000000000 1.1.4
0000000000000000000000000000000000000000 1.1.4
a39848239f3ab933d5e62089357dd6fd3a59e393 1.1.4
5c4cf8d15ef0e298734daf16203278d7fa62fa7a 1.1.5-rc1
226f5957186ae4369467b070aeb61b1c631c9a5c 1.1.5-rc2
ae96ae28f3ddc48b9e2676e9538008eab2b9d60a 1.1.5
8500947421cb412b5f4f2dfffdf1a35b6fb369e0 FORK
155d45d0653025f45b58ab96b6ba0d5e6fb7fcf8 1.1.6
8500947421cb412b5f4f2dfffdf1a35b6fb369e0 FORK
0000000000000000000000000000000000000000 FORK
ec348f6043998ca77d2b3122ef47157c82055ccd proposed_merged
ec348f6043998ca77d2b3122ef47157c82055ccd proposed_merged
371f899276ed15d796ae324a88421109c847922b proposed_merged
371f899276ed15d796ae324a88421109c847922b proposed_merged
80584f0e851a725470a42e41607fe21775f2dac8 proposed_merged
80584f0e851a725470a42e41607fe21775f2dac8 proposed_merged
cf09fde3d7f5da1aac5b8ec0412da83af732ac8d proposed_merged
cf09fde3d7f5da1aac5b8ec0412da83af732ac8d proposed_merged
7ca81c10ba06a3a722c825ce94b6a01bc6b39b04 proposed_merged
7ca81c10ba06a3a722c825ce94b6a01bc6b39b04 proposed_merged
2a510c541472ccd14e2fe83051ade7ddc5ae23f5 proposed_merged
2a510c541472ccd14e2fe83051ade7ddc5ae23f5 proposed_merged
0117a7746b2166b861ff66c42b21115cd17bfcc5 proposed_merged
0117a7746b2166b861ff66c42b21115cd17bfcc5 proposed_merged
09e2a6d796ef8cd55295c635e36ba5a0e2bf7cad proposed_merged
09e2a6d796ef8cd55295c635e36ba5a0e2bf7cad proposed_merged
7c5449ddc434828e77517cb893c882d740b5a4d6 proposed_merged
f916f4fc3d99b05adf5e6c94cef089568de7b252 1.2.0-rc1
7c5449ddc434828e77517cb893c882d740b5a4d6 proposed_merged
75633912f364ad94a82e197d918c75b4745998f8 proposed_merged
75633912f364ad94a82e197d918c75b4745998f8 proposed_merged
7ef8ab1d664f300fb5ad8f102c8b2fdafa609518 proposed_merged
7ef8ab1d664f300fb5ad8f102c8b2fdafa609518 proposed_merged
7b57dc5a681fd642a218971da9af9af7356152d9 proposed_merged
7b57dc5a681fd642a218971da9af9af7356152d9 proposed_merged
5d19d6f3e1bd03adc8869e294d0c4b13e0977fd6 proposed_merged
5d19d6f3e1bd03adc8869e294d0c4b13e0977fd6 proposed_merged
d00b5914351e83fa90b2ea09f8c51cd82b312157 proposed_merged
d00b5914351e83fa90b2ea09f8c51cd82b312157 proposed_merged
fb9282c75ec51eb43690413c5b66a3192dfc79d3 proposed_merged
fb9282c75ec51eb43690413c5b66a3192dfc79d3 proposed_merged
043b894b0511b6beb155576e9e2c509a21be8360 proposed_merged
08e72b858f03a77869792cb8ad8e0acbc83c2590 1.2.0-rc2
f937feb727347445f8afb7759a97e34c76c0ba7b 1.2.0
ab6457399be2762b3e85bd173ba754ff758ef060 1.2.1-rc1
043b894b0511b6beb155576e9e2c509a21be8360 proposed_merged
0000000000000000000000000000000000000000 proposed_merged
13948c684c354d8c891ca5e2a5f1d76d1f176afe 1.2.1-rc2
19d01728f26f7318b5e851d3e5aae9703fa540ff 1.2.1
9caedf4a058b5ec7274c84201bfad986bc7f943c 1.2.1a
6446c0eea54742c8745c2efdad7963c65e74df5a 1.2.1b
19d01728f26f7318b5e851d3e5aae9703fa540ff 1.2.1
0000000000000000000000000000000000000000 1.2.1
nextepc-0.3.10/lib/freeDiameter-1.2.1/CMakeLists.txt 0000664 0000000 0000000 00000010713 13335533574 0021615 0 ustar 00root root 0000000 0000000 # This file is the source for generating the Makefile for the project, using cmake tool (cmake.org)
# Name of the project
PROJECT("freeDiameter")
# Informations to display in daemon's help
SET(FD_PROJECT_NAME freeDiameter)
SET(FD_PROJECT_BINARY freeDiameterd)
SET(FD_PROJECT_COPYRIGHT "Copyright (c) 2008-2015, WIDE Project (www.wide.ad.jp) and NICT (www.nict.go.jp)")
# Version of the source code
SET(FD_PROJECT_VERSION_MAJOR 1)
SET(FD_PROJECT_VERSION_MINOR 2)
SET(FD_PROJECT_VERSION_REV 1)
# Version of the API with the library
SET(FD_PROJECT_VERSION_API 6)
# The test framework, using CTest and CDash.
INCLUDE(CTest)
# CMake version
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
# Location of additional CMake modules
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
# The default directories
SET(DEFAULT_CONF_PATH ${CMAKE_INSTALL_PREFIX}/etc/freeDiameter CACHE PATH "Default location of freeDiameter configuration files")
IF (NOT DEFINED LIB_INSTALL_DIR)
SET(LIB_INSTALL_DIR lib CACHE PATH "Default library path name on the system, to accomodate RPM-based systems that use lib64")
ENDIF (NOT DEFINED LIB_INSTALL_DIR)
SET(INSTALL_HEADERS_SUFFIX include/freeDiameter CACHE PATH "Directory where the headers are installed (relative to CMAKE_INSTALL_PREFIX).")
SET(INSTALL_DAEMON_SUFFIX bin CACHE PATH "Directory where the daemon binary is installed (relative to CMAKE_INSTALL_PREFIX).")
SET(INSTALL_LIBRARY_SUFFIX ${LIB_INSTALL_DIR} CACHE PATH "Directory where the freeDiameter libraries are installed (relative to CMAKE_INSTALL_PREFIX).")
SET(INSTALL_EXTENSIONS_SUFFIX ${LIB_INSTALL_DIR}/freeDiameter CACHE PATH "Directory where the extensions are installed / searched (relative to CMAKE_INSTALL_PREFIX).")
# All source code should be POSIX 200112L compatible, but some other extensions might be used, so:
ADD_DEFINITIONS(-D_GNU_SOURCE)
# Set a default build type if none was specified
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to 'Debug' as none was specified.")
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
"MinSizeRel" "RelWithDebInfo" "Profiling" "MaxPerformance" "DebianPackage" "DebugValgrind")
endif()
# Add a "Profiling" build type
# SET(CMAKE_BUILD_TYPE Profiling)
SET(CMAKE_C_FLAGS_PROFILING "-fprofile-arcs -ftest-coverage -fstack-protector -g -Wall")
# Add a "MaxPerformance" build type -- this is very silent...
# SET(CMAKE_BUILD_TYPE MaxPerformance)
SET(CMAKE_C_FLAGS_MAXPERFORMANCE "${CMAKE_C_FLAGS_RELEASE} -DSTRIP_DEBUG_CODE")
# Add a "DebianPackage" build type used when creating the Debian packages
SET(CMAKE_C_FLAGS_DEBIANPACKAGE "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
# Set the "Debug" flags
SET(CMAKE_C_FLAGS_DEBUG "-Wall -g -O0")
# Add a "DebugValgrind" build type used for checking execution with Valgrind tool
SET(CMAKE_C_FLAGS_DEBUGVALGRIND "-Wall -g -O0")
# Set the DEBUG flag for Debug and Profiling builds
IF (CMAKE_BUILD_TYPE MATCHES "Debug|Profiling|DebugValgrind")
SET(DEBUG 1)
ENDIF (CMAKE_BUILD_TYPE MATCHES "Debug|Profiling|DebugValgrind")
# some subfolders use yacc and lex parsers
SET(BISON_GENERATE_DEFINES TRUE)
SET(BISON_PREFIX_OUTPUTS TRUE)
INCLUDE(CMakeUserUseBison)
SET(FLEX_PREFIX_OUTPUTS TRUE)
INCLUDE(CMakeUserUseFlex)
IF( NOT BISON_EXECUTABLE OR NOT FLEX_EXECUTABLE )
MESSAGE( SEND_ERROR "Bison and Flex are required" )
ENDIF( NOT BISON_EXECUTABLE OR NOT FLEX_EXECUTABLE )
# Check that flex is at least 2.5.20 to support bison-bridge
# how to do the check with cmake???
# Add this to workaround an apparent bug in FreeBSD cmake (already defined in Linux)
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-rdynamic")
# For Darwin systems
IF(APPLE)
SET(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "${CMAKE_SHARED_MODULE_CREATE_C_FLAGS} -flat_namespace -undefined dynamic_lookup")
SET(CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS "${CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS} -flat_namespace -undefined dynamic_lookup")
ENDIF(APPLE)
# Location for the include files
INCLUDE_DIRECTORIES(include)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/include)
SUBDIRS(include/freeDiameter)
# Location for the source code
SUBDIRS(libfdproto)
SUBDIRS(libfdcore)
SUBDIRS(freeDiameterd)
# Extensions (there is no use of freeDiameter without any extension)
SUBDIRS(extensions)
# The unary tests directory
IF ( BUILD_TESTING )
SUBDIRS(tests)
ENDIF ( BUILD_TESTING )
nextepc-0.3.10/lib/freeDiameter-1.2.1/CTestConfig.cmake 0000664 0000000 0000000 00000000547 13335533574 0022233 0 ustar 00root root 0000000 0000000 # Configuration for sumitting the test result.
# Check http://www.freediameter.net/CDash for detail.
set(CTEST_PROJECT_NAME "freeDiameter")
set(CTEST_NIGHTLY_START_TIME "00:00:00 JST")
set(CTEST_DROP_METHOD "http")
set(CTEST_DROP_SITE "www.freediameter.net")
set(CTEST_DROP_LOCATION "/CDash/submit.php?project=freeDiameter")
set(CTEST_DROP_SITE_CDASH TRUE)
nextepc-0.3.10/lib/freeDiameter-1.2.1/INSTALL 0000664 0000000 0000000 00000002663 13335533574 0020113 0 ustar 00root root 0000000 0000000 This package uses CMake (cmake.org) as building system. You'll need the cmake tool in order
to generate the Makefiles for your platform. You can also select which extensions must be built
with cmake. After the initial cmake configuration, you will need several tools such as make, a
C compiler (tested mostly with gcc), flex (> 2.5.4), bison, ...
You may retrieve the source package in several ways:
- as a pre-packaged version for your platform. Check the website for supported platforms.
- as a tarball containing the source.
- directly from the repository using Mercurial tool:
hg clone http://www.freediameter.net/hg/freeDiameter
In order to update later:
hg pull -u
Building in a separate directory is recommended:
# mkdir build
# cd build
# cmake ../
# make
You can pass options to instruct cmake about which components to compile on the command-line.
You can also use a CMake front-end (for example ccmake or cmake-gui).
If your cmake installation is recent, the edit_cache target is a good help as well:
# mkdir build
# cd build
# cmake ../
# make help
# make edit_cache
# make
You can disable the unit tests by doing:
# cmake -DBUILD_TESTING:BOOL=OFF ../
# make
When the tests are enabled, you can run them with:
# make test
See the INSTALL.* files for additional platform-specific information.
Note that the most up-to-date INSTALL file is the Ubuntu one. You may want to read there
in addition to your own platform file.
nextepc-0.3.10/lib/freeDiameter-1.2.1/INSTALL.Fedora 0000664 0000000 0000000 00000002261 13335533574 0021304 0 ustar 00root root 0000000 0000000 ### Very short install notes for Fedora (tested on Fedora 13 and 14)
# Please refer to other INSTALL files for more detailed instructions (e.g. extension-specific notes).
Dependencies on Fedora 13 (from minimal system):
# yum install cmake make gcc gcc-c++ flex bison lksctp-tools-devel gnutls-devel libgcrypt-devel libidn-devel
In addition, if you have not already retrieved the latest source:
# yum install mercurial
Following dependencies are optional, depending on which extensions you plan to compile
app_acct:
# yum install postgresql-devel
optional:
# yum install postgresql-server
app_sip:
app_diameap:
# yum install mysql-devel
optional:
# yum install mysql-server
dict_legacy_xml:
# yum install libxml2 libxml2-devel
dbg_interactive:
# yum install swig python-devel
NOTE: You may need to change something in SELinux to allow binding the SCTP socket on Diameter port.
The following command is the very naive way to do it, you can probably do better (feedback appreciated!)
# setenforce Permissive
There is currently no Fedora-specific package for freeDiameter.
You are welcome to contribute packaging scripts.
Please contact dev@freediameter.net for more details.
nextepc-0.3.10/lib/freeDiameter-1.2.1/INSTALL.FreeBSD 0000664 0000000 0000000 00000006654 13335533574 0021330 0 ustar 00root root 0000000 0000000 See INSTALL file for general instructions on building freeDiameter.
------------------
QUICK INSTRUCTIONS
------------------
On FreeBSD-8.0 at least the following ports packages were required (should be same on FreeBSD-7.x):
cmake flex bison gnutls
Then the cmake command had to look like:
cmake -DFLEX_EXECUTABLE:FILEPATH=/usr/local/bin/flex -DSCTP_USE_MAPPED_ADDRESSES:BOOL=ON ...
---------------------
COMPLETE INSTRUCTIONS
---------------------
1) If you don't have freeBSD yet:
Install minimal system + ports using initial installer /usr/sbin/sysinstall
2) Install 'cmake'
a) from sources:
# cd /usr/ports/devel/cmake
# make install
b) or from package (don't forget to set your PACKAGEROOT appropriately. Ex: set PACKAGEROOT=ftp://ftp.jp.freebsd.org):
# pkg_add -v -r cmake
3) Install 'mercurial' (optional)
(replace 'cmake' by 'mercurial' in the previous command)
4) Install 'flex' and 'bison', same way.
5) Install 'gnutls' and 'libidn', same way also.
6) Retrieve freeDiameter source code:
# cd ~
# /usr/local/bin/hg clone http://www.freediameter.net/hg/freeDiameter/
6b) Make a build directory
# mkdir fD-build
# cd fD-build
7) Run cmake for freeDiameter (add other flags as you see fit, see INSTALL for more details)
# /usr/local/bin/cmake -DFLEX_EXECUTABLE:FILEPATH=/usr/local/bin/flex -DSCTP_USE_MAPPED_ADDRESSES:BOOL=ON ../freeDiameter
8) Compile, optionnaly test
# make
# make test
9) Install
# make install
10) Run (the install path can be changed during cmake step):
# /usr/local/bin/freeDiameterd --help
------------------------------
app_acct test ADDITIONAL STEPS
------------------------------
Here is additional steps in order to run the test for app_acct
1) Install the required packages
# pkg_add -v -r postgresql84-client
# pkg_add -v -r postgresql84-server
2) Prepare access to the database:
# echo postgresql_enable=YES >> /etc/rc.conf
# /usr/local/etc/rc.d/postgresql initdb
# su - pgsql
> /usr/local/bin/pg_ctl -D /usr/local/pgsql/data -l logfile start
> /usr/local/bin/createuser root
Shall the new user be allowed to create databases? (y/n) y
> logout
# /usr/local/bin/createdb root
# /usr/local/bin/psql root
root=# CREATE TABLE incoming_test (
root(# recorded_on timestamp with time zone NOT NULL,
root(# "Accounting-Record-Type" integer,
root(# "Session-Id" bytea,
root(# "Accounting-Record-Number" integer,
root(# "Route-Record1" bytea,
root(# "Route-Record2" bytea,
root(# "Route-Record3" bytea,
root(# "Route-Record4" bytea );
root=# \q
3) configure the sources
# make edit_cache
BUILD_APP_ACCT:BOOL=ON
TEST_APP_ACCT:BOOL=ON
TEST_APP_ACCT_CONNINFO:STRING="user=root dbname=root"
4) run the test
# tests/testappacct -d
or
# make test
----------------------------------
Segmentation fault on program exit
----------------------------------
In case you encounter a segmentation fault on program termination like this:
[...]
freeDiameterd framework is terminated.
Segmentation fault: 11 (core dumped)
with a backtrace like this:
#0 0x0000000801a414a0 in ?? ()
#1 0x0000000800f99274 in __cxa_finalize () from /lib/libc.so.7
#2 0x0000000800f460b7 in exit () from /lib/libc.so.7
You may try to add the following compilation directive in cmake:
-DSKIP_DLCLOSE:BOOL=ON
Note: this segmentation fault was experienced with:
- FreeBSD 8.1
- 64 bits architecture only.
- Profiling mode only.
nextepc-0.3.10/lib/freeDiameter-1.2.1/INSTALL.OSX 0000664 0000000 0000000 00000004714 13335533574 0020562 0 ustar 00root root 0000000 0000000 See INSTALL file for general instructions on building freeDiameter.
------------------
QUICK INSTRUCTIONS
------------------
Starting from version 1.1.5, freeDiameter is available through Homebrew:
1) Install Homebrew
a) Install Command Line Tools for Xcode or Xcode:
- Command Line Tools (your OS X Version) for Xcode:
https://developer.apple.com/downloads (Free Apple Developer ID Registration Required)
- or Xcode:
https://itunes.apple.com/us/app/xcode/id497799835 (Free App Store Account Required)
b) Install Homebrew
$ ruby -e "$(curl -fsSkL raw.github.com/mxcl/homebrew/go)"
2) Install freeDiameter:
$ brew install freediameter
After installation is done "Caveats" section will provide information
how to start freeDiameterd through launchd at system startup.
To view this information again:
$ brew info freediameter
To learn more about freeDiameter configuration options, read:
http://www.freediameter.net/trac/wiki/Configuration
For more information on available extension and how to configure them, read:
http://www.freediameter.net/trac/wiki/Extensions
------------
FROM SOURCES
------------
1) Install Homebrew:
See QUICK INSTRUCTIONS Step #1 above.
2) Install dependencies:
$ brew install mercurial cmake gnutls libgcrypt postgres mysql libidn
Notes:
* GNU IDN (libidn) is optional, see below
* When libusrsctp package is available, you can use it as well.
However, it requires some rework on the source code as libusrsctp is not fully
compliant with the other SCTP stack.
3) Retrieve source code:
$ hg clone http://www.freediameter.net/hg/freeDiameter
4) Enter source folder:
$ cd freeDiameter
5) Create build folder:
$ mkdir freeDiameter-build
6) Enter build folder:
$ cd freeDiameter-build
7) Configure:
$ cmake .. -DDISABLE_SCTP:BOOL=ON
or for ncurses-based configuration:
$ ccmake .. -DDISABLE_SCTP:BOOL=ON
Notes:
* GNU IDN (Support for International Domain Names) can be disabled with:
-DDIAMID_IDNA_IGNORE=ON or -DDIAMID_IDNA_REJECT=ON
* For more information on available configuration options, read:
http://www.freediameter.net/trac/wiki/Installation
8) Compile:
$ make
9) Install (might require to be root):
$ make install
------------------------------------------------
These instructions have been tested on OS X:
- 10.6.8 (Snow Leopard)
- 10.7.5 (Lion)
- 10.8.2 (Mountain Lion)
nextepc-0.3.10/lib/freeDiameter-1.2.1/INSTALL.OpenSUSE 0000664 0000000 0000000 00000001747 13335533574 0021515 0 ustar 00root root 0000000 0000000 ### Very short install notes for OpenSUSE (tested on OpenSUSE 11.3)
# Please refer to other INSTALL files for more detailed instructions (e.g. extension-specific notes).
Dependencies on OpenSUSE 11.3 (from minimal server system installation):
# zypper install cmake make gcc gcc-c++ flex bison lksctp-tools-devel libgnutls-devel libgcrypt-devel libidn-devel
# zypper install mercurial
Following dependencies are optional, depending on which extensions you plan to compile
app_acct:
# zypper install postgresql-server postgresql-devel
app_sip:
app_diameap:
# zypper install libmysqlclient-devel
(would also need a server, not sure which package is appropriate)
dict_legacy_xml:
# zypper install libxml2 libxml2-devel
dbg_interactive:
# zypper install swig python-devel
sample:
# zypper install gcc-c++
There is currently no OpenSUSE-specific package for freeDiameter.
You are welcome to contribute packaging scripts! Please contact with
dev@freediameter.net for more details.
nextepc-0.3.10/lib/freeDiameter-1.2.1/INSTALL.OpenWRT 0000664 0000000 0000000 00000000173 13335533574 0021402 0 ustar 00root root 0000000 0000000 There is a package script available for the OpenWRT platform.
Please refer to contrib/OpenWRT/HOWTO for more information.
nextepc-0.3.10/lib/freeDiameter-1.2.1/INSTALL.Ubuntu 0000664 0000000 0000000 00000007537 13335533574 0021401 0 ustar 00root root 0000000 0000000 See http://www.freediameter.net/trac/wiki/DebRepository for instructions on how to
install freeDiameter from existing package.
See INSTALL file for general instructions on building freeDiameter from sources.
The remaining of this file contains specific instructions for building the freeDiameter
package files for Debian and Ubuntu systems.
freeDiameter is shipped with the necessary files to generate the Debian package.
All related files are in the directory "contrib/debian" of the distribution.
As a first step, you have to link this directory from your top-level dir:
ln -s contrib/debian
============================================
The following packages are required to compile freeDiameter from source:
cmake make gcc g++ flex bison libsctp1 libsctp-dev libgnutls-dev libgcrypt-dev libidn11-dev
(note that libidn and libsctp can be avoided by defining DISABLE_SCTP and DIAMID_IDNA_REJECT)
Additionnaly, these ones may be useful:
mercurial gdb
Extensions additional dependencies:
app_acct:
libpq-dev
app_sip:
app_diameap:
libmysqlclient-dev
dict_legacy_xml:
libxml2-dev
dbg_interactive:
swig python-dev
============================================
If your debhelper environment is recent (> 7.3.9 for cmake support),
the following commands should generate the freeDiameter packages for you:
# Install the dependencies for building the source:
sudo apt-get -y install mercurial cmake make gcc g++ bison flex libsctp-dev libgnutls-dev libgcrypt-dev libidn11-dev ssl-cert debhelper fakeroot \
libpq-dev libmysqlclient-dev libxml2-dev swig python-dev
# Retrieve the latest version of the source package
cd
hg clone http://www.freediameter.net/hg/freeDiameter
cd freeDiameter
# Prepare for Debian package
ln -s contrib/debian
# Build the packages
fakeroot dh binary
# Install the packages
cd ..
sudo dpkg -i *.deb
# The following lines may help you getting started.... (execute as root)
ln -s /etc/ssl/certs/ssl-cert-snakeoil.pem /etc/ssl/certs/freeDiameter.pem
ln -s /etc/ssl/private/ssl-cert-snakeoil.key /etc/ssl/private/freeDiameter.key
zcat /usr/share/doc/freediameter-daemon/examples/freediameter.conf.sample.gz > /etc/freeDiameter/freeDiameter.conf
echo "Identity=\"localhost.localdomain\";" >> /etc/freeDiameter/freeDiameter.conf
freeDiameterd
===========================================
freeDiameter is tested regularly on all current Ubuntu distributions since Intrepid (compiled from source as described below)
Ubuntu Hardy support is known to be broken.
The Debian package has been generated with success on Debian (>=Squeeze) and Ubuntu (>=Karmic).
===========================================-
Step by step instructions without using the debhelper tools:
1) Install all packages dependencies
# sudo apt-get install mercurial cmake make gcc g++ bison flex libsctp-dev libgnutls-dev libgcrypt-dev libidn11-dev
2) (OPTION) If you will compile modules that require postgresql, also install:
# sudo apt-get install libpq-dev
and for mysql:
# sudo apt-get install libmysqlclient-dev
3) (OPTION) If you want a more user-friendly interface, install this:
# sudo apt-get install cmake-curses-gui
4) Retrieve the source files
# hg clone http://www.freediameter.net/hg/freeDiameter
5) Create a build directory, and enter it
# mkdir fDbuild
# cd fDbuild
6) Configure and generate the Makefiles
# cmake ../freeDiameter
# make edit_cache
7) Compile all files:
# make
8) (OPTION) See available targets:
# make help
9) (OPTION) Check the software has a correct basic behavior on your environment. -- only if you did not disable the tests in step 6
# make test
10) (OPTION) Install the software in configured locations:
# sudo make install
===========================================
Note: On Ubuntu Quantal Quetzal, you may have to force use of python 2.7
library for the dbg_interactive extension, as on some systems CMake selects the 3.2 library
by default.
nextepc-0.3.10/lib/freeDiameter-1.2.1/INSTALL.pkgsrc 0000664 0000000 0000000 00000001205 13335533574 0021372 0 ustar 00root root 0000000 0000000 The simplest way to install on NetBSD, DragonFly, MirBSD or other
pkgsrc platforms is:
pkg_add freeDiameter
If no binary package exists:
cd /usr/pkgsrc/net/freeDiameter
make install
If you want to build and install freeDiameter from the repository,
you'll need to install:
pkg_add bison pkg-config libidn gnutls libgcrypt mercurial
and follow the usual installation note.
NetBSD does not support SCTP, so you have to add
-DDISABLE_SCTP:BOOL=ON
to the cmake command line.
For the optional extensions, you need mysql*-client, postgres*-client,
libxml2. For the debugging extensions, you also need swig and a
python -- install as usual.
nextepc-0.3.10/lib/freeDiameter-1.2.1/LICENSE 0000664 0000000 0000000 00000004111 13335533574 0020055 0 ustar 00root root 0000000 0000000 Unless specified otherwise, this software package is copyrighted under the terms of the BSD license, as follow:
Software License Agreement (BSD License)
Copyright (c) 2008-2011, WIDE Project and NICT
All rights reserved.
Redistribution and use of this software in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the WIDE Project or NICT nor the
names of its contributors may be used to endorse or
promote products derived from this software without
specific prior written permission of WIDE Project and
NICT.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The following authors have contributed the following files. See source files for copyright information.
* Alexandre Westfahl:
extensions/dict_sip/*
extensions/app_sip/*
extensions/app_radgw/rgwx_sip.c
* Souheil Ben Ayed:
extensions/app_diameap/*
* Francois Bard:
extensions/dict_mip6a/*
extensions/dict_mip6i/*
extensions/dict_nas_mipv6/*
extensions/dict_rfc5777/*
nextepc-0.3.10/lib/freeDiameter-1.2.1/Makefile.am 0000664 0000000 0000000 00000001176 13335533574 0021114 0 ustar 00root root 0000000 0000000 ## Process this file with automake to produce Makefile.in
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = libfdproto libfdcore extensions
MAINTAINERCLEANFILES = \
configure include/freeDiameter/config.h.in \
aclocal.m4 m4/ltsugar.m4 m4/libtool.m4 m4/ltversion.m4 \
m4/lt~obsolete.m4 m4/ltoptions.m4 \
build-aux/ar-lib build-aux/config.guess build-aux/depcomp \
build-aux/ltmain.sh build-aux/test-driver build-aux/compile \
build-aux/config.sub build-aux/missing build-aux/install-sh \
build-aux/ylwrap \
Makefile.in \
include/freeDiameter/version.h libfdcore/fdd.tab.y libfdcore/lex.fdd.l
MOSTLYCLEANFILES = core *.stackdump
nextepc-0.3.10/lib/freeDiameter-1.2.1/NEWS 0000664 0000000 0000000 00000000337 13335533574 0017555 0 ustar 00root root 0000000 0000000 The digested changelog can be found under:
contrib/debian/changelog
You can also find the exhaustive list of change using mercurial history,
or at the following URL: http://www.freediameter.net/hg/freeDiameter/shortlog
nextepc-0.3.10/lib/freeDiameter-1.2.1/README 0000664 0000000 0000000 00000004106 13335533574 0017734 0 ustar 00root root 0000000 0000000 freeDiameter is an implementation of the Diameter protocol.
Diameter is a protocol designed to carry Authentication, Authorization and
Accounting (AAA) payload. It is an evolution of the RADIUS protocol (as the
name suggests).
Diameter is an extensible protocol. RFC3588 (currently under revision) defines the
Base Protocol that all Diameter nodes must support, while other documents define
the additional protocol support for specific applications. Such applications include
for example Network Access Servers (RFC4005), EAP (RFC4072), ...
The implementation consists in several components:
- libfdproto : this shared library provides the functions to manipulate Diameter
messages and dictionary. This library is meant to be re-used by other projects
that would require parsing or manipulating Diameter messages.
- libfdcore : this shared library contains the core of the framework. It establishes
the network connections with other Diameter peers and performs the tasks described
in Diameter Base Protocol, such as watchdogs, basic routing, ... It also handles
the loading of extensions (see below).
- freeDiameterd : this simple daemon parses the command line and initializes the
freeDiameter framework. Use it for your Diameter server & agent components.
In case of Diameter clients, you probably will prefer linking the libfdcore
directly with your client application that must be made Diameter-aware.
- extensions : the extensions provide the mean to augment the features of the
freeDiameterd framework. Extensions can provide the handling of a Diameter
server application, but also advanced routing features, peer management, etc.
See http://www.freediameter.net/ for more information on the project.
freeDiameter was previously known as the "waaad" project (WIDE AAA Daemon)
This project is not related to the "freediameter" project from Sun on sourceforge.
Author: Sebastien Decugis.
See LICENSE file for legal information on this software.
See INSTALL for information on building and using this software.
nextepc-0.3.10/lib/freeDiameter-1.2.1/cmake/ 0000775 0000000 0000000 00000000000 13335533574 0020133 5 ustar 00root root 0000000 0000000 nextepc-0.3.10/lib/freeDiameter-1.2.1/cmake/Modules/ 0000775 0000000 0000000 00000000000 13335533574 0021543 5 ustar 00root root 0000000 0000000 nextepc-0.3.10/lib/freeDiameter-1.2.1/cmake/Modules/CMakeUserUseBison.cmake 0000664 0000000 0000000 00000005534 13335533574 0026043 0 ustar 00root root 0000000 0000000 # - Look for GNU Bison, the parser generator
# Based off a news post from Andy Cedilnik at Kitware
# Defines the following:
# BISON_EXECUTABLE - path to the bison executable
# BISON_FILE - parse a file with bison
# BISON_PREFIX_OUTPUTS - Set to true to make BISON_FILE produce prefixed
# symbols in the generated output based on filename.
# So for ${filename}.y, you'll get ${filename}parse(), etc.
# instead of yyparse().
# BISON_GENERATE_DEFINES - Set to true to make BISON_FILE output the matching
# .h file for a .c file. You want this if you're using
# flex.
IF(NOT DEFINED BISON_PREFIX_OUTPUTS)
SET(BISON_PREFIX_OUTPUTS FALSE)
ENDIF(NOT DEFINED BISON_PREFIX_OUTPUTS)
IF(NOT DEFINED BISON_GENERATE_DEFINES)
SET(BISON_GENERATE_DEFINES FALSE)
ENDIF(NOT DEFINED BISON_GENERATE_DEFINES)
IF(NOT BISON_EXECUTABLE)
MESSAGE(STATUS "Looking for bison")
FIND_PROGRAM(BISON_EXECUTABLE bison)
IF(BISON_EXECUTABLE)
MESSAGE(STATUS "Looking for bison -- ${BISON_EXECUTABLE}")
ENDIF(BISON_EXECUTABLE)
MARK_AS_ADVANCED(BISON_EXECUTABLE)
ENDIF(NOT BISON_EXECUTABLE)
IF(BISON_EXECUTABLE)
MACRO(BISON_FILE FILENAME)
GET_FILENAME_COMPONENT(PATH "${FILENAME}" PATH)
IF("${PATH}" STREQUAL "")
SET(PATH_OPT "")
ELSE("${PATH}" STREQUAL "")
SET(PATH_OPT "/${PATH}")
ENDIF("${PATH}" STREQUAL "")
GET_FILENAME_COMPONENT(HEAD "${FILENAME}" NAME_WE)
IF(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}")
FILE(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}")
ENDIF(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}")
IF(BISON_PREFIX_OUTPUTS)
SET(PREFIX "${HEAD}")
ELSE(BISON_PREFIX_OUTPUTS)
SET(PREFIX "yy")
ENDIF(BISON_PREFIX_OUTPUTS)
SET(OUTFILE "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}/${HEAD}.tab.c")
IF(BISON_GENERATE_DEFINES)
SET(HEADER "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}/${HEAD}.tab.h")
ADD_CUSTOM_COMMAND(
OUTPUT "${OUTFILE}" "${HEADER}"
COMMAND "${BISON_EXECUTABLE}"
ARGS "--name-prefix=${PREFIX}"
"--defines"
"--output-file=${OUTFILE}"
"${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}")
SET_SOURCE_FILES_PROPERTIES("${OUTFILE}" "${HEADER}" PROPERTIES GENERATED TRUE)
SET_SOURCE_FILES_PROPERTIES("${HEADER}" PROPERTIES HEADER_FILE_ONLY TRUE)
ELSE(BISON_GENERATE_DEFINES)
ADD_CUSTOM_COMMAND(
OUTPUT "${OUTFILE}"
COMMAND "${BISON_EXECUTABLE}"
ARGS "--name-prefix=${PREFIX}"
"--output-file=${OUTFILE}"
"${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}")
SET_SOURCE_FILES_PROPERTIES("${OUTFILE}" PROPERTIES GENERATED TRUE)
ENDIF(BISON_GENERATE_DEFINES)
ENDMACRO(BISON_FILE)
ENDIF(BISON_EXECUTABLE)
nextepc-0.3.10/lib/freeDiameter-1.2.1/cmake/Modules/CMakeUserUseFlex.cmake 0000664 0000000 0000000 00000003300 13335533574 0025654 0 ustar 00root root 0000000 0000000 # - Look for GNU flex, the lexer generator.
# Defines the following:
# FLEX_EXECUTABLE - path to the flex executable
# FLEX_FILE - parse a file with flex
# FLEX_PREFIX_OUTPUTS - Set to true to make FLEX_FILE produce outputs of
# lex.${filename}.c, not lex.yy.c . Passes -P to flex.
IF(NOT DEFINED FLEX_PREFIX_OUTPUTS)
SET(FLEX_PREFIX_OUTPUTS FALSE)
ENDIF(NOT DEFINED FLEX_PREFIX_OUTPUTS)
IF(NOT FLEX_EXECUTABLE)
MESSAGE(STATUS "Looking for flex")
FIND_PROGRAM(FLEX_EXECUTABLE flex)
IF(FLEX_EXECUTABLE)
MESSAGE(STATUS "Looking for flex -- ${FLEX_EXECUTABLE}")
ENDIF(FLEX_EXECUTABLE)
MARK_AS_ADVANCED(FLEX_EXECUTABLE)
ENDIF(NOT FLEX_EXECUTABLE)
IF(FLEX_EXECUTABLE)
MACRO(FLEX_FILE FILENAME)
GET_FILENAME_COMPONENT(PATH "${FILENAME}" PATH)
IF("${PATH}" STREQUAL "")
SET(PATH_OPT "")
ELSE("${PATH}" STREQUAL "")
SET(PATH_OPT "/${PATH}")
ENDIF("${PATH}" STREQUAL "")
IF(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}")
FILE(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}")
ENDIF(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}")
IF(FLEX_PREFIX_OUTPUTS)
GET_FILENAME_COMPONENT(PREFIX "${FILENAME}" NAME_WE)
ELSE(FLEX_PREFIX_OUTPUTS)
SET(PREFIX "yy")
ENDIF(FLEX_PREFIX_OUTPUTS)
SET(OUTFILE "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}/lex.${PREFIX}.c")
ADD_CUSTOM_COMMAND(
OUTPUT "${OUTFILE}"
COMMAND "${FLEX_EXECUTABLE}"
ARGS "-P${PREFIX}"
"-o${OUTFILE}"
"${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}")
SET_SOURCE_FILES_PROPERTIES("${OUTFILE}" PROPERTIES GENERATED TRUE)
ENDMACRO(FLEX_FILE)
ENDIF(FLEX_EXECUTABLE)
nextepc-0.3.10/lib/freeDiameter-1.2.1/cmake/Modules/FindGcrypt.cmake 0000664 0000000 0000000 00000002011 13335533574 0024610 0 ustar 00root root 0000000 0000000 # - Find gnutls
# Find the native GCRYPT includes and library
#
# GCRYPT_FOUND - True if gnutls found.
# GCRYPT_INCLUDE_DIR - where to find gnutls.h, etc.
# GCRYPT_LIBRARIES - List of libraries when using gnutls.
if (GCRYPT_INCLUDE_DIR AND GCRYPT_LIBRARIES)
set(GCRYPT_FIND_QUIETLY TRUE)
endif (GCRYPT_INCLUDE_DIR AND GCRYPT_LIBRARIES)
# Include dir
find_path(GCRYPT_INCLUDE_DIR
NAMES
gcrypt.h
)
# Library
find_library(GCRYPT_LIBRARY
NAMES gcrypt
)
# handle the QUIETLY and REQUIRED arguments and set GCRYPT_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GCRYPT DEFAULT_MSG GCRYPT_LIBRARY GCRYPT_INCLUDE_DIR)
IF(GCRYPT_FOUND)
SET( GCRYPT_LIBRARIES ${GCRYPT_LIBRARY} )
ELSE(GCRYPT_FOUND)
SET( GCRYPT_LIBRARIES )
ENDIF(GCRYPT_FOUND)
# Lastly make it so that the GCRYPT_LIBRARY and GCRYPT_INCLUDE_DIR variables
# only show up under the advanced options in the gui cmake applications.
MARK_AS_ADVANCED( GCRYPT_LIBRARY GCRYPT_INCLUDE_DIR )
nextepc-0.3.10/lib/freeDiameter-1.2.1/cmake/Modules/FindGnuTLS.cmake 0000664 0000000 0000000 00000005247 13335533574 0024472 0 ustar 00root root 0000000 0000000 # - Find gnutls
# Find the native GNUTLS includes and library
#
# GNUTLS_FOUND - True if gnutls found.
# GNUTLS_INCLUDE_DIR - where to find gnutls.h, etc.
# GNUTLS_LIBRARIES - List of libraries when using gnutls.
# GNUTLS_VERSION_210 - true if GnuTLS version is >= 2.10.0 (does not require additional separate gcrypt initialization)
# GNUTLS_VERSION_212 - true if GnuTLS version is >= 2.12.0 (supports gnutls_transport_set_vec_push_function)
# GNUTLS_VERSION_300 - true if GnuTLS version is >= 3.00.0 (x509 verification functions changed)
# GNUTLS_VERSION_310 - true if GnuTLS version is >= 3.01.0 (stabilization branch with new APIs)
if (GNUTLS_INCLUDE_DIR AND GNUTLS_LIBRARIES)
set(GNUTLS_FIND_QUIETLY TRUE)
endif (GNUTLS_INCLUDE_DIR AND GNUTLS_LIBRARIES)
# Include dir
find_path(GNUTLS_INCLUDE_DIR
NAMES
gnutls.h
gnutls/gnutls.h
)
# Library
find_library(GNUTLS_LIBRARY
NAMES gnutls
)
# handle the QUIETLY and REQUIRED arguments and set GNUTLS_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNUTLS DEFAULT_MSG GNUTLS_LIBRARY GNUTLS_INCLUDE_DIR)
IF(GNUTLS_FOUND)
SET( GNUTLS_LIBRARIES ${GNUTLS_LIBRARY} )
ELSE(GNUTLS_FOUND)
SET( GNUTLS_LIBRARIES )
ENDIF(GNUTLS_FOUND)
# Lastly make it so that the GNUTLS_LIBRARY and GNUTLS_INCLUDE_DIR variables
# only show up under the advanced options in the gui cmake applications.
MARK_AS_ADVANCED( GNUTLS_LIBRARY GNUTLS_INCLUDE_DIR )
# Now check if the library is recent. gnutls_hash was added in 2.10.0.
# Also test library is even more recent. gnutls_x509_trust_list_verify_crt was added in 3.00.0.
IF(GNUTLS_FOUND)
IF( NOT( "${GNUTLS_VERSION_TEST_FOR}" STREQUAL "${GNUTLS_LIBRARY}" ))
INCLUDE (CheckLibraryExists)
MESSAGE(STATUS "Checking GNUTLS version")
UNSET(GNUTLS_VERSION_210)
UNSET(GNUTLS_VERSION_210 CACHE)
UNSET(GNUTLS_VERSION_212)
UNSET(GNUTLS_VERSION_212 CACHE)
UNSET(GNUTLS_VERSION_300)
UNSET(GNUTLS_VERSION_300 CACHE)
UNSET(GNUTLS_VERSION_310)
UNSET(GNUTLS_VERSION_310 CACHE)
GET_FILENAME_COMPONENT(GNUTLS_PATH ${GNUTLS_LIBRARY} PATH)
CHECK_LIBRARY_EXISTS(gnutls gnutls_hash ${GNUTLS_PATH} GNUTLS_VERSION_210)
CHECK_LIBRARY_EXISTS(gnutls gnutls_transport_set_vec_push_function ${GNUTLS_PATH} GNUTLS_VERSION_212)
CHECK_LIBRARY_EXISTS(gnutls gnutls_x509_trust_list_verify_crt ${GNUTLS_PATH} GNUTLS_VERSION_300)
CHECK_LIBRARY_EXISTS(gnutls gnutls_handshake_set_timeout ${GNUTLS_PATH} GNUTLS_VERSION_310)
SET( GNUTLS_VERSION_TEST_FOR ${GNUTLS_LIBRARY} CACHE INTERNAL "Version the test was made against" )
ENDIF (NOT( "${GNUTLS_VERSION_TEST_FOR}" STREQUAL "${GNUTLS_LIBRARY}" ))
ENDIF(GNUTLS_FOUND)
nextepc-0.3.10/lib/freeDiameter-1.2.1/cmake/Modules/FindIDNA.cmake 0000664 0000000 0000000 00000002173 13335533574 0024064 0 ustar 00root root 0000000 0000000 # - Try to find GNU IDN library and headers
# Once done, this will define
#
# IDNA_FOUND - system has IDNA
# IDNA_INCLUDE_DIR - the IDNA include directories ()
# IDNA_LIBRARIES - link these to use IDNA (idna_to_ascii_8z)
if (IDNA_INCLUDE_DIR AND IDNA_LIBRARIES)
set(IDNA_FIND_QUIETLY TRUE)
endif (IDNA_INCLUDE_DIR AND IDNA_LIBRARIES)
# Include dir
find_path(IDNA_INCLUDE_DIR
NAMES idna.h
)
# Library
find_library(IDNA_LIBRARY
NAMES idn
)
# handle the QUIETLY and REQUIRED arguments and set IDNA_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(IDNA DEFAULT_MSG IDNA_LIBRARY IDNA_INCLUDE_DIR)
# If we successfully found the idn library then add the library to the
# IDNA_LIBRARIES cmake variable otherwise set IDNA_LIBRARIES to nothing.
IF(IDNA_FOUND)
SET( IDNA_LIBRARIES ${IDNA_LIBRARY} )
ELSE(IDNA_FOUND)
SET( IDNA_LIBRARIES )
ENDIF(IDNA_FOUND)
# Lastly make it so that the IDNA_LIBRARY and IDNA_INCLUDE_DIR variables
# only show up under the advanced options in the gui cmake applications.
MARK_AS_ADVANCED( IDNA_LIBRARY IDNA_INCLUDE_DIR )
nextepc-0.3.10/lib/freeDiameter-1.2.1/cmake/Modules/FindLibXml2.cmake 0000664 0000000 0000000 00000003740 13335533574 0024623 0 ustar 00root root 0000000 0000000 # - Try to find the LibXml2 xml processing library
# Once done this will define
#
# LIBXML2_FOUND - System has LibXml2
# LIBXML2_INCLUDE_DIR - The LibXml2 include directory
# LIBXML2_LIBRARIES - The libraries needed to use LibXml2
# LIBXML2_DEFINITIONS - Compiler switches required for using LibXml2
# LIBXML2_XMLLINT_EXECUTABLE - The XML checking tool xmllint coming with LibXml2
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
# Copyright 2006 Alexander Neundorf
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distributed this file outside of CMake, substitute the full
# License text for the above reference.)
# use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
FIND_PACKAGE(PkgConfig)
PKG_CHECK_MODULES(PC_LIBXML libxml-2.0)
SET(LIBXML2_DEFINITIONS ${PC_LIBXML_CFLAGS_OTHER})
FIND_PATH(LIBXML2_INCLUDE_DIR NAMES libxml/xpath.h
HINTS
${PC_LIBXML_INCLUDEDIR}
${PC_LIBXML_INCLUDE_DIRS}
PATH_SUFFIXES libxml2
)
FIND_LIBRARY(LIBXML2_LIBRARIES NAMES xml2 libxml2
HINTS
${PC_LIBXML_LIBDIR}
${PC_LIBXML_LIBRARY_DIRS}
)
FIND_PROGRAM(LIBXML2_XMLLINT_EXECUTABLE xmllint)
# for backwards compat. with KDE 4.0.x:
SET(XMLLINT_EXECUTABLE "${LIBXML2_XMLLINT_EXECUTABLE}")
# handle the QUIETLY and REQUIRED arguments and set LIBXML2_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARIES LIBXML2_INCLUDE_DIR)
MARK_AS_ADVANCED(LIBXML2_INCLUDE_DIR LIBXML2_LIBRARIES LIBXML2_XMLLINT_EXECUTABLE)
nextepc-0.3.10/lib/freeDiameter-1.2.1/cmake/Modules/FindMySQL.cmake 0000664 0000000 0000000 00000002535 13335533574 0024320 0 ustar 00root root 0000000 0000000 # - Find mysqlclient
#
# -*- cmake -*-
#
# Find the native MySQL includes and library
#
# MySQL_INCLUDE_DIR - where to find mysql.h, etc.
# MySQL_LIBRARIES - List of libraries when using MySQL.
# MySQL_FOUND - True if MySQL found.
IF (MySQL_INCLUDE_DIR AND MySQL_LIBRARY)
# Already in cache, be silent
SET(MySQL_FIND_QUIETLY TRUE)
ENDIF (MySQL_INCLUDE_DIR AND MySQL_LIBRARY)
# Include dir
FIND_PATH(MySQL_INCLUDE_DIR
NAMES mysql.h
PATH_SUFFIXES mysql
)
# Library
#SET(MySQL_NAMES mysqlclient mysqlclient_r)
#SET(MySQL_NAMES mysqlclient_r)
SET(MySQL_NAMES mysqlclient_r mysqlclient)
FIND_LIBRARY(MySQL_LIBRARY
NAMES ${MySQL_NAMES}
PATHS /usr/lib /usr/local/lib
PATH_SUFFIXES mysql
)
IF (MySQL_INCLUDE_DIR AND MySQL_LIBRARY)
SET(MySQL_FOUND TRUE)
SET( MySQL_LIBRARIES ${MySQL_LIBRARY} )
ELSE (MySQL_INCLUDE_DIR AND MySQL_LIBRARY)
SET(MySQL_FOUND FALSE)
SET( MySQL_LIBRARIES )
ENDIF (MySQL_INCLUDE_DIR AND MySQL_LIBRARY)
IF (MySQL_FOUND)
IF (NOT MySQL_FIND_QUIETLY)
MESSAGE(STATUS "Found MySQL: ${MySQL_LIBRARY}")
ENDIF (NOT MySQL_FIND_QUIETLY)
ELSE (MySQL_FOUND)
IF (MySQL_FIND_REQUIRED)
MESSAGE(STATUS "Looked for MySQL libraries named ${MySQL_NAMES}.")
MESSAGE(FATAL_ERROR "Could NOT find MySQL library")
ENDIF (MySQL_FIND_REQUIRED)
ENDIF (MySQL_FOUND)
MARK_AS_ADVANCED(
MySQL_LIBRARY
MySQL_INCLUDE_DIR
)
nextepc-0.3.10/lib/freeDiameter-1.2.1/cmake/Modules/FindPostgreSQL.cmake 0000664 0000000 0000000 00000002174 13335533574 0025355 0 ustar 00root root 0000000 0000000 # - Find PostgreSQL library
#
# This module defines:
# POSTGRESQL_FOUND - True if the package is found
# POSTGRESQL_INCLUDE_DIR - containing libpq-fe.h
# POSTGRESQL_LIBRARIES - Libraries to link to use PQ functions.
if (POSTGRESQL_INCLUDE_DIR AND POSTGRESQL_LIBRARIES)
set(POSTGRESQL_FIND_QUIETLY TRUE)
endif (POSTGRESQL_INCLUDE_DIR AND POSTGRESQL_LIBRARIES)
# Include dir
find_path(POSTGRESQL_INCLUDE_DIR
NAMES libpq-fe.h
PATH_SUFFIXES pgsql postgresql
)
# Library
find_library(POSTGRESQL_LIBRARY
NAMES pq
)
# handle the QUIETLY and REQUIRED arguments and set POSTGRESQL_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(POSTGRESQL DEFAULT_MSG POSTGRESQL_LIBRARY POSTGRESQL_INCLUDE_DIR)
IF(POSTGRESQL_FOUND)
SET( POSTGRESQL_LIBRARIES ${POSTGRESQL_LIBRARY} )
ELSE(POSTGRESQL_FOUND)
SET( POSTGRESQL_LIBRARIES )
ENDIF(POSTGRESQL_FOUND)
# Lastly make it so that the POSTGRESQL_LIBRARY and POSTGRESQL_INCLUDE_DIR variables
# only show up under the advanced options in the gui cmake applications.
MARK_AS_ADVANCED( POSTGRESQL_LIBRARY POSTGRESQL_INCLUDE_DIR )
nextepc-0.3.10/lib/freeDiameter-1.2.1/cmake/Modules/FindSCTP.cmake 0000664 0000000 0000000 00000002601 13335533574 0024116 0 ustar 00root root 0000000 0000000 # - Try to find SCTP library and headers
# Once done, this will define
#
# SCTP_FOUND - system has SCTP
# SCTP_INCLUDE_DIR - the SCTP include directories
# SCTP_LIBRARIES - link these to use SCTP
if (SCTP_INCLUDE_DIR AND SCTP_LIBRARIES)
set(SCTP_FIND_QUIETLY TRUE)
endif (SCTP_INCLUDE_DIR AND SCTP_LIBRARIES)
# Include dir
find_path(SCTP_INCLUDE_DIR
NAMES netinet/sctp.h
)
# Library
find_library(SCTP_LIBRARY
NAMES sctp
)
# Set the include dir variables and the libraries and let libfind_process do the rest.
# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
#set(SCTP_PROCESS_INCLUDES SCTP_INCLUDE_DIR)
#set(SCTP_PROCESS_LIBS SCTP_LIBRARY)
#libfind_process(SCTP)
# handle the QUIETLY and REQUIRED arguments and set SCTP_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SCTP DEFAULT_MSG SCTP_LIBRARY SCTP_INCLUDE_DIR)
# If we successfully found the sctp library then add the library to the
# SCTP_LIBRARIES cmake variable otherwise set SCTP_LIBRARIES to nothing.
IF(SCTP_FOUND)
SET( SCTP_LIBRARIES ${SCTP_LIBRARY} )
ELSE(SCTP_FOUND)
SET( SCTP_LIBRARIES )
ENDIF(SCTP_FOUND)
# Lastly make it so that the SCTP_LIBRARY and SCTP_INCLUDE_DIR variables
# only show up under the advanced options in the gui cmake applications.
MARK_AS_ADVANCED( SCTP_LIBRARY SCTP_INCLUDE_DIR )
nextepc-0.3.10/lib/freeDiameter-1.2.1/cmake/Modules/GetVersionWithHg.cmake 0000664 0000000 0000000 00000001213 13335533574 0025742 0 ustar 00root root 0000000 0000000 # This file is called at build time. It regenerates the version.h file based on the hg version.
EXECUTE_PROCESS(
COMMAND ${HGCOMMAND} id -i
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
RESULT_VARIABLE reshash
OUTPUT_VARIABLE verhash
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
EXECUTE_PROCESS(
COMMAND ${HGCOMMAND} id -n
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
RESULT_VARIABLE resval
OUTPUT_VARIABLE verval
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (reshash EQUAL 0)
SET(FD_PROJECT_VERSION_HG "${verval}(${verhash})")
message(STATUS "Source version: ${FD_PROJECT_VERSION_HG}")
endif (reshash EQUAL 0)
CONFIGURE_FILE(${SRC} ${DST})
nextepc-0.3.10/lib/freeDiameter-1.2.1/configure.ac 0000664 0000000 0000000 00000017320 13335533574 0021344 0 ustar 00root root 0000000 0000000 dnl Process this file with autoconf to produce a configure script.
dnl
dnl This file is free software; as a special exception the author gives
dnl unlimited permission to copy and/or distribute it, with or without
dnl modifications, as long as this notice is preserved.
dnl
dnl This program is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
AC_INIT([nextepc], [1.2.1], [acetcom@gmail.com])
AC_SUBST(LIBVERSION)
LIBVERSION=1:0:0
dnl Must come before AM_INIT_AUTOMAKE.
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([1.10 -Wall -Werror foreign])
# Where to generate output; srcdir location.
AC_CONFIG_HEADERS([include/freeDiameter/config.h])
AC_CANONICAL_HOST
case $host in
*-freebsd*)
AC_DEFINE_UNQUOTED([SCTP_USE_MAPPED_ADDRESSES],
[1], [Disable SCTP])
;;
*)
;;
esac
AH_TOP([
#ifndef FD_IS_CONFIG
#define FD_IS_CONFIG
#define _GNU_SOURCE 1
#ifdef __cplusplus
extern "C" {
#endif
])
AH_BOTTOM([
#define FD_PROJECT_COPYRIGHT "Copyright (c) 2008-2015, WIDE Project (www.wide.ad.jp) and NICT (www.nict.go.jp)"
#ifndef FD_DEFAULT_CONF_FILENAME
#define FD_DEFAULT_CONF_FILENAME "freeDiameter.conf"
#endif /* FD_DEFAULT_CONF_FILENAME */
/* Maximum number of hooks handlers that can be registered. Make this compilation option if needed */
#define FD_HOOK_HANDLE_LIMIT 5
#ifdef __cplusplus
}
#endif
#endif /* FD_IS_CONFIG */
])
dnl kernel style compile messages
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
dnl Checks CC and freinds
AC_PROG_MAKE_SET
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_YACC
AC_PROG_LEX
AM_PROG_AR
LT_INIT([dlopen pic-only disable-static])
dnl Checks for compile flag
dnl AX_CHECK_COMPILE_FLAG([-Wno-format-truncation],[CFLAGS="$CFLAGS -Wno-format-truncation"])
dnl Check Endian
AC_C_BIGENDIAN
#############################
#### From FreeDiameter CMAKE
#############################
touch include/freeDiameter/version.h
rm -f libfdcore/fdd.tab.y
ln -s fdd.y libfdcore/fdd.tab.y
rm -f libfdcore/lex.fdd.l
ln -s fdd.l libfdcore/lex.fdd.l
AC_DEFINE_UNQUOTED([FD_PROJECT_BINARY],
["freeDiameterd"], [Project Binary])
AC_DEFINE_UNQUOTED([FD_PROJECT_NAME],
["freeDiameter"], [Project Name])
AC_DEFINE_UNQUOTED([FD_PROJECT_VERSION_MAJOR],
[`echo $PACKAGE_VERSION | $SED 's/^\([[^\.]]\+\)\.\([[^\.]]\+\)\.\([[^\.]]\+\).*/\1/'`],
[Major version of this package])
AC_DEFINE_UNQUOTED([FD_PROJECT_VERSION_MINOR],
[`echo $PACKAGE_VERSION | $SED 's/^\([[^\.]]\+\)\.\([[^\.]]\+\)\.\([[^\.]]\+\).*/\2/'`],
[Minor version of this package])
AC_DEFINE_UNQUOTED([FD_PROJECT_VERSION_REV],
[`echo $PACKAGE_VERSION | $SED 's/^\([[^\.]]\+\)\.\([[^\.]]\+\)\.\([[^\.]]\+\).*/\3/'`],
[Patch version of this package])
AC_DEFINE_UNQUOTED([FD_PROJECT_VERSION_API],
[6],
[API version of this package])
# adl_RECURSIVE_EVAL(VALUE, RESULT)
# =================================
# Interpolate the VALUE in loop until it doesn't change,
# and set the result to $RESULT.
# WARNING: It's easy to get an infinite loop with some unsane input.
# For example ${datadir} becomes ${datarootdir}, and then ${prefix}/share, and
# finally ${prefix} is replaced by the prefix.
AC_DEFUN([adl_RECURSIVE_EVAL],
[_lcl_receval="$1"
$2=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix"
test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
_lcl_receval_old=''
while test "[$]_lcl_receval_old" != "[$]_lcl_receval"; do
_lcl_receval_old="[$]_lcl_receval"
eval _lcl_receval="\"[$]_lcl_receval\""
done
echo "[$]_lcl_receval")`])
adl_RECURSIVE_EVAL(["${libdir}"], [LIB_DIR])
adl_RECURSIVE_EVAL(["${sysconfdir}"], [SYSCONF_DIR])
AC_SUBST(extlibdir)
extlibdir=${libdir}/nextepc/freeDiameter
AC_DEFINE_UNQUOTED([DEFAULT_CONF_PATH],
["${SYSCONF_DIR}/nextepc/freeDiameter"], [Default Configuration Path])
AC_DEFINE_UNQUOTED([DEFAULT_EXTENSIONS_PATH],
["${LIB_DIR}/nextepc/freeDiameter"], [Default Extensions Path])
AC_SUBST(PREFIX)
AC_CHECK_FUNCS([strndup])
AC_CHECK_DECL([ntohll],[AC_DEFINE([HAVE_NTOHLL], [1],
[Define to 1 if you have ntohll.])])
AC_CHECK_DECL([AI_ADDRCONFIG],
[AC_DEFINE([HAVE_AI_ADDRCONFIG], [1], [Define AI_ADDRCONFIG])], [], [[#include ]])
AC_SEARCH_LIBS([clock_gettime], [rt],
[AC_DEFINE([HAVE_CLOCK_GETTIME], [1], [Define clock_gettime])])
AC_SEARCH_LIBS([dlopen], [dl dld])
AC_SEARCH_LIBS([pthread_barrier_wait], [pthread],
[AC_DEFINE([HAVE_PTHREAD_BAR], [1],
[Define to 1 if you have pthread_barrier_wait in libpthread])],
[])
AC_SEARCH_LIBS([sctp_sendmsg], [sctp], [have_sctp_lib=yes])
if test x$have_sctp_lib != xyes; then
AC_DEFINE([DISABLE_SCTP], [1], [Disable SCTP])
fi
AM_CONDITIONAL([SCTP], [test x$have_sctp_lib = xyes])
AC_SEARCH_LIBS([gnutls_global_init], [gnutls],, [have_gnutls_lib=no])
if test x$have_gnutls_lib == xno; then
AC_MSG_ERROR([You must install the GnuTLS libraries and development headers to enable GnuTLS support.])
fi
AC_SEARCH_LIBS([gnutls_hash], [gnutls],
[AC_DEFINE(GNUTLS_VERSION_210, 1,
[Define to 1 if you have gnutls 2.10 installed])], [])
AC_SEARCH_LIBS([gnutls_transport_set_vec_push_function], [gnutls],
[AC_DEFINE(GNUTLS_VERSION_212, 1,
[Define to 1 if you have gnutls 2.10 installed])], [])
AC_SEARCH_LIBS([gnutls_x509_trust_list_verify_crt], [gnutls],
[AC_DEFINE(GNUTLS_VERSION_300, 1,
[Define to 1 if you have gnutls 3.0 installed])], [])
AC_SEARCH_LIBS([gnutls_handshake_set_timeout], [gnutls],
[AC_DEFINE(GNUTLS_VERSION_310, 1,
[Define to 1 if you have gnutls 3.1 installed])], [])
AC_SEARCH_LIBS([gcry_control], [gcrypt],, [have_gcrypt_lib=no])
if test x$have_gcrypt_lib == xno; then
AC_MSG_ERROR([You must install the Libgcrypt libraries and development headers to enable Libgcrypt support.])
fi
AC_SEARCH_LIBS([idna_strerror], [idn],, [have_idn_lib=no])
if test x$have_idn_lib == xno; then
AC_MSG_ERROR([You must install the GNU Libidn libraries and development headers to enable GNU Libidn support.])
fi
AC_CACHE_CHECK([whether sctp_connectx function accepts 4 arguments],
[ap_cv_sctp_connectx],
[AC_TRY_COMPILE(
[#include
#include ],
[sctp_connectx(0, NULL, 0, NULL);],
[ap_cv_sctp_connectx=yes], [ap_cv_sctp_connectx=no])
])
if test "$ap_cv_sctp_connectx" = "yes"; then
AC_DEFINE([SCTP_CONNECTX_4_ARGS], [1],
[Define 1 if sctp_connectx function accepts 4 arguments])
fi
#####################
#### Conclusion. ####
#####################
AC_CONFIG_FILES([include/freeDiameter/freeDiameter-host.h:include/freeDiameter/freeDiameter-host.hin])
AC_CONFIG_FILES([libfdproto/Makefile])
AC_CONFIG_FILES([libfdcore/Makefile])
AC_CONFIG_FILES([extensions/dbg_msg_dumps/Makefile])
AC_CONFIG_FILES([extensions/dict_rfc5777/Makefile])
AC_CONFIG_FILES([extensions/dict_mip6i/Makefile])
AC_CONFIG_FILES([extensions/dict_nasreq/Makefile])
AC_CONFIG_FILES([extensions/dict_nas_mipv6/Makefile])
AC_CONFIG_FILES([extensions/dict_dcca/Makefile])
AC_CONFIG_FILES([extensions/dict_dcca_3gpp/Makefile])
AC_CONFIG_FILES([extensions/dict_s6a/Makefile])
AC_CONFIG_FILES([extensions/Makefile])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
echo "
FreeDiameter configuration
--------------------
version : ${PACKAGE_VERSION}
host : ${host}
source code location : ${srcdir}
compiler : ${CC}
compiler flags : ${CFLAGS}
linker flags : ${LDFLAGS} ${LIBS}
config directory : ${SYSCONF_DIR}/nextepc/freeDiameter
extensions directory : ${LIB_DIR}/nextepc
"
nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/ 0000775 0000000 0000000 00000000000 13335533574 0020513 5 ustar 00root root 0000000 0000000 nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/CxDx/ 0000775 0000000 0000000 00000000000 13335533574 0021361 5 ustar 00root root 0000000 0000000 nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/CxDx/README 0000664 0000000 0000000 00000000550 13335533574 0022241 0 ustar 00root root 0000000 0000000 Date: Thu, 13 Oct 2011 14:01:40 -0300
From: "Norberto R. de Goes Jr."
To: help@freediameter.net
Subject: [Help] Cx dictionary (samples "c" and "xml")
Hi.
Just a contribution, they were not tested.
Best regards,
--
Norberto R. de Goes Jr.
CPqD - DRC
Tel.: +55 19 3705-4241 / Fax: +55 19 3705-6125
norberto@cpqd.com.br
www.cpqd.com.br
nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/CxDx/dict_cxdx.c 0000664 0000000 0000000 00000214132 13335533574 0023501 0 ustar 00root root 0000000 0000000 /*********************************************************************************************************
* Software License Agreement (BSD License) *
* Author: Norberto R. de Goes Jr. *
* *
* Copyright (c) 2011, Norberto R. de Goes Jr.. *
* *
* All rights reserved. *
* *
* Redistribution and use of this software in source and binary forms, with or without modification, are *
* permitted provided that the following conditions are met: *
* *
* * Redistributions of source code must retain the above *
* copyright notice, this list of conditions and the *
* following disclaimer. *
* *
* * Redistributions in binary form must reproduce the above *
* copyright notice, this list of conditions and the *
* following disclaimer in the documentation and/or other *
* materials provided with the distribution. *
* *
* * Neither the name of the Teraoka Laboratory nor the *
* names of its contributors may be used to endorse or *
* promote products derived from this software without *
* specific prior written permission of Teraoka Laboratory *
* *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
*********************************************************************************************************/
/*********************************************************************************************************
=== CpqD/DRC - Projeto ADRIMS - Mar/2011 ===
=== Dicionario Dx/Cx ===
Baseado no "dict_sip" do FreeDiameter (www.freediameter.net)
Norberto R Goes Jr
*********************************************************************************************************/
#include
/* The content of this file follows the same structure as dict_base_proto.c */
#define CHECK_dict_new( _type, _data, _parent, _ref ) \
CHECK_FCT( fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref)) );
#define CHECK_dict_search( _type, _criteria, _what, _result ) \
CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
struct local_rules_definition
{
char *avp_name;
enum rule_position position;
int min;
int max;
};
/*==================================================================*/
#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
/*==================================================================*/
#define PARSE_loc_rules( _rulearray, _parent, _avp_search_flag) { \
int __ar; \
for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
struct dict_rule_data __data = { NULL, \
(_rulearray)[__ar].position, \
0, \
(_rulearray)[__ar].min, \
(_rulearray)[__ar].max}; \
__data.rule_order = RULE_ORDER(__data.rule_position); \
\
CHECK_FCT( fd_dict_search( \
fd_g_config->cnf_dict, \
DICT_AVP, \
_avp_search_flag, \
(_rulearray)[__ar].avp_name, \
&__data.rule_avp, 0 ) ); \
if ( !__data.rule_avp ) { \
TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_name ); \
return ENOENT; \
} \
\
CHECK_FCT_DO( fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &__data, _parent, NULL), \
{ \
TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
(_rulearray)[__ar].avp_name ); \
return EINVAL; \
} ); \
} \
}
#define enumval_def_u32( _val_, _str_ ) \
{ _str_, { .u32 = _val_ }}
#define enumval_def_os( _len_, _val_, _str_ ) \
{ _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
/*==================================================================*/
/*==================================================================*/
/*==================================================================*/
/*==================================================================*/
int cxdx_dict_init(char * conffile)
{
#define VENDOR_3GPP_Id 10415
struct dict_object * vendor_dict;
{
struct dict_vendor_data vendor_data = { VENDOR_3GPP_Id, "3GPP" };
CHECK_dict_new (DICT_VENDOR, &vendor_data, NULL, &vendor_dict);
}
struct dict_object * cxdx_dict;
{
struct dict_application_data data = { 16777216 /* NRGJ */, "Diameter CxDx Application" };
CHECK_dict_new (DICT_APPLICATION, &data, vendor_dict, &cxdx_dict);
}
/* ##### AVP section #################################### */
{
struct dict_object * UTF8String_type;
struct dict_object * DiameterURI_type;
CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
/* Digest AVPs: */
/* Visited-Network-Identifier */
{
struct dict_avp_data data =
{
600, /* Code */
VENDOR_3GPP_Id, /* Vendor */
"Visited-Network-Identifier", /* Name */
AVP_FLAG_MANDATORY | AVP_FLAG_VENDOR, /* Fixed flags */
AVP_FLAG_MANDATORY | AVP_FLAG_VENDOR, /* Fixed flag values */
AVP_TYPE_OCTETSTRING /* base type of data */
};
CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
}
/* Public-Identity */
{
struct dict_avp_data data =
{
601, /* Code */
VENDOR_3GPP_Id, /* Vendor */
"Public-Identity", /* Name */
AVP_FLAG_MANDATORY | AVP_FLAG_VENDOR, /* Fixed flags */
AVP_FLAG_MANDATORY | AVP_FLAG_VENDOR, /* Fixed flag values */
AVP_TYPE_OCTETSTRING /* base type of data */
};
CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
}
/* Server-Name */
{
struct dict_avp_data data =
{
602, /* Code */
VENDOR_3GPP_Id, /* Vendor */
"Server-Name", /* Name */
AVP_FLAG_MANDATORY | AVP_FLAG_VENDOR, /* Fixed flags */
AVP_FLAG_MANDATORY | AVP_FLAG_VENDOR, /* Fixed flag values */
AVP_TYPE_OCTETSTRING /* base type of data */
};
CHECK_dict_new( DICT_AVP, &data , DiameterURI_type/*UTF8String_type*/, NULL);
}
/* Optional-Capability */
{
struct dict_avp_data data =
{
605, /* Code */
VENDOR_3GPP_Id, /* Vendor */
"Optional-Capability", /* Name */
AVP_FLAG_MANDATORY | AVP_FLAG_VENDOR, /* Fixed flags */
AVP_FLAG_MANDATORY | AVP_FLAG_VENDOR, /* Fixed flag values */
AVP_TYPE_UNSIGNED32 /* base type of data */
};
CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
}
/* Feature-List-ID */
{
struct dict_avp_data data =
{
629, /* Code */
VENDOR_3GPP_Id, /* Vendor */
"Feature-List-ID", /* Name */
AVP_FLAG_VENDOR, /* Fixed flags */
AVP_FLAG_VENDOR, /* Fixed flag values */
AVP_TYPE_UNSIGNED32 /* base type of data */
};
CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
}
/* Feature-List */
{
struct dict_avp_data data =
{
630, /* Code */
VENDOR_3GPP_Id, /* Vendor */
"Feature-List", /* Name */
AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
AVP_FLAG_MANDATORY, /* Fixed flag values */
AVP_TYPE_UNSIGNED32 /* base type of data */
};
CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
}
/* Server-Capabilities */
{
struct dict_object * avp;
struct dict_avp_data data =
{
603, /* Code */
VENDOR_3GPP_Id, /* Vendor */
"Server-Capabilities", /* Name */
AVP_FLAG_MANDATORY | AVP_FLAG_VENDOR, /* Fixed flags */
AVP_FLAG_MANDATORY | AVP_FLAG_VENDOR, /* Fixed flag values */
AVP_TYPE_GROUPED /* base type of data */
};
struct local_rules_definition rules[] =
{
{ "Vendor-Id", RULE_REQUIRED, -1, 1 },
{ "Feature-List-ID", RULE_REQUIRED, -1, 1 },
{ "Feature-List", RULE_REQUIRED, -1, 1 }
};
CHECK_dict_new (DICT_AVP, &data , NULL, &avp);
PARSE_loc_rules(rules, avp, AVP_BY_NAME_ALL_VENDORS );
}
/* User-Authorization-Type */
{
struct dict_avp_data data =
{
623, /* Code */
VENDOR_3GPP_Id, /* Vendor */
"User-Authorization-Type", /* Name */
AVP_FLAG_MANDATORY | AVP_FLAG_VENDOR, /* Fixed flags */
AVP_FLAG_MANDATORY | AVP_FLAG_VENDOR, /* Fixed flag values */
AVP_TYPE_OCTETSTRING /* base type of data */
};
CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
}
/* Supported-Features */
{
struct dict_object * avp;
struct dict_avp_data data =
{
628, /* Code */
VENDOR_3GPP_Id, /* Vendor */
"Supported-Features", /* Name */
AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
AVP_FLAG_MANDATORY, /* Fixed flag values */
AVP_TYPE_GROUPED /* base type of data */
};
struct local_rules_definition rules[] =
{
{ "Vendor-Id", RULE_REQUIRED, -1, 1 },
{ "Feature-List-ID", RULE_REQUIRED, -1, 1 },
{ "Feature-List", RULE_REQUIRED, -1, 1 }
};
CHECK_dict_new (DICT_AVP, &data , NULL, &avp);
PARSE_loc_rules(rules, avp, AVP_BY_NAME_ALL_VENDORS );
}
} /* end AVP section */
/* ### Command section ############################# */
{
/* User-Authorization-Request (UAR) Command */
{
/*
The User-Authorization-Request (UAR) is indicated by the Command-Code
set to 283 and the Command Flags' 'R' bit set. The Diameter client
in a SIP server sends this command to the Diameter server to request
authorization for the SIP User Agent to route a SIP REGISTER request.
Because the SIP REGISTER request implicitly carries a permission to
bind an AOR to a contact address, the Diameter client uses the
Diameter UAR as a first authorization request towards the Diameter
server to authorize the registration. For instance, the Diameter
server can verify that the AOR is a legitimate user of the realm.
The Diameter client in the SIP server requests authorization for one
of the possible values defined in the SIP-User-Authorization-Type AVP
(Section 9.10).
The user name used for authentication of the user is conveyed in a
User-Name AVP (defined in the Diameter base protocol, RFC 3588
[RFC3588]). The location of the authentication user name in the SIP
REGISTER request varies depending on the authentication mechanism.
When the authentication mechanism is HTTP Digest as defined in RFC
2617 [RFC2617], the authentication user name is found in the
"username" directive of the SIP Authorization header field value.
This Diameter SIP application only provides support for HTTP Digest
authentication in SIP; other authentication mechanisms are not
currently supported.
The SIP or SIPS URI to be registered is conveyed in the SIP-AOR AVP
(Section 9.8). Typically this SIP or SIPS URI is found in the To
header field value of the SIP REGISTER request that triggered the
Diameter UAR message.
The SIP-Visited-Network-Id AVP indicates the network that is
providing SIP services (e.g., SIP proxy functionality or any other
kind of services) to the SIP User Agent.
The Message Format of the UAR command is as follows:
< UAR> ::=< Diameter Header: 300, REQ, PXY, 16777216 >
< Session-Id >
{ Vendor-Specific-Application-Id }
{ Auth-Session-State }
{ Origin-Host }
{ Origin-Realm }
[ Destination-Host ]
{ Destination-Realm }
{ User-Name }
*[ Supported-Features ]
{ Public-Identity }
{ Visited-Network-Identifier }
[ User-Authorization-Type ]
[ UAR-Flags ]
*[ AVP ]
*[ Proxy-Info ]
*[ Route-Record ]
*/
struct dict_object * cmd;
struct dict_cmd_data data =
{
300, /* Code */
"User-Authorization-Request", /* Name */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */
};
struct local_rules_definition rules[] =
{
{ "Session-Id", RULE_FIXED_HEAD, -1, 1 },
{ "Vendor-Specific-Application-Id", RULE_REQUIRED, -1, 1 },
{ "Auth-Session-State", RULE_REQUIRED, -1, 1 },
{ "Origin-Host", RULE_REQUIRED, -1, 1 },
{ "Origin-Realm", RULE_REQUIRED, -1, 1 },
// { "Destination-Host", RULE_OPTIONAL, -1, 1 },
{ "Destination-Realm", RULE_REQUIRED, -1, 1 },
{ "User-Name", RULE_REQUIRED, -1, 1 },
// { "Supported-Features", RULE_OPTIONAL, -1, -1 },
{ "Public-Identity", RULE_REQUIRED, -1, 1 },
{ "Visited-Network-Identifier", RULE_REQUIRED, -1, 1 },
// { "UAR-Flags", RULE_OPTIONAL, -1, 1 },
// { "User-Authorization-Type", RULE_OPTIONAL, -1, 1 },
// { "Proxy-Info", RULE_OPTIONAL, -1, -1 },
// { "Route-Record", RULE_OPTIONAL, -1, -1 }
};
CHECK_dict_new( DICT_COMMAND, &data , cxdx_dict, &cmd);
PARSE_loc_rules( rules, cmd, AVP_BY_NAME_ALL_VENDORS);
}
/* User-Authorization-Answer (UAA) Command */
{
/*
The User-Authorization-Answer (UAA) is indicated by the Command-Code
set to 283 and the Command Flags' 'R' bit cleared. The Diameter
server sends this command in response to a previously received
Diameter User-Authorization-Request (UAR) command. The Diameter
server indicates the result of the requested registration
authorization. Additionally, the Diameter server may indicate a
collection of SIP capabilities that assists the Diameter client to
select a SIP proxy to the AOR under registration.
In addition to the values already defined in RFC 3588 [RFC3588], the
Result-Code AVP may contain one of the values defined in
Section 10.1.
Whenever the Diameter server fails to process the Diameter UAR
message, it MUST stop processing and return the relevant error in the
Diameter UAA message. When there is success in the process, the
Diameter server MUST set the code to DIAMETER_SUCCESS in the Diameter
UAA message.
If the Diameter server requires a User-Name AVP value to process the
Diameter UAR request, but the Diameter UAR message did not contain a
User-Name AVP value, the Diameter server MUST set the Result-Code AVP
value to DIAMETER_USER_NAME_REQUIRED (see Section 10.1.2) and return
it in a Diameter UAA message. Upon reception of this Diameter UAA
message with the Result-Code AVP value set to
DIAMETER_USER_NAME_REQUIRED, the SIP server typically requests
authentication by sending a SIP 401 (Unauthorized) or SIP 407 (Proxy
Authentication Required) response back to the originator.
When the authorization procedure succeeds, the Diameter server
constructs a User-Authorization-Answer (UAA) message that MUST
include (1) the address of the SIP server already assigned to the
user name, (2) the capabilities needed by the SIP server (Diameter
client) to select another SIP server for the user, or (3) a
combination of the previous two options.
If the Diameter server is already aware of a SIP server allocated to
the user, the Diameter UAA message contains the address of that SIP
server.
The Diameter UAA message contains the capabilities required by a SIP
server to trigger and execute services. It is required that these
capabilities are present in the Diameter UAA message due to the
possibility that the Diameter client (in the SIP server) allocates a
different SIP server to trigger and execute services for that
particular user.
If a User-Name AVP is present in the Diameter UAR message, then the
Diameter server MUST verify the existence of the user in the realm,
i.e., the User-Name AVP value is a valid user within that realm. If
the Diameter server does not recognize the user name received in the
User-Name AVP, the Diameter server MUST build a Diameter User-
Authorization-Answer (UAA) message and MUST set the Result-Code AVP
to DIAMETER_ERROR_USER_UNKNOWN.
If a User-Name AVP is present in the Diameter UAR message, then the
Diameter server MUST authorize that User-Name AVP value is able to
register the SIP or SIPS URI included in the SIP-AOR AVP. If this
authorization fails, the Diameter server must set the Result-Code AVP
to DIAMETER_ERROR_IDENTITIES_DONT_MATCH and send it in a Diameter
User-Authorization-Answer (UAA) message.
Note: Correlation between User-Name and SIP-AOR AVP values is
required in order to avoid registration of a SIP-AOR allocated to
another user.
If there is a SIP-Visited-Network-Id AVP in the Diameter UAR message,
and the SIP-User-Authorization-Type AVP value received in the
Diameter UAR message is set to REGISTRATION or REGISTRATION&
CAPABILITIES, then the Diameter server SHOULD verify whether the user
is allowed to roam into the network specified in the
SIP-Visited-Network-Id AVP in the Diameter UAR message. If the user
is not allowed to roam into that network, the Diameter AAA server
MUST set the Result-Code AVP value in the Diameter UAA message to
DIAMETER_ERROR_ROAMING_NOT_ALLOWED.
If the SIP-User-Authorization-Type AVP value received in the Diameter
UAR message is set to REGISTRATION or REGISTRATION&CAPABILITIES, then
the Diameter server SHOULD verify whether the SIP-AOR AVP value is
authorized to register in the Home Realm. Where the SIP AOR is not
authorized to register in the Home Realm, the Diameter server MUST
set the Result-Code AVP to DIAMETER_AUTHORIZATION_REJECTED and send
it in a Diameter UAA message.
When the SIP-User-Authorization-Type AVP is not present in the
Diameter UAR message, or when it is present and its value is set to
REGISTRATION, then:
o If the Diameter server is not aware of any previous registration
of the user name (including registrations of other SIP AORs
allocated to the same user name), then the Diameter server does
not know of any SIP server allocated to the user. In this case,
the Diameter server MUST set the Result-Code AVP value to
DIAMETER_FIRST_REGISTRATION in the Diameter UAA message, and the
Diameter server SHOULD include the required SIP server
capabilities in the SIP-Server-Capabilities AVP value in the
Diameter UAA message. The SIP-Server-Capabilities AVP assists the
Diameter client (SIP server) to select an appropriate SIP server
for the user, according to the required capabilities.
o In some cases, the Diameter server is aware of a previously
assigned SIP server for the same or different SIP AORs allocated
to the same user name. In these cases, re-assignment of a new SIP
server may or may not be needed, depending on the capabilities of
the SIP server. The Diameter server MUST always include the
allocated SIP server URI in the SIP-Server-URI AVP of the UAA
message. If the Diameter server does not return the SIP
capabilities, the Diameter server MUST set the Result-Code AVP in
the Diameter UAA message to DIAMETER_SUBSEQUENT_REGISTRATION.
Otherwise (i.e., if the Diameter server includes a
SIP-Server-Capabilities AVP), then the Diameter server MUST set
the Result-Code AVP in the Diameter UAA message to
DIAMETER_SERVER_SELECTION. Then the Diameter client determines,
based on the received information, whether it needs to select a
new SIP server.
When the SIP-User-Authorization-Type AVP value received in the
Diameter UAR message is set to REGISTRATION&CAPABILITIES, then
Diameter Server MUST return the list of capabilities in the
SIP-Server-Capabilities AVP value of the Diameter UAA message, it
MUST set the Result-Code to DIAMETER_SUCCESS, and it MUST NOT return
a SIP-Server-URI AVP. The SIP-Server-Capabilities AVP enables the
SIP server (Diameter client) to select another appropriate SIP server
for invoking and executing services for the user, depending on the
required capabilities. The Diameter server MAY leave the list of
capabilities empty to indicate that any SIP server can be selected.
When the SIP-User-Authorization-Type AVP value received in the
Diameter UAR message is set to DEREGISTRATION, then:
o If the Diameter server is aware of a SIP server assigned to the
SIP AOR under deregistration, the Diameter server MUST set the
Result-Code AVP to DIAMETER_SUCCESS and MUST set the
SIP-Server-URI AVP value to the known SIP server, and return them
in the Diameter UAA message.
o If the Diameter server is not aware of a SIP server assigned to
the SIP AOR under deregistration, then the Diameter server MUST
set the Result-Code AVP in the Diameter UAA message to
DIAMETER_ERROR_IDENTITY_NOT_REGISTERED.
The Message Format of the UAA command is as follows:
::= < Diameter Header: 283, PXY >
< Session-Id >
{ Auth-Application-Id }
{ Auth-Session-State }
{ Result-Code }
{ Origin-Host }
{ Origin-Realm }
[ SIP-Server-URI ]
[ SIP-Server-Capabilities ]
[ Authorization-Lifetime ]
[ Auth-Grace-Period ]
[ Redirect-Host ]
[ Redirect-Host-Usage ]
[ Redirect-Max-Cache-Time ]
* [ Proxy-Info ]
* [ Route-Record ]
* [ AVP ]
*/
struct dict_object * cmd;
struct dict_cmd_data data =
{
300, /* Code */
"User-Authorization-Answer", /* Name */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
CMD_FLAG_PROXIABLE /* Fixed flag values */
};
struct local_rules_definition rules[] =
{
{ "Session-Id", RULE_FIXED_HEAD, -1, 1 },
{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 },
{ "Auth-Session-State", RULE_REQUIRED, -1, 1 },
{ "Result-Code", RULE_REQUIRED, -1, 1 },
{ "Origin-Host", RULE_REQUIRED, -1, 1 },
{ "Origin-Realm", RULE_REQUIRED, -1, 1 },
{ "Proxy-Info", RULE_OPTIONAL, -1, -1 },
{ "Route-Record", RULE_OPTIONAL, -1, -1 }
};
CHECK_dict_new( DICT_COMMAND, &data , cxdx_dict, &cmd);
PARSE_loc_rules( rules, cmd, AVP_BY_NAME );
}
#if 0 /* TODO - NRGJ : alterar conforme RFC-3GPP : */
/* Multimedia-Auth-Request (MAR) Command */
{
/*
The Multimedia-Auth-Request (MAR) command is indicated by the
Command-Code set to 286 and the Command Flags' 'R' bit set. The
Diameter client in a SIP server sends this command to the Diameter
server to request that the Diameter server authenticate and authorize
a user attempt to use some SIP service (in this context, SIP service
can be something as simple as a SIP subscription or using the proxy
services for a SIP request).
The MAR command may also register the SIP server's own URI to the
Diameter server, so that future LIR/LIA messages can return this URI.
If the SIP server is acting as a SIP registrar (see examples in
Sections 6.2 and 6.3), its Diameter client MUST include a SIP-
Server-URI AVP in the MAR command. In any other cases (see example
in Section 6.4), its Diameter client MUST NOT include a SIP-Server-
URI AVP in the MAR command.
The SIP-Method AVP MUST include the SIP method name of the SIP
request that triggered this Diameter MAR message. The Diameter
server can use this AVP to authorize some SIP requests depending on
the method.
The Diameter MAR message MUST include a SIP-AOR AVP. The SIP-AOR AVP
indicates the target of the SIP request. The value of the AVP is
extracted from different places in SIP request, depending on the
semantics of the SIP request. For SIP REGISTER messages the SIP-AOR
AVP value indicates the intended public user identity under
registration, and it is the SIP or SIPS URI populated in the To
header field value (addr-spec as per RFC 3261 [RFC3261]) of the SIP
REGISTER request. For other types of SIP requests, such as INVITE,
SUBSCRIBE, MESSAGE, etc., the SIP-AOR AVP value indicates the
intended destination of the request. This is typically populated in
the Request-URI of the SIP request. Extracting the SIP-AOR AVP value
from the proper SIP header field is the Diameter client's
responsibility. Extensions to SIP (new SIP methods or new semantics)
may require the SIP-AOR to be extracted from other parts of the
request.
If the SIP request includes some sort of authentication information,
the Diameter client MUST include the user name, extracted from the
authentication information of the SIP request, in the User-Name AVP
value.
The Message Format of the MAR command is as follows:
::= < Diameter Header: 286, REQ, PXY >
< Session-Id >
{ Auth-Application-Id }
{ Auth-Session-State }
{ Origin-Host }
{ Origin-Realm }
{ Destination-Realm }
{ SIP-AOR }
{ SIP-Method }
[ Destination-Host ]
[ User-Name ]
[ SIP-Server-URI ]
[ SIP-Number-Auth-Items ]
[ SIP-Auth-Data-Item ]
* [ Proxy-Info ]
* [ Route-Record ]
* [ AVP ]
*/
struct dict_object * cmd;
struct dict_cmd_data data =
{
303, /* Code */
"Multimedia-Auth-Request", /* Name */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */
};
struct local_rules_definition rules[] =
{ { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
,{ "Auth-Session-State", RULE_REQUIRED, -1, 1 }
,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
,{ "Destination-Realm", RULE_REQUIRED, -1, 1 }
,{ "SIP-AOR", RULE_REQUIRED, -1, 1 }
,{ "SIP-Method", RULE_REQUIRED, -1, 1 }
,{ "Destination-Host", RULE_OPTIONAL, -1, 1 }
,{ "User-Name", RULE_OPTIONAL, -1, 1 }
,{ "SIP-Server-URI", RULE_OPTIONAL, -1, 1 }
,{ "SIP-Number-Auth-Items", RULE_OPTIONAL, -1, 1 }
,{ "SIP-Auth-Data-Item", RULE_OPTIONAL, -1, 1 }
,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
,{ "Route-Record", RULE_OPTIONAL, -1, -1 }
};
CHECK_dict_new( DICT_COMMAND, &data , cxdx_dict, &cmd);
PARSE_loc_rules( rules, cmd, AVP_BY_NAME );
}
/* Multimedia-Auth-Answer (MAA) Command */
{
/*
The Multimedia-Auth-Answer (MAA) is indicated by the Command-Code set
to 286 and the Command Flags' 'R' bit cleared. The Diameter server
sends this command in response to a previously received Diameter
Multimedia-Auth-Request (MAR) command.
In addition to the values already defined in RFC 3588 [RFC3588], the
Result-Code AVP may contain one of the values defined in
Section 10.1.
If the Diameter server requires a User-Name AVP value to process the
Diameter MAR request, but the Diameter MAR message did not contain a
User-Name AVP value, the Diameter server MUST set the Result-Code AVP
value to DIAMETER_USER_NAME_REQUIRED (see Section 10.1.2) and return
it in a Diameter MAA message. The Diameter server MAY include a
SIP-Number-Auth-Items AVP and one or more SIP-Auth-Data-Item AVPs
with authentication information (e.g., a challenge). Upon reception
of this Diameter MAA message with the Result-Code AVP value set to
DIAMETER_USER_NAME_REQUIRED, the SIP server typically requests
authentication by generating a SIP 401 (Unauthorized) or SIP 407
(Proxy Authentication Required) response back to the originator.
If the User-Name AVP is present in the Diameter MAR message, the
Diameter server MUST verify the existence of the user in the realm,
i.e., the User-Name AVP value is a valid user within that realm. If
the Diameter server does not recognize the user name received in the
User-Name AVP, the Diameter server MUST build a Diameter
Multimedia-Auth-Answer (MAA) message and MUST set the Result-Code AVP
to DIAMETER_ERROR_USER_UNKNOWN.
If the SIP-Methods AVP value of the Diameter MAR message is set to
REGISTER and a User-Name AVP is present, then the Diameter server
MUST authorize that User-Name AVP value is able to use the URI
included in the SIP-AOR AVP. If this authorization fails, the
Diameter server must set the Result-Code AVP to
DIAMETER_ERROR_IDENTITIES_DONT_MATCH and send it in a Diameter
Multimedia-Auth-Answer (MAA) message.
Note: Correlation between User-Name and SIP-AOR AVP values is only
required for SIP REGISTER request, to prevent a user from
registering a SIP-AOR allocated to another user. In other types
of SIP requests (e.g., INVITE), the SIP-AOR indicates the intended
destination of the request, rather than the originator of it.
The Diameter server MUST verify whether the authentication scheme
(SIP-Authentication-Scheme AVP value) indicated in the grouped
SIP-Auth-Data-Item AVP is supported or not. If that authentication
scheme is not supported, then the Diameter server MUST set the
Result-Code AVP to DIAMETER_ERROR_AUTH_SCHEME_NOT_SUPPORTED and send
it in a Diameter Multimedia-Auth-Answer (MAA) message.
If the SIP-Number-Auth-Items AVP is present in the Diameter MAR
message, it indicates the number of authentication data items that
the Diameter client is requesting. It is RECOMMENDED that the
Diameter server, when building the Diameter MAA message, includes a
number of SIP-Auth-Data-Item AVPs that are a subset of the
authentication data items requested by the Diameter client in the
SIP-Number-Auth-Items AVP value of the Diameter MAR message.
If the SIP-Server-URI AVP is present in the Diameter MAR message,
then the Diameter server MUST compare the stored SIP server (assigned
to the user) with the SIP-Server-URI AVP value (received in the
Diameter MAR message). If they don't match, the Diameter server MUST
temporarily save the newly received SIP server assigned to the user,
and MUST set an "authentication pending" flag for the user. If they
match, the Diameter server shall clear the "authentication pending"
flag for the user.
In any other situation, if there is a success in processing the
Diameter MAR command and the Diameter server stored the
SIP-Server-URI, the Diameter server MUST set the Result-Code AVP
value to DIAMETER_SUCCESS and return it in a Diameter MAA message.
If there is a success in processing the Diameter MAR command, but the
Diameter server does not store the SIP-Server-URI because the AVP was
not present in the Diameter MAR command, then the Diameter server
MUST set the Result-Code AVP value to either:
1. DIAMETER_SUCCESS_AUTH_SENT_SERVER_NOT_STORED, if the Diameter
server is sending authentication credentials to create a
challenge.
2. DIAMETER_SUCCESS_SERVER_NAME_NOT_STORED, if the Diameter server
successfully authenticated the user and authorized the SIP server
to proceed with the SIP request.
Otherwise, the Diameter server MUST set the Result-Code AVP value to
DIAMETER_UNABLE_TO_COMPLY, and it MUST NOT include any
SIP-Auth-Data-Item AVP.
The Message Format of the MAA command is as follows:
::= < Diameter Header: 286, PXY >
< Session-Id >
{ Auth-Application-Id }
{ Result-Code }
{ Auth-Session-State }
{ Origin-Host }
{ Origin-Realm }
[ User-Name ]
[ SIP-AOR ]
[ SIP-Number-Auth-Items ]
* [ SIP-Auth-Data-Item ]
[ Authorization-Lifetime ]
[ Auth-Grace-Period ]
[ Redirect-Host ]
[ Redirect-Host-Usage ]
[ Redirect-Max-Cache-Time ]
* [ Proxy-Info ]
* [ Route-Record ]
* [ AVP ]
*/
struct dict_object * cmd;
struct dict_cmd_data data = {
286, /* Code */
"Multimedia-Auth-Answer", /* Name */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
CMD_FLAG_PROXIABLE /* Fixed flag values */
};
struct local_rules_definition rules[] =
{ { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
,{ "Result-Code", RULE_REQUIRED, -1, 1 }
,{ "Auth-Session-State", RULE_REQUIRED, -1, 1 }
,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
,{ "User-Name", RULE_OPTIONAL, -1, 1 }
,{ "SIP-AOR", RULE_OPTIONAL, -1, 1 }
,{ "SIP-Number-Auth-Items", RULE_OPTIONAL, -1, 1 }
,{ "SIP-Auth-Data-Item", RULE_OPTIONAL, -1, -1 }
,{ "Authorization-Lifetime", RULE_OPTIONAL, -1, 1 }
,{ "Auth-Grace-Period", RULE_OPTIONAL, -1, 1 }
,{ "Redirect-Host", RULE_OPTIONAL, -1, 1 }
,{ "Redirect-Host-Usage", RULE_OPTIONAL, -1, 1 }
,{ "Redirect-Max-Cache-Time", RULE_OPTIONAL, -1, 1 }
,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
,{ "Route-Record", RULE_OPTIONAL, -1, -1 }
};
CHECK_dict_new( DICT_COMMAND, &data , cxdx_dict, &cmd);
PARSE_loc_rules( rules, cmd, AVP_BY_NAME );
}
/* Server-Assignment-Request (SAR) Command */
{
/*
The Server-Assignment-Request (SAR) command is indicated by the
Command-Code set to 284 and the Command Flags' 'R' bit set. The
Diameter client in a SIP server sends this command to the Diameter
server to indicate the completion of the authentication process and
to request that the Diameter server store the URI of the SIP server
that is currently serving the user. The main functions of the
Diameter SAR command are to inform the Diameter server of the URI of
the SIP server allocated to the user, and to store or clear it from
the Diameter server. Additionally, the Diameter client can request
to download the user profile or part of it.
During the registration procedure, a SIP server becomes assigned to
the user. The Diameter client in the assigned SIP server MUST
include its own URI in the SIP-Server-URI AVP of the
Server-Assignment-Request (SAR) Diameter message and send it to the
Diameter server. The Diameter server then becomes aware of the
allocation of the SIP server to the user name and the server's URI.
The Diameter client in the SIP server MAY send a Diameter SAR message
because of other reasons. These reasons are identified in the
SIP-Server-Assignment-Type AVP (Section 9.4) value. For instance, a
Diameter client in a SIP server may contact the Diameter server to
request deregistration of a user, to inform the Diameter server of an
authentication failure, or just to download the user profile. For a
complete description of all the SIP-Server-Assignment-Type AVP
values, see Section 9.4.
Typically the reception of a SIP REGISTER request in a SIP server
will trigger the Diameter client in the SIP server to send the
Diameter SAR message. However, if a SIP server is receiving other
SIP request, such as INVITE, and the SIP server does not have the
user profile, the Diameter client in the SIP server may send the
Diameter SAR message to the Diameter server in order to download the
user profile and make the Diameter server aware of the SIP server
assigned to the user.
The user profile is an important piece of information that dictates
the behavior of the SIP server when triggering or providing services
for the user. Typically the user profile is divided into:
o Services to be rendered to the user when the user is registered
and initiates a SIP request.
o Services to be rendered to the user when the user is registered
and a SIP request destined to that user arrives to the SIP proxy.
o Services to be rendered to the user when the user is not
registered and a SIP request destined to that user arrives to the
SIP proxy.
The SIP-Server-Assignment-Type AVP indicates the reason why the
Diameter client (SIP server) contacted the Diameter server. If the
Diameter client sets the SIP-Server-Assignment-Type AVP value to
REGISTRATION, RE_REGISTRATION, UNREGISTERED_USER, NO_ASSIGNMENT,
AUTHENTICATION_FAILURE or AUTHENTICATION_TIMEOUT, the Diameter client
MUST include exactly one SIP-AOR AVP in the Diameter SAR message.
The SAR message MAY contain zero or more SIP-Supported-User-Data-Type
AVPs. Each of them contains a type of user data understood by the
SIP server. This allows the Diameter client to provide an indication
to the Diameter server of the different format of user data
understood by the SIP server. The Diameter server uses this
information to select one or more SIP-User-Data AVPs that will be
included in the SAA message.
The Message Format of the SAR command is as follows:
::= < Diameter Header: 284, REQ, PXY >
< Session-Id >
{ Auth-Application-Id }
{ Auth-Session-State }
{ Origin-Host }
{ Origin-Realm }
{ Destination-Realm }
{ SIP-Server-Assignment-Type }
{ SIP-User-Data-Already-Available }
[ Destination-Host ]
[ User-Name ]
[ SIP-Server-URI ]
* [ SIP-Supported-User-Data-Type ]
* [ SIP-AOR ]
* [ Proxy-Info ]
* [ Route-Record ]
* [ AVP ]
*/
struct dict_object * cmd;
struct dict_cmd_data data = {
284, /* Code */
"Server-Assignment-Request", /* Name */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */
};
struct local_rules_definition rules[] =
{ { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
,{ "Auth-Session-State", RULE_REQUIRED, -1, 1 }
,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
,{ "Destination-Realm", RULE_REQUIRED, -1, 1 }
,{ "SIP-Server-Assignment-Type", RULE_REQUIRED, -1, 1 }
,{ "SIP-User-Data-Already-Available", RULE_REQUIRED, -1, 1 }
,{ "Destination-Host", RULE_OPTIONAL, -1, 1 }
,{ "User-Name", RULE_OPTIONAL, -1, 1 }
,{ "SIP-Server-URI", RULE_OPTIONAL, -1, 1 }
,{ "SIP-Supported-User-Data-Type", RULE_OPTIONAL, -1, -1 }
,{ "SIP-AOR", RULE_OPTIONAL, -1, -1 }
,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
,{ "Route-Record", RULE_OPTIONAL, -1, -1 }
};
CHECK_dict_new( DICT_COMMAND, &data , cxdx_dict, &cmd);
PARSE_loc_rules( rules, cmd, AVP_BY_NAME );
}
/* Server-Assignment-Answer (SAA) Command */
{
/*
The Server-Assignment-Answer (SAA) is indicated by the Command-Code
set to 284 and the Command Flags' 'R' bit cleared. The Diameter
server sends this command in response to a previously received
Diameter Server-Assignment-Request (SAR) command. The response may
include the user profile or part of it, if requested.
In addition to the values already defined in RFC 3588 [RFC3588], the
Result-Code AVP may contain one of the values defined in
Section 10.1.
The Result-Code AVP value in the Diameter SAA message may indicate a
success or an error in the execution of the Diameter SAR command. If
Result-Code AVP value in the Diameter SAA message does not contain an
error code, the SAA message MAY include one or more SIP-User-Data
AVPs that typically contain the profile of the user, indicating
services that the SIP server can provide to that user.
The Diameter server MAY include one or more
SIP-Supported-User-Data-Type AVPs, each one identifying a type of
user data format supported in the Diameter server. If there is not a
common supported user data type between the Diameter client and the
Diameter server, the Diameter server SHOULD declare its list of
supported user data types by including one or more
SIP-Supported-User-Data-Type AVPs in a Diameter SAA message. This
indication is merely for debugging reasons, since there is not a
fallback mechanism that allows the Diameter client to retrieve the
profile in a supported format.
If the Diameter server requires a User-Name AVP value to process the
Diameter SAR request, but the Diameter SAR message did not contain a
User-Name AVP value, the Diameter server MUST set the Result-Code AVP
value to DIAMETER_USER_NAME_REQUIRED (see Section 10.1.2) and return
it in a Diameter SAA message. Upon reception of this Diameter SAA
message with the Result-Code AVP value set to
DIAMETER_USER_NAME_REQUIRED, the SIP server typically requests
authentication by generating a SIP 401 (Unauthorized) or SIP 407
(Proxy Authentication Required) response back to the originator.
If the User-Name AVP is included in the Diameter SAR message, upon
reception of the Diameter SAR message, the Diameter server MUST
verify the existence of the user in the realm, i.e., the User-Name
AVP value is a valid user within that realm. If the Diameter server
does not recognize the user name received in the User-Name AVP, the
Diameter server MUST build a Diameter Server-Assignment-Answer (SAA)
message and MUST set the Result-Code AVP to
DIAMETER_ERROR_USER_UNKNOWN.
Then the Diameter server MUST authorize that User-Name AVP value is a
valid authentication name for the SIP or SIPS URI included in the
SIP-AOR AVP of the Diameter SAR message. If this authorization
fails, the Diameter server must set the Result-Code AVP to
DIAMETER_ERROR_IDENTITIES_DONT_MATCH and send it in a Diameter
Server-Assignment-Answer (SAA) message.
After successful execution of the Diameter SAR command, the Diameter
server MUST clear the "authentication pending" flag and SHOULD move
the temporarily stored SIP server URI to permanent storage.
The actions of the Diameter server upon reception of the Diameter SAR
message depend on the value of the SIP-Server-Assignment-Type:
o If the SIP-Server-Assignment-Type AVP value in the Diameter SAR
message is set to REGISTRATION or RE_REGISTRATION, the Diameter
server SHOULD verify that there is only one SIP-AOR AVP.
Otherwise, the Diameter server MUST answer with a Diameter SAA
message with the Result-Code AVP value set to
DIAMETER_AVP_OCCURS_TOO_MANY_TIMES and MUST NOT include any
SIP-User-Data AVP. If there is only one SIP-AOR AVP and if the
SIP-User-Data-Already-Available AVP value is set to
USER_DATA_NOT_AVAILABLE, then the Diameter server SHOULD include
one or more user profile data with the SIP or SIPS URI (SIP-AOR
AVP) and all other SIP identities associated with that AVP in the
SIP-User-Data AVP value of the Diameter SAA message. On selecting
the type of user data, the Diameter server SHOULD take into
account the supported formats at the SIP server
(SIP-Supported-User-Data-Type AVP in the SAR message) and the
local policy. Additionally, the Diameter server MUST set the
Result-Code AVP value to DIAMETER_SUCCESS in the Diameter SAA
message. The Diameter server considers the SIP AOR authenticated
and registered.
o If the SIP-Server-Assignment-Type AVP value in the Diameter SAR
message is set to UNREGISTERED_USER, then the Diameter server MUST
store the SIP server address included in the SIP-Server-URI AVP
value. The Diameter server will return the SIP server address in
Diameter Location-Info-Answer (LIA) messages. If the
SIP-User-Data-Already-Available AVP value is set to
USER_DATA_NOT_AVAILABLE, then the Diameter server SHOULD include
one or more user profile data associated with the SIP or SIPS URI
(SIP-AOR AVP) and associated identities in the SIP-User-Data AVP
value of the Diameter SAA message. On selecting the type of user
data, the Diameter server SHOULD take into account the supported
formats at the SIP server (SIP-Supported-User-Data-Type AVP in the
SAR message) and the local policy. The Diameter server MUST set
the Result-Code AVP value to DIAMETER_SUCCESS. The Diameter
server considers the SIP AOR UNREGISTERED, but with a SIP server
allocated to trigger and provide services for unregistered users.
Note that in case of UNREGISTERED_USER (SIP-Server-Assignment-Type
AVP), the Diameter server MUST verify that there is only one
SIP-AOR AVP. Otherwise, the Diameter server MUST answer the
Diameter SAR message with a Diameter SAA message, and it MUST set
the Result-Code AVP value to DIAMETER_AVP_OCCURS_TOO_MANY_TIMES
and MUST NOT include any SIP-User-Data AVP.
If the User-Name AVP was not present in the Diameter SAR message
and the SIP-AOR is not known for the Diameter server, the Diameter
server MUST NOT include a User-Name AVP in the Diameter SAA
message and MUST set the Result-Code AVP value to
DIAMETER_ERROR_USER_UNKNOWN.
o If the SIP-Server-Assignment-Type AVP value in the Diameter SAR
message is set to TIMEOUT_DEREGISTRATION, USER_DEREGISTRATION,
DEREGISTRATION_TOO_MUCH_DATA, or ADMINISTRATIVE_DEREGISTRATION,
the Diameter server MUST clear the SIP server address associated
with all SIP AORs indicated in each of the SIP-AOR AVP values
included in the Diameter SAR message. The Diameter server
considers all of these SIP AORs as not registered. The Diameter
server MUST set the Result-Code AVP value to DIAMETER_SUCCESS in
the Diameter SAA message.
o If the SIP-Server-Assignment-Type AVP value in the Diameter SAR
message is set to TIMEOUT_DEREGISTRATION_STORE_SERVER_NAME or
USER_DEREGISTRATION_STORE_SERVER_NAME, the Diameter server MAY
keep the SIP server address associated with the SIP AORs included
in the SIP-AOR AVP values of the Diameter SAR message, even though
the SIP AORs become unregistered. This feature allows a SIP
server to request that the Diameter server remain an assigned SIP
server for those SIP AORs (SIP-AOR AVP values) allocated to the
same user name, and avoid SIP server assignment. The Diameter
server MUST consider all these SIP AORs as not registered. If the
Diameter server honors the request of the Diameter client (SIP
server) to remain as an allocated SIP server, then the Diameter
server MUST keep the SIP server assigned to those SIP AORs
allocated to the username and MUST set the Result-Code AVP value
to DIAMETER_SUCCESS in the Diameter SAA message. Otherwise, when
the Diameter server does not honor the request of the Diameter
client (SIP server) to remain as an allocated SIP server, the
Diameter server MUST clear the SIP server name assigned to those
SIP AORs and it MUST set the Result-Code AVP value to
DIAMETER_SUCCESS_SERVER_NAME_NOT_STORED in the Diameter SAA
message.
o If the SIP-Server-Assignment-Type AVP value in the Diameter SAR
message is set to NO_ASSIGNMENT, the Diameter server SHOULD first
verify that the SIP-Server-URI AVP value in the Diameter SAR
message is the same URI as the one assigned to the SIP-AOR AVP
value. If they differ, then the Diameter server MUST set the
Result-Code AVP value to DIAMETER_UNABLE_TO_COMPLY in the Diameter
SAA message. Otherwise, if the SIP-User-Data-Already-Available
AVP value is set to USER_DATA_NOT_AVAILABLE, then the Diameter
server SHOULD include the user profile data with the SIP or SIPS
URI (SIP-AOR AVP) and all other SIP identities associated with
that AVP in the SIP-User-Data AVP value of the Diameter SAA
message. On selecting the type of user data, the Diameter server
SHOULD take into account the supported formats at the SIP server
(SIP-Supported-User-Data-Type AVP in the SAR message) and the
local policy.
o If the SIP-Server-Assignment-Type AVP value in the Diameter SAR
message is set to AUTHENTICATION_FAILURE or
AUTHENTICATION_TIMEOUT, the Diameter server MUST verify that there
is exactly one SIP-AOR AVP in the Diameter SAR message. If the
number of occurrences of the SIP-AOR AVP is not exactly one, the
Diameter server MUST set the Result-Code AVP value to
DIAMETER_AVP_OCCURS_TOO_MANY_TIMES in the Diameter SAA message,
and SHOULD not take further actions. If there is exactly one
SIP-AOR AVP in the Diameter SAR message, the Diameter server MUST
clear the address of the SIP server assigned to the SIP AOR
allocated to the user name, and the Diameter server MUST set the
Result-Code AVP value to DIAMETER_SUCCESS in the Diameter SAA
message. The Diameter server MUST consider the SIP AOR as not
registered.
The Message Format of the SAA command is as follows:
::= < Diameter Header: 284, PXY >
< Session-Id >
{ Auth-Application-Id }
{ Result-Code }
{ Auth-Session-State }
{ Origin-Host }
{ Origin-Realm }
* [ SIP-User-Data ]
[ SIP-Accounting-Information ]
* [ SIP-Supported-User-Data-Type ]
[ User-Name ]
[ Auth-Grace-Period ]
[ Authorization-Lifetime ]
[ Redirect-Host ]
[ Redirect-Host-Usage ]
[ Redirect-Max-Cache-Time ]
* [ Proxy-Info ]
* [ Route-Record ]
* [ AVP ]
*/
struct dict_object * cmd;
struct dict_cmd_data data = {
284, /* Code */
"Server-Assignment-Answer", /* Name */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
CMD_FLAG_PROXIABLE /* Fixed flag values */
};
struct local_rules_definition rules[] =
{ { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
,{ "Result-Code", RULE_REQUIRED, -1, 1 }
,{ "Auth-Session-State", RULE_REQUIRED, -1, 1 }
,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
,{ "SIP-User-Data", RULE_OPTIONAL, -1, -1 }
,{ "SIP-Accounting-Information", RULE_OPTIONAL, -1, 1 }
,{ "SIP-Supported-User-Data-Type", RULE_OPTIONAL, -1, -1 }
,{ "User-Name", RULE_OPTIONAL, -1, 1 }
,{ "Auth-Grace-Period", RULE_OPTIONAL, -1, 1 }
,{ "Authorization-Lifetime", RULE_OPTIONAL, -1, 1 }
,{ "Redirect-Host", RULE_OPTIONAL, -1, 1 }
,{ "Redirect-Host-Usage", RULE_OPTIONAL, -1, 1 }
,{ "Redirect-Max-Cache-Time", RULE_OPTIONAL, -1, 1 }
,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
,{ "Route-Record", RULE_OPTIONAL, -1, -1 }
};
CHECK_dict_new( DICT_COMMAND, &data , cxdx_dict, &cmd);
PARSE_loc_rules( rules, cmd, AVP_BY_NAME );
}
/* Location-Info-Request (LIR) Command */
{
/*
The Location-Info-Request (LIR) is indicated by the Command-Code set
to 285 and the Command Flags' 'R' bit set. The Diameter client in a
SIP server sends this command to the Diameter server to request
routing information, e.g., the URI of the SIP server assigned to the
SIP-AOR AVP value allocated to the users.
The Message Format of the LIR command is as follows:
::= < Diameter Header: 285, REQ, PXY >
< Session-Id >
{ Auth-Application-Id }
{ Auth-Session-State }
{ Origin-Host }
{ Origin-Realm }
{ Destination-Realm }
{ SIP-AOR }
[ Destination-Host ]
* [ Proxy-Info ]
* [ Route-Record ]
* [ AVP ]
*/
struct dict_object * cmd;
struct dict_cmd_data data = {
285, /* Code */
"Location-Info-Request", /* Name */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */
};
struct local_rules_definition rules[] =
{ { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
,{ "Auth-Session-State", RULE_REQUIRED, -1, 1 }
,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
,{ "Destination-Realm", RULE_REQUIRED, -1, 1 }
,{ "SIP-AOR", RULE_REQUIRED, -1, 1 }
,{ "Destination-Host", RULE_OPTIONAL, -1, 1 }
,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
,{ "Route-Record", RULE_OPTIONAL, -1, -1 }
};
CHECK_dict_new( DICT_COMMAND, &data , cxdx_dict, &cmd);
PARSE_loc_rules( rules, cmd, AVP_BY_NAME );
}
/* Location-Info-Answer (LIA) Command */
{
/*
The Location-Info-Answer (LIA) is indicated by the Command-Code set
to 285 and the Command Flags' 'R' bit cleared. The Diameter server
sends this command in response to a previously received Diameter
Location-Info-Request (LIR) command.
In addition to the values already defined in RFC 3588 [RFC3588], the
Result-Code AVP may contain one of the values defined in
Section 10.1. When the Diameter server finds an error in processing
the Diameter LIR message, the Diameter server MUST stop the process
of the message and answer with a Diameter LIA message that includes
the appropriate error code in the Result-Code AVP value. When there
is no error, the Diameter server MUST set the Result-Code AVP value
to DIAMETER_SUCCESS in the Diameter LIA message.
One of the errors that the Diameter server may find is that the
SIP-AOR AVP value is not a valid user in the realm. In such cases,
the Diameter server MUST set the Result-Code AVP value to
DIAMETER_ERROR_USER_UNKNOWN and return it in a Diameter LIA message.
If the Diameter server cannot process the Diameter LIR command, e.g.,
due to a database error, the Diameter server MUST set the Result-Code
AVP value to DIAMETER_UNABLE_TO_COMPLY and return it in a Diameter
LIA message. The Diameter server MUST NOT include any SIP-Server-URI
or SIP-Server-Capabilities AVP in the Diameter LIA message.
The Diameter server may or may not be aware of a SIP server assigned
to the SIP-AOR AVP value included in the Diameter LIR message. If
the Diameter server is aware of a SIP server allocated to that
particular user, the Diameter server MUST include the URI of such SIP
server in the SIP-Server-URI AVP and return it in a Diameter LIA
message. This is typically the situation when the user is either
registered, or unregistered but a SIP server is still assigned to the
user.
When the Diameter server is not aware of a SIP server allocated to
the user (typically the case when the user unregistered), the
Result-Code AVP value in the Diameter LIA message depends on whether
the Diameter server is aware that the user has services defined for
unregistered users:
o Those users who have services defined for unregistered users may
require the allocation of a SIP server to trigger and perhaps
execute those services. Therefore, when the Diameter server is
not aware of an assigned SIP server, but the user has services
defined for unregistered users, the Diameter server MUST set the
Result-Code AVP value to DIAMETER_UNREGISTERED_SERVICE and return
it in a Diameter LIA message. The Diameter server MAY also
include a SIP-Server-Capabilities AVP to facilitate the SIP server
(Diameter client) with the selection of an appropriate SIP server
with the required capabilities. Absence of the SIP-Server-
Capabilities AVP indicates to the SIP server (Diameter client)
that any SIP server is suitable to be allocated for the user.
o Those users who do not have service defined for unregistered users
do not require further processing. The Diameter server MUST set
the Result-Code AVP value to
DIAMETER_ERROR_IDENTITY_NOT_REGISTERED and return it to the
Diameter client in a Diameter LIA message. The SIP server
(Diameter client) may return the appropriate SIP response (e.g.,
480 (Temporarily unavailable)) to the original SIP request.
The Message Format of the LIA command is as follows:
::= < Diameter Header: 285, PXY >
< Session-Id >
{ Auth-Application-Id }
{ Result-Code }
{ Auth-Session-State }
{ Origin-Host }
{ Origin-Realm }
[ SIP-Server-URI ]
[ SIP-Server-Capabilities ]
[ Auth-Grace-Period ]
[ Authorization-Lifetime ]
[ Redirect-Host ]
[ Redirect-Host-Usage ]
[ Redirect-Max-Cache-Time ]
* [ Proxy-Info ]
* [ Route-Record ]
* [ AVP ]
*/
struct dict_object * cmd;
struct dict_cmd_data data = {
285, /* Code */
"Location-Info-Answer", /* Name */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
CMD_FLAG_PROXIABLE /* Fixed flag values */
};
struct local_rules_definition rules[] =
{ { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
,{ "Result-Code", RULE_REQUIRED, -1, 1 }
,{ "Auth-Session-State", RULE_REQUIRED, -1, 1 }
,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
,{ "SIP-Server-URI", RULE_OPTIONAL, -1, 1 }
,{ "SIP-Server-Capabilities", RULE_OPTIONAL, -1, 1 }
,{ "Auth-Grace-Period", RULE_OPTIONAL, -1, 1 }
,{ "Authorization-Lifetime", RULE_OPTIONAL, -1, 1 }
,{ "Redirect-Host", RULE_OPTIONAL, -1, 1 }
,{ "Redirect-Host-Usage", RULE_OPTIONAL, -1, 1 }
,{ "Redirect-Max-Cache-Time", RULE_OPTIONAL, -1, 1 }
,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
,{ "Route-Record", RULE_OPTIONAL, -1, -1 }
};
CHECK_dict_new( DICT_COMMAND, &data , cxdx_dict, &cmd);
PARSE_loc_rules( rules, cmd, AVP_BY_NAME );
}
/* Registration-Termination-Request (RTR) Command */
{
/*
The Registration-Termination-Request (RTR) command is indicated by
the Command-Code set to 287 and the Command Flags' 'R' bit set. The
Diameter server sends this command to the Diameter client in a SIP
server to indicate to the SIP server that one or more SIP AORs have
to be deregistered. The command allows an operator to
administratively cancel the registration of a user from a centralized
Diameter server.
The Diameter server has the capability to initiate the deregistration
of a user and inform the SIP server by means of the Diameter RTR
command. The Diameter server can decide whether only one SIP AOR is
going to be deregistered, a list of SIP AORs, or all the SIP AORs
allocated to the user.
The absence of a SIP-AOR AVP in the Diameter RTR message indicates
that all the SIP AORs allocated to the user identified by the
User-Name AVP are being deregistered.
The Diameter server MUST include a SIP-Deregistration-Reason AVP
value to indicate the reason for the deregistration.
The Message Format of the RTR command is as follows:
::= < Diameter Header: 287, REQ, PXY >
< Session-Id >
{ Auth-Application-Id }
{ Auth-Session-State }
{ Origin-Host }
{ Origin-Realm }
{ Destination-Host }
{ SIP-Deregistration-Reason }
[ Destination-Realm ]
[ User-Name ]
* [ SIP-AOR ]
* [ Proxy-Info ]
* [ Route-Record ]
* [ AVP ]
*/
struct dict_object * cmd;
struct dict_cmd_data data =
{
287, /* Code */
"Registration-Termination-Request", /* Name */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */
};
struct local_rules_definition rules[] =
{
{ "Session-Id", RULE_FIXED_HEAD, -1, 1 },
{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 },
{ "Auth-Session-State", RULE_REQUIRED, -1, 1 },
{ "Origin-Host", RULE_REQUIRED, -1, 1 },
{ "Origin-Realm", RULE_REQUIRED, -1, 1 },
{ "Destination-Host", RULE_REQUIRED, -1, 1 },
{ "SIP-Deregistration-Reason",RULE_REQUIRED, -1, 1 },
{ "Destination-Realm", RULE_OPTIONAL, -1, 1 },
{ "User-Name", RULE_OPTIONAL, -1, 1 },
{ "SIP-AOR", RULE_REQUIRED, -1, -1 },
{ "Proxy-Info", RULE_OPTIONAL, -1, -1 },
{ "Route-Record", RULE_OPTIONAL, -1, -1 }
};
CHECK_dict_new( DICT_COMMAND, &data , cxdx_dict, &cmd);
PARSE_loc_rules( rules, cmd, AVP_BY_NAME );
}
/* Registration-Termination-Answer (RTA) Command */
{
/*
The Registration-Termination-Answer (RTA) is indicated by the
Command-Code set to 287 and the Command Flags' 'R' bit cleared. The
Diameter client sends this command in response to a previously
received Diameter Registration-Termination-Request (RTR) command.
In addition to the values already defined in RFC 3588 [RFC3588], the
Result-Code AVP may contain one of the values defined in
Section 10.1.
If the SIP server (Diameter client) requires a User-Name AVP value to
process the Diameter RTR request, but the Diameter RTR message did
not contain a User-Name AVP value, the Diameter client MUST set the
Result-Code AVP value to DIAMETER_USER_NAME_REQUIRED (see Section
10.1.2) and return it in a Diameter RTA message.
The SIP server (Diameter client) applies the administrative
deregistration to each of the URIs included in each of the SIP-AOR
AVP values, or, if there is no SIP-AOR AVP present in the Diameter
RTR request, to all the URIs allocated to the User-Name AVP value.
The value of the SIP-Deregistration-Reason AVP in the Diameter RTR
command has an effect on the actions performed at the SIP server
(Diameter client):
o If the value is set to PERMANENT_TERMINATION, then the user has
terminated his/her registration to the realm. If informing the
interested parties (e.g., subscribers to the "reg" event
[RFC3680]) about the administrative deregistration is supported
through SIP procedures, the SIP server (Diameter client) will do
so. The Diameter Client in the SIP Server SHOULD NOT request a
new user registration. The SIP server clears the registration
state of the deregistered AORs.
o If the value is set to NEW_SIP_SERVER_ASSIGNED, the Diameter
server informs the SIP server (Diameter client) that a new SIP
server has been allocated to the user, due to some reason. The
SIP server, if supported through SIP procedures, will inform the
interested parties (e.g., subscribers to the "reg" event
[RFC3680]) about the administrative deregistration at this SIP
server. The Diameter client in the SIP server SHOULD NOT request
a new user registration. The SIP server clears the registration
state of the deregistered SIP AORs.
o If the value is set to SIP_SERVER_CHANGE, the Diameter server
informs the SIP server (Diameter client) that a new SIP server has
to be allocated to the user, e.g., due to user's capabilities
requiring a new SIP server, or not enough resources in the current
SIP server. If informing the interested parties about the
administrative deregistration is supported through SIP procedures
(e.g., subscriptions to the "reg" event [RFC3680]), the SIP server
will do so. The Diameter client in the SIP Server SHOULD NOT
request a new user registration. The SIP server clears the
registration state of the deregistered SIP AORs.
o If the value is set to REMOVE_SIP_SERVER, the Diameter server
informs the SIP server (Diameter client) that the SIP server will
no longer be bound in the Diameter server with that user. The SIP
server can delete all data related to the user.
The Message Format of the RTA command is as follows:
::= < Diameter Header: 287, PXY >
< Session-Id >
{ Auth-Application-Id }
{ Result-Code }
{ Auth-Session-State }
{ Origin-Host }
{ Origin-Realm }
[ Authorization-Lifetime ]
[ Auth-Grace-Period ]
[ Redirect-Host ]
[ Redirect-Host-Usage ]
[ Redirect-Max-Cache-Time ]
* [ Proxy-Info ]
* [ Route-Record ]
* [ AVP ]
*/
struct dict_object * cmd;
struct dict_cmd_data data = {
287, /* Code */
"Registration-Termination-Answer", /* Name */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
CMD_FLAG_PROXIABLE /* Fixed flag values */
};
struct local_rules_definition rules[] =
{ { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
,{ "Result-Code", RULE_REQUIRED, -1, 1 }
,{ "Auth-Session-State", RULE_REQUIRED, -1, 1 }
,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
,{ "Authorization-Lifetime", RULE_OPTIONAL, -1, 1 }
,{ "Auth-Grace-Period", RULE_OPTIONAL, -1, 1 }
,{ "Redirect-Host", RULE_OPTIONAL, -1, 1 }
,{ "Redirect-Host-Usage", RULE_OPTIONAL, -1, 1 }
,{ "Redirect-Max-Cache-Time", RULE_OPTIONAL, -1, 1 }
,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
,{ "Route-Record", RULE_OPTIONAL, -1, -1 }
};
CHECK_dict_new( DICT_COMMAND, &data , cxdx_dict, &cmd);
PARSE_loc_rules( rules, cmd, AVP_BY_NAME );
}
/* Push-Profile-Request (PPR) Command */
{
/*
The Push-Profile-Request (PPR) command is indicated by the
Command-Code set to 288 and the Command Flags' 'R' bit set. The
Diameter server sends this command to the Diameter client in a SIP
server to update either the user profile of an already registered
user in that SIP server or the SIP accounting information. This
allows an operator to modify the data of a user profile or the
accounting information and push it to the SIP server where the user
is registered.
Each user has a user profile associated with him/her and other
accounting information. The profile or the accounting information
may change with time, e.g., due to addition of new services to the
user. When the user profile or the accounting information changes,
the Diameter server sends a Diameter Push-Profile-Request (PPR)
command to the Diameter client in a SIP server, in order to start
applying those new services.
A PPR command MAY contain a SIP-Accounting-Information AVP that
updates the addresses of the accounting servers. Changes in the
addresses of the accounting servers take effect immediately. The
Diameter client SHOULD close any existing accounting session with the
existing server and start providing accounting information to the
newly acquired accounting server.
A PPR command MAY contain zero or more SIP-User-Data AVP values
containing the new user profile. On selecting the type of user data,
the Diameter server SHOULD take into account the supported formats at
the SIP server (SIP-Supported-User-Data-Type AVP sent in a previous
SAR message) and the local policy.
The User-Name AVP indicates the user to whom the profile is
applicable.
The Message Format of the PPR command is as follows:
::= < Diameter Header: 288, REQ, PXY >
< Session-Id >
{ Auth-Application-Id }
{ Auth-Session-State }
{ Origin-Host }
{ Origin-Realm }
{ Destination-Realm }
{ User-Name }
* [ SIP-User-Data ]
[ SIP-Accounting-Information ]
[ Destination-Host ]
[ Authorization-Lifetime ]
[ Auth-Grace-Period ]
* [ Proxy-Info ]
* [ Route-Record ]
* [ AVP ]
*/
struct dict_object * cmd;
struct dict_cmd_data data = {
288, /* Code */
"Push-Profile-Request", /* Name */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */
};
struct local_rules_definition rules[] =
{ { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
,{ "Auth-Session-State", RULE_REQUIRED, -1, 1 }
,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
,{ "Destination-Realm", RULE_REQUIRED, -1, 1 }
,{ "User-Name", RULE_REQUIRED, -1, 1 }
,{ "SIP-User-Data", RULE_OPTIONAL, -1, -1 }
,{ "SIP-Accounting-Information", RULE_OPTIONAL, -1, 1 }
,{ "Destination-Host", RULE_OPTIONAL, -1, 1 }
,{ "Authorization-Lifetime", RULE_OPTIONAL, -1, 1 }
,{ "Auth-Grace-Period", RULE_OPTIONAL, -1, 1 }
,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
,{ "Route-Record", RULE_OPTIONAL, -1, -1 }
};
CHECK_dict_new( DICT_COMMAND, &data , cxdx_dict, &cmd);
PARSE_loc_rules( rules, cmd, AVP_BY_NAME );
}
/* Push-Profile-Answer (PPA) Command */
{
/*
The Push-Profile-Answer (PPA) is indicated by the Command-Code set to
288 and the Command Flags' 'R' bit cleared. The Diameter client
sends this command in response to a previously received Diameter
Push-Profile-Request (PPR) command.
In addition to the values already defined in RFC 3588 [RFC3588], the
Result-Code AVP may contain one of the values defined in
Section 10.1.
If there is no error when processing the received Diameter PPR
message, the SIP server (Diameter client) MUST download the received
user profile from the SIP-User-Data AVP values in the Diameter PPR
message and store it associated with the user specified in the
User-Name AVP value.
If the SIP server does not recognize or does not support some of the
data transferred in the SIP-User-Data AVP values, the Diameter client
in the SIP server MUST return a Diameter PPA message that includes a
Result-Code AVP set to the value DIAMETER_ERROR_NOT_SUPPORTED_USER_DATA.
If the SIP server (Diameter client) receives a Diameter PPR message
with a User-Name AVP that is unknown, the Diameter client MUST set
the Result-Code AVP value to DIAMETER_ERROR_USER_UNKNOWN and MUST
return it to the Diameter server in a Diameter PPA message.
If the SIP server (Diameter client) receives in the
SIP-User-Data-Content AVP value (of the grouped SIP-User-Data AVP)
more data than it can accept, it MUST set the Result-Code AVP value
to DIAMETER_ERROR_TOO_MUCH_DATA and MUST return it to the Diameter
server in a Diameter PPA message. The SIP server MUST NOT override
the existing user profile with the one received in the PPR message.
If the Diameter server receives the Result-Code AVP value set to
DIAMETER_ERROR_TOO_MUCH_DATA in a Diameter PPA message, it SHOULD
force a new re-registration of the user by sending to the Diameter
client a Diameter Registration-Termination-Request (RTR) with the
SIP-Deregistration-Reason AVP value set to SIP_SERVER_CHANGE. This
will force a re-registration of the user and will trigger a selection
of a new SIP server.
If the Diameter client is not able to honor the command, for any
other reason, it MUST set the Result-Code AVP value to
DIAMETER_UNABLE_TO_COMPLY and it MUST return it in a Diameter PPA
message.
The Message Format of the PPA command is as follows:
::= < Diameter Header: 288, PXY >
< Session-Id >
{ Auth-Application-Id }
{ Result-Code }
{ Auth-Session-State }
{ Origin-Host }
{ Origin-Realm }
[ Redirect-Host ]
[ Redirect-Host-Usage ]
[ Redirect-Max-Cache-Time ]
* [ Proxy-Info ]
* [ Route-Record ]
* [ AVP ]
*/
struct dict_object * cmd;
struct dict_cmd_data data = {
288, /* Code */
"Push-Profile-Answer", /* Name */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
CMD_FLAG_PROXIABLE /* Fixed flag values */
};
struct local_rules_definition rules[] =
{ { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
,{ "Result-Code", RULE_REQUIRED, -1, 1 }
,{ "Auth-Session-State", RULE_REQUIRED, -1, 1 }
,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
,{ "Redirect-Host", RULE_OPTIONAL, -1, 1 }
,{ "Redirect-Host-Usage", RULE_OPTIONAL, -1, 1 }
,{ "Redirect-Max-Cache-Time", RULE_OPTIONAL, -1, 1 }
,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
,{ "Route-Record", RULE_OPTIONAL, -1, -1 }
};
CHECK_dict_new( DICT_COMMAND, &data , cxdx_dict, &cmd);
PARSE_loc_rules( rules, cmd, AVP_BY_NAME );
}
#endif /* TODO - NRGJ */
} /* end Command section */
TRACE_DEBUG(INFO, "Extension 'Dictionary CxDx' initialized");
return 0;
}
EXTENSION_ENTRY("dict_cxdx", cxdx_dict_init);
nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/CxDx/dict_cxdx.xml 0000664 0000000 0000000 00000031261 13335533574 0024057 0 ustar 00root root 0000000 0000000
nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/OpenWRT/ 0000775 0000000 0000000 00000000000 13335533574 0022011 5 ustar 00root root 0000000 0000000 nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/OpenWRT/HOWTO 0000664 0000000 0000000 00000025774 13335533574 0022653 0 ustar 00root root 0000000 0000000 #####################
# !! IMPORTANT !! #
#####################
The uClibc library that is shipped with OpenWRT lacks support for several POSIX thread
features, such as pthread_cleanup_{push,pop}, that are required by the freeDiameter
framework.
Until these features are included in the base OpenWRT system, the framework will not
behave correctly on this platform.
Therefore, the OpenWRT port is NOT usable properly at this moment with uClibc.
A test software is included in test_required for checking if new uClibc distributions
support the required features. You'll have to adapt the Makefile according to your environment.
An alternative choice if your hardware allows it is to use (e)glibc in your openwrt image.
#####################
This HOWTO describes how to generate a set of ipkg modules for
providing support of freeDiameter in an OpenWRT system.
This HOWTO is written for OpenWRT 10.03 (BackFire) and no guarantee is provided
that it will work for you. Be prepared to eventually brick your routeur...
Table of contents:
0) Quick HOWTO: optimistic step-by-step instructions.
1) Prerequisites: get the OpenWRT development environment ready.
2) Supplied packages: use the existing packages when possible (gnutls, ...)
3) Other dependencies: provide for additional missing dependencies (sctp ...)
4) freediameter package: now create the freeDiameter package
5) Configuration: how to set the configuration on the router.
This HOWTO will NOT cover how to install OpenWRT on your access device, nor
its basic configuration. Please refer to OpenWRT website for this type of HOWTOs.
==============================================
0) Quick HOWTO
==============================================
The following instructions should allow you to put freeDiameter on your OpenWRT-compatible router.
In case something goes wrong, you should follow the detailed instructions in the remaining of
this file.
Be warned: playing with the software in your router may brick it, i.e. make it unusable forever.
Do it at your own risk.
1) Get the OpenWRT environment:
$ git clone git://nbd.name/openwrt.git
$ cd openwrt
2) Get the feeds
$ cp feeds.conf.default feeds.conf
$ echo "src-hg freediameter http://www.freediameter.net/hg/fD-OWRT-packages" >> feeds.conf
$ scripts/feeds update
$ scripts/feeds install freeDiameter
3) Configure your image
$ make menuconfig
(set Target System and Target Profile as needed for your equipment)
- Network --->
freeDiameter (M)
freeDiameter-test (M)
wpad (*)
wpad-mini ( )
4) Set the C library to glibc instead of uClibc (broken support, see #26)
- Advanced configuration options (for developers) --->
- Toolchain Options ---->
C Library implementation (Use eglibc)
5) Build the image and packages, this takes a while
$ make world
6) Export the bin/* directory through a webserver.
We assume it is available at http://192.168.1.25/owrt
7) Flash the router with your new image -- THIS DESTROYS ALL CONFIG ON THE ROUTER!
$ ssh root@192.168.1.1
# cd /tmp
# wget http://192.168.1.25/owrt/openwrt-brcm47xx-squashfs.trx
;; change the file name with yours
# mtd -r write openwrt-brcm47xx-squashfs.trx linux
;; wait for reboot
$ telnet 192.168.1.1
# passwd
# sync
# exit
8) Update the opkg router's config to get your new packages
ssh root@192.168.1.1
# echo "src/gz localrepo http://192.168.1.25/owrt/packages" >> /etc/opkg.conf
# opkg update
9) Install freeDiameter, you're done. Optionnaly, install also certtool on the router before, to
generate the TLS certificate automatically.
# opkg install freeDiameter
==============================================
1) Prerequisites:
==============================================
We will first need a working OpenWRT toolchain environment. You can retrieve
pre-compiled binaries of such toolchains ("Image builder") on the OpenWRT website. Anyway,
in case the architecture you are interested in is not listed, you can build
the full toolchain from source. This is the path we are following in this HOWTO.
a) Retrieve the latest OpenWRT source, using subversion or git.
Since I have to go through a proxy, I use the later here, svn being quite annoying with proxies.
Note, the following commands must not be run as root.
$ git clone git://nbd.name/openwrt.git
(Note: you might instead use "backfire.git" if you want to stick with an OpenWRT release.)
$ cd openwrt
$ cp feeds.conf.default feeds.conf
b) If you are using git, you have to edit the feeds.conf file to use git as well for packages.
Do the following modifications in this case:
$ vi feeds.conf
Comment out this line:
src-svn packages https://svn.openwrt.org/openwrt/packages
Add this line instead:
src-git packages git://nbd.name/packages.git
You can leave uncommented the luci (for GNUTLS) and Xwrt (webif) repositories. Since these repositories
use svn over http, you can use subversion even if you are behind a proxy.
c) Then issue the following command to update the package list:
$ scripts/feeds update
d) Now, let's already create the toolchain and basic image.
$ make menuconfig
This will open a menu for you. You must select the target you are building for.
See http://wiki.openwrt.org/toh/start for the table of hardware and associated information.
In my case, I am using a Buffalo WZR-HP-G300NH router. I therefore select these options:
- Target System --->
Atheros AR71xx/AR7240/AR913x
- Target Profile --->
Buffalo WZR-HP-G300NH
For many routeurs, the recommended kernel is a 2.4x version. I have NOT tried with such kernel,
and the SCTP support is likely to be different in this generation of kernels. I strongly recommend
to go with a 2.6x kernel, whenever possible.
e) As per freeDiameter ticket #26, you also need to change the library to glibc instead of uClibc.
Change the option as follow:
- Advanced configuration options (for developers) --->
- Toolchain Options ---->
C Library implementation (Use eglibc)
f) Once configured, create the toolchain and default image (this takes a while):
$ make world
After this command completes successfully, your build environment is ready.
The resulting image and packages are stored in the "bin/" subdirectory.
It is very convenient if you make this repository available in http to your routeur.
You should probably try at this early stage to flash your device with the image you have generated.
If the default basic image does not work, it is probably not worth adding new problems on top of it.
For troubleshooting, please consult OpenWRT documentation directly.
"make prereq" may help you building the initial image also.
See http://downloads.openwrt.org/docs/buildroot-documentation.html for additional information
concerning this step.
You should now be able to login on your routeur with telnet (first time) or ssh (after setting a password).
==============================================
2) Supplied packages:
==============================================
There are some dependencies of freeDiameter already available in the OpenWRT packages repository.
You can check for the available packages with the script:
$ ./scripts/feeds search
We will now describe how to install these dependencies. At the time this HOWTO is written,
the OpenWRT repositories contains packages for sctp, ipv6, gnutls, pthreads and hostapd.
Follow these instructions to build them.
Alternatively, you can find these packages pre-compiled in the OpenWRT packages repository.
a) Add the packages
$ scripts/feeds install libgnutls
$ scripts/feeds install sctp
b) Select the following components in the menu:
$ make menuconfig
- Base system --->
libpthread (M)
- Network --->
sctp (M)
hostapd (M)
wpad-mini ( )
- Libraries --->
SSL --->
libgnutls (M)
- Kernel modules --->
Network Support --->
kmod-ipv6 (M)
Quit and save the new config, then:
$ make world
This will add a bunch of modules in your bin directory that will be required for freeDiameter.
Since we are removing the wpad-mini daemon from the base image, this image (trx or bin file) is also recompiled.
Note that if you are setting your device as WPA supplicant also (wireless client), you must select wpad instead of hostapd.
(in any case, the -mini version is not suitable since we will use the RADIUS authentication).
You should now reflash your routeur with the new firmware image. The simplest way to achieve if your routeur has enough
flash memory is to:
- copy the new trx image to your routeur's /tmp (using wget or scp)
- run this command (on the device) -- replace with your actual filename:
root@OpenWrt:~# mtd -r write linux
WARNING: this will erase your existing configuration on the routeur.
In case you need to save it, you may try the sysupgrade command instead.
This will reboot the device after writing the new image file.
Afterwards, if you have set up the http server on your development machine properly
(let's assume it has IP address 192.168.1.25)
you can run the following command on your router:
root@OpenWrt:~# echo "src/gz mydev http://192.168.1.25/packages" >> /etc/opkg.conf
root@OpenWrt:~# opkg update
Install the newly compiled packages with:
root@OpenWrt:~# opkg install kmod-ipv6 hostapd libpthread sctp
==============================================
3) Missing packages:
==============================================
UPDATE: Starting from revision r22917, sctp and kmod-sctp are included in the OpenWRT distribution, and have been removed
from freeDiameter package. One may consider using a freeDiameter package prior to 2010/09/05 in order to get the sctp
package, or a more recent OpenWRT environment.
PREVIOUS SITUATION: If you are using components prior to 2010/09/05, the following applies:
P:
P: There are other dependencies for freeDiameter that are not provided by OpenWRT packages.
P: For convenience, we include these meta-packages in the freeDiameter distribution -- but they
P: might not be up-to-date.
P:
P: a) Adding the contributed directory to the feeds
P: Add the following line in your feeds.conf file:
P: src-link freediameter /path/to/freediameter/contrib/OpenWRT/packages/
P:
P: Then run:
P: $ scripts/feeds update
P:
P: This should allow you to install the missing dependencies as follow:
P:
P:
P: b) SCTP library (note: you might alternatively compile freeDiameter without SCTP support).
P: $ scripts/feeds install sctp
P:
P:
P: c) Select these components in the menu:
P: $ make menuconfig
P: - Libraries --->
P: sctp (M)
P:
P: Quit and save the new config, then:
P: $ make world
P:
P:
P: d) Install this on the router as well:
P: root@OpenWrt:~# opkg update
P: root@OpenWrt:~# opkg install sctp
==============================================
4) freediameter package:
==============================================
Now, your environment should be ready to compile the freeDiameter ipkg package.
$ scripts/feeds install freeDiameter
Note that in order to build this package, you need to have cmake & flex on your compilation machine.
$ make menuconfig
- Network --->
freeDiameter (M)
freeDiameter-test (M)
Quit and save the new config, then:
$ make world
On your router, run:
# opkg update
# opkg install freeDiameter
nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/OpenWRT/others/ 0000775 0000000 0000000 00000000000 13335533574 0023315 5 ustar 00root root 0000000 0000000 nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/OpenWRT/others/D-Link_DIR-330_netconfig.patch 0000664 0000000 0000000 00000003274 13335533574 0030457 0 ustar 00root root 0000000 0000000 diff --git a/target/linux/brcm47xx/base-files/etc/init.d/netconfig b/target/linux/brcm47xx/base-files/etc/init.d/netconfig
index d7839b6..6446483 100755
--- a/target/linux/brcm47xx/base-files/etc/init.d/netconfig
+++ b/target/linux/brcm47xx/base-files/etc/init.d/netconfig
@@ -150,6 +150,30 @@ start() {
}
}
}
+ if (model == "D-Link DIR-330") { # boardtype is 0x0472, so we need to reset the parameters
+ # The switch is on eth1, this script defaults to switch on eth0, so we write the values directly instead.
+ print "#### DIR-330: eth1 must be up for configuring the switch "
+ print "config interface switchport"
+ print " option ifname \"eth1\""
+ print " option proto none"
+ print ""
+ print "config switch eth1"
+ print " option enable 1"
+ print ""
+ print "config switch_vlan eth1_0"
+ print " option device \"eth1\""
+ print " option vlan 0"
+ print " option ports \"0 1 2 3 5t\""
+ print ""
+ print "config switch_vlan eth1_1"
+ print " option device \"eth1\""
+ print " option vlan 1"
+ print " option ports \"4 5t\""
+ print ""
+ c["lan_ifname"] = "eth0.0"
+ c["wan_ifname"] = "eth0.1"
+ }
+
# Buffalo WBR-B11 and Buffalo WBR-G54
if (nvram["boardtype"] == "bcm94710ap") {
c["vlan0ports"] = "0 1 2 3 4 5u"
nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/OpenWRT/packages/ 0000775 0000000 0000000 00000000000 13335533574 0023567 5 ustar 00root root 0000000 0000000 nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/OpenWRT/packages/freeDiameter/ 0000775 0000000 0000000 00000000000 13335533574 0026163 5 ustar 00root root 0000000 0000000 nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/OpenWRT/packages/freeDiameter/Makefile 0000664 0000000 0000000 00000022226 13335533574 0027627 0 ustar 00root root 0000000 0000000 #
# Software License Agreement (BSD License)
#
# Copyright (c) 2013, WIDE Project and NICT
# All rights reserved.
#
# See LICENSE file from freeDiameter source package for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=freeDiameter
PKG_REV:=696
PKG_VERSION:=r$(PKG_REV)
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=hg
PKG_SOURCE_VERSION:=$(PKG_REV)
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://www.freediameter.net/hg/freeDiameter
# PKG_MD5SUM:=
PKG_FIXUP:=libtool
PKG_INSTALL:=1
include $(INCLUDE_DIR)/package.mk
define Package/freeDiameter
SECTION:=freeDiameter
CATEGORY:=Network
TITLE:=freeDiameter
URL:=http://www.freediameter.net
DEPENDS:=+sctp +libgnutls +libpthread +kmod-ipv6
endef
define Package/freeDiameter-test
SECTION:=freeDiameter
CATEGORY:=Network
TITLE:=freeDiameter-test
URL:=http://www.freediameter.net
DEPENDS:=+freeDiameter
endef
define Package/freeDiameter/description
freeDiameter + RADIUS/Diameter gateway extension package.
endef
define Package/freeDiameter-test/description
The app_test.fdx extension for freeDiameter, useful only to perform some
tests between freeDiameter peers (ping-like for Diameter).
endef
define Package/freeDiameter/conffiles
/etc/freeDiameter/freeDiameter.conf
/etc/freeDiameter/rgw.conf
endef
define Build/Configure
IN_OPENWRT=1 \
AR="$(TARGET_CROSS)ar" \
AS="$(TARGET_CC) -c $(TARGET_CFLAGS)" \
LD="$(TARGET_CROSS)ld" \
NM="$(TARGET_CROSS)nm" \
CC="$(TARGET_CC)" \
GCC="$(TARGET_CC)" \
CXX="$(TARGET_CROSS)g++" \
RANLIB="$(TARGET_CROSS)ranlib" \
STRIP="$(TARGET_CROSS)strip" \
OBJCOPY="$(TARGET_CROSS)objcopy" \
OBJDUMP="$(TARGET_CROSS)objdump" \
TARGET_CPPFLAGS="$(TARGET_CPPFLAGS)" \
TARGET_CFLAGS="$(TARGET_CFLAGS)" \
TARGET_LDFLAGS="$(TARGET_LDFLAGS)" \
cmake \
-DCMAKE_PREFIX_PATH:PATH=$(STAGING_DIR)/usr \
-DCMAKE_INSTALL_PREFIX:PATH=/usr \
-DDIAMID_IDNA_REJECT:BOOL=ON \
-DBUILD_TESTING:BOOL=OFF \
-DCMAKE_BUILD_TYPE:STRING=DebianPackage \
-DDEFAULT_CONF_PATH:PATH=/etc/freeDiameter \
-DBUILD_APP_RADGW:BOOL=ON \
-DBUILD_DBG_MONITOR:BOOL=ON \
-DBUILD_TEST_APP:BOOL=ON \
VERBOSE=1 \
$(PKG_BUILD_DIR)/CMakeLists.txt
endef
TARGET_LDFLAGS := -L$(STAGING_DIR)/usr/lib $(TARGET_LDFLAGS)
define Package/freeDiameter/install
# binaries
$(INSTALL_DIR) $(1)/usr/bin
$(CP) \
$(PKG_INSTALL_DIR)/usr/bin/freeDiameterd* \
$(1)/usr/bin/
# libraries & extensions
$(INSTALL_DIR) $(1)/usr/lib/
$(CP) \
$(PKG_INSTALL_DIR)/usr/lib/* \
$(1)/usr/lib/
# Remove the test_app from the main package (see freeDiameter-test)
$(RM) $(1)/usr/lib/freeDiameter/test_app*
# configuration files
$(INSTALL_DIR) $(1)/etc/freeDiameter
$(INSTALL_CONF) \
$(PKG_BUILD_DIR)/doc/freediameter.conf.sample \
$(1)/etc/freeDiameter/freeDiameter.conf
$(SED) 's,TLS_Cred,#TLS_Cred,g' $(1)/etc/freeDiameter/freeDiameter.conf
echo "" >> $(1)/etc/freeDiameter/freeDiameter.conf
echo "### OPENWRT specific" >> $(1)/etc/freeDiameter/freeDiameter.conf
echo "TLS_Cred = \"/etc/freeDiameter/freeDiameter.pem\", \"/etc/freeDiameter/freeDiameter.key\";" \
>> $(1)/etc/freeDiameter/freeDiameter.conf
echo "TLS_CA = \"/etc/freeDiameter/freeDiameter.ca.pem\";" \
>> $(1)/etc/freeDiameter/freeDiameter.conf
echo "TLS_DH_File = \"/etc/freeDiameter/dh.pem\";" \
>> $(1)/etc/freeDiameter/freeDiameter.conf
echo "SCTP_streams = 3;" >> $(1)/etc/freeDiameter/freeDiameter.conf
echo "LoadExtension = \"dict_nasreq.fdx\";" >> $(1)/etc/freeDiameter/freeDiameter.conf
echo "LoadExtension = \"dict_eap.fdx\";" >> $(1)/etc/freeDiameter/freeDiameter.conf
echo "LoadExtension = \"app_radgw.fdx\":\"rgw.conf\";" \
>> $(1)/etc/freeDiameter/freeDiameter.conf
echo "# test_app.fdx provided in freeDiameter-test package:" \
>> $(1)/etc/freeDiameter/freeDiameter.conf
echo "# LoadExtension = \"test_app.fdx\";" >> $(1)/etc/freeDiameter/freeDiameter.conf
echo "## Add overrides below this point" >> $(1)/etc/freeDiameter/freeDiameter.conf
$(INSTALL_CONF) \
$(PKG_BUILD_DIR)/doc/app_radgw.conf.sample \
$(1)/etc/freeDiameter/rgw.conf
$(SED) 's,RGWX,#RGWX,g' $(1)/etc/freeDiameter/rgw.conf
echo "" >> $(1)/etc/freeDiameter/rgw.conf
echo "### OPENWRT specific" >> $(1)/etc/freeDiameter/rgw.conf
echo " RGWX = \"auth.rgwx\" : auth;" >> $(1)/etc/freeDiameter/rgw.conf
echo " RGWX = \"acct.rgwx\" : acct;" >> $(1)/etc/freeDiameter/rgw.conf
echo "" >> $(1)/etc/freeDiameter/rgw.conf
echo " cli = 127.0.0.1 / \"secret key\" ;" >> $(1)/etc/freeDiameter/rgw.conf
echo " auth_server_ip4 = 127.0.0.1;" >> $(1)/etc/freeDiameter/rgw.conf
echo " auth_server_ip6 = ::1 ;" >> $(1)/etc/freeDiameter/rgw.conf
echo " acct_server_ip4 = 127.0.0.1;" >> $(1)/etc/freeDiameter/rgw.conf
echo " acct_server_ip6 = ::1 ;" >> $(1)/etc/freeDiameter/rgw.conf
endef
define Package/freeDiameter-test/install
# Only the test_app extension
$(INSTALL_DIR) $(1)/usr/lib/freeDiameter/
$(CP) $(PKG_INSTALL_DIR)/usr/lib/freeDiameter/test_app* \
$(1)/usr/lib/freeDiameter/
endef
define Package/freeDiameter/postinst
#!/bin/sh
# Test if the configuration file contains the local identity already
localid=`sed -n -r -e "s/^[[:space:]]*Identity[[:space:]]*=[[:space:]]*\"([^\"]*)\"[[:space:]]*;/\1/p" /etc/freeDiameter/freeDiameter.conf`
if [ -z "$$localid" ]; then
# Ask for the local name
echo -n "Full name of your access point? (openwrt.localdomain) : "
read localid
if [ -z "$$localid" ]; then
localid="openwrt.localdomain"
fi
echo "Identity = \"$$localid\";" >> /etc/freeDiameter/freeDiameter.conf
fi
# Is there already a ConnectPeer directive?
grep -q -E -e "^[[:space:]]*ConnectPeer[[:space:]]*=" /etc/freeDiameter/freeDiameter.conf
if [ "$$?" -eq "1" ]; then
echo -n "Diameter Identity of your Diameter server: "
read serverid
if [ -z "$$serverid" ]; then
echo "Skipped. Please add ConnectPeer directive to your /etc/freeDiameter/freeDiameter.conf file later."
else
echo -n "IP or IPv6 address of your Diameter server? (leave blank for dynamic resolution) "
read serverip
connstr=""
if [ -n "$$serverip" ]; then
connstr=" { ConnectTo = \"$$serverip\"; }"
fi
echo "ConnectPeer = \"$$serverid\"$$connstr;" >> /etc/freeDiameter/freeDiameter.conf
fi
fi
# Certificate configuration
if [ ! -f "/usr/bin/certtool" ]; then
echo "certtool is not installed, skipping creation of default certificate and DH parameters."
echo "The following files are expected by freeDiameter:"
echo " /etc/freeDiameter/freeDiameter.key"
echo " /etc/freeDiameter/freeDiameter.pem"
echo " /etc/freeDiameter/freeDiameter.ca.pem"
echo " /etc/freeDiameter/dh.pem"
exit 0
fi
if [ ! -f "/etc/freeDiameter/freeDiameter.key" ]; then
echo "Creating a new private key for freeDiameter, please wait"
certtool -p --outfile /etc/freeDiameter/freeDiameter.key
fi
if [ ! -f "/etc/freeDiameter/freeDiameter.pem" ]; then
echo "organization = freeDiameter" > /tmp/template.cnf
echo "unit = OpenWRT" >>/tmp/template.cnf
echo "state = internet" >>/tmp/template.cnf
echo "country = net" >>/tmp/template.cnf
echo "cn = $$localid" >>/tmp/template.cnf
echo "expiration_days = 3650" >>/tmp/template.cnf
echo "signing_key" >>/tmp/template.cnf
echo "encryption_key" >>/tmp/template.cnf
if [ ! -f "/etc/freeDiameter/freeDiameter.csr" ]; then
echo "Creating a new CSR (use if you have a separate CA)"
certtool -q --load-privkey /etc/freeDiameter/freeDiameter.key \
--outfile /etc/freeDiameter/freeDiameter.csr \
--template /tmp/template.cnf
fi
echo "Creating a new certificate for freeDiameter"
certtool -s --load-privkey /etc/freeDiameter/freeDiameter.key \
--outfile /etc/freeDiameter/freeDiameter.pem \
--template /tmp/template.cnf
rm -f /tmp/template.cnf
cat /etc/freeDiameter/freeDiameter.pem >> /etc/freeDiameter/freeDiameter.ca.pem
echo "Done."
echo "========================================================================"
echo "To enable TLS communication, you should either:"
echo " - use a real certificate signed by your server's CA:"
echo " Use the CSR provided in /etc/freeDiameter/freeDiameter.csr"
echo " Save the new certificate as /etc/freeDiameter/freeDiameter.pem"
echo " Replace the contents of /etc/freeDiameter/freeDiameter.ca.pem with your CA's certificate"
echo " - or, declare the certificates as trusted as follow: "
echo " Add your server's CA certificate into /etc/freeDiameter/freeDiameter.ca.pem"
echo " Add the content of /etc/freeDiameter/freeDiameter.pem into your server's trusted CA file"
echo "========================================================================"
fi
if [ ! -f "/etc/freeDiameter/dh.pem" ]; then
echo "Creating new Diffie-Hellman parameters file. This operation takes a while..."
certtool --generate-dh-params --outfile /etc/freeDiameter/dh.pem
echo "Done."
fi
echo "freeDiameter configuration completed and stored in /etc/freeDiameter/."
endef
$(eval $(call BuildPackage,freeDiameter))
$(eval $(call BuildPackage,freeDiameter-test))
nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/OpenWRT/packages/freeDiameter/patches/ 0000775 0000000 0000000 00000000000 13335533574 0027612 5 ustar 00root root 0000000 0000000 01-freeDiameter-OpenWRT.patch 0000664 0000000 0000000 00000001416 13335533574 0034664 0 ustar 00root root 0000000 0000000 nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/OpenWRT/packages/freeDiameter/patches diff -Nur freeDiameter/CMakeLists.txt freeDiameter-OpenWRT/CMakeLists.txt
--- freeDiameter/CMakeLists.txt 2010-08-13 16:19:35.000000000 +0900
+++ freeDiameter-OpenWRT/CMakeLists.txt 2010-08-13 16:21:32.000000000 +0900
@@ -51,6 +51,14 @@
SET(DEBUG 1)
ENDIF (CMAKE_BUILD_TYPE MATCHES "Debug|Profiling|DebugValgrind")
+# OpenWRT
+SET(IN_OPENWRT $ENV{IN_OPENWRT})
+IF (IN_OPENWRT)
+ ADD_DEFINITIONS("$ENV{TARGET_LDFLAGS}" "$ENV{TARGET_CPPFLAGS}" "$ENV{TARGET_CFLAGS}")
+ INCLUDE_DIRECTORIES("$ENV{TARGET_LDFLAGS}" "$ENV{TARGET_CPPFLAGS}" "$ENV{TARGET_CFLAGS}")
+ENDIF(IN_OPENWRT)
+
+
# some subfolders use yacc and lex parsers
SET(BISON_GENERATE_DEFINES TRUE)
SET(BISON_PREFIX_OUTPUTS TRUE)
Binary files freeDiameter/.hg/dirstate and freeDiameter-OpenWRT/.hg/dirstate differ
nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/OpenWRT/test_required/ 0000775 0000000 0000000 00000000000 13335533574 0024670 5 ustar 00root root 0000000 0000000 nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/OpenWRT/test_required/Makefile 0000664 0000000 0000000 00000001407 13335533574 0026332 0 ustar 00root root 0000000 0000000 OWRT_ENV_ROOT=/root/openwrt-env/openwrt
STAGING_UCLIBC_ROOT=$(OWRT_ENV_ROOT)/staging_dir/target-mipsel_uClibc-0.9.31
STAGING_GCC_ROOT=$(OWRT_ENV_ROOT)/staging_dir/toolchain-mipsel_gcc-4.3.3+cs_uClibc-0.9.31
CFLAGS=-Os -pipe -mips32 -mtune=mips32 -funit-at-a-time -fhonour-copts -msoft-float -I$(STAGING_UCLIBC_ROOT)/usr/include -I$(STAGING_UCLIBC_ROOT)/include -I$(STAGING_GCC_ROOT)/usr/include -I$(STAGING_GCC_ROOT)/include
LDFLAGS=-L$(STAGING_UCLIBC_ROOT)/usr/lib -L$(STAGING_UCLIBC_ROOT)/lib -L$(STAGING_GCC_ROOT)/usr/lib -L$(STAGING_GCC_ROOT)/lib
GCC=mipsel-openwrt-linux-uclibc-gcc
PATH:=$(STAGING_GCC_ROOT)/bin/:$(PATH)
testcase: testcase.o
$(GCC) $(LDFLAGS) -lpthread testcase.o -o testcase
testcase.o: testcase.c
$(GCC) $(CFLAGS) -o testcase.o -c testcase.c
nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/OpenWRT/test_required/testcase.c 0000664 0000000 0000000 00000003760 13335533574 0026655 0 ustar 00root root 0000000 0000000 #include
#include
#include
#include
static pthread_barrier_t bar;
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cnd = PTHREAD_COND_INITIALIZER;
static int called = 0;
#ifndef ASSERT
#define ASSERT(x) assert(x)
#endif /* ASSERT */
static void cleanupmutex(void * arg)
{
printf("cancelation cleanup handler called\n");
if (arg) {
ASSERT( pthread_mutex_unlock((pthread_mutex_t *)arg) == 0 );
called++;
}
}
static void * mythread(void * a)
{
int ret;
/* lock mutex */
ASSERT( pthread_mutex_lock(&mtx) == 0 );
/* Push cleanup */
pthread_cleanup_push(cleanupmutex, &mtx);
printf("thread synchronization (mutex acquired)\n");
/* Wake the other thread */
ret = pthread_barrier_wait(&bar);
ASSERT( (ret == 0) || (ret == PTHREAD_BARRIER_SERIAL_THREAD) );
/* Now wait for the condition, this unlocks the mutex */
do {
printf("thread waiting cond\n");
ASSERT( pthread_cond_wait(&cnd, &mtx) == 0);
printf("thread woken\n");
} while (1);
/* Cleanup, never reached */
pthread_cleanup_pop(1);
return NULL;
}
int main(int argc, char * argv[])
{
int ret;
pthread_t thr;
void * dummy;
/* initialize the barrier */
ASSERT( pthread_barrier_init(&bar, NULL, 2) == 0 );
printf("Creating thread\n");
/* Create the thread */
ASSERT( pthread_create(&thr, NULL, mythread, NULL) == 0 );
printf("main synchronization\n");
ret = pthread_barrier_wait(&bar);
ASSERT( (ret == 0) || (ret == PTHREAD_BARRIER_SERIAL_THREAD) );
ASSERT( pthread_mutex_lock(&mtx) == 0 );
printf("main: thread is now waiting for condvar\n");
/* Cancel the thread */
ASSERT( pthread_cancel(thr) == 0 );
/* Now, unlock, so that the thread can actually really exit */
ASSERT( pthread_mutex_unlock(&mtx) == 0 );
/* Release thread resources */
ASSERT( pthread_join(thr, &dummy) == 0 );
if (called == 1)
printf("Test successful!\n");
else
printf("Test failed! Cleanup was not called (& lock not released)\n");
return 0;
}
nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/PKI/ 0000775 0000000 0000000 00000000000 13335533574 0021136 5 ustar 00root root 0000000 0000000 nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/PKI/ca_script/ 0000775 0000000 0000000 00000000000 13335533574 0023105 5 ustar 00root root 0000000 0000000 nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/PKI/ca_script/Makefile 0000664 0000000 0000000 00000013405 13335533574 0024550 0 ustar 00root root 0000000 0000000 #!/usr/bin/make -s
#
# This file is designed to automatize the CA tasks such as:
# -> init : create the initial CA tree and the CA root certificate.
# -> newcsr: create a new private key and csr. $name and $email must be set. C, ST, L, O, OU may be overwitten (example: make newcsr C=FR)
# -> cert : sign a pending CSR and generate the certificate. $name must be provided.
# -> revoke: revoke a certificate. $name must be provided.
# -> gencrl: update/create the CRL.
#
# The file should be located in the directory STATIC_DIR as defined below.
# The DIR directory will contain the data of the CA. It might be placed in /var.
# The DIR should also be configured in openssl.cnf file under [ CA_default ]->dir.
#
# Here are the steps to install the CA scripts in default environment:
## mkdir /etc/openssl-ca.static
## cp Makefile openssl.cnf /etc/openssl-ca.static
# ( configure the default parameters of your CA in /etc/openssl-ca/openssl.cnf ) ##
## mkdir /etc/openssl-ca
## make -f /etc/openssl-ca.static/Makefile destroy force=y
## cd /etc/openssl-ca
## make init
## make help
DIR = /home/thedoc/testbed.aaa/ca
STATIC_DIR = /home/thedoc/testbed.aaa/ca
CONFIG = -config $(DIR)/openssl.cnf
#Defaults for new CSR
C = JP
ST = Tokyo
L = Koganei
O = WIDE
OU = "AAA WG"
#Default lifetime
DAYS = 365
#Values for the CA
CA_CN = mgr.testbed.aaa
CA_mail = sdecugis@freediameter.net
#Disable "make destroy"
force =
# Default: print the help
all: help
# Help message
help:
@echo "\n\
Default values (can be overwritten on command-line):\n\
[C=$(C)] [ST=$(ST)] [L=$(L)] [O=$(O)] [OU=$(OU)]\n\
[CA_CN=$(CA_CN)] [CA_mail=$(CA_mail)]\n\n\
Available commands:\n\
make init\n\
Creates the initial CA structure in $(DIR)\n\
make gencrl\n\
Regenerates the CRL. Should be run at least once a month.\n\
make newcsr name=foo email=b@r [type=ca]\n\
Create private key and csr in clients subdir (named foo.*)\n\
make cert name=foo\n\
Signs the CSR foo.csr and creates the certificate foo.cert.\n\
make revoke name=foo\n\
Revokes the certificate foo.cert and regenerates the CRL.\n\
\n\
Notes:\n\
Content from public-www should be available from Internet. \n\
The URL to CRL should be set in openssl.cnf.\n\
A cron job should execute make gencrl once a month.\n\
";
# Destroy the CA completely. Use with care.
destroy:
@if [ -z "$(force)" ]; then echo "Restart disabled, use: make destroy force=y"; exit 1; fi
@if [ ! -d $(STATIC_DIR) ]; then echo "Error in setup"; exit 1; fi
@echo "Removing everything (for debug purpose)..."
@rm -rf $(DIR)/*
@ln -sf $(STATIC_DIR)/Makefile $(DIR)
@ln -sf $(STATIC_DIR)/openssl.cnf $(DIR)
# Initialize the CA structure and keys.
init:
@if [ -d $(DIR)/private ]; then echo "CA already initialized."; exit 1; fi
@echo "Creating CA structure..."
@mkdir $(DIR)/crl
@mkdir $(DIR)/certs
@mkdir $(DIR)/newcerts
@mkdir $(DIR)/public-www
@mkdir $(DIR)/private
@chmod 700 $(DIR)/private
@mkdir $(DIR)/clients
@mkdir $(DIR)/clients/privkeys
@mkdir $(DIR)/clients/csr
@mkdir $(DIR)/clients/certs
@echo "01" > $(DIR)/serial
@touch $(DIR)/index.txt
@openssl req $(CONFIG) -new -batch -x509 -days 3650 -nodes -newkey rsa:2048 -out $(DIR)/public-www/cacert.pem \
-keyout $(DIR)/private/cakey.pem -subj /C=$(C)/ST=$(ST)/L=$(L)/O=$(O)/OU=$(OU)/CN=$(CA_CN)/emailAddress=$(CA_mail)
@ln -s $(DIR)/public-www/cacert.pem $(DIR)/certs/`openssl x509 -noout -hash < $(DIR)/public-www/cacert.pem`.0
@$(MAKE) -f $(DIR)/Makefile gencrl
# Regenerate the Certificate Revocation List.
# This list should be available publicly
gencrl:
@openssl ca $(CONFIG) -gencrl -out $(DIR)/public-www/crl.pem
@ln -sf $(DIR)/public-www/crl.pem $(DIR)/crl/`openssl crl -noout -hash < $(DIR)/public-www/crl.pem`.r0
# Create a new private key and a CSR, in case the client does not provide the CSR by another mean.
# Usage is: make newcsr name=peer.client.fqdn email=admin@client.fqdn
newcsr:
@if [ -z "$(name)" -o -z "$(email)" ]; then echo "Please provide certificate name and email address: make newcsr name=mn.nautilus.org email=you@mail.com"; exit 1; fi
@if [ -e $(DIR)/clients/csr/$(name).csr ]; then echo "There is already a pending csr for this name."; exit 1; fi
@if [ ! -e $(DIR)/clients/privkeys/$(name).key.pem ]; \
then echo "Generating a private key for $(name) ..."; \
openssl genrsa -out $(DIR)/clients/privkeys/$(name).key.pem 1024; \
fi;
@echo "Creating the CSR in $(DIR)/clients/csr/$(name).csr";
@openssl req $(CONFIG) -new -batch -out $(DIR)/clients/csr/$(name).csr \
-key $(DIR)/clients/privkeys/$(name).key.pem \
-subj /C=$(C)/ST=$(ST)/L=$(L)/O=$(O)/OU=$(OU)/CN=$(name)/emailAddress=$(email)
# Process a CSR to create a x509 certificate. The certificate is valid for 1 year.
# It should be sent to the client by any mean.
cert:
@if [ -z "$(name)" ]; then echo "name must be provided: make cert name=mn.n6.org"; exit 1; fi
@if [ ! -e $(DIR)/clients/csr/$(name).csr ]; then echo "Could not find CSR in $(DIR)/clients/csr/$(name).csr."; exit 1; fi
@if [ -e $(DIR)/clients/certs/$(name).cert ]; \
then echo "Revoking old certificate..."; \
$(MAKE) revoke name=$(name); \
fi;
@openssl ca $(CONFIG) -in $(DIR)/clients/csr/$(name).csr \
-out $(DIR)/clients/certs/$(name).cert \
-days $(DAYS) \
-batch
@ln -s $(DIR)/clients/certs/$(name).cert $(DIR)/certs/`openssl x509 -noout -hash < $(DIR)/clients/certs/$(name).cert`.0
# Revoke a certificate.
revoke:
@if [ -z "$(name)" ]; then echo "name must be provided: make revoke name=mn.n6.org"; exit 1; fi
@if [ ! -e $(DIR)/clients/certs/$(name).cert ]; \
then echo "$(DIR)/clients/certs/$(name).cert not found"; \
exit 1; \
fi;
@openssl ca $(CONFIG) -revoke $(DIR)/clients/certs/$(name).cert;
@rm -f $(DIR)/certs/`openssl x509 -noout -hash < $(DIR)/clients/certs/$(name).cert`.0
@$(MAKE) gencrl
# End of file...
nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/PKI/ca_script/openssl.cnf 0000664 0000000 0000000 00000022412 13335533574 0025261 0 ustar 00root root 0000000 0000000 #
# OpenSSL example configuration file.
# This is mostly being used for generation of certificate requests.
#
# This definition stops the following lines choking if HOME isn't
# defined.
HOME = .
RANDFILE = $ENV::HOME/.rnd
# Extra OBJECT IDENTIFIER info:
#oid_file = $ENV::HOME/.oid
oid_section = new_oids
# To use this configuration file with the "-extfile" option of the
# "openssl x509" utility, name here the section containing the
# X.509v3 extensions to use:
# extensions =
# (Alternatively, use a configuration file that has only
# X.509v3 extensions in its main [= default] section.)
[ new_oids ]
# We can add new OIDs in here for use by 'ca' and 'req'.
# Add a simple OID like this:
# testoid1=1.2.3.4
# Or use config file substitution like this:
# testoid2=${testoid1}.5.6
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
####################################################################
[ CA_default ]
dir = /etc/openssl-ca # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
#unique_subject = no # Set to 'no' to allow creation of
# several ctificates with same subject.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = $dir/public-www/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
# crlnumber = $dir/crlnumber # the current crl number
# must be commented out to leave a V1 CRL
crl = $dir/public-www/crl.pem # The current CRL
private_key = $dir/private/cakey.pem# The private key
RANDFILE = $dir/private/.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
# Extension copying option: use with caution.
# copy_extensions = copy
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crlnumber must also be commented out to leave a V1 CRL.
# crl_extensions = crl_ext
default_days = 365 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = sha1 # which md to use.
preserve = no # keep passed DN ordering
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
# policy = policy_match
policy = policy_anything
# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ req ]
default_bits = 1024
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
# Passwords for private keys if not present they will be prompted for
# input_password = fdsecret
# output_password = fdsecret
# This sets a mask for permitted string types. There are several options.
# default: PrintableString, T61String, BMPString.
# pkix : PrintableString, BMPString.
# utf8only: only UTF8Strings.
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
# MASK:XXXX a literal mask value.
# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
# so use this option with caution!
string_mask = utf8only
# req_extensions = v3_req # The extensions to add to a certificate request
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = JP
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Tokyo
localityName = Locality Name (eg, city)
localityName_default = Koganei
0.organizationName = Organization Name (eg, company)
0.organizationName_default = WIDE
# we can do this but it is not needed normally :-)
1.organizationName = Second Organization Name (eg, company)
1.organizationName_default = NICT
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = AAA WG
commonName = Common Name (i.e. Diameter Agent hostname)
commonName_max = 64
emailAddress = Email Address (i.e. Diameter agent administrator)
emailAddress_max = 64
# SET-ex3 = SET extension number 3
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 0
challengePassword_max = 20
unstructuredName = An optional company name
[ usr_cert ]
# These extensions are added when 'ca' signs a request.
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ]
# Extensions for a typical CA
# PKIX recommendation.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
# This is what PKIX recommends but some broken software chokes on critical
# extensions.
#basicConstraints = critical,CA:true
# So we do this instead.
basicConstraints = CA:true
# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
# keyUsage = cRLSign, keyCertSign
# Some might want this also
# nsCertType = sslCA, emailCA
# Include email address in subject alt name: another PKIX recommendation
# subjectAltName=email:copy
# Copy issuer details
# issuerAltName=issuer:copy
# DER hex encoding of an extension: beware experts only!
# obj=DER:02:03
# Where 'obj' is a standard or added object
# You can even override a supported extension:
# basicConstraints= critical, DER:30:03:01:01:FF
[ crl_ext ]
# CRL extensions.
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
# issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always,issuer:always
[ proxy_cert_ext ]
# These extensions should be added when creating a proxy certificate
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
# This really needs to be in place for it to be a proxy certificate.
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/PKI/ca_script2/ 0000775 0000000 0000000 00000000000 13335533574 0023167 5 ustar 00root root 0000000 0000000 nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/PKI/ca_script2/Makefile 0000664 0000000 0000000 00000021525 13335533574 0024634 0 ustar 00root root 0000000 0000000 #!/usr/bin/make -s
#
# This file is inspired from freeDiameter's contrib/ca_script and
# improved to handle multiple CA in a hierarchical fashion.
# Warning: the directory structure is flat, does not reflect the CA hierarchy
SCRIPT_DIR = .
DATA_DIR = ./ca_data
CONFIG = -config $(SCRIPT_DIR)/openssl.cnf
REMAKE = $(MAKE) -f $(SCRIPT_DIR)/Makefile
#Disable "make destroy" -- overwrite on command line
force =
#RSA key sizes, can be overwritten on command line
cakeysize = 2048
keysize = 1024
# Save current date
DATE=`date +%Y%m%d-%H%M%S`
# Default: print the help
all: help
# Help message
help:
@echo "\n\
Available commands:\n\
make init topca=name\n\
Creates the initial top-level CA structure\n\
make newca name=newcaname ca=parentca\n\
Creates a new sub-CA that can be used for certificates later.\n\
make newcert name=foo ca=parentca\n\
Create private key and csr, then issue the certificate (named foo.*)\n\
make p12 name=foo ca=parentca\n\
Same as newcert, but additionnaly creates a pkcs12 file to ship client certificate to Windows or Mac\n\
make ship name=foo ca=parentca\n\
Create an archive with the data for the client (useful for freeDiameter peers)\n\
make revoke name=foo ca=parentca\n\
Revokes the certificate foo.cert issued by parentca and regenerates the CRL.\n\
make gencrl ca=caname\n\
Regenerates the CRL of CA caname. Should be run periodically.\n\
\n\
";
# Destroy the CA hierarchy completely. Use with care.
destroy:
@if [ -z "$(force)" ]; then echo "Destroy disabled, use: make destroy force=y"; exit 1; fi
@if [ ! -d $(SCRIPT_DIR) ]; then echo "Error in setup"; exit 1; fi
@echo "Removing everything (for debug purpose)..."
@rm -rf $(DATA_DIR)/*
# Initialize the CA structure
structure:
@if [ -z "$(caname)" ]; then echo "Internal error: caname is missing"; exit 1; fi
@if [ -d $(DATA_DIR)/$(caname) ]; then echo "CA $(caname) already exists."; exit 1; fi
# Creating CA structure
@mkdir -p $(DATA_DIR)/$(caname)
@mkdir $(DATA_DIR)/$(caname)/public
@mkdir $(DATA_DIR)/$(caname)/public/crl
@mkdir $(DATA_DIR)/$(caname)/private
@chmod 700 $(DATA_DIR)/$(caname)/private
@mkdir $(DATA_DIR)/$(caname)/clients
@echo "01" > $(DATA_DIR)/$(caname)/serial
@echo "01" > $(DATA_DIR)/$(caname)/crlnumber
@touch $(DATA_DIR)/$(caname)/index.txt
# Initialize the top-level CA structure and keys.
init:
@if [ -z "$(topca)" ]; then echo "Please specify the name of the root CA. Ex: make init topca=rootca.testbed.aaa"; exit 1; fi
# Create the folder hierarchy
@$(REMAKE) structure caname=$(topca)
# Generate the self-signed certificate
@CA_ROOT_DIR=$(DATA_DIR)/$(topca) openssl req $(CONFIG) -new -batch -x509 -days 3650 -nodes -newkey rsa:$(cakeysize) -out $(DATA_DIR)/$(topca)/public/cacert.pem \
-keyout $(DATA_DIR)/$(topca)/private/cakey.pem -extensions ca_cert -subj /CN=$(topca)
@ln -s cacert.pem $(DATA_DIR)/$(topca)/public/`openssl x509 -noout -hash < $(DATA_DIR)/$(topca)/public/cacert.pem`.0
@touch $(DATA_DIR)/$(topca)/public/cachain.pem
@ln -s ../../$(topca)/public/cacert.pem $(DATA_DIR)/$(topca)/public/caroot.pem
@$(REMAKE) gencrl ca=$(topca)
# Create a secondary CA
newca:
@if [ -z "$(name)" -o -z "$(ca)" ]; then echo "Missing parameter. Ex: make newca name=subca.testbed.aaa ca=rootca.testbed.aaa"; exit 1; fi
@if [ ! -e $(DATA_DIR)/$(ca)/private/cakey.pem ]; then echo "The parent CA $(ca) does not exist."; exit 1; fi
@if [ ! -d $(DATA_DIR)/$(name) ]; then $(REMAKE) structure caname=$(name); fi
# Generate the private key and CSR for the new CA if needed
@if [ ! -e $(DATA_DIR)/$(name)/private/cakey.pem ]; then \
openssl genrsa -out $(DATA_DIR)/$(name)/private/cakey.pem $(cakeysize) ; fi
@if [ ! -e $(DATA_DIR)/$(name)/private/cacsr.pem ]; then \
CA_ROOT_DIR=$(DATA_DIR)/$(name) openssl req $(CONFIG) -new -batch -out $(DATA_DIR)/$(name)/private/cacsr.pem \
-key $(DATA_DIR)/$(name)/private/cakey.pem \
-subj /CN=$(name) -reqexts v3_req_ca; fi
# Revoke a previous certificate for this CA if any
@if [ -e $(DATA_DIR)/$(name)/public/cacert.pem ]; then \
echo "Revoking previous certificate ..."; \
$(REMAKE) revoke name=$(name) ca=$(ca); \
mv $(DATA_DIR)/$(name)/public/cacert.pem $(DATA_DIR)/$(name)/public/cacert-$(DATE).pem; fi
# Issue the new CA certificate
@CA_ROOT_DIR=$(DATA_DIR)/$(ca) openssl ca $(CONFIG) -in $(DATA_DIR)/$(name)/private/cacsr.pem \
-out $(DATA_DIR)/$(name)/public/cacert.pem \
-batch -extensions ca_cert
# Hash and link to parent
@ln -s cacert.pem $(DATA_DIR)/$(ca)/public/`openssl x509 -noout -hash < $(DATA_DIR)/$(name)/public/cacert.pem`.0
@rm -f $(DATA_DIR)/$(name)/parent
@ln -s ../$(ca) $(DATA_DIR)/$(name)/parent
@cat $(DATA_DIR)/$(name)/public/cacert.pem $(DATA_DIR)/$(ca)/public/cachain.pem > $(DATA_DIR)/$(name)/public/cachain.pem
@ln -s ../../$(ca)/public/caroot.pem $(DATA_DIR)/$(name)/public/caroot.pem
@for CRLFILE in `cd $(DATA_DIR)/$(ca)/public/crl && ls -1`; do ln -sf ../../../$(ca)/public/crl/$$CRLFILE $(DATA_DIR)/$(name)/public/crl/$$CRLFILE; done
@$(REMAKE) gencrl ca=$(name)
# Create a new certificate for use in TLS communications and other terminal usages
newcert:
@if [ -z "$(name)" -o -z "$(ca)" ]; then echo "Missing parameter. Ex: make newcert name=service.testbed.aaa ca=ca.testbed.aaa"; exit 1; fi
@if [ ! -e $(DATA_DIR)/$(ca)/private/cakey.pem ]; then echo "The parent CA $(ca) does not exist."; exit 1; fi
@if [ ! -d $(DATA_DIR)/$(ca)/clients/$(name) ]; then mkdir $(DATA_DIR)/$(ca)/clients/$(name); fi
# Create a private key if needed
@if [ ! -e $(DATA_DIR)/$(ca)/clients/$(name)/privkey.pem ]; then \
openssl genrsa -out $(DATA_DIR)/$(ca)/clients/$(name)/privkey.pem $(keysize); fi
# Create a CSR if needed
@if [ ! -e $(DATA_DIR)/$(ca)/clients/$(name)/csr.pem ]; then \
CA_ROOT_DIR=$(DATA_DIR)/$(ca) openssl req $(CONFIG) -new -batch -out $(DATA_DIR)/$(ca)/clients/$(name)/csr.pem \
-key $(DATA_DIR)/$(ca)/clients/$(name)/privkey.pem \
-subj /CN=$(name); fi
# Revoke a previous certificate if any
@if [ -e $(DATA_DIR)/$(ca)/clients/$(name)/cert.pem ]; then \
$(REMAKE) revoke name=$(name) ca=$(ca); \
mv $(DATA_DIR)/$(ca)/clients/$(name)/cert.pem $(DATA_DIR)/$(ca)/clients/$(name)/cert-$(DATE).pem; fi
# Now sign the new certificate with the CA key
@CA_ROOT_DIR=$(DATA_DIR)/$(ca) openssl ca $(CONFIG) -in $(DATA_DIR)/$(ca)/clients/$(name)/csr.pem \
-out $(DATA_DIR)/$(ca)/clients/$(name)/cert.pem \
-batch
# Hash
@ln -sf `cat $(DATA_DIR)/$(ca)/serial.old`.pem $(DATA_DIR)/$(ca)/public/`openssl x509 -noout -hash < $(DATA_DIR)/$(ca)/clients/$(name)/cert.pem`.0
# Compiled informations for the client
@cat $(DATA_DIR)/$(ca)/clients/$(name)/cert.pem $(DATA_DIR)/$(ca)/public/cachain.pem > $(DATA_DIR)/$(ca)/clients/$(name)/certchain.pem
@ln -sf ../../public/crl $(DATA_DIR)/$(ca)/clients/$(name)/crl
@ln -sf ../../public/caroot.pem $(DATA_DIR)/$(ca)/clients/$(name)/ca.pem
# Create a PKCS#12 file containing the client's information
p12: newcert
# Create the PKCS#12 file
@cat $(DATA_DIR)/$(ca)/clients/$(name)/privkey.pem \
$(DATA_DIR)/$(ca)/clients/$(name)/certchain.pem \
$(DATA_DIR)/$(ca)/clients/$(name)/ca.pem \
| openssl pkcs12 -export -out $(DATA_DIR)/$(ca)/clients/$(name)/$(name).p12
@echo "Client certificate is created in $(DATA_DIR)/$(ca)/clients/$(name)/$(name).p12"
# Create an archive to send the data to the client node
ship:
@if [ -z "$(name)" -o -z "$(ca)" ]; then echo "Missing parameter. Ex: make ship name=service.testbed.aaa ca=ca.testbed.aaa"; exit 1; fi
@if [ ! -e $(DATA_DIR)/$(ca)/private/cakey.pem ]; then echo "The parent CA $(ca) does not exist."; exit 1; fi
@if [ ! -e $(DATA_DIR)/$(ca)/clients/$(name)/privkey.pem ]; then echo "The client $(name) does not exist, use 'make newcert' first."; exit 1; fi
# Ship the data
@tar -c -C $(DATA_DIR)/$(ca)/clients/$(name) -z -f $(ca)_$(name).tar.gz -h .
@echo "The files have been packaged into archive: $(ca)_$(name).tar.gz"
# Revoke a certificate
revoke:
@if [ -z "$(name)" -o -z "$(ca)" ]; then echo "Missing parameter. Ex: make revoke name=service.testbed.aaa ca=ca.testbed.aaa"; exit 1; fi
@if [ ! -e $(DATA_DIR)/$(ca)/private/cakey.pem ]; then echo "The parent CA $(ca) does not exist."; exit 1; fi
@if [ ! -e $(DATA_DIR)/$(ca)/clients/$(name)/cert.pem ]; \
then echo "$(DATA_DIR)/$(ca)/clients/$(name)/cert.pem not found"; \
exit 1; \
fi;
# Revoke the certificate
@CA_ROOT_DIR=$(DATA_DIR)/$(ca) openssl ca $(CONFIG) -revoke $(DATA_DIR)/$(ca)/clients/$(name)/cert.pem;
@$(REMAKE) gencrl ca=$(ca)
# Regenerate the Certificate Revocation List.
gencrl:
@if [ -z "$(ca)" ]; then echo "Missing parameter. Ex: make gencrl ca=ca.testbed.aaa"; exit 1; fi
# Create the CRL
@CA_ROOT_DIR=$(DATA_DIR)/$(ca) openssl ca $(CONFIG) -gencrl -out $(DATA_DIR)/$(ca)/public/crl/$(ca).pem
@ln -s crl/$(ca).pem $(DATA_DIR)/$(ca)/public/local.pem
@ln -s local.pem $(DATA_DIR)/$(ca)/public/`openssl crl -noout -hash < $(DATA_DIR)/$(ca)/public/crl/$(ca).pem`.r0
# End of file...
nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/PKI/ca_script2/openssl.cnf 0000664 0000000 0000000 00000007375 13335533574 0025356 0 ustar 00root root 0000000 0000000 # Note: for this file to be working, an environment var CA_ROOT_DIR = directory
# must be defined and pointing to the CA top-level directory.
HOME = .
RANDFILE = $ENV::HOME/.rnd
oid_section = new_oids
[ new_oids ]
####################################################################
[ req ]
default_bits = 1024
# default_keyfile = privkey.pem
string_mask = utf8only
distinguished_name = req_distinguished_name
attributes = req_attributes
req_extensions = v3_req # overwrite with -reqexts
x509_extensions = ca_cert # overwrite with -extensions; used for self-signed keys only
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = JP
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Tokyo
localityName = Locality Name (eg, city)
localityName_default = Koganei
0.organizationName = Organization Name (eg, company)
0.organizationName_default = WIDE
1.organizationName = Second Organization Name (eg, company)
1.organizationName_default = NICT
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = AAA WG testbed
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 0
challengePassword_max = 20
unstructuredName = An optional company name
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_req_ca ]
# Extensions to add to a certificate request for CA
basicConstraints = CA:TRUE
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
[ CA_default ]
dir = $ENV::CA_ROOT_DIR # Where everything is kept
certs = $dir/public # Where the issued certs are kept
crl_dir = $dir/public # Where the issued crl are kept
database = $dir/index.txt # database index file.
#unique_subject = no # Set to 'no' to allow creation of
# several ctificates with same subject.
new_certs_dir = $dir/public # default place for new certs.
certificate = $dir/public/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
crlnumber = $dir/crlnumber # the current crl number
crl = $dir/public/local.pem # The current CRL
private_key = $dir/private/cakey.pem # The private key
x509_extensions = usr_cert # The extentions to add to the cert
# overwrite with -extensions
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
crl_extensions = crl_ext
default_days = 3650 # how long to certify for
default_crl_days= 365 # how long before next CRL
default_md = sha1 # which md to use.
preserve = no # keep passed DN ordering
# We accept to sign anything, but a real deployment would limit to proper domain etc...
policy = policy_anything
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ usr_cert ]
basicConstraints=CA:FALSE
# This is typical in keyUsage for a client certificate.
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
[ ca_cert ]
# Extensions for a typical CA
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
basicConstraints = critical,CA:true # Remove "critical," in case of problems
keyUsage = cRLSign, keyCertSign
# subjectAltName=email:copy
# Copy issuer details
# issuerAltName=issuer:copy
[ crl_ext ]
# CRL extensions.
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
# issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always,issuer:always
nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/PKI/phpki-0.82.patch 0000664 0000000 0000000 00000030763 13335533574 0023670 0 ustar 00root root 0000000 0000000 diff -Nur phpki-0.82/ca/main.php phpki-0.82-fD/ca/main.php
--- phpki-0.82/ca/main.php 2005-11-17 10:17:20.000000000 +0900
+++ phpki-0.82-fD/ca/main.php 2010-05-27 17:04:44.000000000 +0900
@@ -36,7 +36,7 @@
else {
?>
- There was an error updating the Certificate Revocation List.
+ There was an error updating the Certificate Revocation List.
Debug Info:
=$errtxt?>
@@ -53,8 +53,11 @@
default:
printHeader('ca');
?>
-
-
+
+
+
+ For freeDiameter specific instructions, scroll down this page...
+
-
+
+
+
+
+
printFooter();
}
diff -Nur phpki-0.82/ca/request_cert.php phpki-0.82-fD/ca/request_cert.php
--- phpki-0.82/ca/request_cert.php 2007-01-04 14:45:09.000000000 +0900
+++ phpki-0.82-fD/ca/request_cert.php 2010-05-27 16:59:16.000000000 +0900
@@ -197,6 +197,7 @@
switch($cert_type) {
case 'server':
+ case 'freediameter':
upload(array("$config[private_dir]/$serial-key.pem","$config[new_certs_dir]/$serial.pem",$config['cacert_pem']), "$common_name ($email).pem",'application/pkix-cert');
break;
case 'email':
@@ -225,7 +226,7 @@
if (! $email) $email = "";
if (! $expiry) $expiry = 1;
if (! $keysize) $keysize = 1024;
- if (! $cert_type) $cert_type = 'email';
+ if (! $cert_type) $cert_type = 'freediameter';
printHeader();
?>
@@ -302,13 +303,14 @@
Certificate Use:
- print 'E-mail, SSL Client ';
- print 'E-mail, SSL Client, Code Signing ';
- print 'SSL Server ';
- print 'VPN Client Only ';
- print 'VPN Server Only ';
- print 'VPN Client, VPN Server ';
- print 'Time Stamping ';
+ print 'E-mail, SSL Client ';
+ print 'E-mail, SSL Client, Code Signing ';
+ print 'SSL Server ';
+ print 'freeDiameter node ';
+ print 'VPN Client Only ';
+ print 'VPN Server Only ';
+ print 'VPN Client, VPN Server ';
+ print 'Time Stamping ';
?>
diff -Nur phpki-0.82/include/openssl_functions.php phpki-0.82-fD/include/openssl_functions.php
--- phpki-0.82/include/openssl_functions.php 2007-01-04 15:47:57.000000000 +0900
+++ phpki-0.82-fD/include/openssl_functions.php 2010-05-27 16:59:57.000000000 +0900
@@ -69,6 +69,13 @@
default_days = 365
policy = policy_supplied
+[ freediameter_cert ]
+x509_extensions = freediameter_ext
+default_days = 730
+policy = policy_supplied
+
+
+
[ vpn_cert ]
x509_extensions = vpn_client_server_ext
default_days = 365
@@ -152,6 +159,24 @@
nsRevocationUrl = ns_revoke_query.php?
nsCaPolicyUrl = $config[base_url]policy.html
+[ freediameter_ext ]
+basicConstraints = CA:false
+keyUsage = critical, digitalSignature, keyEncipherment
+extendedKeyUsage = critical, serverAuth, clientAuth
+nsCertType = critical, server, client
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid:always, issuer:always
+subjectAltName = DNS:$common_name,email:copy
+issuerAltName = issuer:copy
+crlDistributionPoints = URI:$config[base_url]index.php?stage=dl_crl
+nsComment = \"PHPki/OpenSSL Generated Secure Certificate for freeDiameter\"
+nsBaseUrl = $config[base_url]
+nsRevocationUrl = ns_revoke_query.php?
+nsCaPolicyUrl = $config[base_url]policy.html
+
+
+
+
[ time_stamping_ext ]
basicConstraints = CA:false
keyUsage = critical, nonRepudiation, digitalSignature
diff -Nur phpki-0.82/openssl.cnf phpki-0.82-fD/openssl.cnf
--- phpki-0.82/openssl.cnf 2006-07-23 00:33:34.000000000 +0900
+++ phpki-0.82-fD/openssl.cnf 2010-05-27 17:00:33.000000000 +0900
@@ -39,6 +39,11 @@
default_days = 365
policy = policy_supplied
+[ freediameter_cert ]
+x509_extensions = freediameter_ext
+default_days = 730
+policy = policy_supplied
+
[ vpn_cert ]
x509_extensions = vpn_client_server_ext
default_days = 365
@@ -115,6 +120,23 @@
nsRevocationUrl = ns_revoke_query.php?
nsCaPolicyUrl = http://www.somewhere.com/phpki/policy.html
+[ freediameter_ext ]
+basicConstraints = CA:false
+keyUsage = critical, digitalSignature, keyEncipherment
+extendedKeyUsage = critical, serverAuth, clientAuth
+nsCertType = critical, server, client
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid:always, issuer:always
+subjectAltName = DNS:$common_name,email:copy
+issuerAltName = issuer:copy
+crlDistributionPoints = URI:$config[base_url]index.php?stage=dl_crl
+nsComment = "PHPki/OpenSSL Generated Secure Certificate for freeDiameter"
+nsBaseUrl = $config[base_url]
+nsRevocationUrl = ns_revoke_query.php?
+nsCaPolicyUrl = $config[base_url]policy.html
+
+
+
[ vpn_client_ext ]
basicConstraints = critical, CA:false
keyUsage = critical, digitalSignature
diff -Nur phpki-0.82/setup.php phpki-0.82-fD/setup.php
--- phpki-0.82/setup.php 2007-07-22 23:34:08.000000000 +0900
+++ phpki-0.82-fD/setup.php 2010-05-27 17:01:41.000000000 +0900
@@ -339,6 +339,11 @@
default_days = 365
policy = policy_supplied
+[ freediameter_cert ]
+x509_extensions = freediameter_ext
+default_days = 730
+policy = policy_supplied
+
[ vpn_cert ]
x509_extensions = vpn_client_server_ext
default_days = 365
@@ -418,6 +423,22 @@
nsRevocationUrl = ns_revoke_query.php?
nsCaPolicyUrl = $config[base_url]policy.html
+[ freediameter_ext ]
+basicConstraints = CA:false
+keyUsage = critical, digitalSignature, keyEncipherment
+extendedKeyUsage = critical, serverAuth, clientAuth
+nsCertType = critical, server, client
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid:always, issuer:always
+subjectAltName = DNS:$common_name,email:copy
+issuerAltName = issuer:copy
+crlDistributionPoints = URI:$config[base_url]index.php?stage=dl_crl
+nsComment = "PHPki/OpenSSL Generated Secure Certificate for freeDiameter"
+nsBaseUrl = $config[base_url]
+nsRevocationUrl = ns_revoke_query.php?
+nsCaPolicyUrl = $config[base_url]policy.html
+
+
[ time_stamping_ext ]
basicConstraints = CA:false
keyUsage = critical, nonRepudiation, digitalSignature
diff -Nur phpki-0.82/setup.php-presetup phpki-0.82-fD/setup.php-presetup
--- phpki-0.82/setup.php-presetup 2007-07-22 23:34:08.000000000 +0900
+++ phpki-0.82-fD/setup.php-presetup 2010-05-27 17:01:41.000000000 +0900
@@ -339,6 +339,11 @@
default_days = 365
policy = policy_supplied
+[ freediameter_cert ]
+x509_extensions = freediameter_ext
+default_days = 730
+policy = policy_supplied
+
[ vpn_cert ]
x509_extensions = vpn_client_server_ext
default_days = 365
@@ -418,6 +423,22 @@
nsRevocationUrl = ns_revoke_query.php?
nsCaPolicyUrl = $config[base_url]policy.html
+[ freediameter_ext ]
+basicConstraints = CA:false
+keyUsage = critical, digitalSignature, keyEncipherment
+extendedKeyUsage = critical, serverAuth, clientAuth
+nsCertType = critical, server, client
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid:always, issuer:always
+subjectAltName = DNS:$common_name,email:copy
+issuerAltName = issuer:copy
+crlDistributionPoints = URI:$config[base_url]index.php?stage=dl_crl
+nsComment = "PHPki/OpenSSL Generated Secure Certificate for freeDiameter"
+nsBaseUrl = $config[base_url]
+nsRevocationUrl = ns_revoke_query.php?
+nsCaPolicyUrl = $config[base_url]policy.html
+
+
[ time_stamping_ext ]
basicConstraints = CA:false
keyUsage = critical, nonRepudiation, digitalSignature
nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/README 0000664 0000000 0000000 00000005515 13335533574 0021401 0 ustar 00root root 0000000 0000000 This file describes the content of the "contrib" directory.
For information about the freeDiameter project, please refer
to top-level README file.
- update_copyright.sh : This script will simply update the copyright information
in all source files in the freeDiameter mercurial repository, based
on the last modification time. Thought I might share it if other people find
it useful for their own project...
- debian : This directory contains the packaging information to create native Debian / Ubuntu
packages. It requires debhelper >= 7.3.9 (support for cmake). To use, simply link the
debian folder from the main freeDiameter folder, then use your building script as
usual ('dh binary' or 'pdebuild' or ...).
If you simply intend to use freeDiameter package, the relevant information is located
at: http://www.freediameter.net/trac/wiki/DebRepository
- PKI : This directory contains useful material related to establishing a
Public Key Infrastructure (PKI) for deploying x509 certificates
and use these for TLS authentication of the freeDiameter nodes.
IMPORTANT: Please note that these solutions are NOT suitable
for use in a production environment! It allows easy deployment of
certificates for tests, and that is their sole purpose.
The directory contains:
- ca_script: a simple Makefile allowing you to generate a self-signed certificate (root)
and then issue new certificates and private keys for your users.
Run "make" without argument to get the help.
- ca_script2: An evolution of the previous Makefile. This one allows you
to create a hierarchy of CA and certificates.
- phpki-0.82.patch : This patch is to be applied to PHPki to customize the use for freeDiameter.
PHPki (http://sourceforge.net/projects/phpki/) is a PHP-based web interface
that provides more or less the same services as ca_script.
- OpenWRT : This directory contains the scripts and documentation related to
the integration of freeDiameter RADIUS/Diameter gateway component in the openWRT
distribution (http://openwrt.org) -- the goal is to give the access point the
ability to "talk" Diameter instead of RADIUS.
- nightly_tests : This directory contains the scripts and documentation for the nightly
tests run on freeDiameter. The results are published at the following URL:
http://www.freediameter.net/CDash/index.php?project=freeDiameter
- dict_legacy: XML and DTD files for the dict_legacy_xml.fdx extension.
- dict_dcca: partial implementations of the DCCA dictionary
- dict_gx: untested implementation of the Gx interface.
- test_Gx: a responder on the Gx interface that always send SUCCESS status.
- wireshark: This contains some information on how to use Wireshark to monitor Diameter
exchange protected with TLS. It involves patching the wireshark software.
nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/RPM/ 0000775 0000000 0000000 00000000000 13335533574 0021151 5 ustar 00root root 0000000 0000000 nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/RPM/build_rpm.txt 0000775 0000000 0000000 00000000554 13335533574 0023676 0 ustar 00root root 0000000 0000000 [krum@ThinkPad DelMe]$ cp freeDiameter.spec /home/krum/rpmbuild/SPECS/
[krum@ThinkPad DelMe]$ cd /home/krum/rpmbuild/SOURCES/
[krum@ThinkPad ~]$ cd /home/krum/rpmbuild/SOURCES/
[krum@ThinkPad SOURCES]$ wget http://www.freediameter.net/hg/freeDiameter/archive/1.1.6.tar.gz
[krum@ThinkPad SOURCES]$ cd ../SPECS/
[krum@ThinkPad SPECS]$ rpmbuild -ba freeDiameter.spec
nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/RPM/freeDiameter.spec 0000775 0000000 0000000 00000003705 13335533574 0024431 0 ustar 00root root 0000000 0000000
Name: freeDiameter
Version: 1.1.6
Release: 1%{?dist}
Packager: krum.boy4ev@gmail.com
Summary: freeDiameter is an implementation of the Diameter protocol.
Group: Development/Libraries
License: BSD License
URL: http://www.freediameter.net
Source0: http://www.freediameter.net/hg/freeDiameter/archive/1.1.6.tar.gz
BuildRequires: cmake make gcc gcc-c++ flex bison lksctp-tools-devel
BuildRequires: gnutls-devel libgcrypt-devel libidn-devel
BuildRequires: mercurial
Requires: lksctp-tools
%description
freeDiameter is an implementation of the Diameter protocol.
Diameter is a protocol designed to carry Authentication, Authorization and
Accounting (AAA) payload. It is an evolution of the RADIUS protocol (as the
name suggests).
See http://www.freediameter.net/ for more information on the project.
freeDiameter was previously known as the "waaad" project (WIDE AAA Daemon)
This project is not related to the "freediameter" project from Sun on sourceforge.
Author: Sebastien Decugis.
%package daemon
Summary: Simple daemon parses the command line and initializes the freeDiameter framework.
Group: Development/Libraries
Requires: freeDiameter
%description daemon
freeDiameterd : this simple daemon parses the command line and initializes the
freeDiameter framework. Use it for your Diameter server & agent components.
In case of Diameter clients, you probably will prefer linking the libfdcore
directly with your client application that must be made Diameter-aware.
%prep
%setup -qn %{name}-%{version}
%build
mkdir -p build
cd build
cmake ../
make %{?_smp_mflags}
%install
rm -rf $RPM_BUILD_ROOT
cd build
make install DESTDIR=$RPM_BUILD_ROOT
make test
%post daemon
echo "/usr/local/lib/" > /etc/ld.so.conf.d/%{name}.conf
/sbin/ldconfig
%files
%defattr(-,root,root,-)
/usr/local/include/
/usr/local/lib/
%files daemon
%defattr(-,root,root,-)
/usr/local/bin/
%changelog
* Sat Jul 5 2013 Krum Boychev - 1.1.6-1
- initial version
nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/app_acct_tools/ 0000775 0000000 0000000 00000000000 13335533574 0023505 5 ustar 00root root 0000000 0000000 nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/app_acct_tools/README 0000664 0000000 0000000 00000005267 13335533574 0024377 0 ustar 00root root 0000000 0000000 This folder contains several tools to use and parse the data from the app_acct.fdx extension.
- database.sql :
An example database format for use with the scripts in this folder.
- app_acct.conf :
The part of app_acct.conf that is relevant to this database schema.
- purge_to_file.php :
This PHP script is used to take the records from the incoming table (stored by app_acct.fdx
extension) and save these records in a file in SQL format. This is similar to pg_dump
command, except that all the records that have been saved in the file are removed from
the table. This can be used in cron jobs for example to maintain a reasonable size of
the incoming table and move the data to another host for off-line processing. It can
also be useful to aggregate the data from different hosts, if you are load-balancing your
accounting servers for example (granted that all app_acct.fdx use identical table format
on all the servers). See the top of the file for configuration parameters.
- process_records.php :
This PHP script processes the records pertaining to users sessions, as follow:
* when a session is complete (STOP record received), it stores a session summary
into the processed records table (see process_database.sql file for format).
* It optionally archives the processed records into a different table, before deleting them.
* It can also move records of unterminated sessions that are older than a configurable time
to an orphan_records table, so that they are not re-processed every time.
This orphans table must have the same structure as the "incoming" table.
- display_results.php, display_self.php, display_stats.php :
These scripts give a few examples of how to display the processed data.
USAGE:
*) Initial: create your database using database.sql file
*) Configure the app_acct.fdx extension using tips from app_acct.conf
The following processing can be run for example as cron jobs.
1) On each accounting server for the realm, configure the app_acct.fdx extension to
dump the records in a local database (all servers must use the same database format).
The table would typically be "incoming".
2) Run the purge_to_file.php script on each server regularly, then move the generated
files onto a single server for processing. This server only needs the other tables.
3) Add the data from the files into the database in this server by running:
psql < file.sql
Each file that has been added should then be archived and removed so that it is not
re-added later.
4) Run the process_records.php script on this processing server. Now, the database
contains the aggregated data that can be visualized with display_*.php scripts.
nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/app_acct_tools/app_acct.conf 0000664 0000000 0000000 00000002752 13335533574 0026134 0 ustar 00root root 0000000 0000000
# This is the configuration for use with the database created by 'database.sql' file.
# One should take care of configuring the ConnInfo properly.
ConnInfo = "";
# The table and special fields names:
Table = "incoming";
Timestamp_field = "recorded_on";
Server_name_field = "recorded_serv";
# The AVPs that are saved in the table:
"Origin-Host";
"Origin-Realm";
"Destination-Realm";
"Destination-Host";
"Session-Id";
"Origin-State-Id";
"Accounting-Record-Type";
"Accounting-Record-Number";
"User-Name";
"Event-Timestamp";
"Acct-Application-Id";
"Accounting-Sub-Session-Id";
"Acct-Session-Id";
"Acct-Multi-Session-Id";
"Origin-AAA-Protocol";
"Acct-Delay-Time";
"NAS-Identifier";
"NAS-IP-Address";
"NAS-IPv6-Address";
"NAS-Port";
"NAS-Port-Id";
"NAS-Port-Type";
"Service-Type";
"Termination-Cause";
"Accounting-Input-Octets";
"Accounting-Input-Packets";
"Accounting-Output-Octets";
"Accounting-Output-Packets";
"Acct-Authentic";
"Acct-Link-Count";
"Acct-Session-Time";
"Acct-Tunnel-Connection";
"Acct-Tunnel-Packets-Lost";
"Callback-Id";
"Callback-Number";
"Called-Station-Id";
"Calling-Station-Id";
"Connect-Info";
"Originating-Line-Info";
"Authorization-Lifetime";
"Session-Timeout";
"Idle-Timeout";
"Port-Limit";
"Accounting-Realtime-Required";
"Acct-Interim-Interval";
"Filter-Id";
"NAS-Filter-Rule";
"QoS-Filter-Rule";
"Login-IP-Host";
"Login-IPv6-Host";
"Login-LAT-Group";
"Login-LAT-Node";
"Login-LAT-Port";
"Login-LAT-Service";
"Login-Service";
"Login-TCP-Port";
"Route-Record" = { multi=5; };
nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/app_acct_tools/database.sql 0000664 0000000 0000000 00000015642 13335533574 0026002 0 ustar 00root root 0000000 0000000 -- database.sql
-- Script to create the tables for process_records.php script to perform.
-- IMPORTANT NOTE: No constraint and almost no index are created by this script.
-- One should consider adding the appropriate indexes according to their utilization of the data.
-- Incoming table table.
-- This table is used by app_acct.fdx to store the Accounting records.
CREATE TABLE incoming (
"Origin-Host" bytea NOT NULL,
"Origin-Realm" bytea NOT NULL,
"Destination-Realm" bytea,
"Destination-Host" bytea,
"Session-Id" bytea NOT NULL,
"Origin-State-Id" integer,
"Accounting-Record-Type" integer NOT NULL,
"Accounting-Record-Number" integer NOT NULL,
"User-Name" bytea,
"Event-Timestamp" bytea,
"Acct-Application-Id" integer,
"Accounting-Sub-Session-Id" bigint,
"Acct-Session-Id" bytea,
"Acct-Multi-Session-Id" bytea,
"Origin-AAA-Protocol" integer,
"Acct-Delay-Time" integer,
"NAS-Identifier" bytea,
"NAS-IP-Address" bytea,
"NAS-IPv6-Address" bytea,
"NAS-Port" integer,
"NAS-Port-Id" bytea,
"NAS-Port-Type" integer,
"Service-Type" integer,
"Termination-Cause" integer,
"Accounting-Input-Octets" bigint,
"Accounting-Input-Packets" bigint,
"Accounting-Output-Octets" bigint,
"Accounting-Output-Packets" bigint,
"Acct-Authentic" integer,
"Acct-Link-Count" integer,
"Acct-Session-Time" integer,
"Acct-Tunnel-Connection" bytea,
"Acct-Tunnel-Packets-Lost" integer,
"Callback-Id" bytea,
"Callback-Number" bytea,
"Called-Station-Id" bytea,
"Calling-Station-Id" bytea,
"Connect-Info" bytea,
"Originating-Line-Info" bytea,
"Authorization-Lifetime" integer,
"Session-Timeout" integer,
"Idle-Timeout" integer,
"Port-Limit" integer,
"Accounting-Realtime-Required" integer,
"Acct-Interim-Interval" integer,
"Filter-Id" bytea,
"NAS-Filter-Rule" bytea,
"QoS-Filter-Rule" bytea,
"Login-IP-Host" bytea,
"Login-IPv6-Host" bytea,
"Login-LAT-Group" bytea,
"Login-LAT-Node" bytea,
"Login-LAT-Port" bytea,
"Login-LAT-Service" bytea,
"Login-Service" integer,
"Login-TCP-Port" integer,
"Route-Record1" bytea,
"Route-Record2" bytea,
"Route-Record3" bytea,
"Route-Record4" bytea,
"Route-Record5" bytea,
"recorded_on" timestamp with time zone NOT NULL,
"recorded_serv" bytea
);
-- Accounting Data.
-- This is is the processed data that is used also by display_results.php
CREATE TABLE processed (
user_name bytea,
user_device bytea,
nas_info bytea,
sess_start timestamp with time zone,
sess_duration interval,
downl_bytes bigint,
upl_bytes bigint,
downl_packets bigint,
upl_packets bigint
);
CREATE INDEX un_index ON processed (user_name);
-- Orphans table.
-- This is optional, and it must match the structure of your incoming table.
CREATE TABLE orphans (
"Origin-Host" bytea NOT NULL,
"Origin-Realm" bytea NOT NULL,
"Destination-Realm" bytea,
"Destination-Host" bytea,
"Session-Id" bytea NOT NULL,
"Origin-State-Id" integer,
"Accounting-Record-Type" integer NOT NULL,
"Accounting-Record-Number" integer NOT NULL,
"User-Name" bytea,
"Event-Timestamp" bytea,
"Acct-Application-Id" integer,
"Accounting-Sub-Session-Id" bigint,
"Acct-Session-Id" bytea,
"Acct-Multi-Session-Id" bytea,
"Origin-AAA-Protocol" integer,
"Acct-Delay-Time" integer,
"NAS-Identifier" bytea,
"NAS-IP-Address" bytea,
"NAS-IPv6-Address" bytea,
"NAS-Port" integer,
"NAS-Port-Id" bytea,
"NAS-Port-Type" integer,
"Service-Type" integer,
"Termination-Cause" integer,
"Accounting-Input-Octets" bigint,
"Accounting-Input-Packets" bigint,
"Accounting-Output-Octets" bigint,
"Accounting-Output-Packets" bigint,
"Acct-Authentic" integer,
"Acct-Link-Count" integer,
"Acct-Session-Time" integer,
"Acct-Tunnel-Connection" bytea,
"Acct-Tunnel-Packets-Lost" integer,
"Callback-Id" bytea,
"Callback-Number" bytea,
"Called-Station-Id" bytea,
"Calling-Station-Id" bytea,
"Connect-Info" bytea,
"Originating-Line-Info" bytea,
"Authorization-Lifetime" integer,
"Session-Timeout" integer,
"Idle-Timeout" integer,
"Port-Limit" integer,
"Accounting-Realtime-Required" integer,
"Acct-Interim-Interval" integer,
"Filter-Id" bytea,
"NAS-Filter-Rule" bytea,
"QoS-Filter-Rule" bytea,
"Login-IP-Host" bytea,
"Login-IPv6-Host" bytea,
"Login-LAT-Group" bytea,
"Login-LAT-Node" bytea,
"Login-LAT-Port" bytea,
"Login-LAT-Service" bytea,
"Login-Service" integer,
"Login-TCP-Port" integer,
"Route-Record1" bytea,
"Route-Record2" bytea,
"Route-Record3" bytea,
"Route-Record4" bytea,
"Route-Record5" bytea,
"recorded_on" timestamp with time zone NOT NULL,
"recorded_serv" bytea
);
-- Archives table.
-- This is also optional, and it must match the structure of your incoming table.
CREATE TABLE archived (
"Origin-Host" bytea NOT NULL,
"Origin-Realm" bytea NOT NULL,
"Destination-Realm" bytea,
"Destination-Host" bytea,
"Session-Id" bytea NOT NULL,
"Origin-State-Id" integer,
"Accounting-Record-Type" integer NOT NULL,
"Accounting-Record-Number" integer NOT NULL,
"User-Name" bytea,
"Event-Timestamp" bytea,
"Acct-Application-Id" integer,
"Accounting-Sub-Session-Id" bigint,
"Acct-Session-Id" bytea,
"Acct-Multi-Session-Id" bytea,
"Origin-AAA-Protocol" integer,
"Acct-Delay-Time" integer,
"NAS-Identifier" bytea,
"NAS-IP-Address" bytea,
"NAS-IPv6-Address" bytea,
"NAS-Port" integer,
"NAS-Port-Id" bytea,
"NAS-Port-Type" integer,
"Service-Type" integer,
"Termination-Cause" integer,
"Accounting-Input-Octets" bigint,
"Accounting-Input-Packets" bigint,
"Accounting-Output-Octets" bigint,
"Accounting-Output-Packets" bigint,
"Acct-Authentic" integer,
"Acct-Link-Count" integer,
"Acct-Session-Time" integer,
"Acct-Tunnel-Connection" bytea,
"Acct-Tunnel-Packets-Lost" integer,
"Callback-Id" bytea,
"Callback-Number" bytea,
"Called-Station-Id" bytea,
"Calling-Station-Id" bytea,
"Connect-Info" bytea,
"Originating-Line-Info" bytea,
"Authorization-Lifetime" integer,
"Session-Timeout" integer,
"Idle-Timeout" integer,
"Port-Limit" integer,
"Accounting-Realtime-Required" integer,
"Acct-Interim-Interval" integer,
"Filter-Id" bytea,
"NAS-Filter-Rule" bytea,
"QoS-Filter-Rule" bytea,
"Login-IP-Host" bytea,
"Login-IPv6-Host" bytea,
"Login-LAT-Group" bytea,
"Login-LAT-Node" bytea,
"Login-LAT-Port" bytea,
"Login-LAT-Service" bytea,
"Login-Service" integer,
"Login-TCP-Port" integer,
"Route-Record1" bytea,
"Route-Record2" bytea,
"Route-Record3" bytea,
"Route-Record4" bytea,
"Route-Record5" bytea,
"recorded_on" timestamp with time zone NOT NULL,
"recorded_serv" bytea
);
nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/app_acct_tools/display_results.php 0000664 0000000 0000000 00000007553 13335533574 0027456 0 ustar 00root root 0000000 0000000 1 && $count<8)
{
$size=$size/1024;
$count++;
}
if( $size >= 100 ) $decimals = 0;
elseif ($size >= 10 ) $decimals = 1;
else $decimals = 2;
$return = number_format($size,$decimals,'.',' ')." ".$format[$count];
return $return;
}
/* Build the SQL query */
$sql = 'SELECT *, to_char(sess_start, \'YYYY-MM-DD HH24:MI:SS (TZ)\') as fmt_sess_start FROM "'.$PROCESSED.'"';
$where=0;
if ($USERS) {
$USERS = array_map(pg_escape_bytea, $USERS);
$sql .= " WHERE user_name IN ('". join("', '", array_values($USERS))."') ";
$where = 1;
}
if ($START_TIME) {
$START_TIME = pg_escape_string($START_TIME);
if ($where++)
$sql .= " AND ";
else
$sql .= " WHERE ";
$sql .= "sess_start >= '".$START_TIME."'";
}
if ($END_TIME) {
$END_TIME = pg_escape_string($END_TIME);
if ($where++)
$sql .= " AND ";
else
$sql .= " WHERE ";
$sql .= "sess_start <= '".$END_TIME."'";
}
$sql .= " ORDER BY sess_start, sess_duration";
if ($LIMIT)
$sql .= " LIMIT $LIMIT";
if ($LIMIT_OFFSET)
$sql .= " OFFSET $LIMIT_OFFSET";
/* Execute the query */
$result = pg_query($dbconn, $sql) or die('Query failed: ' . pg_last_error() . "\n");
$recs = pg_num_rows($result);
if ($recs == 0) {
echo "Sorry, no data is available in this selection.
\n";
} else {
echo "$recs records found.
\n";
?>
Device identifier
Access Device information
Session started on
Duration
Downloaded
Uploaded
\n";
echo " ";
echo htmlentities(pg_unescape_bytea($record["user_device"]));
echo " \n";
echo " ";
echo htmlentities(pg_unescape_bytea($record["nas_info"]));
echo " \n";
echo " ";
echo $record["fmt_sess_start"];
echo " \n";
echo " ";
echo htmlentities($record["sess_duration"]);
echo " \n";
echo " ";
echo human_readable( $record["downl_bytes"] )." (".$record["downl_packets"]."pckts)";
echo " \n";
echo " ";
echo human_readable( $record["upl_bytes"] )." (".$record["upl_packets"]."pckts)";
echo " \n";
echo " \n";
}
}
pg_free_result($result);
/* Closing connection */
pg_close($dbconn);
?>
nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/app_acct_tools/display_self.php 0000664 0000000 0000000 00000011605 13335533574 0026677 0 ustar 00root root 0000000 0000000
# SSLVerifyClient require
# SSLVerifyDepth 2
#
/* Check the client is correctly SSL authenticated with his server */
if (!isset($_SERVER["SSL_CLIENT_VERIFY"]) || $_SERVER["SSL_CLIENT_VERIFY"] != "SUCCESS")
die("SSL authentication failed, the webserver is probably not configured correctly.\n");
/* Force some parameters to integer values */
if ($_GET["t_limit"])
$_GET["t_limit"] = (int) $_GET["t_limit"];
if ($_GET["t_offset"])
$_GET["t_offset"] = (int) $_GET["t_offset"];
/* Default form values */
if (!isset($_GET["Submit"])) {
$_GET["t_limit"] = 50;
$_GET["c_limit"] = 1;
$_GET["t_offset"] = 0;
}
/* Output the form */
?>
Accounting Data
Accounting data
Note well: this page displays only data about terminated sessions.
Currently displaying user
nextepc-0.3.10/lib/freeDiameter-1.2.1/contrib/app_acct_tools/display_stats.php 0000664 0000000 0000000 00000020534 13335533574 0027105 0 ustar 00root root 0000000 0000000
Accounting Data
Statistical accounting data
Note well: this page displays only data about terminated sessions.
= '".pg_escape_string($START_TIME)."'";
}
if ($END_TIME) {
if ($sql_cond)
$sql_cond .= " AND ";
$sql_cond .= "sess_start =< '".pg_escape_string($END_TIME)."'";
}
/* Function to format download size (from php.net) */
function human_readable( $size )
{
$count = 0;
$format = array("B","KB","MB","GB","TB","PB","EB","ZB","YB");
while(($size/1024)>1 && $count<8)
{
$size=$size/1024;
$count++;
}
if( $size >= 100 ) $decimals = 0;
elseif ($size >= 10 ) $decimals = 1;
else $decimals = 2;
$return = number_format($size,$decimals,'.',' ')." ".$format[$count];
return $return;
}
?>
No data is available in the selected period. \n";
die("\n");
}
$data = pg_fetch_array($result, null, PGSQL_ASSOC);
?>
Total accounted data
First session started: ".$data["first_sess"]." \n";
echo " Last session started: ".$data["last_sess"]." \n";
echo " Total data downloaded: ".human_readable($data["total_down"])." \n";
echo " Total data uploaded: ".human_readable($data["total_up"])." \n";
echo " Number of users who connected at least once: ".$data["nb_users"]." \n";
echo " Number of access points involved: ".$data["nb_ap"]." \n";
echo " \n";
echo "
\n";
pg_free_result($result);
?>
Top-5 downloading users
\n";
echo " ".htmlentities(pg_unescape_bytea($data["user_name"]))." \n";
echo " ".human_readable($data["total_down"])." \n";
echo " \n";
}
pg_free_result($result);
?>
Top-5 uploading users
\n";
echo " ".htmlentities(pg_unescape_bytea($data["user_name"]))." \n";
echo " ".human_readable($data["total_up"])." \n";
echo " \n";
}
pg_free_result($result);
?>
Top-8 access devices (by number of users)
\n";
echo " ".htmlentities(pg_unescape_bytea($data["nas_info"]))." \n";
echo " ".$data["unc"]." \n";
echo " \n";
}
pg_free_result($result);
?>
Top-8 access devices (by traffic: up+down)
\n";
echo " ".htmlentities(pg_unescape_bytea($data["nas_info"]))." \n";
echo " ".human_readable($data["traffic"])." \n";
echo " \n";
}
pg_free_result($result);
?>
Data generated by scripts from the freeDiameter project.