run indent on the whole tree and update copyright dates in prep for 1.0.5

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@16579 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2010-02-06 03:38:24 +00:00
parent 7b347417e5
commit 886e1ddb4d
229 changed files with 20252 additions and 20192 deletions

View File

@ -1,5 +1,5 @@
#!/bin/sh
echo -n "-brs -npsl -di0 -br -ce -d0 -cli0 -npcs -nfc1 -ut -i4 -ts4 -l155 -cs -T size_t " > ./.indent.pro
grep typedef `find ./src/include/ -name \*.h` | grep apr_ | grep -v "\*\|{" | sed -e s/struct// | perl -ne '@l = split; $l[2] =~ s/;//g ; print "-T $l[2] "' >> ./.indent.pro
grep typedef `find ./src/include/ -name \*.h` | grep switch_ | grep -v "\*\|{" | sed -e s/struct// | perl -ne '@l = split; $l[2] =~ s/;//g ; print "-T $l[2] "' >> ./.indent.pro
grep "typedef struct.*_t;" `find ./src/include/ -name \*.h` | grep apr_ | grep -v "\*\|{" | sed -e s/struct// | perl -ne '@l = split; $l[2] =~ s/;//g ; print "-T $l[2] "' >> ./.indent.pro
grep "typedef struct.*_t;" `find ./src/include/ -name \*.h` | grep switch_ | grep -v "\*\|{" | sed -e s/struct// | perl -ne '@l = split; $l[2] =~ s/;//g ; print "-T $l[2] "' >> ./.indent.pro
grep "} switch_" ./src/include/*.h | perl -ne '@l = split; $l[1] =~ s/;//g ; print " -T $l[1] "' >> ./.indent.pro

View File

@ -35,58 +35,58 @@
#include "g711.h"
/* Copied from the CCITT G.711 specification */
static const uint8_t ulaw_to_alaw_table[256] =
{
42, 43, 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, 38, 39, 36, 37,
58, 59, 56, 57, 62, 63, 60, 61, 50, 51, 48, 49, 54, 55, 52, 53,
10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6, 7, 4, 26,
27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17, 22, 23, 20, 21, 106,
104, 105, 110, 111, 108, 109, 98, 99, 96, 97, 102, 103, 100, 101, 122, 120,
126, 127, 124, 125, 114, 115, 112, 113, 118, 119, 116, 117, 75, 73, 79, 77,
66, 67, 64, 65, 70, 71, 68, 69, 90, 91, 88, 89, 94, 95, 92, 93,
82, 82, 83, 83, 80, 80, 81, 81, 86, 86, 87, 87, 84, 84, 85, 85,
170, 171, 168, 169, 174, 175, 172, 173, 162, 163, 160, 161, 166, 167, 164, 165,
186, 187, 184, 185, 190, 191, 188, 189, 178, 179, 176, 177, 182, 183, 180, 181,
138, 139, 136, 137, 142, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 154,
155, 152, 153, 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149, 234,
232, 233, 238, 239, 236, 237, 226, 227, 224, 225, 230, 231, 228, 229, 250, 248,
254, 255, 252, 253, 242, 243, 240, 241, 246, 247, 244, 245, 203, 201, 207, 205,
194, 195, 192, 193, 198, 199, 196, 197, 218, 219, 216, 217, 222, 223, 220, 221,
210, 210, 211, 211, 208, 208, 209, 209, 214, 214, 215, 215, 212, 212, 213, 213
static const uint8_t ulaw_to_alaw_table[256] = {
42, 43, 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, 38, 39, 36, 37,
58, 59, 56, 57, 62, 63, 60, 61, 50, 51, 48, 49, 54, 55, 52, 53,
10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6, 7, 4, 26,
27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17, 22, 23, 20, 21, 106,
104, 105, 110, 111, 108, 109, 98, 99, 96, 97, 102, 103, 100, 101, 122, 120,
126, 127, 124, 125, 114, 115, 112, 113, 118, 119, 116, 117, 75, 73, 79, 77,
66, 67, 64, 65, 70, 71, 68, 69, 90, 91, 88, 89, 94, 95, 92, 93,
82, 82, 83, 83, 80, 80, 81, 81, 86, 86, 87, 87, 84, 84, 85, 85,
170, 171, 168, 169, 174, 175, 172, 173, 162, 163, 160, 161, 166, 167, 164, 165,
186, 187, 184, 185, 190, 191, 188, 189, 178, 179, 176, 177, 182, 183, 180, 181,
138, 139, 136, 137, 142, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 154,
155, 152, 153, 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149, 234,
232, 233, 238, 239, 236, 237, 226, 227, 224, 225, 230, 231, 228, 229, 250, 248,
254, 255, 252, 253, 242, 243, 240, 241, 246, 247, 244, 245, 203, 201, 207, 205,
194, 195, 192, 193, 198, 199, 196, 197, 218, 219, 216, 217, 222, 223, 220, 221,
210, 210, 211, 211, 208, 208, 209, 209, 214, 214, 215, 215, 212, 212, 213, 213
};
/* These transcoding tables are copied from the CCITT G.711 specification. To achieve
optimal results, do not change them. */
static const uint8_t alaw_to_ulaw_table[256] =
{
42, 43, 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, 38, 39, 36, 37,
57, 58, 55, 56, 61, 62, 59, 60, 49, 50, 47, 48, 53, 54, 51, 52,
10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6, 7, 4, 5,
26, 27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17, 22, 23, 20, 21,
98, 99, 96, 97, 102, 103, 100, 101, 93, 93, 92, 92, 95, 95, 94, 94,
116, 118, 112, 114, 124, 126, 120, 122, 106, 107, 104, 105, 110, 111, 108, 109,
72, 73, 70, 71, 76, 77, 74, 75, 64, 65, 63, 63, 68, 69, 66, 67,
86, 87, 84, 85, 90, 91, 88, 89, 79, 79, 78, 78, 82, 83, 80, 81,
170, 171, 168, 169, 174, 175, 172, 173, 162, 163, 160, 161, 166, 167, 164, 165,
185, 186, 183, 184, 189, 190, 187, 188, 177, 178, 175, 176, 181, 182, 179, 180,
138, 139, 136, 137, 142, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 133,
154, 155, 152, 153, 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149,
226, 227, 224, 225, 230, 231, 228, 229, 221, 221, 220, 220, 223, 223, 222, 222,
244, 246, 240, 242, 252, 254, 248, 250, 234, 235, 232, 233, 238, 239, 236, 237,
200, 201, 198, 199, 204, 205, 202, 203, 192, 193, 191, 191, 196, 197, 194, 195,
214, 215, 212, 213, 218, 219, 216, 217, 207, 207, 206, 206, 210, 211, 208, 209
static const uint8_t alaw_to_ulaw_table[256] = {
42, 43, 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, 38, 39, 36, 37,
57, 58, 55, 56, 61, 62, 59, 60, 49, 50, 47, 48, 53, 54, 51, 52,
10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6, 7, 4, 5,
26, 27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17, 22, 23, 20, 21,
98, 99, 96, 97, 102, 103, 100, 101, 93, 93, 92, 92, 95, 95, 94, 94,
116, 118, 112, 114, 124, 126, 120, 122, 106, 107, 104, 105, 110, 111, 108, 109,
72, 73, 70, 71, 76, 77, 74, 75, 64, 65, 63, 63, 68, 69, 66, 67,
86, 87, 84, 85, 90, 91, 88, 89, 79, 79, 78, 78, 82, 83, 80, 81,
170, 171, 168, 169, 174, 175, 172, 173, 162, 163, 160, 161, 166, 167, 164, 165,
185, 186, 183, 184, 189, 190, 187, 188, 177, 178, 175, 176, 181, 182, 179, 180,
138, 139, 136, 137, 142, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 133,
154, 155, 152, 153, 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149,
226, 227, 224, 225, 230, 231, 228, 229, 221, 221, 220, 220, 223, 223, 222, 222,
244, 246, 240, 242, 252, 254, 248, 250, 234, 235, 232, 233, 238, 239, 236, 237,
200, 201, 198, 199, 204, 205, 202, 203, 192, 193, 191, 191, 196, 197, 194, 195,
214, 215, 212, 213, 218, 219, 216, 217, 207, 207, 206, 206, 210, 211, 208, 209
};
uint8_t alaw_to_ulaw(uint8_t alaw)
{
return alaw_to_ulaw_table[alaw];
return alaw_to_ulaw_table[alaw];
}
/*- End of function --------------------------------------------------------*/
uint8_t ulaw_to_alaw(uint8_t ulaw)
{
return ulaw_to_alaw_table[ulaw];
return ulaw_to_alaw_table[ulaw];
}
/*- End of function --------------------------------------------------------*/
/*- End of file ------------------------------------------------------------*/

View File

@ -302,13 +302,17 @@ template < class SOCHAR > struct SimpleGlobBase {
const char *GetFileNameS(char) const {
return m_oFindDataA.cFileName;
} const wchar_t *GetFileNameS(wchar_t) const {
}
const wchar_t *GetFileNameS(wchar_t) const {
return m_oFindDataW.cFileName;
} bool IsDirS(char) const {
}
bool IsDirS(char) const {
return GetFileTypeS(m_oFindDataA.dwFileAttributes) == SG_FILETYPE_DIR;
} bool IsDirS(wchar_t) const {
}
bool IsDirS(wchar_t) const {
return GetFileTypeS(m_oFindDataW.dwFileAttributes) == SG_FILETYPE_DIR;
} SG_FileType GetFileTypeS(const char *a_pszPath) {
}
SG_FileType GetFileTypeS(const char *a_pszPath) {
return GetFileTypeS(GetFileAttributesA(a_pszPath));
}
SG_FileType GetFileTypeS(const wchar_t *a_pszPath) {
@ -390,10 +394,12 @@ template < class SOCHAR > struct SimpleGlobBase {
const char *GetFileNameS(char) const {
SG_ASSERT(m_uiCurr != (size_t) -1);
return m_glob.gl_pathv[m_uiCurr];
} bool IsDirS(char) const {
}
bool IsDirS(char) const {
SG_ASSERT(m_uiCurr != (size_t) -1);
return m_bIsDir;
} SG_FileType GetFileTypeS(const char *a_pszPath) const {
}
SG_FileType GetFileTypeS(const char *a_pszPath) const {
struct stat sb;
if (0 != stat(a_pszPath, &sb)) {
return SG_FILETYPE_INVALID;
@ -777,7 +783,7 @@ template < class SOCHAR > int CSimpleGlobTempl < SOCHAR >::fileSortCompare(const
// ---------------------------------------------------------------------------
typedef CSimpleGlobTempl < char >CSimpleGlobA; /*!< @brief ASCII/MBCS version of CSimpleGlob */
typedef CSimpleGlobTempl < wchar_t >CSimpleGlobW; /*!< @brief wchar_t version of CSimpleGlob */
typedef CSimpleGlobTempl < wchar_t > CSimpleGlobW; /*!< @brief wchar_t version of CSimpleGlob */
#if defined(_UNICODE)
# define CSimpleGlob CSimpleGlobW /*!< @brief TCHAR version dependent on if _UNICODE is defined */
#else

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -115,7 +115,7 @@ struct switch_core_session {
switch_codec_implementation_t write_impl;
switch_codec_implementation_t video_read_impl;
switch_codec_implementation_t video_write_impl;
switch_audio_resampler_t *read_resampler;
switch_audio_resampler_t *write_resampler;
@ -130,7 +130,7 @@ struct switch_core_session {
void *streams[SWITCH_MAX_STREAMS];
int stream_count;
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH+1];
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
void *private_info;
switch_queue_t *event_queue;
switch_queue_t *message_queue;

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -40,12 +40,11 @@
#define SWITCH_APR_H
SWITCH_BEGIN_EXTERN_C
#ifdef WIN32
typedef DWORD switch_thread_id_t;
typedef DWORD switch_thread_id_t;
#else
#include <pthread.h>
typedef pthread_t switch_thread_id_t;
typedef pthread_t switch_thread_id_t;
#endif
SWITCH_DECLARE(switch_thread_id_t) switch_thread_self(void);
@ -108,7 +107,7 @@ SWITCH_DECLARE(void) switch_pool_clear(switch_memory_pool_t *p);
* @bug We aught to provide an alternative to RTLD_GLOBAL, which
* is the only supported method of loading DSOs today.
*/
SWITCH_DECLARE(switch_status_t) switch_dso_load(switch_dso_handle_t **res_handle, const char *path, switch_memory_pool_t *ctx);
SWITCH_DECLARE(switch_status_t) switch_dso_load(switch_dso_handle_t ** res_handle, const char *path, switch_memory_pool_t *ctx);
/**
* Close a DSO library.
@ -378,7 +377,7 @@ SWITCH_DECLARE(void) switch_micro_sleep(switch_interval_time_t t);
* it will behave as either a nested or an unnested lock.
*
*/
SWITCH_DECLARE(switch_status_t) switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_mutex_init(switch_mutex_t ** lock, unsigned int flags, switch_memory_pool_t *pool);
/**
@ -420,7 +419,7 @@ SWITCH_DECLARE(switch_status_t) switch_mutex_trylock(switch_mutex_t *lock);
/** Opaque structure used for the rwlock */
typedef struct apr_thread_rwlock_t switch_thread_rwlock_t;
SWITCH_DECLARE(switch_status_t) switch_thread_rwlock_create(switch_thread_rwlock_t **rwlock, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_thread_rwlock_create(switch_thread_rwlock_t ** rwlock, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_thread_rwlock_destroy(switch_thread_rwlock_t *rwlock);
SWITCH_DECLARE(switch_memory_pool_t *) switch_thread_rwlock_pool_get(switch_thread_rwlock_t *rwlock);
SWITCH_DECLARE(switch_status_t) switch_thread_rwlock_rdlock(switch_thread_rwlock_t *rwlock);
@ -454,7 +453,7 @@ SWITCH_DECLARE(switch_status_t) switch_thread_rwlock_unlock(switch_thread_rwlock
* will be stored.
* @param pool the pool from which to allocate the mutex.
*/
SWITCH_DECLARE(switch_status_t) switch_thread_cond_create(switch_thread_cond_t **cond, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_thread_cond_create(switch_thread_cond_t ** cond, switch_memory_pool_t *pool);
/**
* Put the active calling thread to sleep until signaled to wake up. Each
@ -580,7 +579,7 @@ SWITCH_DECLARE(switch_status_t) switch_md5_string(char digest_str[SWITCH_MD5_DIG
* @param queue_capacity maximum size of the queue
* @param pool a pool to allocate queue from
*/
SWITCH_DECLARE(switch_status_t) switch_queue_create(switch_queue_t **queue, unsigned int queue_capacity, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_queue_create(switch_queue_t ** queue, unsigned int queue_capacity, switch_memory_pool_t *pool);
/**
* pop/get an object from the queue, blocking if the queue is already empty
@ -774,17 +773,14 @@ SWITCH_DECLARE(switch_status_t) switch_queue_trypush(switch_queue_t *queue, void
* @remark If perm is SWITCH_FPROT_OS_DEFAULT and the file is being created,
* appropriate default permissions will be used.
*/
SWITCH_DECLARE(switch_status_t) switch_file_open(switch_file_t **newf, const char *fname, int32_t flag, switch_fileperms_t perm,
SWITCH_DECLARE(switch_status_t) switch_file_open(switch_file_t ** newf, const char *fname, int32_t flag, switch_fileperms_t perm,
switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_file_seek(switch_file_t *thefile, switch_seek_where_t where, int64_t *offset);
SWITCH_DECLARE(switch_status_t) switch_file_copy(const char *from_path,
const char *to_path,
switch_fileperms_t perms,
switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_file_copy(const char *from_path, const char *to_path, switch_fileperms_t perms, switch_memory_pool_t *pool);
/**
* Close the specified file.
@ -844,7 +840,7 @@ SWITCH_DECLARE(switch_status_t) switch_file_read(switch_file_t *thefile, void *b
SWITCH_DECLARE(switch_status_t) switch_file_write(switch_file_t *thefile, const void *buf, switch_size_t *nbytes);
SWITCH_DECLARE(int) switch_file_printf(switch_file_t *thefile, const char *format, ...);
SWITCH_DECLARE(switch_status_t) switch_file_mktemp(switch_file_t **thefile, char *templ, int32_t flags, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_file_mktemp(switch_file_t ** thefile, char *templ, int32_t flags, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_size_t) switch_file_get_size(switch_file_t *thefile);
@ -885,7 +881,7 @@ SWITCH_DECLARE(switch_status_t) switch_dir_make_recursive(const char *path, swit
};
typedef struct switch_array_header_t switch_array_header_t;
SWITCH_DECLARE(switch_status_t) switch_dir_open(switch_dir_t **new_dir, const char *dirname, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_dir_open(switch_dir_t ** new_dir, const char *dirname, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_dir_close(switch_dir_t *thedir);
SWITCH_DECLARE(const char *) switch_dir_next_file(switch_dir_t *thedir, char *buf, switch_size_t len);
@ -920,7 +916,7 @@ SWITCH_DECLARE(switch_status_t) switch_threadattr_priority_increase(switch_threa
* @param new_attr The newly created threadattr.
* @param pool The pool to use
*/
SWITCH_DECLARE(switch_status_t) switch_threadattr_create(switch_threadattr_t **new_attr, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_threadattr_create(switch_threadattr_t ** new_attr, switch_memory_pool_t *pool);
/**
* Set if newly created threads should be created in detached state.
@ -937,7 +933,7 @@ SWITCH_DECLARE(switch_status_t) switch_threadattr_detach_set(switch_threadattr_t
* @param data Any data to be passed to the starting function
* @param cont The pool to use
*/
SWITCH_DECLARE(switch_status_t) switch_thread_create(switch_thread_t **new_thread, switch_threadattr_t *attr,
SWITCH_DECLARE(switch_status_t) switch_thread_create(switch_thread_t ** new_thread, switch_threadattr_t *attr,
switch_thread_start_t func, void *data, switch_memory_pool_t *cont);
/** @} */
@ -1006,7 +1002,7 @@ SWITCH_DECLARE(switch_status_t) switch_thread_create(switch_thread_t **new_threa
* @param protocol The protocol of the socket (e.g., SWITCH_PROTO_TCP).
* @param pool The pool to use
*/
SWITCH_DECLARE(switch_status_t) switch_socket_create(switch_socket_t **new_sock, int family, int type, int protocol, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_socket_create(switch_socket_t ** new_sock, int family, int type, int protocol, switch_memory_pool_t *pool);
/**
* Shutdown either reading, writing, or both sides of a socket.
@ -1055,7 +1051,7 @@ SWITCH_DECLARE(switch_status_t) switch_socket_listen(switch_socket_t *sock, int3
* @param sock The socket we are listening on.
* @param pool The pool for the new socket.
*/
SWITCH_DECLARE(switch_status_t) switch_socket_accept(switch_socket_t **new_sock, switch_socket_t *sock, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_socket_accept(switch_socket_t ** new_sock, switch_socket_t *sock, switch_memory_pool_t *pool);
/**
* Issue a connection request to a socket either on the same machine
@ -1095,7 +1091,7 @@ SWITCH_DECLARE(int) switch_sockaddr_equal(const switch_sockaddr_t *sa1, const sw
* </PRE>
* @param pool The pool for the apr_sockaddr_t and associated storage.
*/
SWITCH_DECLARE(switch_status_t) switch_sockaddr_info_get(switch_sockaddr_t **sa, const char *hostname,
SWITCH_DECLARE(switch_status_t) switch_sockaddr_info_get(switch_sockaddr_t ** sa, const char *hostname,
int32_t family, switch_port_t port, int32_t flags, switch_memory_pool_t *pool);
/**
@ -1124,7 +1120,8 @@ SWITCH_DECLARE(switch_status_t) switch_socket_send(switch_socket_t *sock, const
* @param buf The data to send
* @param len The length of the data to send
*/
SWITCH_DECLARE(switch_status_t) switch_socket_sendto(switch_socket_t *sock, switch_sockaddr_t *where, int32_t flags, const char *buf, switch_size_t *len);
SWITCH_DECLARE(switch_status_t) switch_socket_sendto(switch_socket_t *sock, switch_sockaddr_t *where, int32_t flags, const char *buf,
switch_size_t *len);
/**
* @param from The apr_sockaddr_t to fill in the recipient info
@ -1219,26 +1216,27 @@ SWITCH_DECLARE(switch_status_t) switch_mcast_hops(switch_socket_t *sock, uint8_t
/** @} */
typedef enum {
SWITCH_NO_DESC, /**< nothing here */
SWITCH_POLL_SOCKET, /**< descriptor refers to a socket */
SWITCH_POLL_FILE, /**< descriptor refers to a file */
SWITCH_POLL_LASTDESC /**< descriptor is the last one in the list */
} switch_pollset_type_t;
typedef enum {
SWITCH_NO_DESC, /**< nothing here */
SWITCH_POLL_SOCKET, /**< descriptor refers to a socket */
SWITCH_POLL_FILE, /**< descriptor refers to a file */
SWITCH_POLL_LASTDESC /**< descriptor is the last one in the list */
} switch_pollset_type_t;
typedef union {
switch_file_t *f; /**< file */
switch_socket_t *s; /**< socket */
} switch_descriptor_t;
typedef union {
switch_file_t *f; /**< file */
switch_socket_t *s; /**< socket */
} switch_descriptor_t;
struct switch_pollfd {
switch_memory_pool_t *p; /**< associated pool */
switch_pollset_type_t desc_type; /**< descriptor type */
int16_t reqevents; /**< requested events */
int16_t rtnevents; /**< returned events */
switch_descriptor_t desc; /**< @see apr_descriptor */
void *client_data; /**< allows app to associate context */
};
struct switch_pollfd {
switch_memory_pool_t *p; /**< associated pool */
switch_pollset_type_t desc_type;
/**< descriptor type */
int16_t reqevents; /**< requested events */
int16_t rtnevents; /**< returned events */
switch_descriptor_t desc; /**< @see apr_descriptor */
void *client_data; /**< allows app to associate context */
};
@ -1277,7 +1275,7 @@ struct switch_pollfd {
* platforms; the apr_pollset_create() call will fail with
* APR_ENOTIMPL on platforms where it is not supported.
*/
SWITCH_DECLARE(switch_status_t) switch_pollset_create(switch_pollset_t **pollset, uint32_t size, switch_memory_pool_t *p, uint32_t flags);
SWITCH_DECLARE(switch_status_t) switch_pollset_create(switch_pollset_t ** pollset, uint32_t size, switch_memory_pool_t *p, uint32_t flags);
/**
* Add a socket or file descriptor to a pollset
@ -1321,10 +1319,10 @@ SWITCH_DECLARE(switch_status_t) switch_poll(switch_pollfd_t *aprset, int32_t num
\param pool the memory pool to use
\return SWITCH_STATUS_SUCCESS when successful
*/
SWITCH_DECLARE(switch_status_t) switch_socket_create_pollfd(switch_pollfd_t **poll, switch_socket_t *sock, int16_t flags, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_socket_create_pollfd(switch_pollfd_t ** poll, switch_socket_t *sock, int16_t flags, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_match_glob(const char *pattern, switch_array_header_t **result, switch_memory_pool_t *p);
SWITCH_DECLARE(switch_status_t) switch_socket_addr_get(switch_sockaddr_t **sa, switch_bool_t remote, switch_socket_t *sock);
SWITCH_DECLARE(switch_status_t) switch_match_glob(const char *pattern, switch_array_header_t ** result, switch_memory_pool_t *p);
SWITCH_DECLARE(switch_status_t) switch_socket_addr_get(switch_sockaddr_t ** sa, switch_bool_t remote, switch_socket_t *sock);
/**
* Create an anonymous pipe.
@ -1332,7 +1330,7 @@ SWITCH_DECLARE(switch_status_t) switch_socket_addr_get(switch_sockaddr_t **sa, s
* @param out The file descriptor to use as output from the pipe.
* @param pool The pool to operate on.
*/
SWITCH_DECLARE(switch_status_t) switch_file_pipe_create(switch_file_t **in, switch_file_t **out, switch_memory_pool_t *p);
SWITCH_DECLARE(switch_status_t) switch_file_pipe_create(switch_file_t ** in, switch_file_t ** out, switch_memory_pool_t *p);
/**
* Get the timeout value for a pipe or manipulate the blocking state.

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -147,7 +147,7 @@ struct switch_caller_extension {
SWITCH_DECLARE(switch_caller_extension_t *) switch_caller_extension_new(_In_ switch_core_session_t *session,
_In_z_ const char *extension_name, _In_z_ const char *extension_number);
SWITCH_DECLARE(switch_status_t) switch_caller_extension_clone(switch_caller_extension_t **new_ext, switch_caller_extension_t *orig,
SWITCH_DECLARE(switch_status_t) switch_caller_extension_clone(switch_caller_extension_t **new_ext, switch_caller_extension_t *orig,
switch_memory_pool_t *pool);
/*!
@ -169,8 +169,8 @@ SWITCH_DECLARE(void) switch_caller_extension_add_application(_In_ switch_core_se
\param fmt optional argument to the application (printf format string)
*/
SWITCH_DECLARE(void) switch_caller_extension_add_application_printf(_In_ switch_core_session_t *session,
_In_ switch_caller_extension_t *caller_extension,
_In_z_ const char *application_name, _In_z_ const char *fmt, ...);
_In_ switch_caller_extension_t *caller_extension,
_In_z_ const char *application_name, _In_z_ const char *fmt, ...);
/*!

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -48,6 +48,7 @@ SWITCH_BEGIN_EXTERN_C struct switch_channel_timetable {
switch_time_t progress_media;
switch_time_t hungup;
switch_time_t transferred;
switch_time_t resurrected;
struct switch_channel_timetable *next;
};
@ -74,21 +75,20 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_get_running_state(switch_c
\param channel channel to test
\return true if the channel is ready
*/
SWITCH_DECLARE(int) switch_channel_test_ready(switch_channel_t *channel, switch_bool_t media);
SWITCH_DECLARE(int) switch_channel_test_ready(switch_channel_t *channel, switch_bool_t check_ready, switch_bool_t check_media);
#define switch_channel_ready(_channel) switch_channel_test_ready(_channel, SWITCH_TRUE, SWITCH_FALSE)
#define switch_channel_media_ready(_channel) switch_channel_test_ready(_channel, SWITCH_TRUE, SWITCH_TRUE)
#define switch_channel_ready(_channel) switch_channel_test_ready(_channel, SWITCH_FALSE)
#define switch_channel_media_ready(_channel) switch_channel_test_ready(_channel, SWITCH_TRUE)
#define switch_channel_up(_channel) (switch_channel_get_state(_channel) < CS_HANGUP)
#define switch_channel_down(_channel) (switch_channel_get_state(_channel) >= CS_HANGUP)
#define switch_channel_media_ack(_channel) (!switch_channel_test_cap(_channel, CC_MEDIA_ACK) || switch_channel_test_flag(_channel, CF_MEDIA_ACK))
SWITCH_DECLARE(void) switch_channel_wait_for_state(switch_channel_t *channel, switch_channel_t *other_channel, switch_channel_state_t want_state);
SWITCH_DECLARE(void) switch_channel_wait_for_state_timeout(switch_channel_t *other_channel, switch_channel_state_t want_state, uint32_t timeout);
SWITCH_DECLARE(switch_status_t) switch_channel_wait_for_flag(switch_channel_t *channel,
switch_channel_flag_t want_flag,
switch_bool_t pres,
uint32_t to,
switch_channel_t *super_channel);
SWITCH_DECLARE(switch_status_t) switch_channel_wait_for_flag(switch_channel_t *channel,
switch_channel_flag_t want_flag,
switch_bool_t pres, uint32_t to, switch_channel_t *super_channel);
SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_channel_t *channel,
const char *file, const char *func, int line, switch_channel_state_t state);
@ -142,7 +142,8 @@ SWITCH_DECLARE(switch_channel_timetable_t *) switch_channel_get_timetable(_In_ s
\param pool memory_pool to use for allocation
\return SWITCH_STATUS_SUCCESS if successful
*/
SWITCH_DECLARE(switch_status_t) switch_channel_alloc(_In_ switch_channel_t **channel, _In_ switch_call_direction_t direction, _In_ switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_channel_alloc(_In_ switch_channel_t **channel, _In_ switch_call_direction_t direction,
_In_ switch_memory_pool_t *pool);
/*!
\brief Connect a newly allocated channel to a session object and setup it's initial state
@ -231,12 +232,12 @@ SWITCH_DECLARE(char *) switch_channel_get_uuid(switch_channel_t *channel);
SWITCH_DECLARE(switch_status_t) switch_channel_set_profile_var(switch_channel_t *channel, const char *name, const char *val);
SWITCH_DECLARE(switch_status_t) switch_channel_set_variable_var_check(switch_channel_t *channel,
SWITCH_DECLARE(switch_status_t) switch_channel_set_variable_var_check(switch_channel_t *channel,
const char *varname, const char *value, switch_bool_t var_check);
SWITCH_DECLARE(switch_status_t) switch_channel_set_variable_printf(switch_channel_t *channel, const char *varname, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_channel_set_variable_name_printf(switch_channel_t *channel, const char *val, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_channel_set_variable_partner_var_check(switch_channel_t *channel,
SWITCH_DECLARE(switch_status_t) switch_channel_set_variable_partner_var_check(switch_channel_t *channel,
const char *varname, const char *value, switch_bool_t var_check);
SWITCH_DECLARE(const char *) switch_channel_get_variable_partner(switch_channel_t *channel, const char *varname);
@ -250,7 +251,9 @@ SWITCH_DECLARE(const char *) switch_channel_get_variable_partner(switch_channel_
\param varname the name of the variable
\return the value of the requested variable
*/
SWITCH_DECLARE(const char *) switch_channel_get_variable(switch_channel_t *channel, const char *varname);
SWITCH_DECLARE(const char *) switch_channel_get_variable_dup(switch_channel_t *channel, const char *varname, switch_bool_t dup);
#define switch_channel_get_variable(_c, _v) switch_channel_get_variable_dup(_c, _v, SWITCH_TRUE)
SWITCH_DECLARE(switch_status_t) switch_channel_get_variables(switch_channel_t *channel, switch_event_t **event);
SWITCH_DECLARE(switch_status_t) switch_channel_pass_callee_id(switch_channel_t *channel, switch_channel_t *other_channel);
@ -300,10 +303,14 @@ SWITCH_DECLARE(uint32_t) switch_channel_test_flag(switch_channel_t *channel, swi
\param channel channel on which to set flag
\param flag or'd list of flags to set
*/
SWITCH_DECLARE(void) switch_channel_set_flag(switch_channel_t *channel, switch_channel_flag_t flag);
SWITCH_DECLARE(void) switch_channel_set_flag_value(switch_channel_t *channel, switch_channel_flag_t flag, uint32_t value);
#define switch_channel_set_flag(_c, _f) switch_channel_set_flag_value(_c, _f, 1)
SWITCH_DECLARE(void) switch_channel_set_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag);
SWITCH_DECLARE(void) switch_channel_set_cap(switch_channel_t *channel, switch_channel_cap_t cap);
SWITCH_DECLARE(void) switch_channel_set_cap_value(switch_channel_t *channel, switch_channel_cap_t cap, uint32_t value);
#define switch_channel_set_cap(_c, _cc) switch_channel_set_cap_value(_c, _cc, 1)
SWITCH_DECLARE(void) switch_channel_clear_cap(switch_channel_t *channel, switch_channel_cap_t cap);
SWITCH_DECLARE(uint32_t) switch_channel_test_cap(switch_channel_t *channel, switch_channel_cap_t cap);
@ -338,6 +345,7 @@ SWITCH_DECLARE(void) switch_channel_set_state_flag(switch_channel_t *channel, sw
\param flag flag to clear
*/
SWITCH_DECLARE(void) switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag);
SWITCH_DECLARE(void) switch_channel_clear_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag);
SWITCH_DECLARE(switch_status_t) switch_channel_perform_answer(switch_channel_t *channel, const char *file, const char *func, int line);
@ -539,7 +547,9 @@ SWITCH_DECLARE(void) switch_channel_clear_app_flag(switch_channel_t *channel, ui
SWITCH_DECLARE(int) switch_channel_test_app_flag(switch_channel_t *channel, uint32_t flags);
SWITCH_DECLARE(void) switch_channel_set_hangup_time(switch_channel_t *channel);
SWITCH_DECLARE(switch_call_direction_t) switch_channel_direction(switch_channel_t *channel);
SWITCH_DECLARE(switch_core_session_t*) switch_channel_get_session(switch_channel_t *channel);
SWITCH_DECLARE(switch_core_session_t *) switch_channel_get_session(switch_channel_t *channel);
SWITCH_DECLARE(char *) switch_channel_get_flag_string(switch_channel_t *channel);
SWITCH_DECLARE(char *) switch_channel_get_cap_string(switch_channel_t *channel);
/** @} */

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -81,12 +81,12 @@ SWITCH_DECLARE(switch_status_t) switch_console_init(switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_console_shutdown(void);
SWITCH_DECLARE(switch_status_t) switch_console_add_complete_func(const char *name, switch_console_complete_callback_t cb);
SWITCH_DECLARE(switch_status_t) switch_console_del_complete_func(const char *name);
SWITCH_DECLARE(switch_status_t) switch_console_run_complete_func(const char *func, const char *line,
SWITCH_DECLARE(switch_status_t) switch_console_run_complete_func(const char *func, const char *line,
const char *last_word, switch_console_callback_match_t **matches);
SWITCH_DECLARE(void) switch_console_push_match(switch_console_callback_match_t **matches, const char *new_val);
SWITCH_DECLARE(void) switch_console_free_matches(switch_console_callback_match_t **matches);
SWITCH_DECLARE(unsigned char) switch_console_complete(const char *line, const char *last_word,
FILE *console_out, switch_stream_handle_t *stream, switch_xml_t xml);
SWITCH_DECLARE(unsigned char) switch_console_complete(const char *line, const char *last_word,
FILE * console_out, switch_stream_handle_t *stream, switch_xml_t xml);
SWITCH_DECLARE(void) switch_console_sort_matches(switch_console_callback_match_t *matches);
SWITCH_DECLARE(void) switch_console_save_history(void);
SWITCH_DECLARE(char *) switch_console_expand_alias(char *cmd, char *arg);

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -369,7 +369,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_lock(_In_ switch_core_s
#ifdef SWITCH_DEBUG_RWLOCKS
SWITCH_DECLARE(switch_status_t) switch_core_session_perform_read_lock_hangup(_In_ switch_core_session_t *session, const char *file, const char *func, int line);
SWITCH_DECLARE(switch_status_t) switch_core_session_perform_read_lock_hangup(_In_ switch_core_session_t *session, const char *file, const char *func,
int line);
#endif
/*!
@ -595,6 +596,9 @@ SWITCH_DECLARE(char *) switch_core_vsprintf(switch_memory_pool_t *pool, _In_z_ _
SWITCH_DECLARE(switch_memory_pool_t *) switch_core_session_get_pool(_In_ switch_core_session_t *session);
///\}
SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_xml(switch_endpoint_interface_t *endpoint_interface,
switch_memory_pool_t **pool, switch_xml_t xml);
///\defgroup sessm Session Creation / Management
///\ingroup core1
///\{
@ -604,7 +608,7 @@ SWITCH_DECLARE(switch_memory_pool_t *) switch_core_session_get_pool(_In_ switch_
\param pool the pool to use for the allocation (a new one will be used if NULL)
\return the newly created session
*/
SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(_In_ switch_endpoint_interface_t *endpoint_interface,
SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(_In_ switch_endpoint_interface_t *endpoint_interface,
_In_ switch_call_direction_t direction,
_Inout_opt_ switch_memory_pool_t **pool, _In_opt_z_ const char *use_uuid);
#define switch_core_session_request(_ep, _d, _p) switch_core_session_request_uuid(_ep, _d, _p, NULL)
@ -645,9 +649,8 @@ SWITCH_DECLARE(switch_size_t) switch_core_session_id(void);
\param pool the pool to use
\return the newly created session
*/
SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_by_name(_In_z_ const char *endpoint_name,
_In_ switch_call_direction_t direction,
_Inout_ switch_memory_pool_t **pool);
SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_by_name(_In_z_ const char *endpoint_name,
_In_ switch_call_direction_t direction, _Inout_ switch_memory_pool_t **pool);
/*!
\brief Launch the session thread (state machine) on a given session
@ -963,7 +966,8 @@ SWITCH_DECLARE(switch_call_cause_t) switch_core_session_outgoing_channel(_In_opt
_In_z_ const char *endpoint_name,
_In_ switch_caller_profile_t *caller_profile,
_Inout_ switch_core_session_t **new_session,
_Inout_ switch_memory_pool_t **pool, _In_ switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
_Inout_ switch_memory_pool_t **pool, _In_ switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause);
SWITCH_DECLARE(switch_call_cause_t) switch_core_session_resurrect_channel(_In_z_ const char *endpoint_name,
_Inout_ switch_core_session_t **new_session,
@ -975,7 +979,7 @@ SWITCH_DECLARE(switch_call_cause_t) switch_core_session_resurrect_channel(_In_z_
\param message the message to recieve
\return the status returned by the message handler
*/
SWITCH_DECLARE(switch_status_t) switch_core_session_perform_receive_message(_In_ switch_core_session_t *session,
SWITCH_DECLARE(switch_status_t) switch_core_session_perform_receive_message(_In_ switch_core_session_t *session,
_In_ switch_core_session_message_t *message,
const char *file, const char *func, int line);
#define switch_core_session_receive_message(_session, _message) switch_core_session_perform_receive_message(_session, _message, \
@ -1013,7 +1017,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_dequeue_event(_In_ switch_co
\param priority event has high priority
\return the status returned by the message handler
*/
SWITCH_DECLARE(switch_status_t) switch_core_session_queue_private_event(_In_ switch_core_session_t *session, _Inout_ switch_event_t **event, switch_bool_t priority);
SWITCH_DECLARE(switch_status_t) switch_core_session_queue_private_event(_In_ switch_core_session_t *session, _Inout_ switch_event_t **event,
switch_bool_t priority);
/*!
@ -1381,10 +1386,10 @@ SWITCH_DECLARE(void) switch_core_session_lock_codec_read(_In_ switch_core_sessio
SWITCH_DECLARE(void) switch_core_session_unlock_codec_read(_In_ switch_core_session_t *session);
SWITCH_DECLARE(switch_status_t) switch_core_session_get_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp);
SWITCH_DECLARE(switch_status_t) switch_core_session_get_write_impl(switch_core_session_t *session, switch_codec_implementation_t *impp);
SWITCH_DECLARE(switch_status_t) switch_core_session_get_video_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp);
SWITCH_DECLARE(switch_status_t) switch_core_session_get_video_write_impl(switch_core_session_t *session, switch_codec_implementation_t *impp);
SWITCH_DECLARE(switch_status_t) switch_core_session_get_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp);
SWITCH_DECLARE(switch_status_t) switch_core_session_get_write_impl(switch_core_session_t *session, switch_codec_implementation_t *impp);
SWITCH_DECLARE(switch_status_t) switch_core_session_get_video_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp);
SWITCH_DECLARE(switch_status_t) switch_core_session_get_video_write_impl(switch_core_session_t *session, switch_codec_implementation_t *impp);
/*!
@ -1636,8 +1641,7 @@ SWITCH_DECLARE(void) switch_core_speech_float_param_tts(switch_speech_handle_t *
\param flags flags in/out for fine tuning
\return SWITCH_STATUS_SUCCESS with len adjusted to the bytes written if successful
*/
SWITCH_DECLARE(switch_status_t) switch_core_speech_read_tts(switch_speech_handle_t *sh,
void *data, switch_size_t *datalen, switch_speech_flag_t *flags);
SWITCH_DECLARE(switch_status_t) switch_core_speech_read_tts(switch_speech_handle_t *sh, void *data, switch_size_t *datalen, switch_speech_flag_t *flags);
/*!
\brief Close an open speech handle
\param sh the speech handle to close
@ -1907,7 +1911,7 @@ SWITCH_DECLARE(FILE *) switch_core_get_console(void);
/*!
\brief Launch a thread
*/
SWITCH_DECLARE(switch_thread_t *) switch_core_launch_thread(void *(SWITCH_THREAD_FUNC *func) (switch_thread_t *, void *),
SWITCH_DECLARE(switch_thread_t *) switch_core_launch_thread(void *(SWITCH_THREAD_FUNC * func) (switch_thread_t *, void *),
void *obj, switch_memory_pool_t *pool);
#endif
@ -1970,7 +1974,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_alias(const char *string);
SWITCH_DECLARE(int) switch_system(const char *cmd, switch_bool_t wait);
SWITCH_DECLARE(void) switch_cond_yield(switch_interval_time_t t);
SWITCH_DECLARE(void) switch_cond_next(void);
SWITCH_DECLARE(switch_status_t) switch_core_chat_send(const char *name, const char *proto, const char *from, const char *to,
SWITCH_DECLARE(switch_status_t) switch_core_chat_send(const char *name, const char *proto, const char *from, const char *to,
const char *subject, const char *body, const char *type, const char *hint);
SWITCH_DECLARE(switch_status_t) switch_ivr_preprocess_session(switch_core_session_t *session, const char *cmds);
@ -1982,51 +1986,51 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_preprocess_session(switch_core_sessio
*/
#define CACHE_DB_LEN 256
typedef enum {
CDF_INUSE = (1 << 0)
} cache_db_flag_t;
typedef enum {
CDF_INUSE = (1 << 0)
} cache_db_flag_t;
typedef enum {
SCDB_TYPE_CORE_DB,
SCDB_TYPE_ODBC
} switch_cache_db_handle_type_t;
typedef enum {
SCDB_TYPE_CORE_DB,
SCDB_TYPE_ODBC
} switch_cache_db_handle_type_t;
typedef union {
switch_core_db_t *core_db_dbh;
switch_odbc_handle_t *odbc_dbh;
} switch_cache_db_native_handle_t;
typedef union {
switch_core_db_t *core_db_dbh;
switch_odbc_handle_t *odbc_dbh;
} switch_cache_db_native_handle_t;
typedef struct {
char *db_path;
} switch_cache_db_core_db_options_t;
typedef struct {
char *db_path;
} switch_cache_db_core_db_options_t;
typedef struct {
char *dsn;
char *user;
char *pass;
} switch_cache_db_odbc_options_t;
typedef struct {
char *dsn;
char *user;
char *pass;
} switch_cache_db_odbc_options_t;
typedef union {
switch_cache_db_core_db_options_t core_db_options;
switch_cache_db_odbc_options_t odbc_options;
} switch_cache_db_connection_options_t;
typedef union {
switch_cache_db_core_db_options_t core_db_options;
switch_cache_db_odbc_options_t odbc_options;
} switch_cache_db_connection_options_t;
typedef struct {
char name[CACHE_DB_LEN];
switch_cache_db_handle_type_t type;
switch_cache_db_native_handle_t native_handle;
time_t last_used;
switch_mutex_t *mutex;
switch_mutex_t *io_mutex;
switch_memory_pool_t *pool;
int32_t flags;
unsigned long hash;
char creator[CACHE_DB_LEN];
char last_user[CACHE_DB_LEN];
} switch_cache_db_handle_t;
typedef struct {
char name[CACHE_DB_LEN];
switch_cache_db_handle_type_t type;
switch_cache_db_native_handle_t native_handle;
time_t last_used;
switch_mutex_t *mutex;
switch_mutex_t *io_mutex;
switch_memory_pool_t *pool;
int32_t flags;
unsigned long hash;
char creator[CACHE_DB_LEN];
char last_user[CACHE_DB_LEN];
} switch_cache_db_handle_t;
static inline const char *switch_cache_db_type_name(switch_cache_db_handle_type_t type)
static inline const char *switch_cache_db_type_name(switch_cache_db_handle_type_t type)
{
const char *type_str = "INVALID";
@ -2046,9 +2050,9 @@ static inline const char *switch_cache_db_type_name(switch_cache_db_handle_type_
return type_str;
}
SWITCH_DECLARE(void) switch_cache_db_release_db_handle(switch_cache_db_handle_t **dbh);
SWITCH_DECLARE(void) switch_cache_db_destroy_db_handle(switch_cache_db_handle_t **dbh);
SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_handle_t **dbh,
SWITCH_DECLARE(void) switch_cache_db_release_db_handle(switch_cache_db_handle_t ** dbh);
SWITCH_DECLARE(void) switch_cache_db_destroy_db_handle(switch_cache_db_handle_t ** dbh);
SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_handle_t ** dbh,
switch_cache_db_handle_type_t type,
switch_cache_db_connection_options_t *connection_options,
const char *file, const char *func, int line);
@ -2056,14 +2060,14 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h
SWITCH_DECLARE(char *) switch_cache_db_execute_sql2str(switch_cache_db_handle_t *dbh, char *sql, char *str, size_t len, char **err);
SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql(switch_cache_db_handle_t *dbh, char *sql, char **err);
SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_callback(switch_cache_db_handle_t *dbh, const char *sql,
SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_callback(switch_cache_db_handle_t *dbh, const char *sql,
switch_core_db_callback_func_t callback, void *pdata, char **err);
SWITCH_DECLARE(void) switch_cache_db_status(switch_stream_handle_t *stream);
SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t **dbh, const char *file, const char *func, int line);
SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t ** dbh, const char *file, const char *func, int line);
#define switch_core_db_handle(_a) _switch_core_db_handle(_a, __FILE__, __SWITCH_FUNC__, __LINE__)
SWITCH_DECLARE(switch_bool_t) switch_cache_db_test_reactive(switch_cache_db_handle_t *db,
SWITCH_DECLARE(switch_bool_t) switch_cache_db_test_reactive(switch_cache_db_handle_t *db,
const char *test_sql, const char *drop_sql, const char *reactive_sql);
SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute(switch_cache_db_handle_t *dbh, const char *sql, uint32_t retries);
SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans(switch_cache_db_handle_t *dbh, char *sql, uint32_t retries);

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -47,7 +47,7 @@ typedef struct switch_io_event_hook_recv_dtmf switch_io_event_hook_recv_dtmf_t;
typedef struct switch_io_event_hook_state_change switch_io_event_hook_state_change_t;
typedef struct switch_io_event_hook_resurrect_session switch_io_event_hook_resurrect_session_t;
typedef switch_status_t (*switch_outgoing_channel_hook_t)
(switch_core_session_t *, switch_event_t *, switch_caller_profile_t *, switch_core_session_t *, switch_originate_flag_t);
(switch_core_session_t *, switch_event_t *, switch_caller_profile_t *, switch_core_session_t *, switch_originate_flag_t);
typedef switch_status_t (*switch_receive_message_hook_t) (switch_core_session_t *, switch_core_session_message_t *);
typedef switch_status_t (*switch_receive_event_hook_t) (switch_core_session_t *, switch_event_t *);
typedef switch_status_t (*switch_read_frame_hook_t) (switch_core_session_t *, switch_frame_t **, switch_io_flag_t, int);

View File

@ -25,10 +25,10 @@ typedef int (*switch_dso_func_t) (void);
#ifdef WIN32
typedef HINSTANCE switch_dso_lib_t;
#else
typedef void * switch_dso_lib_t;
typedef void *switch_dso_lib_t;
#endif
typedef void * switch_dso_data_t;
typedef void *switch_dso_data_t;
SWITCH_DECLARE(void) switch_dso_destroy(switch_dso_lib_t *lib);
SWITCH_DECLARE(switch_dso_lib_t) switch_dso_open(const char *path, int global, char **err);
@ -48,4 +48,3 @@ SWITCH_DECLARE(void *) switch_dso_data_sym(switch_dso_lib_t lib, const char *sym
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4
*/

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -237,7 +237,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_bind(const char *id, switch_event_t
\param node bind handle to later remove the binding.
\return SWITCH_STATUS_SUCCESS if the event was binded
*/
SWITCH_DECLARE(switch_status_t) switch_event_bind_removable(const char *id, switch_event_types_t event, const char *subclass_name,
SWITCH_DECLARE(switch_status_t) switch_event_bind_removable(const char *id, switch_event_types_t event, const char *subclass_name,
switch_event_callback_t callback, void *user_data, switch_event_node_t **node);
/*!
\brief Unbind a bound event consumer
@ -342,15 +342,16 @@ SWITCH_DECLARE(switch_status_t) switch_event_create_pres_in_detailed(_In_z_ char
*/
#define switch_event_create(event, id) switch_event_create_subclass(event, id, SWITCH_EVENT_SUBCLASS_ANY)
static inline switch_status_t switch_event_create_plain(switch_event_t **event, switch_event_types_t event_id)
static inline switch_status_t switch_event_create_plain(switch_event_t **event, switch_event_types_t event_id)
{
switch_status_t status = switch_event_create(event, SWITCH_EVENT_CLONE);
if (status == SWITCH_STATUS_SUCCESS) {
(*event)->event_id = event_id;
}
return status;
}
/*!
\brief Deliver an event to all of the registered event listeners
\param event the event to send (will be nulled)

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -46,7 +46,7 @@ SWITCH_BEGIN_EXTERN_C
/*! the originating source of the frame */
const char *source;
/*! the raw packet */
void *packet;
void *packet;
/*! the size of the raw packet when applicable */
uint32_t packetlen;
/*! the extra frame data */

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -123,7 +123,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_park(switch_core_session_t *session,
\param timeout a timeout in milliseconds
\return SWITCH_STATUS_SUCCESS to keep the collection moving.
*/
SWITCH_DECLARE(switch_status_t) switch_ivr_collect_digits_callback(switch_core_session_t *session, switch_input_args_t *args, uint32_t digit_timeout, uint32_t abs_timeout);
SWITCH_DECLARE(switch_status_t) switch_ivr_collect_digits_callback(switch_core_session_t *session, switch_input_args_t *args, uint32_t digit_timeout,
uint32_t abs_timeout);
/*!
\brief Wait for specified number of DTMF digits, untile terminator is received or until the channel hangs up.
@ -304,7 +305,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_stop_tone_detect_session(switch_core_
*/
SWITCH_DECLARE(switch_status_t) switch_ivr_tone_detect_session(switch_core_session_t *session,
const char *key, const char *tone_spec,
const char *flags, time_t timeout, int hits,
const char *flags, time_t timeout, int hits,
const char *app, const char *data, switch_tone_detect_callback_t callback);
@ -321,7 +322,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_tone_detect_session(switch_core_sessi
SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *session, switch_file_handle_t *fh, const char *file,
switch_input_args_t *args);
SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_silence(switch_core_session_t *session, uint32_t thresh, uint32_t silence_hits,
SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_silence(switch_core_session_t *session, uint32_t thresh, uint32_t silence_hits,
uint32_t listen_hits, uint32_t timeout_ms, const char *file);
SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *session, const char *script, int32_t loops, switch_input_args_t *args);
@ -408,11 +409,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
const switch_state_handler_table_t *table,
const char *cid_name_override,
const char *cid_num_override,
switch_caller_profile_t *caller_profile_override,
switch_event_t *ovars,
switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause
);
switch_caller_profile_t *caller_profile_override,
switch_event_t *ovars, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
SWITCH_DECLARE(switch_status_t) switch_ivr_enterprise_originate(switch_core_session_t *session,
switch_core_session_t **bleg,
@ -422,10 +420,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_enterprise_originate(switch_core_sess
const switch_state_handler_table_t *table,
const char *cid_name_override,
const char *cid_num_override,
switch_caller_profile_t *caller_profile_override,
switch_event_t *ovars,
switch_originate_flag_t flags
);
switch_caller_profile_t *caller_profile_override,
switch_event_t *ovars, switch_originate_flag_t flags);
SWITCH_DECLARE(void) switch_ivr_bridge_display(switch_core_session_t *session, switch_core_session_t *peer_session);
@ -571,17 +567,17 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_transfer_variable(switch_core_session
/******************************************************************************************************/
struct switch_ivr_digit_stream_parser;
typedef struct switch_ivr_digit_stream_parser switch_ivr_digit_stream_parser_t;
struct switch_ivr_digit_stream;
typedef struct switch_ivr_digit_stream switch_ivr_digit_stream_t;
struct switch_ivr_digit_stream_parser;
typedef struct switch_ivr_digit_stream_parser switch_ivr_digit_stream_parser_t;
struct switch_ivr_digit_stream;
typedef struct switch_ivr_digit_stream switch_ivr_digit_stream_t;
/*!
\brief Create a digit stream parser object
\param pool the pool to use for the new hash
\param parser a pointer to the object pointer
\return SWITCH_STATUS_SUCCESS if all is well
*/
SWITCH_DECLARE(switch_status_t) switch_ivr_digit_stream_parser_new(switch_memory_pool_t *pool, switch_ivr_digit_stream_parser_t **parser);
SWITCH_DECLARE(switch_status_t) switch_ivr_digit_stream_parser_new(switch_memory_pool_t *pool, switch_ivr_digit_stream_parser_t ** parser);
/*!
\brief Destroy a digit stream parser object
@ -596,14 +592,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_digit_stream_parser_destroy(switch_iv
\param stream a pointer to the stream object pointer
\return NULL if no match found or consumer data that was associated with a given digit string when matched
*/
SWITCH_DECLARE(switch_status_t) switch_ivr_digit_stream_new(switch_ivr_digit_stream_parser_t *parser, switch_ivr_digit_stream_t **stream);
SWITCH_DECLARE(switch_status_t) switch_ivr_digit_stream_new(switch_ivr_digit_stream_parser_t *parser, switch_ivr_digit_stream_t ** stream);
/*!
\brief Destroys a digit stream object
\param stream a pointer to the stream object
\return NULL if no match found or consumer data that was associated with a given digit string when matched
*/
SWITCH_DECLARE(switch_status_t) switch_ivr_digit_stream_destroy(switch_ivr_digit_stream_t **stream);
SWITCH_DECLARE(switch_status_t) switch_ivr_digit_stream_destroy(switch_ivr_digit_stream_t ** stream);
/*!
\brief Set a digit string to action mapping
@ -660,25 +656,25 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_digit_stream_parser_set_terminator(sw
* @{
*/
typedef enum {
SWITCH_IVR_MENU_FLAG_FALLTOMAIN = (1 << 0),
SWITCH_IVR_MENU_FLAG_FREEPOOL = (1 << 1),
SWITCH_IVR_MENU_FLAG_STACK = (1 << 2)
} switch_ivr_menu_flags;
typedef enum {
SWITCH_IVR_MENU_FLAG_FALLTOMAIN = (1 << 0),
SWITCH_IVR_MENU_FLAG_FREEPOOL = (1 << 1),
SWITCH_IVR_MENU_FLAG_STACK = (1 << 2)
} switch_ivr_menu_flags;
/* Actions are either set in switch_ivr_menu_bind_function or returned by a callback */
typedef enum {
SWITCH_IVR_ACTION_DIE, /* Exit the menu. */
SWITCH_IVR_ACTION_EXECMENU, /* Goto another menu in the stack. */
SWITCH_IVR_ACTION_EXECAPP, /* Execute an application. */
SWITCH_IVR_ACTION_PLAYSOUND, /* Play a sound. */
SWITCH_IVR_ACTION_BACK, /* Go back 1 menu. */
SWITCH_IVR_ACTION_TOMAIN, /* Go back to the top level menu. */
SWITCH_IVR_ACTION_NOOP /* No operation */
} switch_ivr_action_t;
struct switch_ivr_menu;
typedef switch_ivr_action_t switch_ivr_menu_action_function_t (struct switch_ivr_menu *, char *, char *, size_t, void *);
typedef struct switch_ivr_menu switch_ivr_menu_t;
typedef struct switch_ivr_menu_action switch_ivr_menu_action_t;
typedef enum {
SWITCH_IVR_ACTION_DIE, /* Exit the menu. */
SWITCH_IVR_ACTION_EXECMENU, /* Goto another menu in the stack. */
SWITCH_IVR_ACTION_EXECAPP, /* Execute an application. */
SWITCH_IVR_ACTION_PLAYSOUND, /* Play a sound. */
SWITCH_IVR_ACTION_BACK, /* Go back 1 menu. */
SWITCH_IVR_ACTION_TOMAIN, /* Go back to the top level menu. */
SWITCH_IVR_ACTION_NOOP /* No operation */
} switch_ivr_action_t;
struct switch_ivr_menu;
typedef switch_ivr_action_t switch_ivr_menu_action_function_t(struct switch_ivr_menu *, char *, char *, size_t, void *);
typedef struct switch_ivr_menu switch_ivr_menu_t;
typedef struct switch_ivr_menu_action switch_ivr_menu_action_t;
/******************************************************************************************************/
/*!
@ -703,7 +699,7 @@ typedef struct switch_ivr_menu_action switch_ivr_menu_action_t;
*\return SWITCH_STATUS_SUCCESS if the menu was created.
*/
SWITCH_DECLARE(switch_status_t) switch_ivr_menu_init(switch_ivr_menu_t **new_menu,
SWITCH_DECLARE(switch_status_t) switch_ivr_menu_init(switch_ivr_menu_t ** new_menu,
switch_ivr_menu_t *main,
const char *name,
const char *greeting_sound,
@ -715,7 +711,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_init(switch_ivr_menu_t **new_men
const char *tts_engine,
const char *tts_voice,
int confirm_attempts,
int inter_timeout, int digit_len, int timeout, int max_failures,
int inter_timeout, int digit_len, int timeout, int max_failures,
int max_timeouts, switch_memory_pool_t *pool);
/*!
@ -726,8 +722,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_init(switch_ivr_menu_t **new_men
*\param bind KeyStrokes to bind the action to.
*\return SWUTCH_STATUS_SUCCESS if the action was binded
*/
SWITCH_DECLARE(switch_status_t) switch_ivr_menu_bind_action(switch_ivr_menu_t *menu, switch_ivr_action_t ivr_action, const char *arg,
const char *bind);
SWITCH_DECLARE(switch_status_t) switch_ivr_menu_bind_action(switch_ivr_menu_t *menu, switch_ivr_action_t ivr_action, const char *arg, const char *bind);
/*!
@ -762,8 +757,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_execute(switch_core_session_t *s
*/
SWITCH_DECLARE(switch_status_t) switch_ivr_menu_stack_free(switch_ivr_menu_t *stack);
struct switch_ivr_menu_xml_ctx;
typedef struct switch_ivr_menu_xml_ctx switch_ivr_menu_xml_ctx_t;
struct switch_ivr_menu_xml_ctx;
typedef struct switch_ivr_menu_xml_ctx switch_ivr_menu_xml_ctx_t;
/*!
*\brief Build a menu stack from an xml source
*\param xml_menu_ctx The XML menu parser context previously created by switch_ivr_menu_stack_xml_init
@ -773,7 +768,7 @@ typedef struct switch_ivr_menu_xml_ctx switch_ivr_menu_xml_ctx_t;
*\return SWITCH_STATUS_SUCCESS if all is well
*/
SWITCH_DECLARE(switch_status_t) switch_ivr_menu_stack_xml_build(switch_ivr_menu_xml_ctx_t *xml_menu_ctx,
switch_ivr_menu_t **menu_stack, switch_xml_t xml_menus, switch_xml_t xml_menu);
switch_ivr_menu_t ** menu_stack, switch_xml_t xml_menus, switch_xml_t xml_menu);
SWITCH_DECLARE(switch_status_t) switch_ivr_menu_str2action(const char *action_name, switch_ivr_action_t *action);
@ -791,7 +786,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_stack_xml_add_custom(switch_ivr_
*\param pool memory pool (NULL to create one)
*\return SWITCH_STATUS_SUCCESS if all is well
*/
SWITCH_DECLARE(switch_status_t) switch_ivr_menu_stack_xml_init(switch_ivr_menu_xml_ctx_t **xml_menu_ctx, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_ivr_menu_stack_xml_init(switch_ivr_menu_xml_ctx_t ** xml_menu_ctx, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro(switch_core_session_t *session, const char *macro_name, const char *data, const char *lang,
switch_input_args_t *args);
@ -806,8 +801,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_read(switch_core_session_t *session,
uint32_t max_digits,
const char *prompt_audio_file,
const char *var_name,
char *digit_buffer,
switch_size_t digit_buffer_length, uint32_t timeout, const char *valid_terminators);
char *digit_buffer, switch_size_t digit_buffer_length, uint32_t timeout, const char *valid_terminators);
SWITCH_DECLARE(switch_status_t) switch_ivr_bind_dtmf_meta_session(switch_core_session_t *session, uint32_t key,
switch_bind_flag_t bind_flags, const char *app);

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -268,7 +268,7 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_unload_module(char *dir,
\param filename the path to the module's dll or so file
\return SWITCH_STATUS_SUCCESS on a successful load
*/
SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(switch_loadable_module_interface_t **module_interface, char *filename);
SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(switch_loadable_module_interface_t ** module_interface, char *filename);
SWITCH_MOD_DECLARE(switch_status_t) switch_module_runtime(void);
/*!
@ -325,14 +325,15 @@ SWITCH_DECLARE(uint32_t) switch_core_codec_next_id(void);
break; \
}
static inline int switch_check_interval(uint32_t rate, uint32_t ptime)
static inline int switch_check_interval(uint32_t rate, uint32_t ptime)
{
uint32_t max_ms = 0, ptime_div = 0;
switch (rate) {
case 22050:
case 11025:
if (ptime < 120) return 1;
if (ptime < 120)
return 1;
break;
case 48000:
max_ms = 40;
@ -350,13 +351,13 @@ static inline int switch_check_interval(uint32_t rate, uint32_t ptime)
case 8000:
max_ms = 120;
ptime_div = 2;
break;
break;
}
if (max_ms && ptime_div && (ptime <= max_ms && (ptime % ptime_div) == 0) && ((rate / 1000) * ptime) < SWITCH_RECOMMENDED_BUFFER_SIZE) {
return 1;
}
return 0;
}
@ -420,7 +421,7 @@ static inline void switch_core_codec_add_implementation(switch_memory_pool_t *po
impl->impl_id = switch_core_codec_next_id();
codec_interface->implementations = impl;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Rejected codec name: %s rate: %u ptime: %u\n",
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Rejected codec name: %s rate: %u ptime: %u\n",
iananame, actual_samples_per_second, microseconds_per_packet / 1000);
}
}

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -114,9 +114,8 @@ SWITCH_DECLARE(void) switch_log_printf(_In_ switch_text_channel_t channel, _In_z
\see switch_types.h
*/
SWITCH_DECLARE(void) switch_log_vprintf(_In_ switch_text_channel_t channel, _In_z_ const char *file,
_In_z_ const char *func, _In_ int line,
_In_opt_z_ const char *userdata, _In_ switch_log_level_t level,
const char *fmt, va_list ap);
_In_z_ const char *func, _In_ int line,
_In_opt_z_ const char *userdata, _In_ switch_log_level_t level, const char *fmt, va_list ap);
#endif
/*!
@ -144,7 +143,7 @@ SWITCH_DECLARE(uint32_t) switch_log_str2mask(_In_z_ const char *str);
#define switch_log_check_mask(_mask, _level) (_mask & (1 << _level))
SWITCH_DECLARE(switch_log_node_t*) switch_log_node_dup(const switch_log_node_t *node);
SWITCH_DECLARE(switch_log_node_t *) switch_log_node_dup(const switch_log_node_t *node);
SWITCH_DECLARE(void) switch_log_node_free(switch_log_node_t **pnode);
///\}

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -45,7 +45,7 @@
SWITCH_BEGIN_EXTERN_C
/*! \brief A table of functions to execute at various states
*/
typedef enum {
typedef enum {
SWITCH_SHN_ON_INIT,
SWITCH_SHN_ON_ROUTING,
SWITCH_SHN_ON_EXECUTE,
@ -106,7 +106,27 @@ struct switch_io_event_hooks;
typedef switch_call_cause_t (*switch_io_outgoing_channel_t)
(switch_core_session_t *, switch_event_t *, switch_caller_profile_t *, switch_core_session_t **, switch_memory_pool_t **, switch_originate_flag_t, switch_call_cause_t *);
(switch_core_session_t *, switch_event_t *, switch_caller_profile_t *, switch_core_session_t **, switch_memory_pool_t **, switch_originate_flag_t,
switch_call_cause_t *);
typedef switch_status_t (*switch_io_read_frame_t) (switch_core_session_t *, switch_frame_t **, switch_io_flag_t, int);
typedef switch_status_t (*switch_io_write_frame_t) (switch_core_session_t *, switch_frame_t *, switch_io_flag_t, int);
typedef switch_status_t (*switch_io_kill_channel_t) (switch_core_session_t *, int);
@ -441,7 +461,7 @@ struct switch_speech_handle {
switch_audio_resampler_t *resampler;
switch_buffer_t *buffer;
switch_byte_t *dbuf;
switch_size_t dbuflen;
switch_size_t dbuflen;
/*! the current samplerate */
uint32_t samplerate;
/*! the current native samplerate */
@ -470,7 +490,7 @@ struct switch_chat_interface {
/*! the name of the interface */
const char *interface_name;
/*! function to open the directory interface */
switch_status_t (*chat_send) (const char *proto, const char *from, const char *to,
switch_status_t (*chat_send) (const char *proto, const char *from, const char *to,
const char *subject, const char *body, const char *type, const char *hint);
switch_thread_rwlock_t *rwlock;
int refs;
@ -680,8 +700,8 @@ struct switch_api_interface {
struct switch_api_interface *next;
};
#define PROTECT_INTERFACE(_it) if (_it) {switch_mutex_lock(_it->reflock); switch_thread_rwlock_rdlock(_it->parent->rwlock); switch_thread_rwlock_rdlock(_it->rwlock); _it->refs++; _it->parent->refs++; switch_mutex_unlock(_it->reflock);} //if (!strcmp(_it->interface_name, "user")) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "+++++++++++LOCK %s %d/%d\n", _it->interface_name, _it->refs, _it->parent->refs);
#define UNPROTECT_INTERFACE(_it) if (_it) {switch_mutex_lock(_it->reflock); switch_thread_rwlock_unlock(_it->rwlock); switch_thread_rwlock_unlock(_it->parent->rwlock); _it->refs--; _it->parent->refs--; switch_mutex_unlock(_it->reflock);} //if (!strcmp(_it->interface_name, "user")) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "---------UNLOCK %s %d/%d\n", _it->interface_name, _it->refs, _it->parent->refs);
#define PROTECT_INTERFACE(_it) if (_it) {switch_mutex_lock(_it->reflock); switch_thread_rwlock_rdlock(_it->parent->rwlock); switch_thread_rwlock_rdlock(_it->rwlock); _it->refs++; _it->parent->refs++; switch_mutex_unlock(_it->reflock);} //if (!strcmp(_it->interface_name, "user")) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "+++++++++++LOCK %s %d/%d\n", _it->interface_name, _it->refs, _it->parent->refs);
#define UNPROTECT_INTERFACE(_it) if (_it) {switch_mutex_lock(_it->reflock); switch_thread_rwlock_unlock(_it->rwlock); switch_thread_rwlock_unlock(_it->parent->rwlock); _it->refs--; _it->parent->refs--; switch_mutex_unlock(_it->reflock);} //if (!strcmp(_it->interface_name, "user")) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "---------UNLOCK %s %d/%d\n", _it->interface_name, _it->refs, _it->parent->refs);
SWITCH_END_EXTERN_C

View File

@ -14,7 +14,6 @@
#define SWITCH_MPRINTF_H
SWITCH_BEGIN_EXTERN_C
/**
* This routine is a variant of the "sprintf()" from the
* standard C library. The resulting string is written into memory

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -38,9 +38,7 @@
#ifndef _SWITCH_NAT_H
#define _SWITCH_NAT_H
SWITCH_BEGIN_EXTERN_C
typedef enum {
SWITCH_BEGIN_EXTERN_C typedef enum {
SWITCH_NAT_TYPE_NONE,
SWITCH_NAT_TYPE_PMP,
SWITCH_NAT_TYPE_UPNP
@ -87,7 +85,8 @@ SWITCH_DECLARE(void) switch_nat_reinit(void);
\param external_port [out] Mapped external port
\param sticky make the mapping permanent
*/
SWITCH_DECLARE(switch_status_t) switch_nat_add_mapping(switch_port_t port, switch_nat_ip_proto_t proto, switch_port_t *external_port, switch_bool_t sticky);
SWITCH_DECLARE(switch_status_t) switch_nat_add_mapping(switch_port_t port, switch_nat_ip_proto_t proto, switch_port_t *external_port,
switch_bool_t sticky);
/*!
\brief Has the NAT subsystem been initialized
*/

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -34,10 +34,8 @@
#include <switch.h>
SWITCH_BEGIN_EXTERN_C
struct switch_odbc_handle;
typedef void * switch_odbc_statement_handle_t;
SWITCH_BEGIN_EXTERN_C struct switch_odbc_handle;
typedef void *switch_odbc_statement_handle_t;
typedef enum {
SWITCH_ODBC_STATE_INIT,
@ -56,14 +54,11 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_disconnect(switch_odbc_h
SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_connect(switch_odbc_handle_t *handle);
SWITCH_DECLARE(void) switch_odbc_handle_destroy(switch_odbc_handle_t **handlep);
SWITCH_DECLARE(switch_odbc_state_t) switch_odbc_handle_get_state(switch_odbc_handle_t *handle);
SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_exec(switch_odbc_handle_t *handle, const char *sql, switch_odbc_statement_handle_t *rstmt, char **err);
SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_exec_string(switch_odbc_handle_t *handle,
const char *sql,
char *resbuf,
size_t len,
char **err);
SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_exec(switch_odbc_handle_t *handle, const char *sql, switch_odbc_statement_handle_t *rstmt,
char **err);
SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_exec_string(switch_odbc_handle_t *handle, const char *sql, char *resbuf, size_t len, char **err);
SWITCH_DECLARE(switch_bool_t) switch_odbc_available(void);
SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_statement_handle_free(switch_odbc_statement_handle_t * stmt);
SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_statement_handle_free(switch_odbc_statement_handle_t *stmt);
/*!
\brief Execute the sql query and issue a callback for each row returned
@ -78,7 +73,8 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_statement_handle_free(switch_od
\note none
*/
SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_callback_exec_detailed(const char *file, const char *func, int line, switch_odbc_handle_t *handle,
const char *sql, switch_core_db_callback_func_t callback, void *pdata, char **err);
const char *sql, switch_core_db_callback_func_t callback, void *pdata,
char **err);
/*!
\brief Execute the sql query and issue a callback for each row returned
\param handle the ODBC handle
@ -92,7 +88,7 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_callback_exec_detailed(c
switch_odbc_handle_callback_exec_detailed(__FILE__, (char * )__SWITCH_FUNC__, __LINE__, \
handle, sql, callback, pdata, err)
SWITCH_DECLARE(char *) switch_odbc_handle_get_error(switch_odbc_handle_t *handle, switch_odbc_statement_handle_t stmt);
SWITCH_END_EXTERN_C
#endif

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -85,7 +85,7 @@ SWITCH_BEGIN_EXTERN_C
#undef inline
#define inline __inline
#ifndef uint32_t
typedef unsigned __int8 uint8_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -68,7 +68,7 @@ SWITCH_DECLARE(switch_status_t) switch_regex_match(const char *target, const cha
\param partial If non-zero returns SUCCESS if the target is a partial match, on successful return, this is set to non-zero if the match was partial and zero if it was a full match
\return Boolean if a match was found or not
*/
SWITCH_DECLARE(switch_status_t) switch_regex_match_partial(const char *target, const char *expression, int * partial_match);
SWITCH_DECLARE(switch_status_t) switch_regex_match_partial(const char *target, const char *expression, int *partial_match);
#define switch_regex_safe_free(re) if (re) {\

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -51,7 +51,7 @@ SWITCH_BEGIN_EXTERN_C
\{
*/
/*! \brief An audio resampling handle */
typedef struct {
typedef struct {
/*! a pointer to store the resampler object */
void *resampler;
/*! the rate to resample from in hz */
@ -61,11 +61,11 @@ typedef struct {
/*! the factor to resample by (from / to) */
double factor;
double rfactor;
int16_t *to;
/*! the size of the to buffer used */
uint32_t to_len;
/*! the total size of the to buffer */
uint32_t to_size;
int16_t *to;
/*! the size of the to buffer used */
uint32_t to_len;
/*! the total size of the to buffer */
uint32_t to_size;
} switch_audio_resampler_t;
@ -79,9 +79,7 @@ typedef struct {
*/
SWITCH_DECLARE(switch_status_t) switch_resample_perform_create(switch_audio_resampler_t **new_resampler,
uint32_t from_rate, uint32_t to_rate, uint32_t to_size,
int quality,
uint32_t channels,
const char *file, const char *func, int line);
int quality, uint32_t channels, const char *file, const char *func, int line);
#define switch_resample_create(_n, _fr, _tr, _ts, _q, _c) switch_resample_perform_create(_n, _fr, _tr, _ts, _q, _c, __FILE__, __SWITCH_FUNC__, __LINE__)

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -45,8 +45,7 @@ SWITCH_BEGIN_EXTERN_C
#define SWITCH_RTP_KEY_LEN 30
#define SWITCH_RTP_CRYPTO_KEY_32 "AES_CM_128_HMAC_SHA1_32"
#define SWITCH_RTP_CRYPTO_KEY_80 "AES_CM_128_HMAC_SHA1_80"
typedef enum {
typedef enum {
SWITCH_RTP_CRYPTO_SEND,
SWITCH_RTP_CRYPTO_RECV,
SWITCH_RTP_CRYPTO_MAX
@ -54,7 +53,7 @@ typedef enum {
typedef enum {
NO_CRYPTO,
AES_CM_128_HMAC_SHA1_80,
AES_CM_128_HMAC_SHA1_80,
AES_CM_128_HMAC_SHA1_32,
AES_CM_128_NULL_AUTH
} switch_rtp_crypto_key_type_t;
@ -97,6 +96,8 @@ SWITCH_DECLARE(void) switch_rtp_shutdown(void);
*/
SWITCH_DECLARE(switch_port_t) switch_rtp_set_start_port(switch_port_t port);
SWITCH_DECLARE(switch_status_t) switch_rtp_set_ssrc(switch_rtp_t *rtp_session, uint32_t ssrc);
/*!
\brief Set/Get RTP end port
\param port new value (if > 0)
@ -166,7 +167,7 @@ SWITCH_DECLARE(switch_rtp_t *) switch_rtp_new(const char *rx_host,
\param port the remote port
\param err pointer for error messages
*/
SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_address(switch_rtp_t *rtp_session, const char *host, switch_port_t port,
SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_address(switch_rtp_t *rtp_session, const char *host, switch_port_t port,
switch_bool_t change_adv_addr, const char **err);
SWITCH_DECLARE(char *) switch_rtp_get_remote_host(switch_rtp_t *rtp_session);
@ -183,8 +184,7 @@ SWITCH_DECLARE(void) switch_rtp_set_max_missed_packets(switch_rtp_t *rtp_session
\param err pointer for error messages
\note this call also binds the RTP session's socket to the new address
*/
SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_session, const char *host,
switch_port_t port, const char **err);
SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_session, const char *host, switch_port_t port, const char **err);
/*!
\brief Kill the socket on an existing RTP session

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -41,8 +41,7 @@ SWITCH_BEGIN_EXTERN_C
#define SWITCH_STUN_DEFAULT_PORT 3478
#define SWITCH_STUN_PACKET_MIN_LEN 20
#define SWITCH_STUN_ATTRIBUTE_MIN_LEN 8
typedef enum {
typedef enum {
SWITCH_STUN_BINDING_REQUEST = 0x0001,
SWITCH_STUN_BINDING_RESPONSE = 0x0101,
SWITCH_STUN_BINDING_ERROR_RESPONSE = 0x0111,

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -181,7 +181,6 @@ SWITCH_BEGIN_EXTERN_C
#define SWITCH_BITS_PER_BYTE 8
#define SWITCH_DEFAULT_FILE_BUFFER_LEN 65536
#define SWITCH_DTMF_LOG_LEN 1000
typedef uint8_t switch_byte_t;
typedef struct {
@ -394,7 +393,7 @@ SWITCH_DECLARE_DATA extern switch_directories SWITCH_GLOBAL_dirs;
#define SWITCH_INTERVAL_PAD 10 /* A little extra buffer space to be safe */
#define SWITCH_MAX_SAMPLE_LEN 48
#define SWITCH_BYTES_PER_SAMPLE 2 /* slin is 2 bytes per sample */
#define SWITCH_RECOMMENDED_BUFFER_SIZE 4096 /* worst case of 32khz @60ms we only do 48khz @10ms which is 960 */
#define SWITCH_RECOMMENDED_BUFFER_SIZE 4096 /* worst case of 32khz @60ms we only do 48khz @10ms which is 960 */
#define SWITCH_MAX_CODECS 50
#define SWITCH_MAX_STATE_HANDLERS 30
#define SWITCH_CORE_QUEUE_LEN 100000
@ -425,7 +424,7 @@ typedef enum {
SWITCH_XML_SECTION_DIRECTORY = (1 << 1),
SWITCH_XML_SECTION_DIALPLAN = (1 << 2),
SWITCH_XML_SECTION_PHRASES = (1 << 3),
/* Nothing after this line */
SWITCH_XML_SECTION_MAX = (1 << 4)
} switch_xml_section_enum_t;
@ -530,36 +529,35 @@ typedef enum {
typedef uint32_t switch_rtp_flag_t;
typedef enum {
RTP_BUG_NONE = 0, /* won't be using this one much ;) */
RTP_BUG_NONE = 0, /* won't be using this one much ;) */
RTP_BUG_CISCO_SKIP_MARK_BIT_2833 = (1 << 0),
/* Some Cisco devices get mad when you send the mark bit on new 2833 because it makes
them flush their jitterbuffer and the dtmf along with it.
This flag will disable the sending of the mark bit on the first DTMF packet.
*/
*/
RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833 = (1 << 1)
/*
Sonus wrongly expects that, when sending a multi-packet 2833 DTMF event, The sender
should increment the RTP timestamp in each packet when, in reality, the sender should
send the same exact timestamp and increment the duration field in the 2833 payload.
This allows a reconstruction of the duration if any of the packets are lost.
/*
Sonus wrongly expects that, when sending a multi-packet 2833 DTMF event, The sender
should increment the RTP timestamp in each packet when, in reality, the sender should
send the same exact timestamp and increment the duration field in the 2833 payload.
This allows a reconstruction of the duration if any of the packets are lost.
final_duration - initial_timestamp = total_samples
final_duration - initial_timestamp = total_samples
However, if the duration value exceeds the space allocated (16 bits), The sender should increment
the timestamp one unit and reset the duration to 0.
Always sending a duration of 0 with a new timestamp should be tolerated but is rarely intentional
and is mistakenly done by many devices.
The issue is that the Sonus expects everyone to do it this way instead of tolerating either way.
Sonus will actually ignore every packet with the same timestamp before concluding if it's DTMF.
This flag will cause each packet to have a new timestamp.
*/
However, if the duration value exceeds the space allocated (16 bits), The sender should increment
the timestamp one unit and reset the duration to 0.
Always sending a duration of 0 with a new timestamp should be tolerated but is rarely intentional
and is mistakenly done by many devices.
The issue is that the Sonus expects everyone to do it this way instead of tolerating either way.
Sonus will actually ignore every packet with the same timestamp before concluding if it's DTMF.
This flag will cause each packet to have a new timestamp.
*/
} switch_rtp_bug_flag_t;
#ifdef _MSC_VER
@ -680,6 +678,8 @@ typedef enum {
SWITCH_MESSAGE_INDICATE_SIMPLIFY,
SWITCH_MESSAGE_INDICATE_DEBUG_AUDIO,
SWITCH_MESSAGE_INDICATE_PROXY_MEDIA,
SWITCH_MESSAGE_INDICATE_APPLICATION_EXEC,
SWITCH_MESSAGE_INDICATE_APPLICATION_EXEC_COMPLETE,
SWITCH_MESSAGE_INVALID
} switch_core_session_message_types_t;
@ -1545,7 +1545,7 @@ typedef void (*switch_application_function_t) (switch_core_session_t *, const ch
typedef void (*switch_event_callback_t) (switch_event_t *);
typedef switch_caller_extension_t *(*switch_dialplan_hunt_function_t) (switch_core_session_t *, void *, switch_caller_profile_t *);
#define SWITCH_STANDARD_DIALPLAN(name) static switch_caller_extension_t * name (switch_core_session_t *session, void *arg, switch_caller_profile_t *caller_profile)
#define SWITCH_STANDARD_DIALPLAN(name) static switch_caller_extension_t *name (switch_core_session_t *session, void *arg, switch_caller_profile_t *caller_profile)
typedef struct switch_scheduler_task switch_scheduler_task_t;
@ -1579,9 +1579,9 @@ typedef switch_status_t (*switch_say_callback_t) (switch_core_session_t *session
char *tosay, switch_say_type_t type, switch_say_method_t method, switch_input_args_t *args);
typedef struct switch_xml *switch_xml_t;
typedef struct switch_core_time_duration switch_core_time_duration_t;
typedef switch_xml_t (*switch_xml_search_function_t) (const char *section,
const char *tag_name, const char *key_name, const char *key_value, switch_event_t *params,
void *user_data);
typedef switch_xml_t(*switch_xml_search_function_t) (const char *section,
const char *tag_name, const char *key_name, const char *key_value, switch_event_t *params,
void *user_data);
typedef struct switch_hash switch_hash_t;
struct HashElem;

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -40,9 +40,7 @@
#include <switch.h>
SWITCH_BEGIN_EXTERN_C
SWITCH_DECLARE(int) switch_toupper(int c);
SWITCH_BEGIN_EXTERN_C SWITCH_DECLARE(int) switch_toupper(int c);
SWITCH_DECLARE(int) switch_tolower(int c);
SWITCH_DECLARE(int) switch_isalnum(int c);
SWITCH_DECLARE(int) switch_isalpha(int c);
@ -74,7 +72,8 @@ SWITCH_DECLARE(int) switch_isxdigit(int c);
\param s the string to test
\return true value if the string is NULL or zero length
*/
static inline int zstr(const char *s) {
static inline int zstr(const char *s)
{
return !s || *s == '\0';
}
@ -106,7 +105,7 @@ static inline int switch_string_has_escaped_data(const char *in)
}
i = strchr(i, '\\');
}
return 0;
}
@ -208,11 +207,11 @@ SWITCH_DECLARE(unsigned short) get_port(struct sockaddr *sa);
/*!
\brief flags to be used with switch_build_uri()
*/
enum switch_uri_flags {
SWITCH_URI_NUMERIC_HOST = 1,
SWITCH_URI_NUMERIC_PORT = 2,
SWITCH_URI_NO_SCOPE = 4
};
enum switch_uri_flags {
SWITCH_URI_NUMERIC_HOST = 1,
SWITCH_URI_NUMERIC_PORT = 2,
SWITCH_URI_NO_SCOPE = 4
};
/*!
\brief build a URI string from components
@ -224,12 +223,7 @@ enum switch_uri_flags {
\param flags logical OR-ed combination of flags from \ref switch_uri_flags
\return number of characters printed (not including the trailing null)
*/
SWITCH_DECLARE(int) switch_build_uri(char *uri,
switch_size_t size,
const char *scheme,
const char *user,
const switch_sockaddr_t *sa,
int flags);
SWITCH_DECLARE(int) switch_build_uri(char *uri, switch_size_t size, const char *scheme, const char *user, const switch_sockaddr_t *sa, int flags);
#define SWITCH_STATUS_IS_BREAK(x) (x == SWITCH_STATUS_BREAK || x == 730035 || x == 35)
@ -313,7 +307,7 @@ switch_mutex_unlock(obj->flag_mutex);
#define switch_set_string(_dst, _src) switch_copy_string(_dst, _src, sizeof(_dst))
static inline char *switch_sanitize_number(char *number)
static inline char *switch_sanitize_number(char *number)
{
char *p = number, *q;
char warp[] = "/:";
@ -323,10 +317,12 @@ static inline char *switch_sanitize_number(char *number)
return number;
}
while((q = strrchr(p, '@'))) *q = '\0';
for(i = 0; i < (int)strlen(warp); i++) {
while(p && (q = strchr(p, warp[i]))) p = q + 1;
while ((q = strrchr(p, '@')))
*q = '\0';
for (i = 0; i < (int) strlen(warp); i++) {
while (p && (q = strchr(p, warp[i])))
p = q + 1;
}
return p;
@ -334,46 +330,46 @@ static inline char *switch_sanitize_number(char *number)
static inline switch_bool_t switch_string_var_check(char *s, switch_bool_t disable)
{
char *p;
char *p;
char *dol = NULL;
for (p = s; p && *p; p++) {
if (*p == '$') {
dol = p;
} else if (dol) {
if (*p == '{') {
for (p = s; p && *p; p++) {
if (*p == '$') {
dol = p;
} else if (dol) {
if (*p == '{') {
if (disable) {
*dol = '%';
dol = NULL;
} else {
return SWITCH_TRUE;
}
} else if (*p != '\\') {
dol = NULL;
}
}
}
return SWITCH_FALSE;
} else if (*p != '\\') {
dol = NULL;
}
}
}
return SWITCH_FALSE;
}
static inline switch_bool_t switch_string_var_check_const(const char *s)
{
const char *p;
const char *p;
int dol = 0;
for (p = s; p && *p; p++) {
if (*p == '$') {
dol = 1;
} else if (dol) {
if (*p == '{') {
return SWITCH_TRUE;
} else if (*p != '\\') {
dol = 0;
}
}
}
return SWITCH_FALSE;
for (p = s; p && *p; p++) {
if (*p == '$') {
dol = 1;
} else if (dol) {
if (*p == '{') {
return SWITCH_TRUE;
} else if (*p != '\\') {
dol = 0;
}
}
}
return SWITCH_FALSE;
}
static inline char *switch_var_clean_string(char *s)
@ -386,7 +382,7 @@ static inline char *switch_clean_string(char *s)
{
char *p;
for (p = s; p && *p; p++) {
uint8_t x = (uint8_t) *p;
uint8_t x = (uint8_t) * p;
if ((x < 32) && x != '\n' && x != '\r') {
*p = ' ';
}
@ -403,7 +399,7 @@ static inline char *switch_clean_string(char *s)
*/
#define switch_safe_free(it) if (it) {free(it);it=NULL;}
static inline char *switch_safe_strdup(const char *it)
static inline char *switch_safe_strdup(const char *it)
{
if (it) {
return strdup(it);
@ -413,14 +409,14 @@ static inline char *switch_safe_strdup(const char *it)
}
static inline char *switch_lc_strdup(const char *it)
static inline char *switch_lc_strdup(const char *it)
{
char *dup;
char *p;
if (it) {
dup = strdup(it);
for(p = dup; p && *p; p++) {
for (p = dup; p && *p; p++) {
*p = (char) switch_tolower(*p);
}
return dup;
@ -430,14 +426,14 @@ static inline char *switch_lc_strdup(const char *it)
}
static inline char *switch_uc_strdup(const char *it)
static inline char *switch_uc_strdup(const char *it)
{
char *dup;
char *p;
if (it) {
dup = strdup(it);
for(p = dup; p && *p; p++) {
for (p = dup; p && *p; p++) {
*p = (char) switch_toupper(*p);
}
return dup;
@ -562,7 +558,7 @@ SWITCH_DECLARE(switch_bool_t) switch_ast2regex(const char *pat, char *rbuf, size
SWITCH_DECLARE(char *) switch_escape_char(switch_memory_pool_t *pool, char *in, const char *delim, char esc);
SWITCH_DECLARE(char *) switch_escape_string(const char *in, char *out, switch_size_t outlen);
SWITCH_DECLARE(char*) switch_escape_string_pool(const char *in, switch_memory_pool_t *pool);
SWITCH_DECLARE(char *) switch_escape_string_pool(const char *in, switch_memory_pool_t *pool);
/*!
\brief Wait for a socket
@ -591,17 +587,14 @@ SWITCH_DECLARE(char *) switch_util_quote_shell_arg(const char *string);
#define SWITCH_READ_ACCEPTABLE(status) (status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK)
SWITCH_DECLARE(size_t) switch_url_encode(const char *url, char *buf, size_t len);
SWITCH_DECLARE(char *) switch_url_decode(char *s);
SWITCH_DECLARE(switch_bool_t) switch_simple_email(const char *to,
const char *from,
const char *headers,
const char *body,
const char *file,
const char *convert_cmd,
const char *convert_ext);
SWITCH_DECLARE(switch_bool_t) switch_simple_email(const char *to,
const char *from,
const char *headers,
const char *body, const char *file, const char *convert_cmd, const char *convert_ext);
SWITCH_DECLARE(char *) switch_find_end_paren(const char *s, char open, char close);
static inline switch_bool_t switch_is_file_path(const char *file)
static inline switch_bool_t switch_is_file_path(const char *file)
{
const char *e;
int r;
@ -611,21 +604,21 @@ static inline switch_bool_t switch_is_file_path(const char *file)
file = e + 1;
}
}
#ifdef WIN32
r = (file && (*file == '\\' || *(file +1) == ':' || *file == '/' || strstr(file, SWITCH_URL_SEPARATOR)));
r = (file && (*file == '\\' || *(file + 1) == ':' || *file == '/' || strstr(file, SWITCH_URL_SEPARATOR)));
#else
r = (file && ((*file == '/') || strstr(file, SWITCH_URL_SEPARATOR)));
#endif
return r ? SWITCH_TRUE : SWITCH_FALSE;
}
SWITCH_DECLARE(int) switch_parse_cidr(const char *string, uint32_t *ip, uint32_t *mask, uint32_t *bitp);
SWITCH_DECLARE(switch_status_t) switch_network_list_create(switch_network_list_t **list, const char *name, switch_bool_t default_type, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_network_list_create(switch_network_list_t **list, const char *name, switch_bool_t default_type,
switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_network_list_add_cidr_token(switch_network_list_t *list, const char *cidr_str, switch_bool_t ok, const char *token);
#define switch_network_list_add_cidr(_list, _cidr_str, _ok) switch_network_list_add_cidr_token(_list, _cidr_str, _ok, NULL)

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -103,7 +103,7 @@ struct switch_xml {
* \param s The string to parse
* \param dup true if you want the string to be strdup()'d automatically
* \return the switch_xml_t or NULL if an error occured
*/
*/
SWITCH_DECLARE(switch_xml_t) switch_xml_parse_str_dynamic(_In_z_ char *s, _In_ switch_bool_t dup);
/*!
@ -156,7 +156,8 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_child(_In_ switch_xml_t xml, _In_z_ cons
///\param attrname the attribute name
///\param value the value
///\return an xml node or NULL
SWITCH_DECLARE(switch_xml_t) switch_xml_find_child(_In_ switch_xml_t node, _In_z_ const char *childname, _In_opt_z_ const char *attrname, _In_opt_z_ const char *value);
SWITCH_DECLARE(switch_xml_t) switch_xml_find_child(_In_ switch_xml_t node, _In_z_ const char *childname, _In_opt_z_ const char *attrname,
_In_opt_z_ const char *value);
SWITCH_DECLARE(switch_xml_t) switch_xml_find_child_multi(_In_ switch_xml_t node, _In_z_ const char *childname, ...);
///\brief returns the next tag of the same name in the same section and depth or NULL
@ -202,7 +203,7 @@ SWITCH_DECLARE(const char *) switch_xml_attr_soft(_In_ switch_xml_t xml, _In_z_
///\ Returns NULL if not found.
///\param xml the xml node
///\return an xml node or NULL
SWITCH_DECLARE(switch_xml_t) switch_xml_get(_In_ switch_xml_t xml, ...);
SWITCH_DECLARE(switch_xml_t) switch_xml_get(_In_ switch_xml_t xml,...);
///\brief Converts an switch_xml structure back to xml. Returns a string of xml data that
///\ must be freed.
@ -218,7 +219,8 @@ SWITCH_DECLARE(char *) switch_xml_toxml(_In_ switch_xml_t xml, _In_ switch_bool_
///\param offset offset to start at
///\param prn_header add <?xml version..> header too
///\return the xml text string
SWITCH_DECLARE(char *) switch_xml_toxml_buf(_In_ switch_xml_t xml, _In_z_ char *buf, _In_ switch_size_t buflen, _In_ switch_size_t offset, _In_ switch_bool_t prn_header);
SWITCH_DECLARE(char *) switch_xml_toxml_buf(_In_ switch_xml_t xml, _In_z_ char *buf, _In_ switch_size_t buflen, _In_ switch_size_t offset,
_In_ switch_bool_t prn_header);
///\brief returns a NULL terminated array of processing instructions for the given
///\ target
@ -346,30 +348,28 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_root(void);
///\return SWITCH_STATUS_SUCCESS if successful root and node will be assigned
SWITCH_DECLARE(switch_status_t) switch_xml_locate(_In_z_ const char *section,
_In_opt_z_ const char *tag_name,
_In_opt_z_ const char *key_name,
_In_opt_z_ const char *key_value,
_Out_ switch_xml_t *root,
_Out_ switch_xml_t *node,
_In_opt_ switch_event_t *params,
_In_ switch_bool_t clone);
_In_opt_z_ const char *key_name,
_In_opt_z_ const char *key_value,
_Out_ switch_xml_t *root,
_Out_ switch_xml_t *node, _In_opt_ switch_event_t *params, _In_ switch_bool_t clone);
SWITCH_DECLARE(switch_status_t) switch_xml_locate_domain(_In_z_ const char *domain_name, _In_opt_ switch_event_t *params, _Out_ switch_xml_t *root, _Out_ switch_xml_t *domain);
SWITCH_DECLARE(switch_status_t) switch_xml_locate_domain(_In_z_ const char *domain_name, _In_opt_ switch_event_t *params, _Out_ switch_xml_t *root,
_Out_ switch_xml_t *domain);
SWITCH_DECLARE(switch_status_t) switch_xml_locate_group(_In_z_ const char *group_name,
_In_z_ const char *domain_name,
_In_z_ const char *domain_name,
_Out_ switch_xml_t *root,
_Out_ switch_xml_t *domain,
_Out_ switch_xml_t *group,
_In_opt_ switch_event_t *params);
_Out_ switch_xml_t *domain, _Out_ switch_xml_t *group, _In_opt_ switch_event_t *params);
SWITCH_DECLARE(switch_status_t) switch_xml_locate_user(_In_z_ const char *key,
_In_z_ const char *user_name,
_In_z_ const char *domain_name,
_In_opt_z_ const char *ip,
_Out_ switch_xml_t *root, _Out_ switch_xml_t *domain, _Out_ switch_xml_t *user, _Out_opt_ switch_xml_t *ingroup,
_In_opt_ switch_event_t *params);
_Out_ switch_xml_t *root, _Out_ switch_xml_t *domain, _Out_ switch_xml_t *user,
_Out_opt_ switch_xml_t *ingroup, _In_opt_ switch_event_t *params);
SWITCH_DECLARE(switch_status_t) switch_xml_locate_user_in_domain(_In_z_ const char *user_name, _In_ switch_xml_t domain, _Out_ switch_xml_t *user, _Out_opt_ switch_xml_t *ingroup);
SWITCH_DECLARE(switch_status_t) switch_xml_locate_user_in_domain(_In_z_ const char *user_name, _In_ switch_xml_t domain, _Out_ switch_xml_t *user,
_Out_opt_ switch_xml_t *ingroup);
///\brief open a config in the core registry
///\param file_path the name of the config section e.g. modules.conf
@ -390,7 +390,8 @@ SWITCH_DECLARE(void) switch_xml_set_binding_user_data(_In_ switch_xml_binding_t
SWITCH_DECLARE(switch_xml_section_t) switch_xml_get_binding_sections(_In_ switch_xml_binding_t *binding);
SWITCH_DECLARE(void *) switch_xml_get_binding_user_data(_In_ switch_xml_binding_t *binding);
SWITCH_DECLARE(switch_status_t) switch_xml_bind_search_function_ret(_In_ switch_xml_search_function_t function, _In_ switch_xml_section_t sections, _In_opt_ void *user_data, switch_xml_binding_t **ret_binding);
SWITCH_DECLARE(switch_status_t) switch_xml_bind_search_function_ret(_In_ switch_xml_search_function_t function, _In_ switch_xml_section_t sections,
_In_opt_ void *user_data, switch_xml_binding_t **ret_binding);
#define switch_xml_bind_search_function(_f, _s, _u) switch_xml_bind_search_function_ret(_f, _s, _u, NULL)

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -36,38 +36,37 @@
#include <switch.h>
SWITCH_BEGIN_EXTERN_C
/*! \brief Type of value to parse */
typedef enum {
SWITCH_CONFIG_INT, /*< (ptr=int* default=int data=NULL) Integer */
SWITCH_CONFIG_STRING, /*< (ptr=[char* or char ** (for alloc)] default=char* data=switch_xml_config_string_options_t*) Zero-terminated C-string */
SWITCH_CONFIG_BOOL, /*< (ptr=switch_bool_t* default=switch_bool_t data=NULL) Yes and no */
SWITCH_CONFIG_CUSTOM, /*< (ptr=<custom function data> default=<custom function data> data=switch_xml_config_callback_t) Custom, get value through function pointer */
SWITCH_CONFIG_ENUM, /*< (ptr=int* default=int data=switch_xml_config_enum_item_t*) */
SWITCH_CONFIG_FLAG, /*< (ptr=int32_t* default=switch_bool_t data=int (flag index) */
SWITCH_CONFIG_FLAGARRAY, /*< (ptr=int8_t* default=switch_bool_t data=int (flag index) */
typedef enum {
SWITCH_CONFIG_INT, /*< (ptr=int* default=int data=NULL) Integer */
SWITCH_CONFIG_STRING, /*< (ptr=[char* or char ** (for alloc)] default=char* data=switch_xml_config_string_options_t*) Zero-terminated C-string */
SWITCH_CONFIG_BOOL, /*< (ptr=switch_bool_t* default=switch_bool_t data=NULL) Yes and no */
SWITCH_CONFIG_CUSTOM, /*< (ptr=<custom function data> default=<custom function data> data=switch_xml_config_callback_t) Custom, get value through function pointer */
SWITCH_CONFIG_ENUM, /*< (ptr=int* default=int data=switch_xml_config_enum_item_t*) */
SWITCH_CONFIG_FLAG, /*< (ptr=int32_t* default=switch_bool_t data=int (flag index) */
SWITCH_CONFIG_FLAGARRAY, /*< (ptr=int8_t* default=switch_bool_t data=int (flag index) */
/* No more past that line */
SWITCH_CONFIG_LAST
} switch_xml_config_type_t;
typedef struct {
char *key; /*< The item's key or NULL if this is the last one in the list */
int value; /*< The item's value */
typedef struct {
char *key; /*< The item's key or NULL if this is the last one in the list */
int value; /*< The item's value */
} switch_xml_config_enum_item_t;
typedef struct {
switch_memory_pool_t *pool; /*< If set, the string will be allocated on the pool (unless the length param is > 0, then you misread this file)*/
switch_size_t length; /*< Length of the char array, or 0 if memory has to be allocated dynamically*/
char *validation_regex; /*< Enforce validation using this regular expression */
switch_memory_pool_t *pool; /*< If set, the string will be allocated on the pool (unless the length param is > 0, then you misread this file) */
switch_size_t length; /*< Length of the char array, or 0 if memory has to be allocated dynamically */
char *validation_regex; /*< Enforce validation using this regular expression */
} switch_xml_config_string_options_t;
SWITCH_DECLARE_DATA extern switch_xml_config_string_options_t switch_config_string_strdup; /*< String options structure for strdup, no validation */
SWITCH_DECLARE_DATA extern switch_xml_config_string_options_t switch_config_string_strdup; /*< String options structure for strdup, no validation */
typedef struct {
switch_bool_t enforce_min;
int min;
switch_bool_t enforce_max;
switch_bool_t enforce_max;
int max;
} switch_xml_config_int_options_t;
@ -85,21 +84,22 @@ typedef enum {
CONFIG_REQUIRED = (1 << 1)
} switch_config_flags_t;
typedef switch_status_t (*switch_xml_config_callback_t)(switch_xml_config_item_t *item, const char *newvalue, switch_config_callback_type_t callback_type, switch_bool_t changed);
typedef switch_status_t (*switch_xml_config_callback_t) (switch_xml_config_item_t *item, const char *newvalue, switch_config_callback_type_t callback_type,
switch_bool_t changed);
/*!
* \brief A configuration instruction read by switch_xml_config_parse
*/
struct switch_xml_config_item {
const char *key; /*< The key of the element, or NULL to indicate the end of the list */
switch_xml_config_type_t type; /*< The type of variable */
int flags; /*< True if the var can be changed on reload */
void *ptr; /*< Ptr to the var to be changed */
const void *defaultvalue; /*< Default value */
void *data; /*< Custom data (depending on the type) */
const char *key; /*< The key of the element, or NULL to indicate the end of the list */
switch_xml_config_type_t type; /*< The type of variable */
int flags; /*< True if the var can be changed on reload */
void *ptr; /*< Ptr to the var to be changed */
const void *defaultvalue; /*< Default value */
void *data; /*< Custom data (depending on the type) */
switch_xml_config_callback_t function; /*< Callback to be called after the var is parsed */
const char *syntax; /*< Optional syntax documentation for this setting */
const char *helptext; /*< Optional documentation text for this setting */
const char *syntax; /*< Optional syntax documentation for this setting */
const char *helptext; /*< Optional documentation text for this setting */
};
#define SWITCH_CONFIG_ITEM(_key, _type, _flags, _ptr, _defaultvalue, _data, _syntax, _helptext) { _key, _type, _flags, _ptr, (void*)_defaultvalue, (void*)_data, NULL, _syntax, _helptext }
@ -110,9 +110,10 @@ struct switch_xml_config_item {
#define SWITCH_CONFIG_SET_ITEM(_item, _key, _type, _flags, _ptr, _defaultvalue, _data, _syntax, _helptext) switch_config_perform_set_item(&(_item), _key, _type, _flags, _ptr, (void*)(_defaultvalue), _data, NULL, _syntax, _helptext)
#define SWITCH_CONFIG_SET_ITEM_CALLBACK(_item, _key, _type, _flags, _ptr, _defaultvalue, _data, _function, _syntax, _helptext) switch_config_perform_set_item(&(_item), _key, _type, _flags, _ptr, (void*)(_defaultvalue), _data, _function, _syntax, _helptext)
SWITCH_DECLARE(void) switch_config_perform_set_item(switch_xml_config_item_t *item, const char *key, switch_xml_config_type_t type, int flags, void *ptr,
const void* defaultvalue, void *data, switch_xml_config_callback_t function, const char *syntax, const char *helptext);
SWITCH_DECLARE(void) switch_config_perform_set_item(switch_xml_config_item_t *item, const char *key, switch_xml_config_type_t type, int flags, void *ptr,
const void *defaultvalue, void *data, switch_xml_config_callback_t function, const char *syntax,
const char *helptext);
/*!
* \brief Gets the int representation of an enum
* \param enum_options the switch_xml_config_enum_item_t array for this enum
@ -125,7 +126,7 @@ SWITCH_DECLARE(switch_status_t) switch_xml_config_enum_str2int(switch_xml_config
* \param enum_options the switch_xml_config_enum_item_t array for this enum
* \param value int value to search
*/
SWITCH_DECLARE(const char*) switch_xml_config_enum_int2str(switch_xml_config_enum_item_t *enum_options, int value);
SWITCH_DECLARE(const char *) switch_xml_config_enum_int2str(switch_xml_config_enum_item_t *enum_options, int value);
/*!
* \brief Prints out an item's documentation on the console
@ -158,7 +159,8 @@ SWITCH_DECLARE(switch_status_t) switch_xml_config_parse_module_settings(const ch
* \param instructions instrutions on how to parse the elements
* \see switch_xml_config_item_t
*/
SWITCH_DECLARE(switch_status_t) switch_xml_config_parse_event(switch_event_t *event, int count, switch_bool_t reload, switch_xml_config_item_t *instructions);
SWITCH_DECLARE(switch_status_t) switch_xml_config_parse_event(switch_event_t *event, int count, switch_bool_t reload,
switch_xml_config_item_t *instructions);
/*!
* \brief Parses a list of xml elements into an event
@ -176,9 +178,7 @@ SWITCH_DECLARE(switch_size_t) switch_event_import_xml(switch_xml_t xml, const ch
SWITCH_DECLARE(void) switch_xml_config_cleanup(switch_xml_config_item_t *instructions);
SWITCH_END_EXTERN_C
#endif /* !defined(SWITCH_XML_CONFIG_H) */
/* For Emacs:
* Local Variables:
* mode:c

View File

@ -52,9 +52,9 @@
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
*/
static int inet_pton4(const char *src, unsigned char *dst);
static int inet_pton4(const char *src, unsigned char *dst);
#ifdef ENABLE_IPV6
static int inet_pton6(const char *src, unsigned char *dst);
static int inet_pton6(const char *src, unsigned char *dst);
#endif
/* int
@ -68,24 +68,23 @@ static int inet_pton6(const char *src, unsigned char *dst);
* author:
* Paul Vixie, 1996.
*/
SWITCH_DECLARE(int)
switch_inet_pton(int af, const char *src, void *dst)
SWITCH_DECLARE(int) switch_inet_pton(int af, const char *src, void *dst)
{
switch (af) {
case AF_INET:
return (inet_pton4(src, (unsigned char *)dst));
switch (af) {
case AF_INET:
return (inet_pton4(src, (unsigned char *) dst));
#ifdef ENABLE_IPV6
#ifndef AF_INET6
#define AF_INET6 (AF_MAX+1) /* just to let this compile */
#define AF_INET6 (AF_MAX+1) /* just to let this compile */
#endif
case AF_INET6:
return (inet_pton6(src, (unsigned char *)dst));
case AF_INET6:
return (inet_pton6(src, (unsigned char *) dst));
#endif
default:
errno = EAFNOSUPPORT;
return (-1);
}
/* NOTREACHED */
default:
errno = EAFNOSUPPORT;
return (-1);
}
/* NOTREACHED */
}
/* int
@ -98,44 +97,43 @@ switch_inet_pton(int af, const char *src, void *dst)
* author:
* Paul Vixie, 1996.
*/
static int
inet_pton4(const char *src, unsigned char *dst)
static int inet_pton4(const char *src, unsigned char *dst)
{
static const char digits[] = "0123456789";
int saw_digit, octets, ch;
unsigned char tmp[INADDRSZ], *tp;
static const char digits[] = "0123456789";
int saw_digit, octets, ch;
unsigned char tmp[INADDRSZ], *tp;
saw_digit = 0;
octets = 0;
tp = tmp;
*tp = 0;
while ((ch = *src++) != '\0') {
const char *pch;
saw_digit = 0;
octets = 0;
tp = tmp;
*tp = 0;
while ((ch = *src++) != '\0') {
const char *pch;
if ((pch = strchr(digits, ch)) != NULL) {
unsigned int val = *tp * 10 + (unsigned int)(pch - digits);
if ((pch = strchr(digits, ch)) != NULL) {
unsigned int val = *tp * 10 + (unsigned int) (pch - digits);
if (val > 255)
return (0);
*tp = (unsigned char)val;
if (! saw_digit) {
if (++octets > 4)
return (0);
saw_digit = 1;
}
} else if (ch == '.' && saw_digit) {
if (octets == 4)
return (0);
*++tp = 0;
saw_digit = 0;
} else
return (0);
}
if (octets < 4)
return (0);
/* bcopy(tmp, dst, INADDRSZ); */
memcpy(dst, tmp, INADDRSZ);
return (1);
if (val > 255)
return (0);
*tp = (unsigned char) val;
if (!saw_digit) {
if (++octets > 4)
return (0);
saw_digit = 1;
}
} else if (ch == '.' && saw_digit) {
if (octets == 4)
return (0);
*++tp = 0;
saw_digit = 0;
} else
return (0);
}
if (octets < 4)
return (0);
/* bcopy(tmp, dst, INADDRSZ); */
memcpy(dst, tmp, INADDRSZ);
return (1);
}
#ifdef ENABLE_IPV6
@ -152,88 +150,85 @@ inet_pton4(const char *src, unsigned char *dst)
* author:
* Paul Vixie, 1996.
*/
static int
inet_pton6(const char *src, unsigned char *dst)
static int inet_pton6(const char *src, unsigned char *dst)
{
static const char xdigits_l[] = "0123456789abcdef",
xdigits_u[] = "0123456789ABCDEF";
unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
const char *xdigits, *curtok;
int ch, saw_xdigit;
unsigned int val;
static const char xdigits_l[] = "0123456789abcdef", xdigits_u[] = "0123456789ABCDEF";
unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
const char *xdigits, *curtok;
int ch, saw_xdigit;
unsigned int val;
memset((tp = tmp), 0, IN6ADDRSZ);
endp = tp + IN6ADDRSZ;
colonp = NULL;
/* Leading :: requires some special handling. */
if (*src == ':')
if (*++src != ':')
return (0);
curtok = src;
saw_xdigit = 0;
val = 0;
while ((ch = *src++) != '\0') {
const char *pch;
memset((tp = tmp), 0, IN6ADDRSZ);
endp = tp + IN6ADDRSZ;
colonp = NULL;
/* Leading :: requires some special handling. */
if (*src == ':')
if (*++src != ':')
return (0);
curtok = src;
saw_xdigit = 0;
val = 0;
while ((ch = *src++) != '\0') {
const char *pch;
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
pch = strchr((xdigits = xdigits_u), ch);
if (pch != NULL) {
val <<= 4;
val |= (pch - xdigits);
if (val > 0xffff)
return (0);
saw_xdigit = 1;
continue;
}
if (ch == ':') {
curtok = src;
if (!saw_xdigit) {
if (colonp)
return (0);
colonp = tp;
continue;
}
if (tp + INT16SZ > endp)
return (0);
*tp++ = (unsigned char) (val >> 8) & 0xff;
*tp++ = (unsigned char) val & 0xff;
saw_xdigit = 0;
val = 0;
continue;
}
if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
inet_pton4(curtok, tp) > 0) {
tp += INADDRSZ;
saw_xdigit = 0;
break; /* '\0' was seen by inet_pton4(). */
}
return (0);
}
if (saw_xdigit) {
if (tp + INT16SZ > endp)
return (0);
*tp++ = (unsigned char) (val >> 8) & 0xff;
*tp++ = (unsigned char) val & 0xff;
}
if (colonp != NULL) {
/*
* Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
*/
const int n = tp - colonp;
int i;
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
pch = strchr((xdigits = xdigits_u), ch);
if (pch != NULL) {
val <<= 4;
val |= (pch - xdigits);
if (val > 0xffff)
return (0);
saw_xdigit = 1;
continue;
}
if (ch == ':') {
curtok = src;
if (!saw_xdigit) {
if (colonp)
return (0);
colonp = tp;
continue;
}
if (tp + INT16SZ > endp)
return (0);
*tp++ = (unsigned char) (val >> 8) & 0xff;
*tp++ = (unsigned char) val & 0xff;
saw_xdigit = 0;
val = 0;
continue;
}
if (ch == '.' && ((tp + INADDRSZ) <= endp) && inet_pton4(curtok, tp) > 0) {
tp += INADDRSZ;
saw_xdigit = 0;
break; /* '\0' was seen by inet_pton4(). */
}
return (0);
}
if (saw_xdigit) {
if (tp + INT16SZ > endp)
return (0);
*tp++ = (unsigned char) (val >> 8) & 0xff;
*tp++ = (unsigned char) val & 0xff;
}
if (colonp != NULL) {
/*
* Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
*/
const int n = tp - colonp;
int i;
for (i = 1; i <= n; i++) {
endp[- i] = colonp[n - i];
colonp[n - i] = 0;
}
tp = endp;
}
if (tp != endp)
return (0);
/* bcopy(tmp, dst, IN6ADDRSZ); */
memcpy(dst, tmp, IN6ADDRSZ);
return (1);
for (i = 1; i <= n; i++) {
endp[-i] = colonp[n - i];
colonp[n - i] = 0;
}
tp = endp;
}
if (tp != endp)
return (0);
/* bcopy(tmp, dst, IN6ADDRSZ); */
memcpy(dst, tmp, IN6ADDRSZ);
return (1);
}
#endif /* ENABLE_IPV6 */

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -28,7 +28,7 @@
* mod_cidlookup.c -- API for querying cid->name services
*
*/
#include <switch.h>
#include <curl/curl.h>
@ -50,12 +50,12 @@ static struct {
char *url;
int curl_timeout;
int curl_warnduration;
char *whitepages_apikey;
switch_bool_t cache;
int cache_expire;
char *odbc_dsn;
char *odbc_user;
char *odbc_pass;
@ -92,22 +92,24 @@ static switch_cache_db_handle_t *cidlookup_get_db_handle(void)
{
switch_cache_db_connection_options_t options = { {0} };
switch_cache_db_handle_t *dbh = NULL;
if (!zstr(globals.odbc_dsn)) {
options.odbc_options.dsn = globals.odbc_dsn;
options.odbc_options.user = globals.odbc_user;
options.odbc_options.pass = globals.odbc_pass;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) dbh = NULL;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS)
dbh = NULL;
}
return dbh;
}
static switch_status_t config_callback_dsn(switch_xml_config_item_t *data, const char *newvalue, switch_config_callback_type_t callback_type, switch_bool_t changed)
static switch_status_t config_callback_dsn(switch_xml_config_item_t *data, const char *newvalue, switch_config_callback_type_t callback_type,
switch_bool_t changed)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_cache_db_handle_t *dbh = NULL;
if (!switch_odbc_available()) {
@ -139,25 +141,31 @@ static switch_status_t config_callback_dsn(switch_xml_config_item_t *data, const
}
switch_goto_status(SWITCH_STATUS_SUCCESS, done);
done:
done:
switch_cache_db_release_db_handle(&dbh);
return status;
}
static switch_xml_config_string_options_t config_opt_dsn = {NULL, 0, NULL}; /* anything is ok here */
static switch_xml_config_string_options_t config_opt_dsn = { NULL, 0, NULL }; /* anything is ok here */
static switch_xml_config_item_t instructions[] = {
/* parameter name type reloadable pointer default value options structure */
SWITCH_CONFIG_ITEM_STRING_STRDUP("url", CONFIG_RELOAD, &globals.url, NULL, "http://server.example.com/app?number=${caller_id_number}", "URL for the CID lookup service"),
SWITCH_CONFIG_ITEM_STRING_STRDUP("whitepages-apikey", CONFIG_RELOAD, &globals.whitepages_apikey, NULL, "api key for whitepages.com", "api key for whitepages.com"),
SWITCH_CONFIG_ITEM_STRING_STRDUP("url", CONFIG_RELOAD, &globals.url, NULL, "http://server.example.com/app?number=${caller_id_number}",
"URL for the CID lookup service"),
SWITCH_CONFIG_ITEM_STRING_STRDUP("whitepages-apikey", CONFIG_RELOAD, &globals.whitepages_apikey, NULL, "api key for whitepages.com",
"api key for whitepages.com"),
SWITCH_CONFIG_ITEM("cache", SWITCH_CONFIG_BOOL, CONFIG_RELOAD, &globals.cache, SWITCH_FALSE, NULL, "true|false", "whether to cache via cidlookup"),
SWITCH_CONFIG_ITEM("cache-expire", SWITCH_CONFIG_INT, CONFIG_RELOAD, &globals.cache_expire, (void *)300, NULL, "expire", "seconds to preserve num->name cache"),
SWITCH_CONFIG_ITEM("curl-timeout", SWITCH_CONFIG_INT, CONFIG_RELOAD, &globals.curl_timeout, (void *)2000, NULL, "timeout for curl", "milliseconds to timeout"),
SWITCH_CONFIG_ITEM("curl-warning-duration", SWITCH_CONFIG_INT, CONFIG_RELOAD, &globals.curl_warnduration, (void *)1000, NULL, "warning when curl queries are longer than specified time", "milliseconds"),
SWITCH_CONFIG_ITEM("cache-expire", SWITCH_CONFIG_INT, CONFIG_RELOAD, &globals.cache_expire, (void *) 300, NULL, "expire",
"seconds to preserve num->name cache"),
SWITCH_CONFIG_ITEM("curl-timeout", SWITCH_CONFIG_INT, CONFIG_RELOAD, &globals.curl_timeout, (void *) 2000, NULL, "timeout for curl",
"milliseconds to timeout"),
SWITCH_CONFIG_ITEM("curl-warning-duration", SWITCH_CONFIG_INT, CONFIG_RELOAD, &globals.curl_warnduration, (void *) 1000, NULL,
"warning when curl queries are longer than specified time", "milliseconds"),
SWITCH_CONFIG_ITEM_STRING_STRDUP("sql", CONFIG_RELOAD, &globals.sql, NULL, "sql whre number=${caller_id_number}", "SQL to run if overriding CID"),
SWITCH_CONFIG_ITEM_STRING_STRDUP("citystate-sql", CONFIG_RELOAD, &globals.citystate_sql, NULL, "sql to look up city/state info", "SQL to run if overriding CID"),
SWITCH_CONFIG_ITEM_STRING_STRDUP("citystate-sql", CONFIG_RELOAD, &globals.citystate_sql, NULL, "sql to look up city/state info",
"SQL to run if overriding CID"),
SWITCH_CONFIG_ITEM_CALLBACK("odbc-dsn", SWITCH_CONFIG_STRING, CONFIG_RELOAD, &globals.odbc_dsn, "", config_callback_dsn, &config_opt_dsn,
"db:user:passwd", "Database to use."),
"db:user:passwd", "Database to use."),
SWITCH_CONFIG_ITEM_END()
};
@ -166,7 +174,7 @@ static switch_status_t do_config(switch_bool_t reload)
if (switch_xml_config_parse_module_settings("cidlookup.conf", reload, instructions) != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_GENERR;
}
return SWITCH_STATUS_SUCCESS;
}
@ -179,10 +187,10 @@ static switch_bool_t cidlookup_execute_sql_callback(char *sql, switch_core_db_ca
{
switch_bool_t retval = SWITCH_FALSE;
switch_cache_db_handle_t *dbh = NULL;
if (globals.odbc_dsn && (dbh = cidlookup_get_db_handle())) {
if (switch_cache_db_execute_sql_callback(dbh, sql, callback, (void *)cbt, err)
== SWITCH_ODBC_FAIL) {
if (switch_cache_db_execute_sql_callback(dbh, sql, callback, (void *) cbt, err)
== SWITCH_ODBC_FAIL) {
retval = SWITCH_FALSE;
} else {
retval = SWITCH_TRUE;
@ -190,7 +198,7 @@ static switch_bool_t cidlookup_execute_sql_callback(char *sql, switch_core_db_ca
} else {
*err = switch_core_sprintf(cbt->pool, "Unable to get ODBC handle. dsn: %s, dbh is %s\n", globals.odbc_dsn, dbh ? "not null" : "null");
}
switch_cache_db_release_db_handle(&dbh);
return retval;
}
@ -199,33 +207,31 @@ static int cidlookup_callback(void *pArg, int argc, char **argv, char **columnNa
{
callback_t *cbt = (callback_t *) pArg;
switch_memory_pool_t *pool = cbt->pool;
if (argc < 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"Unexpected number of columns returned for SQL. Returned column count: %d. ",
argc);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unexpected number of columns returned for SQL. Returned column count: %d. ", argc);
return SWITCH_STATUS_GENERR;
}
cbt->name = switch_core_strdup(pool, switch_str_nil(argv[0]));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Name: %s\n", cbt->name);
return SWITCH_STATUS_SUCCESS;
}
/* make a new string with digits only */
static char *string_digitsonly(switch_memory_pool_t *pool, const char *str)
static char *string_digitsonly(switch_memory_pool_t *pool, const char *str)
{
char *p, *np, *newstr;
size_t len;
p = (char *)str;
p = (char *) str;
len = strlen(str);
newstr = switch_core_alloc(pool, len+1);
newstr = switch_core_alloc(pool, len + 1);
switch_assert(newstr);
np = newstr;
while(*p) {
while (*p) {
if (switch_isdigit(*p)) {
*np = *p;
np++;
@ -237,16 +243,17 @@ static char *string_digitsonly(switch_memory_pool_t *pool, const char *str)
return newstr;
}
static cid_data_t *check_cache(switch_memory_pool_t *pool, const char *number) {
static cid_data_t *check_cache(switch_memory_pool_t *pool, const char *number)
{
char *cmd;
char *name = NULL;
char *area = NULL;
char *src = NULL;
cid_data_t *cid = NULL;
switch_stream_handle_t stream = { 0 };
SWITCH_STANDARD_STREAM(stream);
cmd = switch_core_sprintf(pool, "get fs:cidlookup:name:%s", number);
if (switch_api_execute("memcache", cmd, NULL, &stream) == SWITCH_STATUS_SUCCESS) {
if (strncmp("-ERR", stream.data, 4)) {
@ -275,7 +282,7 @@ static cid_data_t *check_cache(switch_memory_pool_t *pool, const char *number) {
src = NULL;
}
}
if (name || area || src) {
cid = switch_core_alloc(pool, sizeof(cid_data_t));
switch_assert(cid);
@ -283,24 +290,21 @@ static cid_data_t *check_cache(switch_memory_pool_t *pool, const char *number) {
cid->area = area;
cid->src = src;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "memcache: k:'%s', vn:'%s', va:'%s', vs:'%s'\n",
cmd,
(name) ? name : "(null)",
(area) ? area : "(null)",
(src) ? src : "(null)"
);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "memcache: k:'%s', vn:'%s', va:'%s', vs:'%s'\n",
cmd, (name) ? name : "(null)", (area) ? area : "(null)", (src) ? src : "(null)");
switch_safe_free(stream.data);
return cid;
}
switch_bool_t set_cache(switch_memory_pool_t *pool, char *number, cid_data_t *cid) {
switch_bool_t set_cache(switch_memory_pool_t *pool, char *number, cid_data_t *cid)
{
char *cmd;
switch_bool_t success = SWITCH_TRUE;
switch_stream_handle_t stream = { 0 };
SWITCH_STANDARD_STREAM(stream);
cmd = switch_core_sprintf(pool, "set fs:cidlookup:name:%s '%s' %d", number, cid->name, globals.cache_expire);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "memcache: %s\n", cmd);
if (switch_api_execute("memcache", cmd, NULL, &stream) == SWITCH_STATUS_SUCCESS) {
@ -334,7 +338,7 @@ switch_bool_t set_cache(switch_memory_pool_t *pool, char *number, cid_data_t *ci
}
}
done:
done:
switch_safe_free(stream.data);
return success;
}
@ -347,17 +351,18 @@ static size_t file_callback(void *ptr, size_t size, size_t nmemb, void *data)
http_data->bytes += realsize;
if (http_data->bytes > http_data->max_bytes) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Oversized file detected [%d bytes]\n", (int)http_data->bytes);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Oversized file detected [%d bytes]\n", (int) http_data->bytes);
http_data->err = 1;
return 0;
}
http_data->stream.write_function(
&http_data->stream, "%.*s", realsize, ptr);
http_data->stream.write_function(&http_data->stream, "%.*s", realsize, ptr);
return realsize;
}
static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, char **response, const char *query, struct curl_httppost *post, struct curl_slist *headers, int timeout) {
static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, char **response, const char *query, struct curl_httppost *post,
struct curl_slist *headers, int timeout)
{
switch_time_t start_time = switch_micro_time_now();
switch_time_t time_diff = 0;
CURL *curl_handle = NULL;
@ -365,20 +370,20 @@ static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, cha
char hostname[256] = "";
struct http_data http_data;
memset(&http_data, 0, sizeof(http_data));
http_data.max_bytes = 10240;
SWITCH_STANDARD_STREAM(http_data.stream);
gethostname(hostname, sizeof(hostname));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "url: %s\n", query);
curl_handle = curl_easy_init();
curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 0);
curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
if (!strncasecmp(query, "https", 5)) {
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
@ -394,7 +399,7 @@ static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, cha
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10);
/*
TIMEOUT_MS is introduced in 7.16.2, we have 7.16.0 in tree
TIMEOUT_MS is introduced in 7.16.2, we have 7.16.0 in tree
*/
#ifdef CURLOPT_TIMEOUT_MS
if (timeout > 0) {
@ -406,7 +411,7 @@ static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, cha
if (timeout > 0) {
curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, timeout);
} else {
curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, globals.curl_timeout/1000);
curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, globals.curl_timeout / 1000);
}
#endif
curl_easy_setopt(curl_handle, CURLOPT_URL, query);
@ -417,34 +422,24 @@ static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, cha
curl_easy_perform(curl_handle);
curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &httpRes);
curl_easy_cleanup(curl_handle);
if ( http_data.stream.data &&
!zstr((char *)http_data.stream.data) &&
strcmp(" ", http_data.stream.data) ) {
if (http_data.stream.data && !zstr((char *) http_data.stream.data) && strcmp(" ", http_data.stream.data)) {
/* don't return UNKNOWN */
if (strcmp("UNKNOWN", http_data.stream.data) ||
strcmp("UNAVAILABLE", http_data.stream.data)) {
if (strcmp("UNKNOWN", http_data.stream.data) || strcmp("UNAVAILABLE", http_data.stream.data)) {
*response = switch_core_strdup(pool, http_data.stream.data);
}
}
time_diff = (switch_micro_time_now() - start_time); /* convert to milli from micro */
if ((time_diff/1000) >= globals.curl_warnduration) {
time_diff = (switch_micro_time_now() - start_time); /* convert to milli from micro */
if ((time_diff / 1000) >= globals.curl_warnduration) {
switch_core_time_duration_t duration;
switch_core_measure_time(time_diff, &duration);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SLOW LOOKUP ("
"%um, "
"%us, "
"%ums"
"): url: %s\n",
duration.min,
duration.sec,
duration.ms,
query);
"%um, " "%us, " "%ums" "): url: %s\n", duration.min, duration.sec, duration.ms, query);
}
switch_safe_free(http_data.stream.data);
return httpRes;
}
@ -463,19 +458,19 @@ static cid_data_t *do_whitepages_lookup(switch_memory_pool_t *pool, switch_event
/* NANPA check */
if (strlen(num) == 11 && num[0] == '1') {
num++; /* skip past leading 1 */
num++; /* skip past leading 1 */
} else {
goto done;
}
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "whitepages-cid", num);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "whitepages-api-key", globals.whitepages_apikey);
query = switch_event_expand_headers(event, "http://api.whitepages.com/reverse_phone/1.0/?phone=${whitepages-cid};api_key=${whitepages-api-key}");
do_lookup_url(pool, event, &xml_s, query, NULL, NULL, 0);
xml = switch_xml_parse_str_dup(xml_s);
if (!xml) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to parse XML: %s\n", xml_s);
goto done;
@ -487,14 +482,14 @@ static cid_data_t *do_whitepages_lookup(switch_memory_pool_t *pool, switch_event
name = switch_core_strdup(pool, switch_xml_txt(node));
goto area;
}
node = switch_xml_get(xml, "wp:listings", 0, "wp:listing", 0, "wp:displayname", -1);
if (node) {
name = switch_core_strdup(pool, switch_xml_txt(node));
}
area:
area:
node = switch_xml_get(xml, "wp:listings", 0, "wp:listing", 0, "wp:address", 0, "wp:city", -1);
if (node) {
city = switch_xml_txt(node);
@ -504,12 +499,12 @@ area:
if (node) {
state = switch_xml_txt(node);
}
if (city || state) {
area = switch_core_sprintf(pool, "%s %s", city ? city : "", state ? state : "");
}
done:
done:
if (query) {
switch_safe_free(query);
@ -519,23 +514,24 @@ done:
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "whitepages XML: %s\n", xml_s);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "whitepages name: %s, area: %s\n", name ? name : "(null)", area ? area : "(null)");
cid = switch_core_alloc(pool, sizeof(cid_data_t));
switch_assert(cid);
cid->name = name;
cid->area = area;
cid->src = "whitepages";
return cid;
}
static char *do_db_lookup(switch_memory_pool_t *pool, switch_event_t *event, const char *num, const char *sql) {
static char *do_db_lookup(switch_memory_pool_t *pool, switch_event_t *event, const char *num, const char *sql)
{
char *name = NULL;
char *newsql = NULL;
char *err = NULL;
callback_t cbt = { 0 };
cbt.pool = pool;
if (globals.odbc_dsn) {
newsql = switch_event_expand_headers(event, sql);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SQL: %s\n", newsql);
@ -551,13 +547,14 @@ static char *do_db_lookup(switch_memory_pool_t *pool, switch_event_t *event, con
return name;
}
static cid_data_t *do_lookup(switch_memory_pool_t *pool, switch_event_t *event, const char *num, switch_bool_t skipurl, switch_bool_t skipcitystate) {
static cid_data_t *do_lookup(switch_memory_pool_t *pool, switch_event_t *event, const char *num, switch_bool_t skipurl, switch_bool_t skipcitystate)
{
char *number = NULL;
char *name = NULL;
char *url_query = NULL;
cid_data_t *cid = NULL;
switch_bool_t save_cache = SWITCH_FALSE;
cid = switch_core_alloc(pool, sizeof(cid_data_t));
switch_assert(cid);
@ -581,40 +578,37 @@ static cid_data_t *do_lookup(switch_memory_pool_t *pool, switch_event_t *event,
goto done;
}
}
if (!skipurl && globals.whitepages_apikey) {
cid = do_whitepages_lookup(pool, event, number);
if (cid && cid->name) { /* only cache if we have a name */
if (cid && cid->name) { /* only cache if we have a name */
save_cache = SWITCH_TRUE;
goto done;
}
}
if (!skipurl && globals.url) {
url_query = switch_event_expand_headers(event, globals.url);
do_lookup_url(pool, event, &name, url_query, NULL, NULL, 0);
if (name) {
cid->name = name;
cid->src = "url";
save_cache = SWITCH_TRUE;
}
if (url_query != globals.url) {
switch_safe_free(url_query);
}
}
done:
done:
if (!cid) {
cid = switch_core_alloc(pool, sizeof(cid_data_t));
switch_assert(cid);
}
/* append area if we can */
if (!cid->area &&
!skipcitystate &&
strlen(number) == 11 && number[0] == '1' &&
switch_odbc_available() && globals.odbc_dsn && globals.citystate_sql) {
if (!cid->area && !skipcitystate && strlen(number) == 11 && number[0] == '1' && switch_odbc_available() && globals.odbc_dsn && globals.citystate_sql) {
/* yes, this is really area */
name = do_db_lookup(pool, event, number, globals.citystate_sql);
if (name) {
@ -626,7 +620,7 @@ done:
}
}
}
if (!cid->area) {
cid->area = "UNKNOWN";
}
@ -636,11 +630,11 @@ done:
if (!cid->src) {
cid->src = "UNKNOWN";
}
if (globals.cache && save_cache) {
set_cache(pool, number, cid);
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "cidlookup source: %s\n", cid->src);
return cid;
@ -649,7 +643,7 @@ done:
SWITCH_STANDARD_APP(cidlookup_app_function)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
char *argv[4] = { 0 };
int argc;
char *mydata = NULL;
@ -663,7 +657,7 @@ SWITCH_STANDARD_APP(cidlookup_app_function)
const char *number = NULL;
switch_bool_t skipurl = SWITCH_FALSE;
switch_bool_t skipcitystate = SWITCH_FALSE;
if (session) {
pool = switch_core_session_get_pool(session);
} else {
@ -674,7 +668,7 @@ SWITCH_STANDARD_APP(cidlookup_app_function)
if (!(mydata = switch_core_session_strdup(session, data))) {
return;
}
if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
if (argc > 0) {
number = switch_core_session_strdup(session, argv[0]);
@ -687,20 +681,20 @@ SWITCH_STANDARD_APP(cidlookup_app_function)
}
}
}
if (!number && profile) {
number = switch_caller_get_field_by_name(profile, "caller_id_number");
}
if (number) {
cid = do_lookup(pool, event, number, skipurl, skipcitystate);
}
if (switch_string_var_check_const(cid->name)) {
switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_CRIT, "Invalid CID data {%s} contains a variable\n", cid->name);
switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_CRIT, "Invalid CID data {%s} contains a variable\n", cid->name);
switch_goto_status(SWITCH_STATUS_GENERR, done);
}
if (cid && channel) {
switch_channel_set_variable(channel, "original_caller_id_name", switch_core_strdup(pool, profile->caller_id_name));
if (!zstr(cid->src)) {
@ -711,10 +705,10 @@ SWITCH_STANDARD_APP(cidlookup_app_function)
}
profile->caller_id_name = switch_core_strdup(profile->pool, cid->name);;
}
switch_goto_status(SWITCH_STATUS_SUCCESS, done);
done:
done:
if (event) {
switch_event_destroy(&event);
}
@ -722,6 +716,7 @@ done:
switch_core_destroy_memory_pool(&pool);
}
}
SWITCH_STANDARD_API(cidlookup_function)
{
switch_status_t status;
@ -736,7 +731,7 @@ SWITCH_STANDARD_API(cidlookup_function)
switch_bool_t skipurl = SWITCH_FALSE;
switch_bool_t skipcitystate = SWITCH_FALSE;
switch_bool_t verbose = SWITCH_FALSE;
if (zstr(cmd)) {
switch_goto_status(SWITCH_STATUS_SUCCESS, usage);
}
@ -753,22 +748,18 @@ SWITCH_STANDARD_API(cidlookup_function)
if (argc < 1) {
switch_goto_status(SWITCH_STATUS_SUCCESS, usage);
}
if (!strcmp("status", argv[0])) {
stream->write_function(stream, "+OK\n url: %s\n cache: %s\n cache-expire: %d\n",
globals.url ? globals.url : "(null)",
(globals.cache) ? "true" : "false",
globals.cache_expire);
stream->write_function(stream, " curl-timeout: %" SWITCH_TIME_T_FMT "\n curl-warn-duration: %" SWITCH_TIME_T_FMT "\n",
globals.curl_timeout,
globals.curl_warnduration);
stream->write_function(stream, " odbc-dsn: %s\n sql: %s\n citystate-sql: %s\n",
globals.odbc_dsn ? globals.odbc_dsn : "(null)",
globals.sql ? globals.sql : "(null)",
globals.citystate_sql ? globals.citystate_sql : "(null)");
stream->write_function(stream, " ODBC Compiled: %s\n", switch_odbc_available() ? "true" : "false");
stream->write_function(stream, "+OK\n url: %s\n cache: %s\n cache-expire: %d\n",
globals.url ? globals.url : "(null)", (globals.cache) ? "true" : "false", globals.cache_expire);
stream->write_function(stream, " curl-timeout: %" SWITCH_TIME_T_FMT "\n curl-warn-duration: %" SWITCH_TIME_T_FMT "\n",
globals.curl_timeout, globals.curl_warnduration);
stream->write_function(stream, " odbc-dsn: %s\n sql: %s\n citystate-sql: %s\n",
globals.odbc_dsn ? globals.odbc_dsn : "(null)",
globals.sql ? globals.sql : "(null)", globals.citystate_sql ? globals.citystate_sql : "(null)");
stream->write_function(stream, " ODBC Compiled: %s\n", switch_odbc_available()? "true" : "false");
switch_goto_status(SWITCH_STATUS_SUCCESS, done);
}
for (i = 1; i < argc; i++) {
@ -784,7 +775,7 @@ SWITCH_STANDARD_API(cidlookup_function)
cid = do_lookup(pool, event, argv[0], skipurl, skipcitystate);
if (cid) {
if (switch_string_var_check_const(cid->name)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Invalid CID data {%s} contains a variable\n", cid->name);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Invalid CID data {%s} contains a variable\n", cid->name);
stream->write_function(stream, "-ERR Invalid CID data {%s} contains a variable\n", cid->name);
switch_goto_status(SWITCH_STATUS_SUCCESS, done);
}
@ -798,11 +789,11 @@ SWITCH_STANDARD_API(cidlookup_function)
}
switch_goto_status(SWITCH_STATUS_SUCCESS, done);
usage:
usage:
stream->write_function(stream, "-ERR\n%s\n", SYNTAX);
switch_goto_status(status, done);
done:
done:
switch_safe_free(mydata);
if (event) {
switch_event_destroy(&event);
@ -822,16 +813,16 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_cidlookup_load)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
memset(&globals, 0, sizeof(globals));
globals.pool = pool;
do_config(SWITCH_FALSE);
if ((switch_event_bind_removable(modname, SWITCH_EVENT_RELOADXML, NULL, event_handler, NULL, &reload_xml_event) != SWITCH_STATUS_SUCCESS)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind event!\n");
return SWITCH_STATUS_TERM;
}
SWITCH_ADD_API(api_interface, "cidlookup", "cidlookup API", cidlookup_function, SYNTAX);
SWITCH_ADD_APP(app_interface, "cidlookup", "Perform a CID lookup", "Perform a CID lookup",
cidlookup_app_function, "[number [skipurl]]", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -52,11 +52,11 @@ int vgo(int i, switch_core_session_t *session);
SWITCH_STANDARD_APP(cluechoo_app)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_channel_answer(channel);
switch_ivr_sleep(session, 1000, SWITCH_FALSE, NULL);
while(switch_channel_ready(channel)) {
while (switch_channel_ready(channel)) {
if (vgo(0, session) < 0) {
break;
}
@ -66,7 +66,7 @@ SWITCH_STANDARD_APP(cluechoo_app)
SWITCH_STANDARD_API(cluechoo_function)
{
//stream->write_function(stream, "+OK Reloading\n");
go(0);
return SWITCH_STATUS_SUCCESS;
}
@ -81,7 +81,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_cluechoo_load)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Hello World!\n");
SWITCH_ADD_API(api_interface, "cluechoo", "Cluechoo API", cluechoo_function, "syntax");
SWITCH_ADD_APP(app_interface, "cluechoo", "cluechoo", "cluechoo", cluechoo_app, "", SAF_NONE);
@ -134,36 +134,45 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_cluechoo_shutdown)
#include <unistd.h>
#include "sl.h"
int ACCIDENT = 0;
int LOGO = 0;
int FLY = 0;
int ACCIDENT = 0;
int LOGO = 0;
int FLY = 0;
int my_mvaddstr(int y, int x, char *str)
{
for ( ; x < 0; ++x, ++str)
if (*str == '\0') return ERR;
for ( ; *str != '\0'; ++str, ++x)
if (mvaddch(y, x, *str) == ERR) return ERR;
return OK;
for (; x < 0; ++x, ++str)
if (*str == '\0')
return ERR;
for (; *str != '\0'; ++str, ++x)
if (mvaddch(y, x, *str) == ERR)
return ERR;
return OK;
}
void option(char *str)
{
extern int ACCIDENT, FLY;
extern int ACCIDENT, FLY;
while (*str != '\0') {
while (*str != '\0') {
switch (*str++) {
case 'a': ACCIDENT = 1; break;
case 'F': FLY = 1; break;
case 'l': LOGO = 1; break;
default: break;
case 'a':
ACCIDENT = 1;
break;
case 'F':
FLY = 1;
break;
case 'l':
LOGO = 1;
break;
default:
break;
}
}
}
}
int go(int i)
{
int x;
int x;
int sleep_len = 40000;
if (i > 0) {
@ -171,23 +180,25 @@ int go(int i)
}
/*
for (i = 1; i < argc; ++i) {
if (*argv[i] == '-') {
option(argv[i] + 1);
}
}
*/
initscr();
signal(SIGINT, SIG_IGN);
noecho();
leaveok(stdscr, TRUE);
scrollok(stdscr, FALSE);
for (i = 1; i < argc; ++i) {
if (*argv[i] == '-') {
option(argv[i] + 1);
}
}
*/
initscr();
signal(SIGINT, SIG_IGN);
noecho();
leaveok(stdscr, TRUE);
scrollok(stdscr, FALSE);
for (x = COLS - 1; ; --x) {
for (x = COLS - 1;; --x) {
if (LOGO == 0) {
if (add_D51(x) == ERR) break;
if (add_D51(x) == ERR)
break;
} else {
if (add_sl(x) == ERR) break;
if (add_sl(x) == ERR)
break;
}
refresh();
if (x == COLS / 4) {
@ -195,9 +206,9 @@ int go(int i)
} else {
usleep(sleep_len);
}
}
mvcur(0, COLS - 1, LINES - 1, 0);
endwin();
}
mvcur(0, COLS - 1, LINES - 1, 0);
endwin();
return 0;
}
@ -205,20 +216,20 @@ int go(int i)
int vgo(int i, switch_core_session_t *session)
{
int x;
int x;
int sleep_len = 40000;
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_frame_t *read_frame;
switch_status_t status;
switch_codec_implementation_t read_impl = {0};
switch_codec_t codec = {0};
switch_codec_implementation_t read_impl = { 0 };
switch_codec_t codec = { 0 };
int hangover_hits = 0, hangunder_hits = 0;
int diff_level = 400;
int hangover = 40, hangunder = 15;
int talking = 0;
int energy_level = 500;
int done = 0;
switch_core_session_get_read_impl(session, &read_impl);
switch_core_session_get_read_impl(session, &read_impl);
printf("%s", SWITCH_SEQ_CLEARSCR);
@ -226,16 +237,16 @@ int vgo(int i, switch_core_session_t *session)
sleep_len = i;
}
initscr();
signal(SIGINT, SIG_IGN);
noecho();
leaveok(stdscr, TRUE);
scrollok(stdscr, FALSE);
initscr();
signal(SIGINT, SIG_IGN);
noecho();
leaveok(stdscr, TRUE);
scrollok(stdscr, FALSE);
if (switch_core_codec_init(&codec,
"L16",
NULL, (int) read_impl.samples_per_second, read_impl.microseconds_per_packet / 1000,
NULL, (int) read_impl.samples_per_second, read_impl.microseconds_per_packet / 1000,
1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
return -1;
@ -243,28 +254,27 @@ int vgo(int i, switch_core_session_t *session)
switch_core_session_set_read_codec(session, &codec);
for (x = COLS - 1; ; --x) {
for (x = COLS - 1;; --x) {
if (!done && !switch_channel_ready(channel)) {
done = 1;
}
if (!done) {
status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
if (!SWITCH_READ_ACCEPTABLE(status)) {
done = 1;
}
}
if (!done)
{
if (!done) {
int16_t *fdata = (int16_t *) read_frame->data;
uint32_t samples = read_frame->datalen / sizeof(*fdata);
uint32_t score, count = 0, j = 0;
double energy = 0;
int divisor = 0;
for (count = 0; count < samples; count++) {
energy += abs(fdata[j]);
j += read_impl.number_of_channels;
@ -275,7 +285,7 @@ int vgo(int i, switch_core_session_t *session)
}
score = (uint32_t) (energy / (samples / divisor));
if (score > energy_level) {
uint32_t diff = score - energy_level;
if (hangover_hits) {
@ -284,7 +294,7 @@ int vgo(int i, switch_core_session_t *session)
if (diff >= diff_level || ++hangunder_hits >= hangunder) {
hangover_hits = hangunder_hits = 0;
if (!talking) {
talking = 1;
}
@ -310,22 +320,24 @@ int vgo(int i, switch_core_session_t *session)
}
if (LOGO == 0) {
if (add_D51(x) == ERR) break;
if (add_D51(x) == ERR)
break;
} else {
if (add_sl(x) == ERR) break;
if (add_sl(x) == ERR)
break;
}
refresh();
/*
if (x == COLS / 4) {
sleep(2);
} else {
usleep(sleep_len);
}
*/
}
mvcur(0, COLS - 1, LINES - 1, 0);
endwin();
if (x == COLS / 4) {
sleep(2);
} else {
usleep(sleep_len);
}
*/
}
mvcur(0, COLS - 1, LINES - 1, 0);
endwin();
switch_core_session_set_read_codec(session, NULL);
switch_core_codec_destroy(&codec);
@ -335,103 +347,114 @@ int vgo(int i, switch_core_session_t *session)
int add_sl(int x)
{
static char *sl[LOGOPATTERNS][LOGOHIGHT + 1]
= {{LOGO1, LOGO2, LOGO3, LOGO4, LWHL11, LWHL12, DELLN},
{LOGO1, LOGO2, LOGO3, LOGO4, LWHL21, LWHL22, DELLN},
{LOGO1, LOGO2, LOGO3, LOGO4, LWHL31, LWHL32, DELLN},
{LOGO1, LOGO2, LOGO3, LOGO4, LWHL41, LWHL42, DELLN},
{LOGO1, LOGO2, LOGO3, LOGO4, LWHL51, LWHL52, DELLN},
{LOGO1, LOGO2, LOGO3, LOGO4, LWHL61, LWHL62, DELLN}};
static char *sl[LOGOPATTERNS][LOGOHIGHT + 1]
= { {LOGO1, LOGO2, LOGO3, LOGO4, LWHL11, LWHL12, DELLN},
{LOGO1, LOGO2, LOGO3, LOGO4, LWHL21, LWHL22, DELLN},
{LOGO1, LOGO2, LOGO3, LOGO4, LWHL31, LWHL32, DELLN},
{LOGO1, LOGO2, LOGO3, LOGO4, LWHL41, LWHL42, DELLN},
{LOGO1, LOGO2, LOGO3, LOGO4, LWHL51, LWHL52, DELLN},
{LOGO1, LOGO2, LOGO3, LOGO4, LWHL61, LWHL62, DELLN}
};
static char *coal[LOGOHIGHT + 1]
= {LCOAL1, LCOAL2, LCOAL3, LCOAL4, LCOAL5, LCOAL6, DELLN};
static char *coal[LOGOHIGHT + 1]
= { LCOAL1, LCOAL2, LCOAL3, LCOAL4, LCOAL5, LCOAL6, DELLN };
static char *car[LOGOHIGHT + 1]
= {LCAR1, LCAR2, LCAR3, LCAR4, LCAR5, LCAR6, DELLN};
static char *car[LOGOHIGHT + 1]
= { LCAR1, LCAR2, LCAR3, LCAR4, LCAR5, LCAR6, DELLN };
int i, y, py1 = 0, py2 = 0, py3 = 0;
if (x < - LOGOLENGTH) return ERR;
y = LINES / 2 - 3;
int i, y, py1 = 0, py2 = 0, py3 = 0;
if (FLY == 1) {
if (x < -LOGOLENGTH)
return ERR;
y = LINES / 2 - 3;
if (FLY == 1) {
y = (x / 6) + LINES - (COLS / 6) - LOGOHIGHT;
py1 = 2; py2 = 4; py3 = 6;
}
py1 = 2;
py2 = 4;
py3 = 6;
}
for (i = 0; i <= LOGOHIGHT; ++i) {
for (i = 0; i <= LOGOHIGHT; ++i) {
my_mvaddstr(y + i, x, sl[(LOGOLENGTH + x) / 3 % LOGOPATTERNS][i]);
my_mvaddstr(y + i + py1, x + 21, coal[i]);
my_mvaddstr(y + i + py2, x + 42, car[i]);
my_mvaddstr(y + i + py3, x + 63, car[i]);
}
if (ACCIDENT == 1) {
}
if (ACCIDENT == 1) {
add_man(y + 1, x + 14);
add_man(y + 1 + py2, x + 45); add_man(y + 1 + py2, x + 53);
add_man(y + 1 + py3, x + 66); add_man(y + 1 + py3, x + 74);
}
add_smoke(y - 1, x + LOGOFUNNEL);
return OK;
add_man(y + 1 + py2, x + 45);
add_man(y + 1 + py2, x + 53);
add_man(y + 1 + py3, x + 66);
add_man(y + 1 + py3, x + 74);
}
add_smoke(y - 1, x + LOGOFUNNEL);
return OK;
}
static int loops = 0;
int add_D51(int x)
{
static char *d51[D51PATTERNS][D51HIGHT + 1]
= {{D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL11, D51WHL12, D51WHL13, D51DEL},
{D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL21, D51WHL22, D51WHL23, D51DEL},
{D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL31, D51WHL32, D51WHL33, D51DEL},
{D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL41, D51WHL42, D51WHL43, D51DEL},
{D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL51, D51WHL52, D51WHL53, D51DEL},
{D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL61, D51WHL62, D51WHL63, D51DEL}};
static char *coal[D51HIGHT + 1]
= {COAL01, COAL02, COAL03, COAL04, COAL05,
COAL06, COAL07, COAL08, COAL09, COAL10, COALDEL};
static char *d51[D51PATTERNS][D51HIGHT + 1]
= { {D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL11, D51WHL12, D51WHL13, D51DEL},
{D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL21, D51WHL22, D51WHL23, D51DEL},
{D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL31, D51WHL32, D51WHL33, D51DEL},
{D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL41, D51WHL42, D51WHL43, D51DEL},
{D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL51, D51WHL52, D51WHL53, D51DEL},
{D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7,
D51WHL61, D51WHL62, D51WHL63, D51DEL}
};
static char *coal[D51HIGHT + 1]
= { COAL01, COAL02, COAL03, COAL04, COAL05,
COAL06, COAL07, COAL08, COAL09, COAL10, COALDEL
};
static char *acoal[D51HIGHT + 1]
= {COAL01, COAL02, COAL03, COAL04, COAL5A,
COAL06, COAL07, COAL08, COAL09, COAL10, COALDEL};
static char *acoal[D51HIGHT + 1]
= { COAL01, COAL02, COAL03, COAL04, COAL5A,
COAL06, COAL07, COAL08, COAL09, COAL10, COALDEL
};
int y, i, dy = 0;
int y, i, dy = 0;
if (x < - D51LENGTH) return ERR;
y = LINES / 2 - 5;
if (x < -D51LENGTH)
return ERR;
y = LINES / 2 - 5;
if (FLY == 1) {
if (FLY == 1) {
y = (x / 7) + LINES - (COLS / 7) - D51HIGHT;
dy = 1;
}
}
for (i = 0; i <= D51HIGHT; ++i) {
for (i = 0; i <= D51HIGHT; ++i) {
my_mvaddstr(y + i, x, d51[(D51LENGTH + x) % D51PATTERNS][i]);
my_mvaddstr(y + i + dy, x + 53, loops > 60 ? coal[i] : acoal[i]);
loops++;
if (loops == 500) loops = -100;
}
if (ACCIDENT == 1) {
if (loops == 500)
loops = -100;
}
if (ACCIDENT == 1) {
add_man(y + 2, x + 43);
add_man(y + 2, x + 47);
}
add_smoke(y - 1, x + D51FUNNEL);
return OK;
}
add_smoke(y - 1, x + D51FUNNEL);
return OK;
}
int add_man(int y, int x)
{
static char *man[2][2] = {{"", "(O)"}, {"Help!", "\\O/"}};
int i;
static char *man[2][2] = { {"", "(O)"}, {"Help!", "\\O/"} };
int i;
for (i = 0; i < 2; ++i) {
for (i = 0; i < 2; ++i) {
my_mvaddstr(y + i, x, man[(LOGOLENGTH + x) / 12 % 2][i]);
}
}
return 0;
}
@ -440,45 +463,51 @@ int add_man(int y, int x)
int add_smoke(int y, int x)
#define SMOKEPTNS 16
{
static struct smokes {
static struct smokes {
int y, x;
int ptrn, kind;
} S[1000];
static int sum = 0;
static char *Smoke[2][SMOKEPTNS]
= {{"( )", "( )", "( )", "( )", "( )",
"( )" , "( )" , "( )" , "()" , "()" ,
"O" , "O" , "O" , "O" , "O" ,
" " },
{"(@@@)", "(@@@@)", "(@@@@)", "(@@@)", "(@@)",
"(@@)" , "(@)" , "(@)" , "@@" , "@@" ,
"@" , "@" , "@" , "@" , "@" ,
" " }};
static char *Eraser[SMOKEPTNS]
= {" ", " ", " ", " ", " ",
" " , " " , " " , " " , " " ,
" " , " " , " " , " " , " " ,
" " };
static int dy[SMOKEPTNS] = { 2, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0 };
static int dx[SMOKEPTNS] = {-2, -1, 0, 1, 1, 1, 1, 1, 2, 2,
2, 2, 2, 3, 3, 3 };
int i;
} S[1000];
static int sum = 0;
static char *Smoke[2][SMOKEPTNS]
= { {"( )", "( )", "( )", "( )", "( )",
"( )", "( )", "( )", "()", "()",
"O", "O", "O", "O", "O",
" "},
{"(@@@)", "(@@@@)", "(@@@@)", "(@@@)", "(@@)",
"(@@)", "(@)", "(@)", "@@", "@@",
"@", "@", "@", "@", "@",
" "}
};
static char *Eraser[SMOKEPTNS]
= { " ", " ", " ", " ", " ",
" ", " ", " ", " ", " ",
" ", " ", " ", " ", " ",
" "
};
static int dy[SMOKEPTNS] = { 2, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0
};
static int dx[SMOKEPTNS] = { -2, -1, 0, 1, 1, 1, 1, 1, 2, 2,
2, 2, 2, 3, 3, 3
};
int i;
if (x % 4 == 0) {
if (x % 4 == 0) {
for (i = 0; i < sum; ++i) {
my_mvaddstr(S[i].y, S[i].x, Eraser[S[i].ptrn]);
S[i].y -= dy[S[i].ptrn];
S[i].x += dx[S[i].ptrn];
S[i].y -= dy[S[i].ptrn];
S[i].x += dx[S[i].ptrn];
S[i].ptrn += (S[i].ptrn < SMOKEPTNS - 1) ? 1 : 0;
my_mvaddstr(S[i].y, S[i].x, Smoke[S[i].kind][S[i].ptrn]);
}
my_mvaddstr(y, x, Smoke[sum % 2][0]);
S[sum].y = y; S[sum].x = x;
S[sum].ptrn = 0; S[sum].kind = sum % 2;
sum ++;
}
S[sum].y = y;
S[sum].x = x;
S[sum].ptrn = 0;
S[sum].kind = sum % 2;
sum++;
}
return 0;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -28,7 +28,7 @@
* mod_curl.c -- API for performing http queries
*
*/
#include <switch.h>
#include <curl/curl.h>
#include <json.h>
@ -75,13 +75,12 @@ static size_t file_callback(void *ptr, size_t size, size_t nmemb, void *data)
http_data->bytes += realsize;
if (http_data->bytes > http_data->max_bytes) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Oversized file detected [%d bytes]\n", (int)http_data->bytes);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Oversized file detected [%d bytes]\n", (int) http_data->bytes);
http_data->err = 1;
return 0;
}
http_data->stream.write_function(
&http_data->stream, "%.*s", realsize, ptr);
http_data->stream.write_function(&http_data->stream, "%.*s", realsize, ptr);
return realsize;
}
@ -90,18 +89,19 @@ static size_t header_callback(void *ptr, size_t size, size_t nmemb, void *data)
register unsigned int realsize = (unsigned int) (size * nmemb);
http_data_t *http_data = data;
char *header = NULL;
header = switch_core_alloc(http_data->pool, realsize+1);
header = switch_core_alloc(http_data->pool, realsize + 1);
switch_copy_string(header, ptr, realsize);
header[realsize] = '\0';
http_data->headers = curl_slist_append(http_data->headers, header);
return realsize;
}
static http_data_t *do_lookup_url(switch_memory_pool_t *pool, const char *url, const char *method, const char *data) {
static http_data_t *do_lookup_url(switch_memory_pool_t *pool, const char *url, const char *method, const char *data)
{
CURL *curl_handle = NULL;
long httpRes = 0;
char hostname[256] = "";
@ -111,19 +111,19 @@ static http_data_t *do_lookup_url(switch_memory_pool_t *pool, const char *url, c
http_data = switch_core_alloc(pool, sizeof(http_data_t));
memset(http_data, 0, sizeof(http_data_t));
http_data->pool = pool;
http_data->max_bytes = 64000;
SWITCH_STANDARD_STREAM(http_data->stream);
gethostname(hostname, sizeof(hostname));
if (!method) {
method = "get";
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "method: %s, url: %s\n", method, url);
curl_handle = curl_easy_init();
if (!strncasecmp(url, "https", 5)) {
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
@ -150,54 +150,53 @@ static http_data_t *do_lookup_url(switch_memory_pool_t *pool, const char *url, c
curl_easy_perform(curl_handle);
curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &httpRes);
curl_easy_cleanup(curl_handle);
if ( http_data->stream.data &&
!zstr((char *)http_data->stream.data) &&
strcmp(" ", http_data->stream.data) ) {
if (http_data->stream.data && !zstr((char *) http_data->stream.data) && strcmp(" ", http_data->stream.data)) {
http_data->http_response = switch_core_strdup(pool, http_data->stream.data);
}
http_data->http_response_code = httpRes;
switch_safe_free(http_data->stream.data);
return http_data;
}
static char *print_json(switch_memory_pool_t *pool, http_data_t *http_data) {
static char *print_json(switch_memory_pool_t *pool, http_data_t *http_data)
{
struct json_object *top = NULL;
struct json_object *headers = NULL;
char *data = NULL;
struct curl_slist *header = http_data->headers;
top = json_object_new_object();
headers = json_object_new_array();
json_object_object_add(top, "status_code", json_object_new_int(http_data->http_response_code));
if (http_data->http_response) {
json_object_object_add(top, "body", json_object_new_string(http_data->http_response));
}
/* parse header data */
while(header) {
while (header) {
struct json_object *obj = NULL;
/* remove trailing \r */
if ((data=rindex(header->data, '\r'))) {
if ((data = rindex(header->data, '\r'))) {
*data = '\0';
}
if (zstr(header->data)) {
header = header->next;
continue;
}
if ((data = index(header->data, ':'))) {
*data = '\0';
data++;
while(*data == ' ' && *data != '\0') {
while (*data == ' ' && *data != '\0') {
data++;
}
obj = json_object_new_object();
obj = json_object_new_object();
json_object_object_add(obj, "key", json_object_new_string(header->data));
json_object_object_add(obj, "value", json_object_new_string(data));
json_object_array_add(headers, obj);
@ -223,15 +222,15 @@ static char *print_json(switch_memory_pool_t *pool, http_data_t *http_data) {
}
json_object_object_add(top, "headers", headers);
data = switch_core_strdup(pool, json_object_to_json_string(top));
json_object_put(top); /* should free up all children */
json_object_put(top); /* should free up all children */
return data;
}
SWITCH_STANDARD_APP(curl_app_function)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
char *argv[10] = { 0 };
int argc;
char *mydata = NULL;
@ -247,8 +246,8 @@ SWITCH_STANDARD_APP(curl_app_function)
struct curl_slist *slist = NULL;
switch_stream_handle_t stream = { 0 };
int i = 0;
if (session) {
pool = switch_core_session_get_pool(session);
} else {
@ -257,24 +256,23 @@ SWITCH_STANDARD_APP(curl_app_function)
if (!(mydata = switch_core_session_strdup(session, data))) {
return;
}
if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
if (argc == 0) {
switch_goto_status(SWITCH_STATUS_SUCCESS, usage);
}
url = switch_core_strdup(pool, argv[0]);
for (i =1; i < argc; i++) {
for (i = 1; i < argc; i++) {
if (!strcasecmp("headers", argv[i])) {
do_headers = SWITCH_TRUE;
} else if (!strcasecmp("json", argv[i])) {
do_json = SWITCH_TRUE;
} else if ( !strcasecmp("get", argv[i]) ||
!strcasecmp("head", argv[i])) {
} else if (!strcasecmp("get", argv[i]) || !strcasecmp("head", argv[i])) {
method = switch_core_strdup(pool, argv[i]);
} else if (!strcasecmp("post", argv[i])) {
if ( ++i < argc) {
if (++i < argc) {
postdata = switch_core_strdup(pool, argv[i]);
switch_url_decode(postdata);
} else {
@ -283,7 +281,7 @@ SWITCH_STANDARD_APP(curl_app_function)
}
}
}
http_data = do_lookup_url(pool, url, method, postdata);
if (do_json) {
switch_channel_set_variable(channel, "curl_response_data", print_json(pool, http_data));
@ -291,7 +289,7 @@ SWITCH_STANDARD_APP(curl_app_function)
SWITCH_STANDARD_STREAM(stream);
if (do_headers) {
slist = http_data->headers;
while(slist) {
while (slist) {
stream.write_function(&stream, "%s\n", slist->data);
slist = slist->next;
}
@ -300,17 +298,16 @@ SWITCH_STANDARD_APP(curl_app_function)
stream.write_function(&stream, "%s", http_data->http_response ? http_data->http_response : "");
switch_channel_set_variable(channel, "curl_response_data", stream.data);
}
switch_channel_set_variable(channel, "curl_response_code",
switch_core_sprintf(pool, "%ld", http_data->http_response_code));
switch_channel_set_variable(channel, "curl_response_code", switch_core_sprintf(pool, "%ld", http_data->http_response_code));
switch_channel_set_variable(channel, "curl_method", method);
switch_goto_status(SWITCH_STATUS_SUCCESS, done);
usage:
usage:
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Usage: %s\n", SYNTAX);
switch_goto_status(status, done);
done:
done:
switch_safe_free(stream.data);
if (http_data && http_data->headers) {
curl_slist_free_all(http_data->headers);
@ -319,6 +316,7 @@ done:
switch_core_destroy_memory_pool(&pool);
}
}
SWITCH_STANDARD_API(curl_function)
{
switch_status_t status;
@ -335,7 +333,7 @@ SWITCH_STANDARD_API(curl_function)
int i = 0;
switch_memory_pool_t *pool = NULL;
if (zstr(cmd)) {
switch_goto_status(SWITCH_STATUS_SUCCESS, usage);
}
@ -351,20 +349,19 @@ SWITCH_STANDARD_API(curl_function)
if (argc < 1) {
switch_goto_status(SWITCH_STATUS_SUCCESS, usage);
}
url = switch_core_strdup(pool, argv[0]);
for (i =1; i < argc; i++) {
for (i = 1; i < argc; i++) {
if (!strcasecmp("headers", argv[i])) {
do_headers = SWITCH_TRUE;
} else if (!strcasecmp("json", argv[i])) {
do_json = SWITCH_TRUE;
} else if ( !strcasecmp("get", argv[i]) ||
!strcasecmp("head", argv[i])) {
} else if (!strcasecmp("get", argv[i]) || !strcasecmp("head", argv[i])) {
method = switch_core_strdup(pool, argv[i]);
} else if (!strcasecmp("post", argv[i])) {
method = "post";
if ( ++i < argc) {
if (++i < argc) {
postdata = switch_core_strdup(pool, argv[i]);
switch_url_decode(postdata);
} else {
@ -372,14 +369,14 @@ SWITCH_STANDARD_API(curl_function)
}
}
}
http_data = do_lookup_url(pool, url, method, postdata);
if (do_json) {
stream->write_function(stream, "%s", print_json(pool, http_data));
} else {
if (do_headers) {
slist = http_data->headers;
while(slist) {
while (slist) {
stream->write_function(stream, "%s\n", slist->data);
slist = slist->next;
}
@ -390,11 +387,11 @@ SWITCH_STANDARD_API(curl_function)
}
switch_goto_status(SWITCH_STATUS_SUCCESS, done);
usage:
usage:
stream->write_function(stream, "-ERR\n%s\n", SYNTAX);
switch_goto_status(status, done);
done:
done:
if (http_data && http_data->headers) {
curl_slist_free_all(http_data->headers);
}
@ -414,7 +411,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_curl_load)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
memset(&globals, 0, sizeof(globals));
globals.pool = pool;
SWITCH_ADD_API(api_interface, "curl", "curl API", curl_function, SYNTAX);

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -40,19 +40,16 @@ SWITCH_MODULE_DEFINITION(mod_directory, mod_directory_load, mod_directory_shutdo
static const char *global_cf = "directory.conf";
static char dir_sql[] =
"CREATE TABLE directory_search (\n"
" hostname VARCHAR(255),\n"
" uuid VARCHAR(255),\n"
" extension VARCHAR(255),\n"
" full_name VARCHAR(255),\n"
" full_name_digit VARCHAR(255),\n"
" first_name VARCHAR(255),\n"
" first_name_digit VARCHAR(255),\n"
" last_name VARCHAR(255),\n"
" last_name_digit VARCHAR(255),\n"
" name_visible INTEGER,\n"
" exten_visible INTEGER\n"
");\n";
"CREATE TABLE directory_search (\n"
" hostname VARCHAR(255),\n"
" uuid VARCHAR(255),\n"
" extension VARCHAR(255),\n"
" full_name VARCHAR(255),\n"
" full_name_digit VARCHAR(255),\n"
" first_name VARCHAR(255),\n"
" first_name_digit VARCHAR(255),\n"
" last_name VARCHAR(255),\n"
" last_name_digit VARCHAR(255),\n" " name_visible INTEGER,\n" " exten_visible INTEGER\n" ");\n";
#define DIR_RESULT_ITEM "directory_result_item"
#define DIR_RESULT_SAY_NAME "directory_result_say_name"
@ -113,51 +110,52 @@ typedef enum {
PFLAG_DESTROY = 1 << 0
} dir_flags_t;
static int digit_matching_keypad(char letter) {
static int digit_matching_keypad(char letter)
{
int result = -1;
switch(toupper(letter)) {
case 'A':
case 'B':
case 'C':
result = 2;
break;
case 'D':
case 'E':
case 'F':
result = 3;
break;
case 'G':
case 'H':
case 'I':
result = 4;
break;
case 'J':
case 'K':
case 'L':
result = 5;
break;
case 'M':
case 'N':
case 'O':
result = 6;
break;
case 'P':
case 'Q':
case 'R':
case 'S':
result = 7;
break;
case 'T':
case 'U':
case 'V':
result = 8;
break;
case 'W':
case 'X':
case 'Y':
case 'Z':
result = 9;
break;
switch (toupper(letter)) {
case 'A':
case 'B':
case 'C':
result = 2;
break;
case 'D':
case 'E':
case 'F':
result = 3;
break;
case 'G':
case 'H':
case 'I':
result = 4;
break;
case 'J':
case 'K':
case 'L':
result = 5;
break;
case 'M':
case 'N':
case 'O':
result = 6;
break;
case 'P':
case 'Q':
case 'R':
case 'S':
result = 7;
break;
case 'T':
case 'U':
case 'V':
result = 8;
break;
case 'W':
case 'X':
case 'Y':
case 'Z':
result = 9;
break;
}
@ -185,7 +183,7 @@ char *string_to_keypad_digit(const char *in)
if (*d) {
*d = '\0';
}
}
}
return dst;
}
@ -206,7 +204,7 @@ static switch_status_t directory_execute_sql(char *sql, switch_mutex_t *mutex)
status = switch_core_db_persistant_execute(db, sql, 1);
switch_core_db_close(db);
end:
end:
if (mutex) {
switch_mutex_unlock(mutex);
}
@ -304,7 +302,7 @@ static switch_bool_t directory_execute_sql_callback(switch_mutex_t *mutex, char
switch_core_db_close(db);
}
end:
end:
if (mutex) {
switch_mutex_unlock(mutex);
}
@ -337,34 +335,32 @@ dir_profile_t *profile_set_config(dir_profile_t *profile)
profile->config_str_pool.pool = profile->pool;
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "next-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
&profile->next_key, "6", &config_dtmf, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "prev-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
&profile->prev_key, "4", &config_dtmf, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "next-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &profile->next_key, "6", &config_dtmf, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "prev-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &profile->prev_key, "4", &config_dtmf, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "terminator-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
&profile->terminator_key, "#", &config_dtmf, NULL, NULL);
&profile->terminator_key, "#", &config_dtmf, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "switch-order-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
&profile->switch_order_key, "*", &config_dtmf, NULL, NULL);
&profile->switch_order_key, "*", &config_dtmf, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "select-name-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
&profile->select_name_key, "1", &config_dtmf, NULL, NULL);
&profile->select_name_key, "1", &config_dtmf, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "new-search-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
&profile->new_search_key, "3", &config_dtmf, NULL, NULL);
&profile->new_search_key, "3", &config_dtmf, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "search-order", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE,
&profile->search_order, "last_name", &profile->config_str_pool, NULL, NULL);
&profile->search_order, "last_name", &profile->config_str_pool, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "digit-timeout", SWITCH_CONFIG_INT, CONFIG_RELOADABLE,
&profile->digit_timeout, 3000, &config_int_digit_timeout, NULL, NULL);
&profile->digit_timeout, 3000, &config_int_digit_timeout, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "min-search-digits", SWITCH_CONFIG_INT, CONFIG_RELOADABLE,
&profile->min_search_digits, 3, &config_int_ht_0, NULL, NULL);
&profile->min_search_digits, 3, &config_int_ht_0, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "max-menu-attempts", SWITCH_CONFIG_INT, CONFIG_RELOADABLE,
&profile->max_menu_attempt, 3, &config_int_ht_0, NULL, NULL);
&profile->max_menu_attempt, 3, &config_int_ht_0, NULL, NULL);
SWITCH_CONFIG_SET_ITEM(profile->config[i++], "max-result", SWITCH_CONFIG_INT, CONFIG_RELOADABLE,
&profile->max_result, 5, &config_int_ht_0, NULL, NULL);
&profile->max_result, 5, &config_int_ht_0, NULL, NULL);
return profile;
}
static dir_profile_t * load_profile(const char *profile_name)
static dir_profile_t *load_profile(const char *profile_name)
{
dir_profile_t *profile = NULL;
switch_xml_t x_profiles, x_profile, cfg, xml = NULL;
@ -413,7 +409,7 @@ static dir_profile_t * load_profile(const char *profile_name)
switch_core_hash_insert(globals.profile_hash, profile->name, profile);
}
end:
end:
switch_xml_free(xml);
return profile;
@ -451,7 +447,7 @@ static switch_status_t load_config(switch_bool_t reload)
return SWITCH_STATUS_SUCCESS;
}
static dir_profile_t * get_profile(const char *profile_name)
static dir_profile_t *get_profile(const char *profile_name)
{
dir_profile_t *profile = NULL;
@ -469,7 +465,8 @@ static dir_profile_t * get_profile(const char *profile_name)
return profile;
}
static switch_status_t populate_database(switch_core_session_t *session, dir_profile_t * profile, const char *domain_name) {
static switch_status_t populate_database(switch_core_session_t *session, dir_profile_t *profile, const char *domain_name)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
char *sql = NULL;
@ -561,8 +558,9 @@ static switch_status_t populate_database(switch_core_session_t *session, dir_pro
firstNameDigit = string_to_keypad_digit(firstName);
/* add user into DB */
sql = switch_mprintf("insert into directory_search values('%q','%q','%q','%q','%q','%q','%q','%q','%q','%d','%d')",
globals.hostname, switch_core_session_get_uuid(session), id, fullName, fullNameDigit, firstName, firstNameDigit, lastName, lastNameDigit, name_visible, exten_visible);
sql = switch_mprintf("insert into directory_search values('%q','%q','%q','%q','%q','%q','%q','%q','%q','%d','%d')",
globals.hostname, switch_core_session_get_uuid(session), id, fullName, fullNameDigit, firstName, firstNameDigit,
lastName, lastNameDigit, name_visible, exten_visible);
if (sqlvalues) {
sqltmp = sqlvalues;
@ -580,10 +578,10 @@ static switch_status_t populate_database(switch_core_session_t *session, dir_pro
}
}
}
sql = switch_mprintf("BEGIN;%s;COMMIT;",sqlvalues);
sql = switch_mprintf("BEGIN;%s;COMMIT;", sqlvalues);
directory_execute_sql(sql, profile->mutex);
end:
end:
switch_safe_free(sql);
switch_safe_free(sqlvalues);
switch_event_destroy(&xml_params);
@ -603,27 +601,27 @@ typedef struct cb_result cbr_t;
static switch_status_t on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
{
switch (itype) {
case SWITCH_INPUT_TYPE_DTMF:
{
switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
cbr_t *cbr = (cbr_t *) buf;
cbr->digit = dtmf->digit;
if (dtmf->digit == *cbr->profile->terminator_key || dtmf->digit == *cbr->profile->switch_order_key) {
return SWITCH_STATUS_BREAK;
}
if (strlen(cbr->digits) < sizeof(cbr->digits) - 2) {
int at = strlen(cbr->digits);
cbr->digits[at++] = dtmf->digit;
cbr->digits[at] = '\0';
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "DTMF buffer is full\n");
return SWITCH_STATUS_BREAK;
}
case SWITCH_INPUT_TYPE_DTMF:
{
switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
cbr_t *cbr = (cbr_t *) buf;
cbr->digit = dtmf->digit;
if (dtmf->digit == *cbr->profile->terminator_key || dtmf->digit == *cbr->profile->switch_order_key) {
return SWITCH_STATUS_BREAK;
}
break;
default:
break;
if (strlen(cbr->digits) < sizeof(cbr->digits) - 2) {
int at = strlen(cbr->digits);
cbr->digits[at++] = dtmf->digit;
cbr->digits[at] = '\0';
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "DTMF buffer is full\n");
return SWITCH_STATUS_BREAK;
}
}
break;
default:
break;
}
return SWITCH_STATUS_BREAK;
@ -650,12 +648,12 @@ static switch_status_t listen_entry(switch_core_session_t *session, dir_profile_
}
if (zstr_buf(buf)) {
switch_snprintf(macro, sizeof(macro), "phrase:%s:%d", DIR_RESULT_ITEM, cbt->want+1);
switch_snprintf(macro, sizeof(macro), "phrase:%s:%d", DIR_RESULT_ITEM, cbt->want + 1);
switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key);
}
if (!zstr_buf(recorded_name) && zstr_buf(buf)) {
switch_ivr_read(session, 0, 1, recorded_name, NULL, buf, sizeof(buf), 1, profile->terminator_key);
switch_ivr_read(session, 0, 1, recorded_name, NULL, buf, sizeof(buf), 1, profile->terminator_key);
}
if (zstr_buf(recorded_name) && zstr_buf(buf)) {
@ -667,7 +665,8 @@ static switch_status_t listen_entry(switch_core_session_t *session, dir_profile_
switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key);
}
if (zstr_buf(buf)) {
switch_snprintf(macro, sizeof(macro), "phrase:%s:%c,%c,%c,%c", DIR_RESULT_MENU, *profile->select_name_key, *profile->next_key, *profile->prev_key, *profile->new_search_key);
switch_snprintf(macro, sizeof(macro), "phrase:%s:%c,%c,%c,%c", DIR_RESULT_MENU, *profile->select_name_key, *profile->next_key, *profile->prev_key,
*profile->new_search_key);
switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), profile->digit_timeout, profile->terminator_key);
}
@ -688,7 +687,8 @@ static switch_status_t listen_entry(switch_core_session_t *session, dir_profile_
return SWITCH_STATUS_SUCCESS;
}
switch_status_t gather_name_digit(switch_core_session_t *session, dir_profile_t *profile, search_params_t *params) {
switch_status_t gather_name_digit(switch_core_session_t *session, dir_profile_t *profile, search_params_t *params)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_status_t status = SWITCH_STATUS_SUCCESS;
cbr_t cbr;
@ -707,7 +707,7 @@ switch_status_t gather_name_digit(switch_core_session_t *session, dir_profile_t
/* Gather the user Name */
switch_snprintf(macro, sizeof(macro), "%s:%c", (params->search_by_last_name?"last_name":"first_name"), *profile->switch_order_key);
switch_snprintf(macro, sizeof(macro), "%s:%c", (params->search_by_last_name ? "last_name" : "first_name"), *profile->switch_order_key);
switch_ivr_phrase_macro(session, DIR_INTRO, macro, NULL, &args);
while (switch_channel_ready(channel)) {
@ -737,7 +737,8 @@ switch_status_t gather_name_digit(switch_core_session_t *session, dir_profile_t
return status;
}
switch_status_t navigate_entrys(switch_core_session_t *session, dir_profile_t *profile, search_params_t *params) {
switch_status_t navigate_entrys(switch_core_session_t *session, dir_profile_t *profile, search_params_t *params)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
char *sql = NULL;
char entry_count[80] = "";
@ -749,7 +750,10 @@ switch_status_t navigate_entrys(switch_core_session_t *session, dir_profile_t *p
cbt.buf = entry_count;
cbt.len = sizeof(entry_count);
sql = switch_mprintf("select count(*) from directory_search where hostname = '%q' and uuid = '%q' and name_visible = 1 and %s like '%q%%'", globals.hostname, switch_core_session_get_uuid(session), (params->search_by_last_name?"last_name_digit":"first_name_digit"), params->digits);
sql =
switch_mprintf("select count(*) from directory_search where hostname = '%q' and uuid = '%q' and name_visible = 1 and %s like '%q%%'",
globals.hostname, switch_core_session_get_uuid(session), (params->search_by_last_name ? "last_name_digit" : "first_name_digit"),
params->digits);
directory_execute_sql_callback(profile->mutex, sql, sql2str_callback, &cbt);
switch_safe_free(sql);
@ -773,7 +777,10 @@ switch_status_t navigate_entrys(switch_core_session_t *session, dir_profile_t *p
memset(&listing_cbt, 0, sizeof(listing_cbt));
listing_cbt.params = params;
sql = switch_mprintf("select extension, full_name, last_name, first_name, name_visible, exten_visible from directory_search where hostname = '%q' and uuid = '%q' and name_visible = 1 and %s like '%q%%' order by last_name, first_name", globals.hostname, switch_core_session_get_uuid(session), (params->search_by_last_name?"last_name_digit":"first_name_digit"), params->digits);
sql =
switch_mprintf
("select extension, full_name, last_name, first_name, name_visible, exten_visible from directory_search where hostname = '%q' and uuid = '%q' and name_visible = 1 and %s like '%q%%' order by last_name, first_name",
globals.hostname, switch_core_session_get_uuid(session), (params->search_by_last_name ? "last_name_digit" : "first_name_digit"), params->digits);
for (cur_entry = 0; cur_entry < result_count; cur_entry++) {
listing_cbt.index = 0;
@ -812,7 +819,7 @@ switch_status_t navigate_entrys(switch_core_session_t *session, dir_profile_t *p
}
}
end:
end:
switch_safe_free(sql);
return status;
@ -825,8 +832,8 @@ SWITCH_STANDARD_APP(directory_function)
char *argv[6] = { 0 };
char *mydata = NULL;
const char *profile_name = NULL;
const char *domain_name = NULL;
dir_profile_t * profile = NULL;
const char *domain_name = NULL;
dir_profile_t *profile = NULL;
int x = 0;
char *sql = NULL;
search_params_t s_param;
@ -866,7 +873,7 @@ SWITCH_STANDARD_APP(directory_function)
s_param.search_by_last_name = 0;
}
attempts = profile->max_menu_attempt;
s_param.try_again = 1;
s_param.try_again = 1;
while (switch_channel_ready(channel) && (s_param.try_again && attempts-- > 0)) {
s_param.try_again = 0;
gather_name_digit(session, profile, &s_param);
@ -895,7 +902,7 @@ SWITCH_STANDARD_APP(directory_function)
sql = switch_mprintf("delete from directory_search where hostname = '%q' and uuid = '%q'", globals.hostname, switch_core_session_get_uuid(session));
directory_execute_sql(sql, profile->mutex);
switch_safe_free(sql);
profile_rwunlock(profile);
profile_rwunlock(profile);
}
SWITCH_MODULE_LOAD_FUNCTION(mod_directory_load)
@ -954,7 +961,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_directory_shutdown)
switch_mutex_lock(globals.mutex);
while((hi = switch_hash_first(NULL, globals.profile_hash))) {
while ((hi = switch_hash_first(NULL, globals.profile_hash))) {
switch_hash_this(hi, &key, &keylen, &val);
profile = (dir_profile_t *) val;

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -64,7 +64,7 @@ struct dist_list {
static void destroy_node(struct dist_node *node)
{
struct dist_node *old;
while(node) {
while (node) {
old = node;
node = node->next;
if (old->name) {
@ -78,7 +78,7 @@ static void destroy_list(struct dist_list *list)
{
struct dist_list *old;
while(list) {
while (list) {
old = list;
list = list->next;
destroy_node(old->nodes);
@ -97,14 +97,14 @@ static struct {
static int load_config(int reloading)
static int load_config(int reloading)
{
struct dist_list *main_list=NULL, *new_list, *old_list=NULL, *lp=NULL;
struct dist_list *main_list = NULL, *new_list, *old_list = NULL, *lp = NULL;
switch_status_t status = SWITCH_STATUS_FALSE;
char *cf = "distributor.conf";
switch_xml_t cfg, xml, lists, list, param;
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
return SWITCH_STATUS_TERM;
@ -120,7 +120,7 @@ static int load_config(int reloading)
for (list = switch_xml_child(lists, "list"); list; list = list->next) {
const char *name = switch_xml_attr(list, "name");
const char *tweight = switch_xml_attr(list, "total-weight");
struct dist_node *node, *np=NULL;
struct dist_node *node, *np = NULL;
int target_weight = 10;
int accum = 0;
@ -128,30 +128,30 @@ static int load_config(int reloading)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing NAME!\n");
continue;
}
if (!zstr(tweight)) {
target_weight = atoi(tweight);
}
switch_zmalloc(new_list, sizeof(*new_list));
new_list->name = strdup(name);
new_list->last = -1;
new_list->target_weight = target_weight;
if (lp) {
lp->next = new_list;
} else {
main_list = new_list;
}
lp = new_list;
for (param = switch_xml_child(list, "node"); param; param = param->next) {
char *name = (char *) switch_xml_attr_soft(param, "name");
char *weight_val = (char *) switch_xml_attr_soft(param, "weight");
int weight = 0, tmp;
if ((tmp = atoi(weight_val)) < 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Weight %d value incorrect, must be > 0\n", tmp);
continue;
@ -163,23 +163,25 @@ static int load_config(int reloading)
}
if (accum + tmp > lp->target_weight) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Target Weight %d already met, ignoring subsequent entries.\n", lp->target_weight);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Target Weight %d already met, ignoring subsequent entries.\n",
lp->target_weight);
continue;
}
accum += tmp;
weight = lp->target_weight - tmp;
if (weight < 0 || weight > lp->target_weight) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Weight %d value incorrect, must be between 1 and %d\n", weight, lp->target_weight);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Weight %d value incorrect, must be between 1 and %d\n", weight,
lp->target_weight);
continue;
}
switch_zmalloc(node, sizeof(*node));
node->name = strdup(name);
node->weight = node->cur_weight = weight;
if (np) {
np->next = node;
@ -198,7 +200,7 @@ static int load_config(int reloading)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Total weight does not add up to total weight %d\n", lp->target_weight);
for(np1 = lp->nodes; np1; np1 = np1->next) {
for (np1 = lp->nodes; np1; np1 = np1->next) {
np1->weight += lp->target_weight - ea;
}
@ -230,7 +232,7 @@ static int reset_list(struct dist_list *list)
{
struct dist_node *np;
for(np = list->nodes; np; np = np->next) {
for (np = list->nodes; np; np = np->next) {
np->cur_weight = np->weight;
}
list->last = -1;
@ -243,8 +245,8 @@ static struct dist_node *find_next(struct dist_list *list)
struct dist_node *np, *match = NULL;
int x = 0, mx = 0;
int matches = 0, loops = 0;
for(;;) {
for (;;) {
if (++loops > 1000) {
break;
@ -255,7 +257,7 @@ static struct dist_node *find_next(struct dist_list *list)
list->last = -1;
}
match = NULL;
for(np = list->nodes; np; np = np->next) {
for (np = list->nodes; np; np = np->next) {
if (np->cur_weight < list->target_weight) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s %d/%d\n", np->name, np->cur_weight, list->target_weight);
matches++;
@ -274,7 +276,7 @@ static struct dist_node *find_next(struct dist_list *list)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Choose %s\n", match->name);
return match;
}
if (matches) {
list->last = -1;
} else {
@ -294,7 +296,7 @@ static char *dist_engine(const char *name)
char *str = NULL;
switch_mutex_lock(globals.mod_lock);
for(lp = globals.list; lp; lp = lp->next) {
for (lp = globals.list; lp; lp = lp->next) {
if (!strcasecmp(name, lp->name)) {
np = find_next(lp);
break;
@ -307,14 +309,14 @@ static char *dist_engine(const char *name)
switch_mutex_unlock(globals.mod_lock);
return str;
}
SWITCH_STANDARD_APP(distributor_exec)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
char *ret = NULL;
if (zstr(data)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "distributor requires an argument\n");
return;
@ -370,11 +372,12 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_distributor_load)
globals.pool = pool;
load_config(SWITCH_FALSE);
SWITCH_ADD_API(api_interface, "distributor", "Distributor API", distributor_function, "<list name>");
SWITCH_ADD_API(api_interface, "distributor_ctl", "Distributor API", distributor_ctl_function, "[reload]");
SWITCH_ADD_APP(app_interface, "distributor", "Distributor APP", "Distributor APP", distributor_exec, "<list name>", SAF_SUPPORT_NOMEDIA|SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "distributor", "Distributor APP", "Distributor APP", distributor_exec, "<list name>",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
/* indicate that the module should continue to be loaded */

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -89,7 +89,7 @@ SWITCH_STANDARD_DIALPLAN(inline_dialplan_hunt)
switch_caller_extension_add_application(session, extension, app, data);
}
caller_profile->destination_number = (char *)caller_profile->rdnis;
caller_profile->destination_number = (char *) caller_profile->rdnis;
caller_profile->rdnis = SWITCH_BLANK_STRING;
return extension;
@ -177,7 +177,8 @@ SWITCH_STANDARD_APP(exe_function)
SWITCH_STANDARD_APP(mkdir_function)
{
switch_dir_make_recursive(data, SWITCH_DEFAULT_DIR_PERMS, switch_core_session_get_pool(session));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s MKDIR: %s\n", switch_channel_get_name(switch_core_session_get_channel(session)), data);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s MKDIR: %s\n",
switch_channel_get_name(switch_core_session_get_channel(session)), data);
}
#define SOFT_HOLD_SYNTAX "<unhold key> [<moh_a>] [<moh_b>]"
@ -276,7 +277,7 @@ SWITCH_STANDARD_APP(dtmf_bind_function)
if (strchr(argv[2], '1')) {
bind_flags |= SBF_ONCE;
}
if (switch_ivr_bind_dtmf_meta_session(session, kval, bind_flags, argv[3]) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Bind Error!\n");
}
@ -375,7 +376,7 @@ SWITCH_STANDARD_APP(eavesdrop_function)
if (e_data.total) {
for (x = 0; x < e_data.total && switch_channel_ready(channel); x++) {
/* If we have a group and 1000 concurrent calls, we will flood the logs. This check avoids this */
if ( !require_group )
if (!require_group)
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Spy: %s\n", e_data.uuid_list[x]);
if ((file = switch_channel_get_variable(channel, "eavesdrop_indicate_new"))) {
switch_ivr_play_file(session, NULL, file, NULL);
@ -437,9 +438,9 @@ SWITCH_STANDARD_APP(set_audio_level_function)
mydata = switch_core_session_strdup(session, data);
argc = switch_split(mydata, ' ', argv);
if (argc != 2) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Error. USAGE: %s\n",
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Error. USAGE: %s\n",
switch_core_session_get_name(session), SET_AUDIO_LEVEL_SYNTAX);
return;
}
@ -447,8 +448,8 @@ SWITCH_STANDARD_APP(set_audio_level_function)
level = atoi(argv[1]);
switch_ivr_session_audio(session, "level", argv[0], level);
}
#define SET_MUTE_SYNTAX "[read|write] [[true|cn level]|false]"
@ -461,19 +462,19 @@ SWITCH_STANDARD_APP(set_mute_function)
mydata = switch_core_session_strdup(session, data);
argc = switch_split(mydata, ' ', argv);
if (argc != 2) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Error. USAGE: %s\n",
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Error. USAGE: %s\n",
switch_core_session_get_name(session), SET_MUTE_SYNTAX);
return;
}
if ((level = atoi(argv[1])) <= 0) {
level = switch_true(argv[1]);
}
switch_ivr_session_audio(session, "mute", argv[0], level);
}
@ -731,7 +732,7 @@ SWITCH_STANDARD_APP(presence_function)
return;
}
switch_channel_presence(channel, argv[0], argv[1], argv[2]);
switch_channel_presence(channel, argv[0], argv[1], argv[2]);
}
SWITCH_STANDARD_APP(pre_answer_function)
@ -787,7 +788,7 @@ SWITCH_STANDARD_APP(deflect_function)
SWITCH_STANDARD_APP(set_function)
{
char *var, *val = NULL;
if (zstr(data)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No variable name specified.\n");
} else {
@ -808,7 +809,8 @@ SWITCH_STANDARD_APP(set_function)
expanded = switch_channel_expand_variables(channel, val);
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s SET [%s]=[%s]\n", switch_channel_get_name(channel), var, expanded ? expanded : "UNDEF");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s SET [%s]=[%s]\n", switch_channel_get_name(channel), var,
expanded ? expanded : "UNDEF");
switch_channel_set_variable_var_check(channel, var, expanded, SWITCH_FALSE);
if (expanded && expanded != val) {
@ -857,7 +859,7 @@ SWITCH_STANDARD_APP(set_profile_var_function)
val = NULL;
}
}
switch_channel_set_profile_var(switch_core_session_get_channel(session), name, val);
}
}
@ -891,8 +893,8 @@ SWITCH_STANDARD_APP(export_function)
}
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "EXPORT %s[%s]=[%s]\n", local ? "" : "(REMOTE ONLY) ", var_name ? var_name : "",
val ? val : "UNDEF");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "EXPORT %s[%s]=[%s]\n", local ? "" : "(REMOTE ONLY) ",
var_name ? var_name : "", val ? val : "UNDEF");
switch_channel_set_variable(channel, var, val);
if (var && val) {
@ -999,11 +1001,11 @@ SWITCH_STANDARD_APP(event_function)
while (*p == ' ')
*p++ = '\0';
val = p;
if (!strcasecmp(var,"Event-Name")) {
if (!strcasecmp(var, "Event-Name")) {
switch_name_event(val, &event->event_id);
switch_event_del_header(event, var);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, var, val);
} else if (!strcasecmp(var,"Event-Subclass")) {
} else if (!strcasecmp(var, "Event-Subclass")) {
size_t len = strlen(val) + 1;
void *new = malloc(len);
switch_assert(new);
@ -1043,7 +1045,8 @@ SWITCH_STANDARD_APP(privacy_function)
switch_clear_flag(caller_profile, SWITCH_CPF_HIDE_NAME);
switch_clear_flag(caller_profile, SWITCH_CPF_HIDE_NUMBER);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "INVALID privacy mode specified. Use a valid mode [no|yes|name|full|number].\n");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
"INVALID privacy mode specified. Use a valid mode [no|yes|name|full|number].\n");
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set Privacy to %s [%d]\n", data, caller_profile->flags);
}
@ -1112,7 +1115,7 @@ SWITCH_STANDARD_API(strftime_api_function)
SWITCH_STANDARD_API(presence_api_function)
{
switch_event_t *event;
char *lbuf = NULL , *argv[4];
char *lbuf = NULL, *argv[4];
int argc = 0;
switch_event_types_t type = SWITCH_EVENT_PRESENCE_IN;
int need = 4;
@ -1158,7 +1161,7 @@ SWITCH_STANDARD_API(presence_api_function)
switch_safe_free(lbuf);
return SWITCH_STATUS_SUCCESS;
error:
error:
switch_safe_free(lbuf);
stream->write_function(stream, "Invalid: presence %s", PRESENCE_USAGE);
@ -1173,8 +1176,7 @@ SWITCH_STANDARD_API(chat_api_function)
if (!zstr(cmd) && (lbuf = strdup(cmd))
&& (argc = switch_separate_string(lbuf, '|', argv, (sizeof(argv) / sizeof(argv[0])))) >= 4) {
if (switch_core_chat_send(argv[0], "dp", argv[1], argv[2], "", argv[3],
!zstr(argv[4]) ? argv[4] : NULL , "") == SWITCH_STATUS_SUCCESS) {
if (switch_core_chat_send(argv[0], "dp", argv[1], argv[2], "", argv[3], !zstr(argv[4]) ? argv[4] : NULL, "") == SWITCH_STATUS_SUCCESS) {
stream->write_function(stream, "Sent");
} else {
stream->write_function(stream, "Error! Message Not Sent");
@ -1206,7 +1208,7 @@ SWITCH_STANDARD_APP(ivr_application_function)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_event_t *params;
const char *name = (const char*)data;
const char *name = (const char *) data;
if (channel) {
switch_xml_t cxml = NULL, cfg = NULL, xml_menus = NULL, xml_menu = NULL;
@ -1234,7 +1236,7 @@ SWITCH_STANDARD_APP(ivr_application_function)
&& switch_ivr_menu_stack_xml_build(xml_ctx, &menu_stack, xml_menus, xml_menu) == SWITCH_STATUS_SUCCESS) {
switch_xml_free(cxml);
cxml = NULL;
switch_ivr_menu_execute(session, menu_stack, (char*)name, NULL);
switch_ivr_menu_execute(session, menu_stack, (char *) name, NULL);
switch_ivr_menu_stack_free(menu_stack);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unable to create menu\n");
@ -1404,7 +1406,7 @@ static switch_status_t on_dtmf(switch_core_session_t *session, void *input, swit
for (p = terminators; p && *p; p++) {
if (*p == dtmf->digit) {
switch_snprintf(sbuf, sizeof(sbuf), "%c", *p);
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, sbuf );
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, sbuf);
return SWITCH_STATUS_BREAK;
}
}
@ -1432,7 +1434,7 @@ SWITCH_STANDARD_APP(sleep_function)
args.input_callback = on_dtmf;
args.buf = buf;
args.buflen = sizeof(buf);
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "" );
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "");
}
switch_ivr_sleep(session, ms, SWITCH_TRUE, &args);
@ -1503,7 +1505,7 @@ SWITCH_STANDARD_APP(speak_function)
args.buf = buf;
args.buflen = sizeof(buf);
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "" );
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "");
switch_ivr_speak_text(session, engine, voice, text, &args);
}
@ -1582,7 +1584,8 @@ static switch_status_t hanguphook(switch_core_session_t *session)
switch_stream_handle_t stream = { 0 };
SWITCH_STANDARD_STREAM(stream);
switch_api_execute("uuid_bridge", id, NULL, &stream);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "\nHangup Command uuid_bridge(%s):\n%s\n", id, switch_str_nil((char *) stream.data));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "\nHangup Command uuid_bridge(%s):\n%s\n", id,
switch_str_nil((char *) stream.data));
switch_safe_free(stream.data);
}
@ -1607,7 +1610,7 @@ SWITCH_STANDARD_APP(att_xfer_function)
switch_channel_set_variable(channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE, bond);
if (switch_ivr_originate(session, &peer_session, &cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL)
if (switch_ivr_originate(session, &peer_session, &cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL)
!= SWITCH_STATUS_SUCCESS || !peer_session) {
goto end;
}
@ -1640,13 +1643,13 @@ SWITCH_STANDARD_APP(att_xfer_function)
switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
switch_snprintf(buf, sizeof(buf), "%s %s", switch_core_session_get_uuid(peer_session), switch_core_session_get_uuid(session));
switch_channel_set_variable(b_channel, "xfer_uuids", buf);
switch_snprintf(buf, sizeof(buf), "%s %s", switch_core_session_get_uuid(peer_session), bond);
switch_channel_set_variable(channel, "xfer_uuids", buf);
switch_core_event_hook_add_state_change(session, hanguphook);
switch_core_event_hook_add_state_change(b_session, hanguphook);
switch_core_session_rwunlock(b_session);
}
}
@ -1654,7 +1657,7 @@ SWITCH_STANDARD_APP(att_xfer_function)
if (!br) {
switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), bond);
}
}
switch_core_session_rwunlock(peer_session);
@ -1813,11 +1816,11 @@ SWITCH_STANDARD_APP(say_function)
if (!zstr(data) && (lbuf = switch_core_session_strdup(session, data))
&& (argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) == 4) {
args.input_callback = on_dtmf;
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "" );
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "");
switch_ivr_say(session, argv[3], argv[0], argv[1], argv[2], &args);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Usage: %s\n", SAY_SYNTAX);
@ -1841,14 +1844,15 @@ SWITCH_STANDARD_APP(phrase_function)
if ((mdata = strchr(macro, ','))) {
*mdata++ = '\0';
}
lang = switch_channel_get_variable(channel, "language");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Execute %s(%s) lang %s\n", macro, switch_str_nil(mdata), switch_str_nil(lang));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Execute %s(%s) lang %s\n", macro, switch_str_nil(mdata),
switch_str_nil(lang));
args.input_callback = on_dtmf;
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "" );
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "");
status = switch_ivr_phrase_macro(session, macro, mdata, lang, &args);
} else {
@ -1878,10 +1882,10 @@ SWITCH_STANDARD_APP(playback_function)
switch_file_handle_t fh = { 0 };
char *p;
const char *file = NULL;
if (data) {
file = switch_core_session_strdup(session, data);
if ((p = strchr(file, '@')) && *(p+1) == '@') {
if ((p = strchr(file, '@')) && *(p + 1) == '@') {
*p = '\0';
p += 2;
if (p && *p) {
@ -1894,7 +1898,7 @@ SWITCH_STANDARD_APP(playback_function)
args.input_callback = on_dtmf;
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "" );
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "");
status = switch_ivr_play_file(session, &fh, file, &args);
@ -1920,8 +1924,8 @@ SWITCH_STANDARD_APP(endless_playback_function)
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_status_t status = SWITCH_STATUS_SUCCESS;
const char *file = data;
while(switch_channel_ready(channel)) {
while (switch_channel_ready(channel)) {
status = switch_ivr_play_file(session, NULL, file, NULL);
if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
@ -1968,7 +1972,7 @@ SWITCH_STANDARD_APP(gentones_function)
args.input_callback = on_dtmf;
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "" );
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "");
switch_ivr_gentones(session, tone_script, loops, &args);
}
@ -2060,7 +2064,7 @@ SWITCH_STANDARD_APP(record_function)
args.input_callback = on_dtmf;
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "" );
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "");
status = switch_ivr_record_file(session, &fh, path, &args, limit);
@ -2071,7 +2075,7 @@ SWITCH_STANDARD_APP(record_function)
SWITCH_STANDARD_APP(preprocess_session_function)
{
switch_ivr_preprocess_session(session, (char *)data);
switch_ivr_preprocess_session(session, (char *) data);
}
SWITCH_STANDARD_APP(record_session_function)
@ -2089,7 +2093,7 @@ SWITCH_STANDARD_APP(record_session_function)
/* Search for a space then a plus followed by only numbers at the end of the path,
if found trim any spaces to the left/right of the plus use the left side as the
path and right side as a time limit on the recording
*/
*/
/* if we find a + and the character before it is a space */
if ((path_end = strrchr(path, '+')) && path_end > path && *(path_end - 1) == ' ') {
@ -2102,7 +2106,7 @@ SWITCH_STANDARD_APP(record_session_function)
path_end--;
/* trim spaces to the left of the plus */
while(path_end > path && *path_end == ' ') {
while (path_end > path && *path_end == ' ') {
path_end--;
}
@ -2165,15 +2169,15 @@ static void *SWITCH_THREAD_FUNC camp_music_thread(switch_thread_t *thread, void
args.input_callback = camp_fire;
args.buf = dbuf;
args.buflen = sizeof(dbuf);
switch_core_session_read_lock(session);
/* don't set this to a local_stream:// or you will not be happy */
if ((greet = switch_channel_get_variable(channel, "campon_announce_sound"))) {
status = switch_ivr_play_file(session, NULL, greet, &args);
}
while(stake->running && switch_channel_ready(channel)) {
while (stake->running && switch_channel_ready(channel)) {
if (status != SWITCH_STATUS_BREAK) {
if (!strcasecmp(moh, "silence")) {
status = switch_ivr_collect_digits_callback(session, &args, 0, 0);
@ -2207,7 +2211,7 @@ SWITCH_STANDARD_APP(audio_bridge_function)
switch_threadattr_t *thd_attr = NULL;
char *camp_data = NULL;
switch_status_t status;
if (zstr(data)) {
return;
}
@ -2218,7 +2222,7 @@ SWITCH_STANDARD_APP(audio_bridge_function)
if ((v_campon = switch_channel_get_variable(caller_channel, "campon")) && switch_true(v_campon)) {
const char *cid_name = NULL;
const char *cid_number = NULL;
if (!(cid_name = switch_channel_get_variable(caller_channel, "effective_caller_id_name"))) {
cid_name = switch_channel_get_variable(caller_channel, "caller_id_name");
}
@ -2239,7 +2243,7 @@ SWITCH_STANDARD_APP(audio_bridge_function)
v_campon_timeout = switch_channel_get_variable(caller_channel, "campon_timeout");
v_campon_sleep = switch_channel_get_variable(caller_channel, "campon_sleep");
v_campon_fallback_exten = switch_channel_get_variable(caller_channel, "campon_fallback_exten");
if (v_campon_retries) {
if ((tmp = atoi(v_campon_retries)) > 0) {
campon_retries = tmp;
@ -2262,10 +2266,10 @@ SWITCH_STANDARD_APP(audio_bridge_function)
camping = 1;
if (cid_name && cid_number) {
camp_data = switch_core_session_sprintf(session, "{origination_caller_id_name='%s',origination_caller_id_number='%s'}%s",
camp_data = switch_core_session_sprintf(session, "{origination_caller_id_name='%s',origination_caller_id_number='%s'}%s",
cid_name, cid_number, data);
} else {
camp_data = (char *)data;
camp_data = (char *) data;
}
if (!(moh = switch_channel_get_variable(caller_channel, "hold_music"))) {
@ -2275,22 +2279,22 @@ SWITCH_STANDARD_APP(audio_bridge_function)
do {
fail = 0;
status = switch_ivr_originate(NULL, &peer_session, &cause, camp_data, campon_timeout, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL);
if (!switch_channel_ready(caller_channel)) {
fail = 1;
break;
}
if (status == SWITCH_STATUS_SUCCESS) {
camping = 0;
break;
} else {
fail = 1;
}
if (camping) {
if (!thread_started && fail && moh && !switch_channel_test_flag(caller_channel, CF_PROXY_MODE) &&
if (!thread_started && fail && moh && !switch_channel_test_flag(caller_channel, CF_PROXY_MODE) &&
!switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA) &&
!switch_true(switch_channel_get_variable(caller_channel, "bypass_media"))) {
switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session));
@ -2311,15 +2315,15 @@ SWITCH_STANDARD_APP(audio_bridge_function)
if (fail) {
int64_t wait = campon_sleep * 1000000;
while(stake.running && wait > 0 && switch_channel_ready(caller_channel)) {
while (stake.running && wait > 0 && switch_channel_ready(caller_channel)) {
switch_yield(100000);
wait -= 100000;
}
}
}
} while (camping && switch_channel_ready(caller_channel));
if (thread) {
stake.running = 0;
switch_channel_set_flag(caller_channel, CF_NOT_READY);
@ -2327,17 +2331,18 @@ SWITCH_STANDARD_APP(audio_bridge_function)
}
switch_channel_clear_flag(caller_channel, CF_NOT_READY);
if (stake.do_xfer && !zstr(v_campon_fallback_exten)) {
switch_ivr_session_transfer(session,
v_campon_fallback_exten,
switch_ivr_session_transfer(session,
v_campon_fallback_exten,
switch_channel_get_variable(caller_channel, "campon_fallback_dialplan"),
switch_channel_get_variable(caller_channel, "campon_fallback_context"));
return;
}
} else {
if ((status = switch_ivr_originate(session, &peer_session, &cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL)) != SWITCH_STATUS_SUCCESS) {
if ((status =
switch_ivr_originate(session, &peer_session, &cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL)) != SWITCH_STATUS_SUCCESS) {
fail = 1;
}
}
@ -2350,23 +2355,23 @@ SWITCH_STANDARD_APP(audio_bridge_function)
'true' to continue on all failures.
'false' to not continue.
A list of codes either names or numbers eg "user_busy,normal_temporary_failure,603"
failure_causes acts as the opposite version
failure_causes acts as the opposite version
EXCEPTION... ATTENDED_TRANSFER never is a reason to continue.......
*/
if (cause != SWITCH_CAUSE_ATTENDED_TRANSFER) {
if (continue_on_fail || failure_causes) {
const char *cause_str;
char cause_num[35] = "";
cause_str = switch_channel_cause2str(cause);
switch_snprintf(cause_num, sizeof(cause_num), "%u", cause);
if (failure_causes) {
char *lbuf = switch_core_session_strdup(session, failure_causes);
char *argv[256] = { 0 };
int argc = switch_separate_string(lbuf, ',', argv, (sizeof(argv) / sizeof(argv[0])));
int i, x = 0;
for (i = 0; i < argc; i++) {
if (!strcasecmp(argv[i], cause_str) || !strcasecmp(argv[i], cause_num)) {
x++;
@ -2374,7 +2379,7 @@ SWITCH_STANDARD_APP(audio_bridge_function)
}
}
if (!x) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
"Failure causes [%s]: Cause: %s\n", failure_causes, cause_str);
return;
}
@ -2388,10 +2393,10 @@ SWITCH_STANDARD_APP(audio_bridge_function)
char *argv[256] = { 0 };
int argc = switch_separate_string(lbuf, ',', argv, (sizeof(argv) / sizeof(argv[0])));
int i;
for (i = 0; i < argc; i++) {
if (!strcasecmp(argv[i], cause_str) || !strcasecmp(argv[i], cause_num)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
"Continue on fail [%s]: Cause: %s\n", continue_on_fail, cause_str);
return;
}
@ -2410,7 +2415,7 @@ SWITCH_STANDARD_APP(audio_bridge_function)
}
return;
} else {
if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) {
switch_ivr_signal_bridge(session, peer_session);
} else {
@ -2439,10 +2444,10 @@ SWITCH_STANDARD_APP(audio_bridge_function)
if (switch_true(switch_channel_get_variable(caller_channel, SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE))) {
switch_channel_set_flag(caller_channel, CF_BYPASS_MEDIA_AFTER_BRIDGE);
}
switch_ivr_multi_threaded_bridge(session, peer_session, func, a_key, b_key);
}
if (peer_session) {
switch_core_session_rwunlock(peer_session);
}
@ -2452,17 +2457,19 @@ SWITCH_STANDARD_APP(audio_bridge_function)
/* fake chan_error */
switch_endpoint_interface_t *error_endpoint_interface;
static switch_call_cause_t error_outgoing_channel(switch_core_session_t *session,
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause);
switch_io_routines_t error_io_routines = {
/*.outgoing_channel */ error_outgoing_channel
};
static switch_call_cause_t error_outgoing_channel(switch_core_session_t *session,
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause)
{
switch_call_cause_t cause = switch_channel_str2cause(outbound_profile->destination_number);
if (cause == SWITCH_CAUSE_NONE) {
@ -2476,17 +2483,19 @@ static switch_call_cause_t error_outgoing_channel(switch_core_session_t *session
/* fake chan_group */
switch_endpoint_interface_t *group_endpoint_interface;
static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session,
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause);
switch_io_routines_t group_io_routines = {
/*.outgoing_channel */ group_outgoing_channel
};
static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session,
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause)
{
char *group = NULL;
switch_call_cause_t cause = SWITCH_CAUSE_NONE;
@ -2501,33 +2510,32 @@ static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session
group = strdup(outbound_profile->destination_number);
if (!group) goto done;
if (!group)
goto done;
if ((domain = strchr(group, '@'))) {
*domain++ = '\0';
} else {
domain = switch_core_get_variable("domain");
}
if (!domain) {
goto done;
}
if (var_event && (skip=switch_event_get_header(var_event, "group_recurse_variables")) && switch_false(skip)) {
if ((var = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) ||
(var = switch_event_get_header(var_event, "leg_timeout"))) {
if (var_event && (skip = switch_event_get_header(var_event, "group_recurse_variables")) && switch_false(skip)) {
if ((var = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) || (var = switch_event_get_header(var_event, "leg_timeout"))) {
timelimit = atoi(var);
}
var_event = NULL;
}
template = switch_mprintf("${group_call(%s@%s)}", group, domain);
if (session) {
switch_channel_t *channel = switch_core_session_get_channel(session);
dest = switch_channel_expand_variables(channel, template);
if ((var = switch_channel_get_variable(channel, SWITCH_CALL_TIMEOUT_VARIABLE)) ||
(var = switch_event_get_header(var_event, "leg_timeout"))) {
if ((var = switch_channel_get_variable(channel, SWITCH_CALL_TIMEOUT_VARIABLE)) || (var = switch_event_get_header(var_event, "leg_timeout"))) {
timelimit = atoi(var);
}
} else if (var_event) {
@ -2542,28 +2550,27 @@ static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session
if (!dest) {
goto done;
}
if (var_event) {
cid_name_override = switch_event_get_header(var_event, "origination_caller_id_name");
cid_num_override = switch_event_get_header(var_event, "origination_caller_id_number");
if ((var = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) ||
(var = switch_event_get_header(var_event, "leg_timeout"))) {
if ((var = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) || (var = switch_event_get_header(var_event, "leg_timeout"))) {
timelimit = atoi(var);
}
}
if ((flags & SOF_FORKED_DIAL)) {
myflags |= SOF_NOBLOCK;
}
if (switch_ivr_originate(session, new_session, &cause, dest, timelimit, NULL,
if (switch_ivr_originate(session, new_session, &cause, dest, timelimit, NULL,
cid_name_override, cid_num_override, NULL, var_event, myflags, cancel_cause) == SWITCH_STATUS_SUCCESS) {
const char *context;
switch_caller_profile_t *cp;
new_channel = switch_core_session_get_channel(*new_session);
if ((context = switch_channel_get_variable(new_channel, "group_context"))) {
if ((cp = switch_channel_get_caller_profile(new_channel))) {
cp->context = switch_core_strdup(cp->pool, context);
@ -2578,9 +2585,9 @@ static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session
if (dest && dest != template) {
switch_safe_free(dest);
}
switch_safe_free(template);
switch_safe_free(group);
switch_safe_free(template);
switch_safe_free(group);
if (cause == SWITCH_CAUSE_NONE) {
cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
@ -2596,7 +2603,8 @@ switch_endpoint_interface_t *user_endpoint_interface;
static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause);
switch_io_routines_t user_io_routines = {
/*.outgoing_channel */ user_outgoing_channel
};
@ -2604,7 +2612,8 @@ switch_io_routines_t user_io_routines = {
static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause)
{
switch_xml_t x_domain = NULL, xml = NULL, x_user = NULL, x_group = NULL, x_param, x_params;
char *user = NULL, *domain = NULL;
@ -2622,22 +2631,22 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
user = strdup(outbound_profile->destination_number);
if (!user) goto done;
if (!user)
goto done;
if ((domain = strchr(user, '@'))) {
*domain++ = '\0';
} else {
domain = switch_core_get_variable("domain");
}
if (!domain) {
goto done;
}
if (var_event && (skip=switch_event_get_header(var_event, "user_recurse_variables")) && switch_false(skip)) {
if ((var = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) ||
(var = switch_event_get_header(var_event, "leg_timeout"))) {
if (var_event && (skip = switch_event_get_header(var_event, "user_recurse_variables")) && switch_false(skip)) {
if ((var = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) || (var = switch_event_get_header(var_event, "leg_timeout"))) {
timelimit = atoi(var);
}
var_event = NULL;
@ -2744,7 +2753,7 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
switch_event_dup(&event, var_event);
switch_event_del_header(event, "dialed_user");
switch_event_del_header(event, "dialed_domain");
if ((varval = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) ||
if ((varval = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) ||
(varval = switch_event_get_header(var_event, "leg_timeout"))) {
timelimit = atoi(varval);
}
@ -2765,10 +2774,12 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
switch_snprintf(stupid, sizeof(stupid), "user/%s", user);
if (switch_stristr(stupid, d_dest)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Waddya Daft? You almost called '%s' in an infinate loop!\n", stupid);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Waddya Daft? You almost called '%s' in an infinate loop!\n",
stupid);
cause = SWITCH_CAUSE_INVALID_IE_CONTENTS;
} else if (switch_ivr_originate(session, new_session, &cause, d_dest, timelimit, NULL,
cid_name_override, cid_num_override, outbound_profile, var_event, myflags, cancel_cause) == SWITCH_STATUS_SUCCESS) {
} else if (switch_ivr_originate(session, new_session, &cause, d_dest, timelimit, NULL,
cid_name_override, cid_num_override, outbound_profile, var_event, myflags,
cancel_cause) == SWITCH_STATUS_SUCCESS) {
const char *context;
switch_caller_profile_t *cp;
@ -2812,7 +2823,7 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
if (params) {
switch_event_destroy(&params);
}
if (var_event && var_event_orig != var_event) {
switch_event_destroy(&var_event);
}
@ -2851,7 +2862,7 @@ SWITCH_STANDARD_APP(wait_for_silence_function)
uint32_t thresh, silence_hits, listen_hits, timeout_ms = 0;
int argc;
char *lbuf = NULL;
if (!zstr(data) && (lbuf = switch_core_session_strdup(session, data))
&& (argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 3) {
thresh = atoi(argv[0]);
@ -2869,8 +2880,8 @@ SWITCH_STANDARD_APP(wait_for_silence_function)
return;
}
}
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Usage: %s\n", WAIT_FOR_SILENCE_SYNTAX);
}
@ -2880,12 +2891,17 @@ static switch_status_t event_chat_send(const char *proto, const char *from, cons
switch_event_t *event;
if (switch_event_create(&event, SWITCH_EVENT_RECV_MESSAGE) == SWITCH_STATUS_SUCCESS) {
if (proto) switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Proto", proto);
if (from) switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "From", from);
if (subject) switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Subject", subject);
if (hint) switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Hint", hint);
if (body) switch_event_add_body(event, "%s", body);
if (to) {
if (proto)
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Proto", proto);
if (from)
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "From", from);
if (subject)
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Subject", subject);
if (hint)
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Hint", hint);
if (body)
switch_event_add_body(event, "%s", body);
if (to) {
const char *v;
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "To", to);
if ((v = switch_core_get_variable(to))) {
@ -2899,18 +2915,18 @@ static switch_status_t event_chat_send(const char *proto, const char *from, cons
switch_event_destroy(&event);
}
return SWITCH_STATUS_MEMERR;
}
static switch_status_t api_chat_send(const char *proto, const char *from, const char *to, const char *subject,
const char *body, const char *type, const char *hint)
{
if (to) {
if (to) {
const char *v;
switch_stream_handle_t stream = { 0 };
char *cmd = NULL, *arg;
if (!(v = switch_core_get_variable(to))) {
v = to;
}
@ -2928,16 +2944,15 @@ static switch_status_t api_chat_send(const char *proto, const char *from, const
switch_api_execute(cmd, arg, NULL, &stream);
if (proto) {
switch_core_chat_send(proto, "api", to, hint && strchr(hint, '/') ? hint : from,
!zstr(type) ? type : NULL, (char *) stream.data, NULL, NULL);
switch_core_chat_send(proto, "api", to, hint && strchr(hint, '/') ? hint : from, !zstr(type) ? type : NULL, (char *) stream.data, NULL, NULL);
}
switch_safe_free(stream.data);
free(cmd);
}
return SWITCH_STATUS_SUCCESS;
}
@ -2998,7 +3013,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_CHAT(chat_interface, "event", event_chat_send);
SWITCH_ADD_CHAT(chat_interface, "api", api_chat_send);
SWITCH_ADD_API(api_interface, "strepoch", "Convert a date string into epoch time", strepoch_api_function, "<string>");
SWITCH_ADD_API(api_interface, "chat", "chat", chat_api_function, "<proto>|<from>|<to>|<message>|[<content-type>]");
SWITCH_ADD_API(api_interface, "strftime", "strftime", strftime_api_function, "<format_string>");
@ -3016,7 +3031,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "check_acl", "Check an ip against an ACL list", "Check an ip against an ACL list", check_acl_function,
"<ip> <acl | cidr> [<hangup_cause>]", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "verbose_events", "Make ALL Events verbose.", "Make ALL Events verbose.", verbose_events_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "verbose_events", "Make ALL Events verbose.", "Make ALL Events verbose.", verbose_events_function, "",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "early_hangup", "Enable early hangup", "", early_hangup_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "sleep", "Pause a channel", SLEEP_LONG_DESC, sleep_function, "<pausemilliseconds>", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "delay_echo", "echo audio at a specified delay", "Delay n ms", delay_function, "<delay ms>", SAF_NONE);
@ -3027,19 +3043,23 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_APP(app_interface, "answer", "Answer the call", "Answer the call for a channel.", answer_function, "", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "hangup", "Hangup the call", "Hangup the call for a channel.", hangup_function, "[<cause>]", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "set_name", "Name the channel", "Name the channel", set_name_function, "<name>", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "presence", "Send Presence", "Send Presence.", presence_function, "<rpid> <status> [<id>]", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "log", "Logs to the logger", LOG_LONG_DESC, log_function, "<log_level> <log_string>", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "presence", "Send Presence", "Send Presence.", presence_function, "<rpid> <status> [<id>]",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "log", "Logs to the logger", LOG_LONG_DESC, log_function, "<log_level> <log_string>",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "info", "Display Call Info", "Display Call Info", info_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "event", "Fire an event", "Fire an event", event_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "sound_test", "Analyze Audio", "Analyze Audio", sound_test_function, "", SAF_NONE);
SWITCH_ADD_APP(app_interface, "export", "Export a channel variable across a bridge", EXPORT_LONG_DESC, export_function, "<varname>=<value>",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "set", "Set a channel variable", SET_LONG_DESC, set_function, "<varname>=<value>", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "set", "Set a channel variable", SET_LONG_DESC, set_function, "<varname>=<value>",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "set_global", "Set a global variable", SET_GLOBAL_LONG_DESC, set_global_function, "<varname>=<value>",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "set_profile_var", "Set a caller profile variable", SET_PROFILE_VAR_LONG_DESC, set_profile_var_function,
"<varname>=<value>", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "unset", "Unset a channel variable", UNSET_LONG_DESC, unset_function, "<varname>", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "unset", "Unset a channel variable", UNSET_LONG_DESC, unset_function, "<varname>",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "ring_ready", "Indicate Ring_Ready", "Indicate Ring_Ready on a channel.", ring_ready_function, "", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "remove_bugs", "Remove media bugs", "Remove all media bugs from a channel.", remove_bugs_function, "", SAF_NONE);
SWITCH_ADD_APP(app_interface, "break", "Break", "Set the break flag.", break_function, "", SAF_SUPPORT_NOMEDIA);
@ -3063,21 +3083,22 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_APP(app_interface, "sched_transfer", SCHED_TRANSF_DESCR, SCHED_TRANSF_DESCR, sched_transfer_function,
"[+]<time> <extension> <dialplan> <context>", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "execute_extension", "Execute an extension", "Execute an extension", exe_function, EXE_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "sched_heartbeat", "Enable Scheduled Heartbeat", "Enable Scheduled Heartbeat",
SWITCH_ADD_APP(app_interface, "sched_heartbeat", "Enable Scheduled Heartbeat", "Enable Scheduled Heartbeat",
sched_heartbeat_function, SCHED_HEARTBEAT_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "enable_heartbeat", "Enable Media Heartbeat", "Enable Media Heartbeat",
SWITCH_ADD_APP(app_interface, "enable_heartbeat", "Enable Media Heartbeat", "Enable Media Heartbeat",
heartbeat_function, HEARTBEAT_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "mkdir", "Create a directory", "Create a directory", mkdir_function, MKDIR_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "soft_hold", "Put a bridged channel on hold", "Put a bridged channel on hold", soft_hold_function, SOFT_HOLD_SYNTAX,
SAF_NONE);
SWITCH_ADD_APP(app_interface, "bind_meta_app", "Bind a key to an application", "Bind a key to an application", dtmf_bind_function, BIND_SYNTAX,
SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "unbind_meta_app", "Unbind a key from an application", "Unbind a key from an application", dtmf_unbind_function,
SWITCH_ADD_APP(app_interface, "unbind_meta_app", "Unbind a key from an application", "Unbind a key from an application", dtmf_unbind_function,
UNBIND_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "intercept", "intercept", "intercept", intercept_function, INTERCEPT_SYNTAX, SAF_NONE);
SWITCH_ADD_APP(app_interface, "eavesdrop", "eavesdrop on a uuid", "eavesdrop on a uuid", eavesdrop_function, eavesdrop_SYNTAX, SAF_MEDIA_TAP);
SWITCH_ADD_APP(app_interface, "three_way", "three way call with a uuid", "three way call with a uuid", three_way_function, threeway_SYNTAX, SAF_MEDIA_TAP);
SWITCH_ADD_APP(app_interface, "set_user", "Set a User", "Set a User", set_user_function, SET_USER_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC );
SWITCH_ADD_APP(app_interface, "three_way", "three way call with a uuid", "three way call with a uuid", three_way_function, threeway_SYNTAX,
SAF_MEDIA_TAP);
SWITCH_ADD_APP(app_interface, "set_user", "Set a User", "Set a User", set_user_function, SET_USER_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "stop_dtmf", "stop inband dtmf", "Stop detecting inband dtmf.", stop_dtmf_session_function, "", SAF_NONE);
SWITCH_ADD_APP(app_interface, "start_dtmf", "Detect dtmf", "Detect inband dtmf on the session", dtmf_session_function, "", SAF_MEDIA_TAP);
SWITCH_ADD_APP(app_interface, "stop_dtmf_generate", "stop inband dtmf generation", "Stop generating inband dtmf.",
@ -3092,11 +3113,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_APP(app_interface, "park_state", "Park State", "Park State", park_state_function, "", SAF_NONE);
SWITCH_ADD_APP(app_interface, "gentones", "Generate Tones", "Generate tones to the channel", gentones_function, "<tgml_script>[|<loops>]", SAF_NONE);
SWITCH_ADD_APP(app_interface, "playback", "Playback File", "Playback a file to the channel", playback_function, "<path>", SAF_NONE);
SWITCH_ADD_APP(app_interface, "endless_playback", "Playback File Endlessly", "Endlessly Playback a file to the channel",
SWITCH_ADD_APP(app_interface, "endless_playback", "Playback File Endlessly", "Endlessly Playback a file to the channel",
endless_playback_function, "<path>", SAF_NONE);
SWITCH_ADD_APP(app_interface, "att_xfer", "Attended Transfer", "Attended Transfer", att_xfer_function, "<channel_url>", SAF_NONE);
SWITCH_ADD_APP(app_interface, "read", "Read Digits", "Read Digits", read_function, "<min> <max> <file> <var_name> <timeout> <terminators>", SAF_NONE);
SWITCH_ADD_APP(app_interface, "play_and_get_digits", "Play and get Digits", "Play and get Digits",
SWITCH_ADD_APP(app_interface, "play_and_get_digits", "Play and get Digits", "Play and get Digits",
play_and_get_digits_function, "<min> <max> <tries> <timeout> <terminators> <file> <invalid_file> <var_name> <regexp>", SAF_NONE);
SWITCH_ADD_APP(app_interface, "stop_record_session", "Stop Record Session", STOP_SESS_REC_DESC, stop_record_session_function, "<path>", SAF_NONE);
SWITCH_ADD_APP(app_interface, "record_session", "Record Session", SESS_REC_DESC, record_session_function, "<path> [+<timeout>]", SAF_MEDIA_TAP);
@ -3116,8 +3137,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "say", "say", "say", say_function, SAY_SYNTAX, SAF_NONE);
SWITCH_ADD_APP(app_interface, "wait_for_silence", "wait_for_silence", "wait_for_silence", wait_for_silence_function, WAIT_FOR_SILENCE_SYNTAX, SAF_NONE);
SWITCH_ADD_APP(app_interface, "session_loglevel", "session_loglevel", "session_loglevel", session_loglevel_function, SESSION_LOGLEVEL_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "wait_for_silence", "wait_for_silence", "wait_for_silence", wait_for_silence_function, WAIT_FOR_SILENCE_SYNTAX,
SAF_NONE);
SWITCH_ADD_APP(app_interface, "session_loglevel", "session_loglevel", "session_loglevel", session_loglevel_function, SESSION_LOGLEVEL_SYNTAX,
SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_DIALPLAN(dp_interface, "inline", inline_dialplan_hunt);

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -38,22 +38,22 @@
#include <switch.h>
typedef struct easyroute_results{
char limit[16];
char dialstring[256];
char group[16];
char acctcode[17];
char translated[17];
typedef struct easyroute_results {
char limit[16];
char dialstring[256];
char group[16];
char acctcode[17];
char translated[17];
} easyroute_results_t;
typedef struct route_callback {
char gateway[129];
char group[129];
char techprofile[129];
char limit[129];
char acctcode[129];
char translated[17];
char gateway[129];
char group[129];
char techprofile[129];
char limit[129];
char acctcode[129];
char translated[17];
} route_callback_t;
static struct {
@ -97,13 +97,13 @@ static switch_status_t load_config(void)
char *cf = "easyroute.conf";
switch_xml_t cfg, xml = NULL, param, settings;
switch_status_t status = SWITCH_STATUS_SUCCESS;
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
status = SWITCH_STATUS_FALSE;
goto done;
}
if ((settings = switch_xml_child(cfg, "settings"))) {
for (param = switch_xml_child(settings, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
@ -123,8 +123,8 @@ static switch_status_t load_config(void)
}
}
}
done:
done:
if (zstr(globals.db_username)) {
set_global_db_username("root");
}
@ -151,7 +151,7 @@ static switch_status_t load_config(void)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opened ODBC Database!\n");
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected ODBC DSN: %s\n", globals.db_dsn);
if (!globals.custom_query){
if (!globals.custom_query) {
if (switch_odbc_handle_exec(globals.master_odbc, "select count(*) from numbers", NULL, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot find SQL Database! (Where\'s the numbers table\?\?)\n");
}
@ -163,7 +163,7 @@ static switch_status_t load_config(void)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open ODBC Connection (did you enable it?!)\n");
}
reallydone:
reallydone:
if (xml) {
switch_xml_free(xml);
@ -177,76 +177,77 @@ static switch_status_t load_config(void)
return status;
}
static char SQL_LOOKUP[] = "SELECT gateways.gateway_ip, gateways.group, gateways.limit, gateways.techprofile, numbers.acctcode, numbers.translated from gateways, numbers where numbers.number = '%q' and numbers.gateway_id = gateways.gateway_id limit 1;";
static char SQL_LOOKUP[] =
"SELECT gateways.gateway_ip, gateways.group, gateways.limit, gateways.techprofile, numbers.acctcode, numbers.translated from gateways, numbers where numbers.number = '%q' and numbers.gateway_id = gateways.gateway_id limit 1;";
static switch_status_t route_lookup(char *dn, easyroute_results_t *results, int noat, char *separator)
{
{
switch_status_t sstatus = SWITCH_STATUS_SUCCESS;
char *sql = NULL;
route_callback_t pdata;
if (!switch_odbc_available()) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT,
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT,
"mod_easyroute requires core ODBC support. Please refer to the documentation on how to enable this\n");
return sstatus;
}
memset(&pdata, 0, sizeof(pdata));
if (!globals.custom_query){
if (!globals.custom_query) {
sql = switch_mprintf(SQL_LOOKUP, dn);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Doing static Query\n[%s]\n", sql);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Doing static Query\n[%s]\n", sql);
} else {
sql = switch_mprintf(globals.custom_query, dn);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Doing custom Query\n[%s]\n", sql);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Doing custom Query\n[%s]\n", sql);
}
if (globals.mutex){
if (globals.mutex) {
switch_mutex_lock(globals.mutex);
}
/* Do the Query */
if (switch_odbc_handle_callback_exec(globals.master_odbc, sql, route_callback, &pdata, NULL) == SWITCH_ODBC_SUCCESS){
if (switch_odbc_handle_callback_exec(globals.master_odbc, sql, route_callback, &pdata, NULL) == SWITCH_ODBC_SUCCESS) {
char tmp_profile[129];
char tmp_gateway[129];
if (zstr(pdata.limit)) {
switch_set_string(results->limit, "9999" );
switch_set_string(results->limit, "9999");
} else {
switch_set_string(results->limit, pdata.limit );
switch_set_string(results->limit, pdata.limit);
}
if (zstr(pdata.techprofile)){
if (zstr(pdata.techprofile)) {
switch_set_string(tmp_profile, globals.default_techprofile);
} else {
switch_set_string(tmp_profile, pdata.techprofile);
}
if (zstr(pdata.gateway)){
if (zstr(pdata.gateway)) {
switch_set_string(tmp_gateway, globals.default_gateway);
} else {
switch_set_string(tmp_gateway, pdata.gateway);
}
if (zstr(pdata.translated)){
if (zstr(pdata.translated)) {
switch_set_string(results->translated, dn);
} else {
switch_set_string(results->translated, pdata.translated);
}
if (noat) {
switch_snprintf(results->dialstring, 256, "%s/%s%s", tmp_profile , results->translated, tmp_gateway);
switch_snprintf(results->dialstring, 256, "%s/%s%s", tmp_profile, results->translated, tmp_gateway);
} else if (separator) {
switch_snprintf(results->dialstring, 256, "%s/%s%s%s", tmp_profile , results->translated, separator, tmp_gateway);
switch_snprintf(results->dialstring, 256, "%s/%s%s%s", tmp_profile, results->translated, separator, tmp_gateway);
} else {
switch_snprintf(results->dialstring, 256, "%s/%s@%s", tmp_profile , results->translated, tmp_gateway);
switch_snprintf(results->dialstring, 256, "%s/%s@%s", tmp_profile, results->translated, tmp_gateway);
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "THE ROUTE [%s]\n", results->dialstring);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "THE ROUTE [%s]\n", results->dialstring);
if (zstr(pdata.group)){
if (zstr(pdata.group)) {
switch_set_string(results->group, "");
} else {
switch_set_string(results->group, pdata.group);
}
if (zstr(pdata.acctcode)){
if (zstr(pdata.acctcode)) {
switch_set_string(results->acctcode, "");
} else {
switch_set_string(results->acctcode, pdata.acctcode);
@ -254,11 +255,11 @@ static switch_status_t route_lookup(char *dn, easyroute_results_t *results, int
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "DB Error Setting Default Route!\n");
switch_set_string(results->limit, "9999");
if (noat){
if (noat) {
switch_snprintf(results->dialstring, 256, "%s/%s%s", globals.default_techprofile, dn, globals.default_gateway);
} else if (separator){
} else if (separator) {
switch_snprintf(results->dialstring, 256, "%s/%s%s%s", globals.default_techprofile, dn, separator, globals.default_gateway);
} else {
} else {
switch_snprintf(results->dialstring, 256, "%s/%s@%s", globals.default_techprofile, dn, globals.default_gateway);
}
switch_set_string(results->group, "");
@ -267,7 +268,7 @@ static switch_status_t route_lookup(char *dn, easyroute_results_t *results, int
switch_safe_free(sql);
if (globals.mutex){
if (globals.mutex) {
switch_mutex_unlock(globals.mutex);
}
return sstatus;
@ -278,7 +279,7 @@ SWITCH_STANDARD_APP(easyroute_app_function)
int argc = 0;
char *argv[4] = { 0 };
char *mydata = NULL;
char *destnum = NULL;
char *destnum = NULL;
int noat = 0;
char *separator = NULL;
@ -289,18 +290,18 @@ SWITCH_STANDARD_APP(easyroute_app_function)
if (!channel) {
return;
}
if (!(mydata = switch_core_session_strdup(session, data))) {
return;
}
if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
destnum = argv[0];
if (argc == 2) {
if (!strcasecmp(argv[1], "noat")) {
noat = 1;
} else if (!strcasecmp(argv[1], "separator")) {
if (argc == 3){
if (argc == 3) {
switch_set_string(separator, argv[2]);
}
}
@ -325,7 +326,7 @@ SWITCH_STANDARD_API(easyroute_function)
int noat = 0;
easyroute_results_t results;
switch_status_t status = SWITCH_STATUS_SUCCESS;
if (session) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "This function cannot be called from the dialplan.\n");
status = SWITCH_STATUS_FALSE;
@ -337,39 +338,40 @@ SWITCH_STANDARD_API(easyroute_function)
status = SWITCH_STATUS_SUCCESS;
goto done;
}
if (!cmd || !(mydata = strdup(cmd))) {
stream->write_function(stream, "Usage: easyroute <number>\n");
status = SWITCH_STATUS_SUCCESS;
goto done;
}
if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
destnum = argv[0];
if (argc < 1 || argc > 3){
if (argc < 1 || argc > 3) {
stream->write_function(stream, "Invalid Input!\n");
status = SWITCH_STATUS_SUCCESS;
goto done;
}
}
if (argc == 2) {
if (!strcasecmp(argv[1], "noat")) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Entering noat.\n");
noat = 1;
} else if (!strcasecmp(argv[1], "separator")) {
if (argc == 3){
if (argc == 3) {
switch_set_string(separator, argv[2]);
}
}
}
if (!route_lookup(destnum, &results, noat, separator) == SWITCH_STATUS_SUCCESS) {
stream->write_function(stream, "No Match!\n");
status = SWITCH_STATUS_SUCCESS;
goto done;
}
if (argc != 2){
if (argc != 2) {
stream->write_function(stream, "Number \tLimit \tGroup \tAcctCode \tDialstring\n");
stream->write_function(stream, "%-10s\t%-10s\t%-10s\t%-10s\t%s\n", destnum, results.limit, results.group, results.acctcode, results.dialstring);
stream->write_function(stream, "%-10s\t%-10s\t%-10s\t%-10s\t%s\n", destnum, results.limit, results.group, results.acctcode,
results.dialstring);
} else {
if (!strncasecmp(argv[1], "dialstring", 10)) {
stream->write_function(stream, "%s", results.dialstring);
@ -386,12 +388,12 @@ SWITCH_STANDARD_API(easyroute_function)
status = SWITCH_STATUS_SUCCESS;
goto done;
}
}
}
} else {
stream->write_function(stream, "Invalid Input!\n");
}
done:
done:
switch_safe_free(mydata);
return status;
}
@ -400,21 +402,22 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_easyroute_load)
{
switch_api_interface_t *api_interface;
switch_application_interface_t *app_interface;
memset(&globals, 0, sizeof(globals));
load_config();
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_API(api_interface, "easyroute", "EasyRoute", easyroute_function, "");
SWITCH_ADD_APP(app_interface, "easyroute", "Perform an easyroute lookup", "Perform an easyroute lookup", easyroute_app_function, "<number>", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "easyroute", "Perform an easyroute lookup", "Perform an easyroute lookup", easyroute_app_function, "<number>",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_easyroute_shutdown)
{
{
switch_odbc_handle_disconnect(globals.master_odbc);
switch_safe_free(globals.db_username);
switch_safe_free(globals.db_password);

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -251,7 +251,7 @@ static void add_result(enum_query_t *q, int order, int preference, char *service
}
}
static void free_results(enum_record_t **results)
static void free_results(enum_record_t ** results)
{
enum_record_t *fp, *rp;
@ -447,7 +447,7 @@ static void dnscb(struct dns_ctx *ctx, void *result, void *data)
free(result);
}
static switch_status_t enum_lookup(char *root, char *in, enum_record_t **results)
static switch_status_t enum_lookup(char *root, char *in, enum_record_t ** results)
{
switch_status_t sstatus = SWITCH_STATUS_SUCCESS;
char *name = NULL;
@ -829,7 +829,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_enum_load)
memset(&globals, 0, sizeof(globals));
do_load();
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_API(api_interface, "enum", "ENUM", enum_function, "");
@ -850,7 +850,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_enum_shutdown)
if (globals.pool) {
switch_core_destroy_memory_pool(&globals.pool);
}
switch_safe_free(globals.root);
switch_safe_free(globals.isn_root);

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -78,10 +78,10 @@ SWITCH_STANDARD_APP(bcast_function)
switch_port_t mcast_control_port = 6061;
char *mcast_port_str = "34567";
const char *esf_broadcast_ip = NULL, *var;
switch_codec_implementation_t read_impl = {0};
switch_codec_implementation_t read_impl = { 0 };
int mcast_ttl = 1;
switch_core_session_get_read_impl(session, &read_impl);
switch_core_session_get_read_impl(session, &read_impl);
if (!zstr((char *) data)) {
mydata = switch_core_session_strdup(session, data);
@ -105,7 +105,7 @@ SWITCH_STANDARD_APP(bcast_function)
if (!zstr(argv[2])) {
mcast_control_port = (switch_port_t) atoi(argv[2]);
}
if (!zstr(argv[3])) {
mcast_ttl = atoi(argv[3]);
if (mcast_ttl < 1 || mcast_ttl > 255) {
@ -136,7 +136,7 @@ SWITCH_STANDARD_APP(bcast_function)
goto fail;
}
if (switch_mcast_hops(socket, (uint8_t)mcast_ttl) != SWITCH_STATUS_SUCCESS) {
if (switch_mcast_hops(socket, (uint8_t) mcast_ttl) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Mutlicast TTL set failed\n");
goto fail;
}
@ -201,8 +201,7 @@ SWITCH_STANDARD_APP(bcast_function)
mcast_port,
read_impl.ianacode,
read_impl.samples_per_packet,
read_impl.microseconds_per_packet,
(switch_rtp_flag_t) flags, "soft", &err, switch_core_session_get_pool(session));
read_impl.microseconds_per_packet, (switch_rtp_flag_t) flags, "soft", &err, switch_core_session_get_pool(session));
if (!switch_rtp_ready(rtp_session)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "RTP Error\n");

View File

@ -20,25 +20,24 @@ extern "C" {
#define BLINK 0
typedef enum
{
BLACK,
BLUE,
GREEN,
CYAN,
RED,
MAGENTA,
BROWN,
LIGHTGRAY,
DARKGRAY,
LIGHTBLUE,
LIGHTGREEN,
LIGHTCYAN,
LIGHTRED,
LIGHTMAGENTA,
YELLOW,
WHITE
} COLORS;
typedef enum {
BLACK,
BLUE,
GREEN,
CYAN,
RED,
MAGENTA,
BROWN,
LIGHTGRAY,
DARKGRAY,
LIGHTBLUE,
LIGHTGREEN,
LIGHTCYAN,
LIGHTRED,
LIGHTMAGENTA,
YELLOW,
WHITE
} COLORS;
#define cgets _cgets
@ -49,17 +48,16 @@ typedef enum
/* blinkvideo */
void clreol (void);
void clrscr (void);
void clreol(void);
void clrscr(void);
int _conio_gettext (int left, int top, int right, int bottom,
char *str);
int _conio_gettext(int left, int top, int right, int bottom, char *str);
/* _conio_kbhit */
void delline (void);
void delline(void);
/* gettextinfo */
void gotoxy(int x, int y);
void gotoxy(int x, int y);
/*
highvideo
insline
@ -69,9 +67,9 @@ movetext
normvideo
*/
void gotoxy(int x, int y);
void gotoxy(int x, int y);
void puttext (int left, int top, int right, int bottom, char *str);
void puttext(int left, int top, int right, int bottom, char *str);
// Screen Variables
@ -89,19 +87,19 @@ ScreenUpdateLine
ScreenVisualBell
_set_screen_lines */
void _setcursortype (int type);
void _setcursortype(int type);
void textattr (int _attr);
void textattr(int _attr);
void textbackground (int color);
void textbackground(int color);
void textcolor (int color);
void textcolor(int color);
/* textmode */
int wherex (void);
int wherex(void);
int wherey (void);
int wherey(void);
/* window */
@ -135,27 +133,26 @@ int wherey (void);
*
*/
char* _cgets (char*);
int _cprintf (const char*, ...);
int _cputs (const char*);
int _cscanf (char*, ...);
char *_cgets(char *);
int _cprintf(const char *, ...);
int _cputs(const char *);
int _cscanf(char *, ...);
int _getch (void);
int _getche (void);
int _kbhit (void);
int _putch (int);
int _ungetch (int);
int _getch(void);
int _getche(void);
int _kbhit(void);
int _putch(int);
int _ungetch(int);
int getch (void);
int getche (void);
int kbhit (void);
int putch (int);
int ungetch (int);
int getch(void);
int getche(void);
int kbhit(void);
int putch(int);
int ungetch(int);
#ifdef __cplusplus
}
#endif
#endif /* _CONIO_H_ */
#endif /* _CONIO_H_ */

View File

@ -19,7 +19,7 @@ extern "C" {
/* Define type of data to use */
typedef double EXPRTYPE;
typedef double EXPRTYPE;
/* Defines for various things */
@ -27,101 +27,96 @@ typedef double EXPRTYPE;
#define EXPR_MAXIDENTSIZE 255
/* Error values */
enum
{
EXPR_ERROR_UNKNOWN = -1, /* Unknown error */
EXPR_ERROR_NOERROR = 0, /* No Error */
EXPR_ERROR_MEMORY, /* Memory allocation failed */
EXPR_ERROR_NULLPOINTER, /* Null pointer passed to function */
EXPR_ERROR_NOTFOUND, /* Item not found in a list */
EXPR_ERROR_UNMATCHEDCOMMENT, /* Unmatched comment tags */
EXPR_ERROR_INVALIDCHAR, /* Invalid characters in expression */
EXPR_ERROR_ALREADYEXISTS, /* An item already called create */
EXPR_ERROR_ALREADYPARSEDBAD, /* Expression parsed already, but unsuccessfully. call free or clear */
EXPR_ERROR_ALREADYPARSEDGOOD, /* Expression parsed already, successfully, call free or clear */
EXPR_ERROR_EMPTYEXPR, /* Empty expression string passed to parse */
EXPR_ERROR_UNMATCHEDPAREN, /* Unmatched parenthesis */
EXPR_ERROR_SYNTAX, /* Syntax error in expression */
EXPR_ERROR_MISSINGSEMICOLON, /* Missing semicolon at end of expression */
EXPR_ERROR_BADIDENTIFIER, /* Identifier was to big or not formed right */
EXPR_ERROR_NOSUCHFUNCTION, /* Function does not exist in function list */
EXPR_ERROR_BADNUMBERARGUMENTS, /* Bad number of arguments in a function call */
EXPR_ERROR_BADEXPR, /* This is a bad expression to evaluate. It has not been parsed or has unsuccessfully */
EXPR_ERROR_UNABLETOASSIGN, /* Unable to do an assignment, maybe no variable list */
EXPR_ERROR_DIVBYZERO, /* Attempted a division by zero */
EXPR_ERROR_NOVARLIST, /* No variable list found but one is needed */
EXPR_ERROR_BREAK, /* Expression was broken by break function */
EXPR_ERROR_CONSTANTASSIGN, /* Assignment to a constant */
EXPR_ERROR_REFCONSTANT, /* Constant used as a reference parameter */
EXPR_ERROR_OUTOFRANGE, /* A bad value was passed to a function */
enum {
EXPR_ERROR_UNKNOWN = -1, /* Unknown error */
EXPR_ERROR_NOERROR = 0, /* No Error */
EXPR_ERROR_MEMORY, /* Memory allocation failed */
EXPR_ERROR_NULLPOINTER, /* Null pointer passed to function */
EXPR_ERROR_NOTFOUND, /* Item not found in a list */
EXPR_ERROR_UNMATCHEDCOMMENT, /* Unmatched comment tags */
EXPR_ERROR_INVALIDCHAR, /* Invalid characters in expression */
EXPR_ERROR_ALREADYEXISTS, /* An item already called create */
EXPR_ERROR_ALREADYPARSEDBAD, /* Expression parsed already, but unsuccessfully. call free or clear */
EXPR_ERROR_ALREADYPARSEDGOOD, /* Expression parsed already, successfully, call free or clear */
EXPR_ERROR_EMPTYEXPR, /* Empty expression string passed to parse */
EXPR_ERROR_UNMATCHEDPAREN, /* Unmatched parenthesis */
EXPR_ERROR_SYNTAX, /* Syntax error in expression */
EXPR_ERROR_MISSINGSEMICOLON, /* Missing semicolon at end of expression */
EXPR_ERROR_BADIDENTIFIER, /* Identifier was to big or not formed right */
EXPR_ERROR_NOSUCHFUNCTION, /* Function does not exist in function list */
EXPR_ERROR_BADNUMBERARGUMENTS, /* Bad number of arguments in a function call */
EXPR_ERROR_BADEXPR, /* This is a bad expression to evaluate. It has not been parsed or has unsuccessfully */
EXPR_ERROR_UNABLETOASSIGN, /* Unable to do an assignment, maybe no variable list */
EXPR_ERROR_DIVBYZERO, /* Attempted a division by zero */
EXPR_ERROR_NOVARLIST, /* No variable list found but one is needed */
EXPR_ERROR_BREAK, /* Expression was broken by break function */
EXPR_ERROR_CONSTANTASSIGN, /* Assignment to a constant */
EXPR_ERROR_REFCONSTANT, /* Constant used as a reference parameter */
EXPR_ERROR_OUTOFRANGE, /* A bad value was passed to a function */
EXPR_ERROR_USER /* Custom errors should be larger than this */
};
EXPR_ERROR_USER /* Custom errors should be larger than this */
};
/* Macros */
/* Forward declarations */
typedef struct _exprNode exprNode;
typedef struct _exprFuncList exprFuncList;
typedef struct _exprValList exprValList;
typedef struct _exprObj exprObj;
typedef struct _exprNode exprNode;
typedef struct _exprFuncList exprFuncList;
typedef struct _exprValList exprValList;
typedef struct _exprObj exprObj;
/* Function types */
typedef int (*exprFuncType)(exprObj *obj, exprNode *nodes, int nodecount, EXPRTYPE **refs, int refcount, EXPRTYPE *val);
typedef int (*exprBreakFuncType)(exprObj *obj);
typedef int (*exprFuncType) (exprObj * obj, exprNode * nodes, int nodecount, EXPRTYPE ** refs, int refcount, EXPRTYPE * val);
typedef int (*exprBreakFuncType) (exprObj * obj);
/* Functions */
/* Version information function */
void exprGetVersion(int *major, int *minor);
void exprGetVersion(int *major, int *minor);
/* Functions for function lists */
int exprFuncListCreate(exprFuncList **flist);
int exprFuncListAdd(exprFuncList *flist, char *name, exprFuncType ptr, int min, int max, int refmin, int refmax);
int exprFuncListFree(exprFuncList *flist);
int exprFuncListClear(exprFuncList *flist);
int exprFuncListInit(exprFuncList *flist);
int exprFuncListCreate(exprFuncList ** flist);
int exprFuncListAdd(exprFuncList * flist, char *name, exprFuncType ptr, int min, int max, int refmin, int refmax);
int exprFuncListFree(exprFuncList * flist);
int exprFuncListClear(exprFuncList * flist);
int exprFuncListInit(exprFuncList * flist);
/* Functions for value lists */
int exprValListCreate(exprValList **vlist);
int exprValListAdd(exprValList *vlist, char *name, EXPRTYPE val);
int exprValListSet(exprValList *vlist, char *name, EXPRTYPE val);
int exprValListGet(exprValList *vlist, char *name, EXPRTYPE *val);
int exprValListAddAddress(exprValList *vlist, char *name, EXPRTYPE *addr);
int exprValListGetAddress(exprValList *vlist, char *name, EXPRTYPE **addr);
void *exprValListGetNext(exprValList *vlist, char **name, EXPRTYPE *value, EXPRTYPE** addr, void *cookie);
int exprValListFree(exprValList *vlist);
int exprValListClear(exprValList *vlist);
int exprValListInit(exprValList *vlist);
int exprValListCreate(exprValList ** vlist);
int exprValListAdd(exprValList * vlist, char *name, EXPRTYPE val);
int exprValListSet(exprValList * vlist, char *name, EXPRTYPE val);
int exprValListGet(exprValList * vlist, char *name, EXPRTYPE * val);
int exprValListAddAddress(exprValList * vlist, char *name, EXPRTYPE * addr);
int exprValListGetAddress(exprValList * vlist, char *name, EXPRTYPE ** addr);
void *exprValListGetNext(exprValList * vlist, char **name, EXPRTYPE * value, EXPRTYPE ** addr, void *cookie);
int exprValListFree(exprValList * vlist);
int exprValListClear(exprValList * vlist);
int exprValListInit(exprValList * vlist);
/* Functions for expression objects */
int exprCreate(exprObj **obj, exprFuncList *flist, exprValList *vlist, exprValList *clist,
exprBreakFuncType breaker, void *userdata);
int exprFree(exprObj *obj);
int exprClear(exprObj *obj);
int exprParse(exprObj *obj, char *expr);
int exprEval(exprObj *obj, EXPRTYPE *val);
int exprEvalNode(exprObj *obj, exprNode *nodes, int curnode, EXPRTYPE *val);
exprFuncList *exprGetFuncList(exprObj *obj);
exprValList *exprGetVarList(exprObj *obj);
exprValList *exprGetConstList(exprObj *obj);
exprBreakFuncType exprGetBreakFunc(exprObj *obj);
int exprGetBreakResult(exprObj *obj);
void* exprGetUserData(exprObj *obj);
void exprSetUserData(exprObj *obj, void *userdata);
void exprSetBreakCount(exprObj *obj, int count);
void exprGetErrorPosition(exprObj *obj, int *start, int *end);
int exprCreate(exprObj ** obj, exprFuncList * flist, exprValList * vlist, exprValList * clist, exprBreakFuncType breaker, void *userdata);
int exprFree(exprObj * obj);
int exprClear(exprObj * obj);
int exprParse(exprObj * obj, char *expr);
int exprEval(exprObj * obj, EXPRTYPE * val);
int exprEvalNode(exprObj * obj, exprNode * nodes, int curnode, EXPRTYPE * val);
exprFuncList *exprGetFuncList(exprObj * obj);
exprValList *exprGetVarList(exprObj * obj);
exprValList *exprGetConstList(exprObj * obj);
exprBreakFuncType exprGetBreakFunc(exprObj * obj);
int exprGetBreakResult(exprObj * obj);
void *exprGetUserData(exprObj * obj);
void exprSetUserData(exprObj * obj, void *userdata);
void exprSetBreakCount(exprObj * obj, int count);
void exprGetErrorPosition(exprObj * obj, int *start, int *end);
/* Other useful routines */
int exprValidIdent(char *name);
int exprValidIdent(char *name);
/* Name mangling */
#ifdef __cplusplus
}
#endif
#endif /* __BAVII_EXPREVAL_H */
#endif /* __BAVII_EXPREVAL_H */

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@
/* Needed for exprNode */
#include "exprpriv.h"
void* exprAllocMem(size_t size);
void *exprAllocMem(size_t size);
void exprFreeMem(void *data);
exprNode *exprAllocNodes(size_t count);

View File

@ -30,196 +30,180 @@ extern "C" {
#define EXPR_VERSIONMINOR 7
/* Node types */
enum
{
EXPR_NODETYPE_UNKNOWN = 0,
EXPR_NODETYPE_MULTI,
EXPR_NODETYPE_ADD,
EXPR_NODETYPE_SUBTRACT,
EXPR_NODETYPE_MULTIPLY,
EXPR_NODETYPE_DIVIDE,
EXPR_NODETYPE_EXPONENT,
EXPR_NODETYPE_NEGATE,
EXPR_NODETYPE_VALUE,
EXPR_NODETYPE_VARIABLE,
EXPR_NODETYPE_ASSIGN,
EXPR_NODETYPE_FUNCTION
};
enum {
EXPR_NODETYPE_UNKNOWN = 0,
EXPR_NODETYPE_MULTI,
EXPR_NODETYPE_ADD,
EXPR_NODETYPE_SUBTRACT,
EXPR_NODETYPE_MULTIPLY,
EXPR_NODETYPE_DIVIDE,
EXPR_NODETYPE_EXPONENT,
EXPR_NODETYPE_NEGATE,
EXPR_NODETYPE_VALUE,
EXPR_NODETYPE_VARIABLE,
EXPR_NODETYPE_ASSIGN,
EXPR_NODETYPE_FUNCTION
};
/* Functions can be evaluated directly in EXPREVAL. If fptr
is NULL, type is used to determine what the function is */
enum
{
EXPR_NODEFUNC_UNKNOWN = 0,
EXPR_NODEFUNC_ABS,
EXPR_NODEFUNC_MOD,
EXPR_NODEFUNC_IPART,
EXPR_NODEFUNC_FPART,
EXPR_NODEFUNC_MIN,
EXPR_NODEFUNC_MAX,
EXPR_NODEFUNC_POW,
EXPR_NODEFUNC_SQRT,
EXPR_NODEFUNC_SIN,
EXPR_NODEFUNC_SINH,
EXPR_NODEFUNC_ASIN,
EXPR_NODEFUNC_COS,
EXPR_NODEFUNC_COSH,
EXPR_NODEFUNC_ACOS,
EXPR_NODEFUNC_TAN,
EXPR_NODEFUNC_TANH,
EXPR_NODEFUNC_ATAN,
EXPR_NODEFUNC_ATAN2,
EXPR_NODEFUNC_LOG,
EXPR_NODEFUNC_POW10,
EXPR_NODEFUNC_LN,
EXPR_NODEFUNC_EXP,
EXPR_NODEFUNC_LOGN,
EXPR_NODEFUNC_CEIL,
EXPR_NODEFUNC_FLOOR,
EXPR_NODEFUNC_RAND,
EXPR_NODEFUNC_RANDOM,
EXPR_NODEFUNC_RANDOMIZE,
EXPR_NODEFUNC_DEG,
EXPR_NODEFUNC_RAD,
EXPR_NODEFUNC_RECTTOPOLR,
EXPR_NODEFUNC_RECTTOPOLA,
EXPR_NODEFUNC_POLTORECTX,
EXPR_NODEFUNC_POLTORECTY,
EXPR_NODEFUNC_IF,
EXPR_NODEFUNC_SELECT,
EXPR_NODEFUNC_EQUAL,
EXPR_NODEFUNC_ABOVE,
EXPR_NODEFUNC_BELOW,
EXPR_NODEFUNC_AVG,
EXPR_NODEFUNC_CLIP,
EXPR_NODEFUNC_CLAMP,
EXPR_NODEFUNC_PNTCHANGE,
EXPR_NODEFUNC_POLY,
EXPR_NODEFUNC_AND,
EXPR_NODEFUNC_OR,
EXPR_NODEFUNC_NOT,
EXPR_NODEFUNC_FOR,
EXPR_NODEFUNC_MANY
};
enum {
EXPR_NODEFUNC_UNKNOWN = 0,
EXPR_NODEFUNC_ABS,
EXPR_NODEFUNC_MOD,
EXPR_NODEFUNC_IPART,
EXPR_NODEFUNC_FPART,
EXPR_NODEFUNC_MIN,
EXPR_NODEFUNC_MAX,
EXPR_NODEFUNC_POW,
EXPR_NODEFUNC_SQRT,
EXPR_NODEFUNC_SIN,
EXPR_NODEFUNC_SINH,
EXPR_NODEFUNC_ASIN,
EXPR_NODEFUNC_COS,
EXPR_NODEFUNC_COSH,
EXPR_NODEFUNC_ACOS,
EXPR_NODEFUNC_TAN,
EXPR_NODEFUNC_TANH,
EXPR_NODEFUNC_ATAN,
EXPR_NODEFUNC_ATAN2,
EXPR_NODEFUNC_LOG,
EXPR_NODEFUNC_POW10,
EXPR_NODEFUNC_LN,
EXPR_NODEFUNC_EXP,
EXPR_NODEFUNC_LOGN,
EXPR_NODEFUNC_CEIL,
EXPR_NODEFUNC_FLOOR,
EXPR_NODEFUNC_RAND,
EXPR_NODEFUNC_RANDOM,
EXPR_NODEFUNC_RANDOMIZE,
EXPR_NODEFUNC_DEG,
EXPR_NODEFUNC_RAD,
EXPR_NODEFUNC_RECTTOPOLR,
EXPR_NODEFUNC_RECTTOPOLA,
EXPR_NODEFUNC_POLTORECTX,
EXPR_NODEFUNC_POLTORECTY,
EXPR_NODEFUNC_IF,
EXPR_NODEFUNC_SELECT,
EXPR_NODEFUNC_EQUAL,
EXPR_NODEFUNC_ABOVE,
EXPR_NODEFUNC_BELOW,
EXPR_NODEFUNC_AVG,
EXPR_NODEFUNC_CLIP,
EXPR_NODEFUNC_CLAMP,
EXPR_NODEFUNC_PNTCHANGE,
EXPR_NODEFUNC_POLY,
EXPR_NODEFUNC_AND,
EXPR_NODEFUNC_OR,
EXPR_NODEFUNC_NOT,
EXPR_NODEFUNC_FOR,
EXPR_NODEFUNC_MANY
};
/* Forward declarations */
typedef struct _exprFunc exprFunc;
typedef struct _exprVal exprVal;
typedef struct _exprFunc exprFunc;
typedef struct _exprVal exprVal;
/* Expression object */
struct _exprObj
{
struct _exprFuncList *flist; /* Functions */
struct _exprValList *vlist; /* Variables */
struct _exprValList *clist; /* Constants */
struct _exprNode *headnode; /* Head parsed node */
struct _exprObj {
struct _exprFuncList *flist; /* Functions */
struct _exprValList *vlist; /* Variables */
struct _exprValList *clist; /* Constants */
struct _exprNode *headnode; /* Head parsed node */
exprBreakFuncType breakerfunc; /* Break function type */
exprBreakFuncType breakerfunc; /* Break function type */
void *userdata; /* User data, can be any 32 bit value */
int parsedgood; /* non-zero if successfully parsed */
int parsedbad; /* non-zero if parsed but unsuccessful */
int breakcount; /* how often to check the breaker function */
int breakcur; /* do we check the breaker function yet */
int starterr; /* start position of an error */
int enderr; /* end position of an error */
};
void *userdata; /* User data, can be any 32 bit value */
int parsedgood; /* non-zero if successfully parsed */
int parsedbad; /* non-zero if parsed but unsuccessful */
int breakcount; /* how often to check the breaker function */
int breakcur; /* do we check the breaker function yet */
int starterr; /* start position of an error */
int enderr; /* end position of an error */
};
/* Object for a function */
struct _exprFunc
{
char *fname; /* Name of the function */
exprFuncType fptr; /* Function pointer */
int min, max; /* Min and max args for the function. */
int refmin, refmax; /* Min and max ref. variables for the function */
int type; /* Function node type. exprEvalNOde solves the function */
struct _exprFunc {
char *fname; /* Name of the function */
exprFuncType fptr; /* Function pointer */
int min, max; /* Min and max args for the function. */
int refmin, refmax; /* Min and max ref. variables for the function */
int type; /* Function node type. exprEvalNOde solves the function */
struct _exprFunc *next; /* For linked list */
};
struct _exprFunc *next; /* For linked list */
};
/* Function list object */
struct _exprFuncList
{
struct _exprFunc *head;
};
struct _exprFuncList {
struct _exprFunc *head;
};
/* Object for values */
struct _exprVal
{
char *vname; /* Name of the value */
EXPRTYPE vval; /* Value of the value */
EXPRTYPE *vptr; /* Pointer to a value. Used only if not NULL */
struct _exprVal {
char *vname; /* Name of the value */
EXPRTYPE vval; /* Value of the value */
EXPRTYPE *vptr; /* Pointer to a value. Used only if not NULL */
struct _exprVal *next; /* For linked list */
};
struct _exprVal *next; /* For linked list */
};
/* Value list */
struct _exprValList
{
struct _exprVal *head;
};
struct _exprValList {
struct _exprVal *head;
};
/* Expression node type */
struct _exprNode
{
int type; /* Node type */
struct _exprNode {
int type; /* Node type */
union _data /* Union of info for various types */
{
struct _oper
{
struct _exprNode *nodes; /* Operation arguments */
int nodecount; /* Number of arguments */
} oper;
union _data { /* Union of info for various types */
struct _oper {
struct _exprNode *nodes; /* Operation arguments */
int nodecount; /* Number of arguments */
} oper;
struct _variable
{
EXPRTYPE *vaddr; /* Used if EXPR_FAST_VAR_ACCESS defined */
} variable;
struct _variable {
EXPRTYPE *vaddr; /* Used if EXPR_FAST_VAR_ACCESS defined */
} variable;
struct _value
{
EXPRTYPE value; /* Value if type is value */
} value;
struct _value {
EXPRTYPE value; /* Value if type is value */
} value;
struct _assign /* Assignment struct */
{
EXPRTYPE *vaddr; /* Used if EXPR_FAST_VAR_ACCESS defined */
struct _exprNode *node; /* Node to evaluate */
} assign;
struct _assign { /* Assignment struct */
EXPRTYPE *vaddr; /* Used if EXPR_FAST_VAR_ACCESS defined */
struct _exprNode *node; /* Node to evaluate */
} assign;
struct _function
{
exprFuncType fptr; /* Function pointer */
struct _exprNode *nodes; /* Array of argument nodes */
int nodecount; /* Number of argument nodes */
EXPRTYPE **refs; /* Reference variables */
int refcount; /* Number of variable references (not a reference counter) */
int type; /* Type of function for exprEvalNode if fptr is NULL */
} function;
} data;
};
struct _function {
exprFuncType fptr; /* Function pointer */
struct _exprNode *nodes; /* Array of argument nodes */
int nodecount; /* Number of argument nodes */
EXPRTYPE **refs; /* Reference variables */
int refcount; /* Number of variable references (not a reference counter) */
int type; /* Type of function for exprEvalNode if fptr is NULL */
} function;
} data;
};
/* Functions for function lists */
int exprFuncListAddType(exprFuncList *flist, char *name, int type, int min, int max, int refmin, int refmax);
int exprFuncListGet(exprFuncList *flist, char *name, exprFuncType *ptr, int *type, int *min, int *max, int *refmin, int *refmax);
int exprFuncListAddType(exprFuncList * flist, char *name, int type, int min, int max, int refmin, int refmax);
int exprFuncListGet(exprFuncList * flist, char *name, exprFuncType * ptr, int *type, int *min, int *max, int *refmin, int *refmax);
#ifdef WIN32
#define SWITCH_DECLARE(type) __declspec(dllimport) type __stdcall
#else
#define SWITCH_DECLARE(type) type
#define SWITCH_DECLARE(type) type
#endif
SWITCH_DECLARE(int) switch_isalnum(int c);
SWITCH_DECLARE(int) switch_isalpha(int c);
SWITCH_DECLARE(int) switch_isdigit(int c);
SWITCH_DECLARE(int) switch_isspace(int c);
SWITCH_DECLARE(int) switch_isalnum(int c);
SWITCH_DECLARE(int) switch_isalpha(int c);
SWITCH_DECLARE(int) switch_isdigit(int c);
SWITCH_DECLARE(int) switch_isspace(int c);
#ifdef __cplusplus
}
#endif
#endif /* __BAVII_EXPRPRIV_H */
#endif /* __BAVII_EXPRPRIV_H */

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -88,12 +88,12 @@ struct pvt_s {
int tx_page_start;
int tx_page_end;
int done;
/* UNUSED AT THE MOMENT
int enable_t38_reinvite;
*/
*/
};
@ -141,7 +141,7 @@ static void spanfax_log_message(int level, const char *msg)
/*
* Called at the end of the document
*/
static void phase_e_handler(t30_state_t * s, void *user_data, int result)
static void phase_e_handler(t30_state_t *s, void *user_data, int result)
{
t30_stats_t t;
const char *local_ident;
@ -153,7 +153,7 @@ static void phase_e_handler(t30_state_t * s, void *user_data, int result)
pvt = (pvt_t *) user_data;
switch_assert(pvt);
session = pvt->session;
switch_assert(session);
@ -184,8 +184,8 @@ static void phase_e_handler(t30_state_t * s, void *user_data, int result)
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote station id: %s\n", far_ident);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Local station id: %s\n", local_ident);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Pages transferred: %i\n",
pvt->app_mode == FUNCTION_TX ? t.pages_rx : t.pages_rx);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Pages transferred: %i\n",
pvt->app_mode == FUNCTION_TX ? t.pages_rx : t.pages_rx);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Total fax pages: %i\n", t.pages_in_file);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Image resolution: %ix%i\n", t.x_resolution, t.y_resolution);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Transfer Rate: %i\n", t.bit_rate);
@ -195,11 +195,12 @@ static void phase_e_handler(t30_state_t * s, void *user_data, int result)
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "remote vendor: %s\n", switch_str_nil(t30_get_rx_vendor(s)));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "remote model: %s\n", switch_str_nil(t30_get_rx_model(s)));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "==============================================================================\n");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
"==============================================================================\n");
/*
Set our channel variables
*/
Set our channel variables
*/
tmp = switch_mprintf("%i", result);
if (tmp) {
@ -250,15 +251,15 @@ static void phase_e_handler(t30_state_t * s, void *user_data, int result)
}
/* switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); */
pvt->done = 1;
/*
TODO Fire events
*/
TODO Fire events
*/
}
static switch_status_t spanfax_init(pvt_t * pvt, transport_mode_t trans_mode)
static switch_status_t spanfax_init(pvt_t *pvt, transport_mode_t trans_mode)
{
switch_core_session_t *session;
@ -342,7 +343,7 @@ static switch_status_t spanfax_init(pvt_t * pvt, transport_mode_t trans_mode)
Here goes the T.38 SpanDSP initializing functions
T.38 will require a big effort as it needs a different approach
but the pieces are already in place
*/
*/
default:
assert(0); /* Whaaat ? */
break;
@ -351,7 +352,7 @@ static switch_status_t spanfax_init(pvt_t * pvt, transport_mode_t trans_mode)
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t spanfax_destroy(pvt_t * pvt)
static switch_status_t spanfax_destroy(pvt_t *pvt)
{
int terminate;
t30_state_t *t30;
@ -403,9 +404,9 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
switch_codec_t write_codec = { 0 };
switch_frame_t *read_frame = { 0 };
switch_frame_t write_frame = { 0 };
switch_codec_implementation_t read_impl = {0};
switch_codec_implementation_t read_impl = { 0 };
int16_t *buf = NULL;
switch_core_session_get_read_impl(session, &read_impl);
switch_core_session_get_read_impl(session, &read_impl);
/* make sure we have a valid channel when starting the FAX application */
channel = switch_core_session_get_channel(session);
@ -414,7 +415,7 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
if (!switch_channel_media_ready(channel)) {
switch_channel_answer(channel);
}
/* Allocate our structs */
pvt = switch_core_session_alloc(session, sizeof(pvt_t));
@ -468,8 +469,8 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
pvt->verbose = globals.verbose;
}
if ( (tmp=switch_channel_get_variable(channel, "fax_force_caller")) ) {
if ( switch_true(tmp) ) {
if ((tmp = switch_channel_get_variable(channel, "fax_force_caller"))) {
if (switch_true(tmp)) {
pvt->caller = 1;
} else {
pvt->caller = 0;
@ -515,7 +516,8 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
pvt->filename = switch_core_session_strdup(session, data);
if (pvt->app_mode == FUNCTION_TX) {
if ((switch_file_exists(pvt->filename, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot send inexistant fax file [%s]\n", switch_str_nil(pvt->filename));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot send inexistant fax file [%s]\n",
switch_str_nil(pvt->filename));
goto done;
}
}
@ -548,12 +550,12 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
}
/*
*** Initialize the SpanDSP elements ***
*** Initialize the SpanDSP elements ***
Note: we could analyze if a fax was already detected in previous stages
and if so, when T.38 will be supported, send a reinvite in T38_MODE,
bypassing AUDIO_MODE.
*/
Note: we could analyze if a fax was already detected in previous stages
and if so, when T.38 will be supported, send a reinvite in T38_MODE,
bypassing AUDIO_MODE.
*/
if ((spanfax_init(pvt, AUDIO_MODE) != SWITCH_STATUS_SUCCESS)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot initialize Fax engine\n");
@ -563,14 +565,14 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
/*
Note: Disable echocan on the channel, remember to call app "disable_ec" in the dialplan
before invoking fax applications
*/
*/
/*
Note: we are disabling the Jitterbuffer, here, before we answer.
If you have set it to something else and the channel is pre-answered,
it will have no effect. Make sure that if you want more reliable
faxes, it is disabled.
*/
Note: we are disabling the Jitterbuffer, here, before we answer.
If you have set it to something else and the channel is pre-answered,
it will have no effect. Make sure that if you want more reliable
faxes, it is disabled.
*/
switch_channel_set_variable(channel, "jitterbuffer_msec", "0");
@ -614,7 +616,7 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
}
switch_ivr_sleep(session, 250, SWITCH_TRUE, NULL);
while (switch_channel_ready(channel)) {
int tx = 0;
switch_status_t status;
@ -628,7 +630,7 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
- call t38_terminal_send_timeout(), sleep for a while
The T.38 stuff can be placed here (and the audio stuff can be skipped)
*/
*/
/* read new audio frame from the channel */
status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
@ -640,7 +642,7 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
/* Skip CNG frames (auto-generated by FreeSWITCH, usually) */
if (!switch_test_flag(read_frame, SFF_CNG)) {
/* pass the new incoming audio frame to the fax_rx function */
/* pass the new incoming audio frame to the fax_rx function */
if (fax_rx(pvt->fax_state, (int16_t *) read_frame->data, read_frame->samples)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "fax_rx reported an error\n");
goto done;
@ -670,13 +672,13 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
}
done:
done:
/* Destroy the SpanDSP structures */
spanfax_destroy(pvt);
/* restore the original codecs over the channel */
switch_core_session_set_read_codec(session, NULL);
switch_core_session_set_read_codec(session, NULL);
if (switch_core_codec_ready(&read_codec)) {
switch_core_codec_destroy(&read_codec);
@ -782,8 +784,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_fax_init)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_APP(app_interface, "rxfax", "FAX Receive Application", "FAX Receive Application", spanfax_rx_function, SPANFAX_RX_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "txfax", "FAX Transmit Application", "FAX Transmit Application", spanfax_tx_function, SPANFAX_TX_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "rxfax", "FAX Receive Application", "FAX Receive Application", spanfax_rx_function, SPANFAX_RX_USAGE,
SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "txfax", "FAX Transmit Application", "FAX Transmit Application", spanfax_tx_function, SPANFAX_TX_USAGE,
SAF_SUPPORT_NOMEDIA);
memset(&globals, 0, sizeof(globals));
switch_core_new_memory_pool(&globals.pool);

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -90,11 +90,10 @@ static switch_status_t on_dtmf(switch_core_session_t *session, void *input, swit
const char *consumer_exit_key = switch_channel_get_variable(channel, "fifo_consumer_exit_key");
if (switch_channel_test_flag(switch_core_session_get_channel(session), CF_BRIDGE_ORIGINATOR)) {
if ( consumer_exit_key && dtmf->digit == *consumer_exit_key ) {
if (consumer_exit_key && dtmf->digit == *consumer_exit_key) {
switch_channel_hangup(bchan, SWITCH_CAUSE_NORMAL_CLEARING);
return SWITCH_STATUS_BREAK;
}
else if ( !consumer_exit_key && dtmf->digit == '*' ) {
} else if (!consumer_exit_key && dtmf->digit == '*') {
switch_channel_hangup(bchan, SWITCH_CAUSE_NORMAL_CLEARING);
return SWITCH_STATUS_BREAK;
} else if (dtmf->digit == '0') {
@ -228,8 +227,8 @@ static switch_status_t caller_read_frame_callback(switch_core_session_t *session
args.buflen = sizeof(buf);
if (switch_ivr_play_file(session, NULL, cd->list[cd->index], &args) != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
}
return SWITCH_STATUS_FALSE;
}
if (caller_exit_key && *buf == *caller_exit_key) {
cd->abort = 1;
@ -250,8 +249,8 @@ static switch_status_t consumer_read_frame_callback(switch_core_session_t *sessi
{
fifo_node_t *node, **node_list = (fifo_node_t **) user_data;
int x = 0, total = 0, i = 0;
for (i = 0 ;; i++) {
for (i = 0;; i++) {
if (!(node = node_list[i])) {
break;
}
@ -288,17 +287,19 @@ switch_cache_db_handle_t *fifo_get_db_handle(void)
{
switch_cache_db_connection_options_t options = { {0} };
switch_cache_db_handle_t *dbh = NULL;
if (!zstr(globals.odbc_dsn)) {
options.odbc_options.dsn = globals.odbc_dsn;
options.odbc_options.user = globals.odbc_user;
options.odbc_options.pass = globals.odbc_pass;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) dbh = NULL;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS)
dbh = NULL;
return dbh;
} else {
options.core_db_options.db_path = globals.dbname;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_CORE_DB, &options) != SWITCH_STATUS_SUCCESS) dbh = NULL;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_CORE_DB, &options) != SWITCH_STATUS_SUCCESS)
dbh = NULL;
return dbh;
}
}
@ -321,7 +322,7 @@ static switch_status_t fifo_execute_sql(char *sql, switch_mutex_t *mutex)
status = switch_cache_db_execute_sql(dbh, sql, NULL);
end:
switch_cache_db_release_db_handle(&dbh);
if (mutex) {
@ -336,16 +337,16 @@ static switch_bool_t fifo_execute_sql_callback(switch_mutex_t *mutex, char *sql,
switch_bool_t ret = SWITCH_FALSE;
char *errmsg = NULL;
switch_cache_db_handle_t *dbh = NULL;
if (mutex) {
switch_mutex_lock(mutex);
}
if (!(dbh = fifo_get_db_handle())) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n");
goto end;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n");
goto end;
}
switch_cache_db_execute_sql_callback(dbh, sql, callback, pdata, &errmsg);
if (errmsg) {
@ -429,7 +430,7 @@ static int node_idle_consumers(fifo_node_t *node)
switch_mutex_unlock(node->mutex);
return total;
}
static switch_status_t hanguphook(switch_core_session_t *session)
@ -441,9 +442,10 @@ static switch_status_t hanguphook(switch_core_session_t *session)
if (state == CS_HANGUP || state == CS_ROUTING) {
if ((uuid = switch_channel_get_variable(channel, "fifo_outbound_uuid"))) {
switch_snprintf(sql, sizeof(sql), "update fifo_outbound set use_count=use_count-1, outbound_call_count=outbound_call_count+1, next_avail=%ld + lag where uuid='%s'",
(long)switch_epoch_time_now(NULL), uuid);
switch_snprintf(sql, sizeof(sql),
"update fifo_outbound set use_count=use_count-1, outbound_call_count=outbound_call_count+1, next_avail=%ld + lag where uuid='%s'",
(long) switch_epoch_time_now(NULL), uuid);
fifo_execute_sql(sql, globals.sql_mutex);
}
switch_core_event_hook_remove_state_change(session, hanguphook);
@ -476,7 +478,7 @@ static void *SWITCH_THREAD_FUNC o_thread_run(switch_thread_t *thread, void *obj)
switch_mutex_lock(globals.mutex);
node = switch_core_hash_find(globals.fifo_hash, h->node_name);
switch_mutex_unlock(globals.mutex);
if (node) {
switch_mutex_lock(node->mutex);
node->ring_consumer_count++;
@ -485,18 +487,20 @@ static void *SWITCH_THREAD_FUNC o_thread_run(switch_thread_t *thread, void *obj)
switch_snprintf(sql, sizeof(sql), "update fifo_outbound set use_count=use_count+1 where uuid='%s'", h->uuid);
fifo_execute_sql(sql, globals.sql_mutex);
switch_event_create(&ovars, SWITCH_EVENT_REQUEST_PARAMS);
switch_assert(ovars);
switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "originate_timeout", "%d", h->timeout);
if (switch_ivr_originate(NULL, &session, &cause, h->originate_string, h->timeout, NULL, NULL, NULL, NULL, ovars, SOF_NONE, NULL) != SWITCH_STATUS_SUCCESS) {
switch_snprintf(sql, sizeof(sql), "update fifo_outbound set use_count=use_count-1, outbound_fail_count=outbound_fail_count+1, next_avail=%ld + lag where uuid='%s'",
(long)switch_epoch_time_now(NULL), h->uuid);
if (switch_ivr_originate(NULL, &session, &cause, h->originate_string, h->timeout, NULL, NULL, NULL, NULL, ovars, SOF_NONE, NULL) !=
SWITCH_STATUS_SUCCESS) {
switch_snprintf(sql, sizeof(sql),
"update fifo_outbound set use_count=use_count-1, outbound_fail_count=outbound_fail_count+1, next_avail=%ld + lag where uuid='%s'",
(long) switch_epoch_time_now(NULL), h->uuid);
fifo_execute_sql(sql, globals.sql_mutex);
goto end;
}
channel = switch_core_session_get_channel(session);
@ -521,7 +525,8 @@ static void *SWITCH_THREAD_FUNC o_thread_run(switch_thread_t *thread, void *obj)
switch_event_destroy(&ovars);
if (node) {
switch_mutex_lock(node->mutex);
if (node->ring_consumer_count-- < 0) node->ring_consumer_count = 0;
if (node->ring_consumer_count-- < 0)
node->ring_consumer_count = 0;
switch_mutex_unlock(node->mutex);
}
switch_core_destroy_memory_pool(&h->pool);
@ -538,7 +543,7 @@ static int place_call_callback(void *pArg, int argc, char **argv, char **columnN
switch_threadattr_t *thd_attr = NULL;
switch_memory_pool_t *pool;
struct call_helper *h;
switch_core_new_memory_pool(&pool);
h = switch_core_alloc(pool, sizeof(*h));
h->pool = pool;
@ -554,7 +559,7 @@ static int place_call_callback(void *pArg, int argc, char **argv, char **columnN
switch_thread_create(&thread, thd_attr, o_thread_run, h, h->pool);
(*need)--;
return *need ? 0 : -1;
}
@ -576,10 +581,10 @@ static void find_consumers(fifo_node_t *node)
static void *SWITCH_THREAD_FUNC node_thread_run(switch_thread_t *thread, void *obj)
{
fifo_node_t *node;
globals.node_thread_running = 1;
while(globals.node_thread_running == 1) {
while (globals.node_thread_running == 1) {
switch_hash_index_t *hi;
void *val;
const void *var;
@ -588,21 +593,21 @@ static void *SWITCH_THREAD_FUNC node_thread_run(switch_thread_t *thread, void *o
switch_mutex_lock(globals.mutex);
for (hi = switch_hash_first(NULL, globals.fifo_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, &var, NULL, &val);
if ((node = (fifo_node_t *) val)) {
if (node->has_outbound && node->ready) {
switch_mutex_lock(node->mutex);
ppl_waiting = node_consumer_wait_count(node);
consumer_total = node->consumer_count;
idle_consumers = node_idle_consumers(node);
if ((node = (fifo_node_t *) val)) {
if (node->has_outbound && node->ready) {
switch_mutex_lock(node->mutex);
ppl_waiting = node_consumer_wait_count(node);
consumer_total = node->consumer_count;
idle_consumers = node_idle_consumers(node);
/* switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"%s waiting %d consumer_total %d idle_consumers %d ring_consumers %d\n", node->name, ppl_waiting, consumer_total, idle_consumers, node->ring_consumer_count); */
if ((ppl_waiting - node->ring_consumer_count > 0)&& (!consumer_total || !idle_consumers)) {
find_consumers(node);
/* switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"%s waiting %d consumer_total %d idle_consumers %d ring_consumers %d\n", node->name, ppl_waiting, consumer_total, idle_consumers, node->ring_consumer_count); */
if ((ppl_waiting - node->ring_consumer_count > 0) && (!consumer_total || !idle_consumers)) {
find_consumers(node);
}
switch_mutex_unlock(node->mutex);
}
switch_mutex_unlock(node->mutex);
}
}
}
switch_mutex_unlock(globals.mutex);
@ -611,7 +616,7 @@ static void *SWITCH_THREAD_FUNC node_thread_run(switch_thread_t *thread, void *o
}
globals.node_thread_running = 0;
return NULL;
}
@ -632,7 +637,7 @@ static int stop_node_thread(void)
if (globals.node_thread_running) {
globals.node_thread_running = -1;
while(globals.node_thread_running) {
while (globals.node_thread_running) {
switch_yield(500000);
if (!--sanity) {
return -1;
@ -643,15 +648,15 @@ static int stop_node_thread(void)
return 0;
}
static void check_cancel(fifo_node_t *node)
static void check_cancel(fifo_node_t *node)
{
int ppl_waiting = node_consumer_wait_count(node);
if (node->ring_consumer_count > 0 && ppl_waiting < 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Outbound call count (%d) exceeds required value for queue %s (%d), "
"Ending extraneous calls\n", node->ring_consumer_count, node->name, ppl_waiting);
switch_core_session_hupall_matching_var("fifo_hangup_check", node->name, SWITCH_CAUSE_ORIGINATOR_CANCEL);
}
}
@ -735,12 +740,12 @@ static uint32_t fifo_add_outbound(const char *node_name, const char *url, uint32
}
switch_mutex_unlock(globals.mutex);
str = switch_mprintf("dial:%s", url);
switch_queue_push(node->fifo_list[priority], (void *) str);
return switch_queue_size(node->fifo_list[priority]);
}
@ -769,16 +774,16 @@ SWITCH_STANDARD_API(fifo_add_outbound_function)
stream->write_function(stream, "%d", fifo_add_outbound(argv[0], argv[1], priority));
free(data);
return SWITCH_STATUS_SUCCESS;
free(data);
return SWITCH_STATUS_SUCCESS;
fail:
fail:
free(data);
free(data);
stream->write_function(stream, "0");
return SWITCH_STATUS_SUCCESS;
return SWITCH_STATUS_SUCCESS;
}
@ -868,7 +873,7 @@ SWITCH_STANDARD_APP(fifo_function)
}
}
if (!(node = switch_core_hash_find(globals.fifo_hash, nlist[i]))) {
node = create_node(nlist[i], importance, globals.sql_mutex);
node->ready = 1;
@ -982,7 +987,7 @@ SWITCH_STANDARD_APP(fifo_function)
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Slot", "%d", p);
switch_event_fire(&event);
}
switch_queue_push(node->fifo_list[p], (void *) strdup(uuid));
switch_snprintf(tmp, sizeof(tmp), "%d", switch_queue_size(node->fifo_list[p]));
switch_channel_set_variable(channel, "fifo_position", tmp);
@ -1300,14 +1305,15 @@ SWITCH_STANDARD_APP(fifo_function)
switch_call_cause_t cause = SWITCH_CAUSE_NONE;
const char *o_announce = NULL;
url = uuid + 5;
if ((o_announce = switch_channel_get_variable(channel, "fifo_outbound_announce"))) {
switch_ivr_play_file(session, NULL, o_announce, NULL);
}
if (switch_ivr_originate(session, &other_session, &cause, url, 120, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL) != SWITCH_STATUS_SUCCESS) {
other_session = NULL;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Originate to [%s] failed, cause: %s\n", url, switch_channel_cause2str(cause));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Originate to [%s] failed, cause: %s\n", url,
switch_channel_cause2str(cause));
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(channel, event);
@ -1317,7 +1323,7 @@ SWITCH_STANDARD_APP(fifo_function)
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Outbound-URL", url);
switch_event_fire(&event);
}
} else {
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(channel, event);
@ -1326,7 +1332,7 @@ SWITCH_STANDARD_APP(fifo_function)
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Result", "success");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Outbound-URL", url);
switch_event_fire(&event);
}
}
url = NULL;
free(uuid);
uuid = strdup(switch_core_session_get_uuid(other_session));
@ -1351,7 +1357,7 @@ SWITCH_STANDARD_APP(fifo_function)
const char *record_template = switch_channel_get_variable(channel, "fifo_record_template");
char *expanded = NULL;
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(channel, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Name", argv[0]);
@ -1385,7 +1391,7 @@ SWITCH_STANDARD_APP(fifo_function)
const char *app = switch_channel_get_variable(other_channel, "current_application");
const char *arg = switch_channel_get_variable(other_channel, "current_application_data");
switch_caller_extension_t *extension = NULL;
switch_mutex_lock(node->mutex);
node->caller_count--;
switch_core_hash_delete(node->caller_hash, uuid);
@ -1454,7 +1460,7 @@ SWITCH_STANDARD_APP(fifo_function)
switch_ivr_multi_threaded_bridge(session, other_session, on_dtmf, other_session, session);
switch_core_media_bug_pause(session);
switch_core_media_bug_pause(other_session);
if (record_template) {
switch_ivr_stop_record_session(session, expanded);
if (expanded != record_template) {
@ -1487,7 +1493,7 @@ SWITCH_STANDARD_APP(fifo_function)
fifo_consumer_wrapup_sound = switch_channel_get_variable(channel, "fifo_consumer_wrapup_sound");
fifo_consumer_wrapup_key = switch_channel_get_variable(channel, "fifo_consumer_wrapup_key");
sfifo_consumer_wrapup_time = switch_channel_get_variable(channel, "fifo_consumer_wrapup_time");
if (!zstr(sfifo_consumer_wrapup_time)){
if (!zstr(sfifo_consumer_wrapup_time)) {
fifo_consumer_wrapup_time = atoi(sfifo_consumer_wrapup_time);
} else {
fifo_consumer_wrapup_time = 5000;
@ -1511,15 +1517,15 @@ SWITCH_STANDARD_APP(fifo_function)
args.buflen = sizeof(buf);
switch_ivr_play_file(session, NULL, fifo_consumer_wrapup_sound, &args);
}
if (fifo_consumer_wrapup_time) {
wrapup_time_started = switch_micro_time_now();
}
if (!zstr(fifo_consumer_wrapup_key) && strcmp(buf, fifo_consumer_wrapup_key)) {
while(switch_channel_ready(channel)) {
while (switch_channel_ready(channel)) {
char terminator = 0;
if (fifo_consumer_wrapup_time) {
wrapup_time_elapsed = (switch_micro_time_now() - wrapup_time_started) / 1000;
if (wrapup_time_elapsed > fifo_consumer_wrapup_time) {
@ -1529,14 +1535,15 @@ SWITCH_STANDARD_APP(fifo_function)
}
}
switch_ivr_collect_digits_count(session, buf, sizeof(buf) - 1, 1, fifo_consumer_wrapup_key, &terminator, 0, 0, (uint32_t) wrapup_time_remaining);
switch_ivr_collect_digits_count(session, buf, sizeof(buf) - 1, 1, fifo_consumer_wrapup_key, &terminator, 0, 0,
(uint32_t) wrapup_time_remaining);
if ((terminator == *fifo_consumer_wrapup_key) || !(switch_channel_ready(channel))) {
break;
}
}
} else if (fifo_consumer_wrapup_time && (zstr(fifo_consumer_wrapup_key) || !strcmp(buf, fifo_consumer_wrapup_key))) {
while(switch_channel_ready(channel)) {
while (switch_channel_ready(channel)) {
wrapup_time_elapsed = (switch_micro_time_now() - wrapup_time_started) / 1000;
if (wrapup_time_elapsed > fifo_consumer_wrapup_time) {
break;
@ -1546,7 +1553,7 @@ SWITCH_STANDARD_APP(fifo_function)
}
switch_channel_set_variable(channel, "fifo_status", "WAITING");
}
if (do_wait && switch_channel_ready(channel)) {
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(channel, event);
@ -1556,7 +1563,7 @@ SWITCH_STANDARD_APP(fifo_function)
}
}
}
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(channel, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Name", argv[0]);
@ -1577,7 +1584,7 @@ SWITCH_STANDARD_APP(fifo_function)
}
}
done:
done:
switch_mutex_lock(globals.mutex);
if (node && node->ready == FIFO_DELAY_DESTROY && node->consumer_count == 0 && node->caller_count == 0) {
@ -1636,7 +1643,7 @@ static int xml_callback(void *pArg, int argc, char **argv, char **columnNames)
switch_xml_set_attr_d(x_out, "outbound-call-count", argv[10]);
switch_xml_set_attr_d(x_out, "outbound-fail-count", argv[11]);
switch_xml_set_attr_d(x_out, "next-available", expires);
switch_xml_set_txt_d(x_out, argv[2]);
return 0;
@ -1657,7 +1664,7 @@ static int xml_outbound(switch_xml_t xml, fifo_node_t *node, char *container, ch
h.verbose = verbose;
fifo_execute_sql_callback(globals.sql_mutex, sql, xml_callback, &h);
switch_safe_free(sql);
return h.cc_off;
@ -1736,7 +1743,7 @@ static void list_node(fifo_node_t *node, switch_xml_t x_report, int *off, int ve
switch_xml_set_attr_d(x_fifo, "waiting_count", tmp);
switch_snprintf(tmp, sizeof(buffer), "%u", node->importance);
switch_xml_set_attr_d(x_fifo, "importance", tmp);
cc_off = xml_outbound(x_fifo, node, "outbound", "member", cc_off, verbose);
cc_off = xml_hash(x_fifo, node->caller_hash, "callers", "caller", cc_off, verbose);
cc_off = xml_hash(x_fifo, node->consumer_hash, "consumers", "consumer", cc_off, verbose);
@ -1851,7 +1858,7 @@ SWITCH_STANDARD_API(fifo_api_function)
}
const char outbound_sql[] =
const char outbound_sql[] =
"create table fifo_outbound (\n"
" uuid varchar(255),\n"
" fifo_name varchar(255),\n"
@ -1861,19 +1868,14 @@ const char outbound_sql[] =
" timeout integer,\n"
" lag integer,\n"
" next_avail integer,\n"
" expires integer,\n"
" static integer,\n"
" outbound_call_count integer,"
" outbound_fail_count integer,"
" hostname varchar(255)\n"
");\n";
" expires integer,\n" " static integer,\n" " outbound_call_count integer," " outbound_fail_count integer," " hostname varchar(255)\n" ");\n";
static switch_status_t load_config(int reload, int del_all)
{
char *cf = "fifo.conf";
switch_xml_t cfg, xml, fifo, fifos, member, settings, param;
switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_status_t status = SWITCH_STATUS_SUCCESS;
char *sql;
switch_bool_t delete_all_outbound_member_on_startup = SWITCH_FALSE;
switch_cache_db_handle_t *dbh = NULL;
@ -1892,7 +1894,7 @@ static switch_status_t load_config(int reload, int del_all)
var = (char *) switch_xml_attr_soft(param, "name");
val = (char *) switch_xml_attr_soft(param, "value");
if (!strcasecmp(var, "odbc-dsn") && !zstr(val)) {
if (switch_odbc_available()) {
globals.odbc_dsn = switch_core_strdup(globals.pool, val);
@ -1915,13 +1917,13 @@ static switch_status_t load_config(int reload, int del_all)
globals.dbname = "fifo";
}
if (!(dbh = fifo_get_db_handle())) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot open DB!\n");
goto done;
}
switch_cache_db_test_reactive(dbh, "delete from fifo_outbound where static = 1", "drop table fifo_outbound", outbound_sql);
switch_cache_db_release_db_handle(&dbh);
@ -1939,12 +1941,12 @@ static switch_status_t load_config(int reload, int del_all)
switch_mutex_unlock(globals.mutex);
}
if ((reload && del_all) || (!reload && delete_all_outbound_member_on_startup) ) {
if ((reload && del_all) || (!reload && delete_all_outbound_member_on_startup)) {
sql = switch_mprintf("delete from fifo_outbound where hostname='%q'", globals.hostname);
} else {
sql = switch_mprintf("delete from fifo_outbound where static=1 and hostname='%q'", globals.hostname);
}
fifo_execute_sql(sql, globals.sql_mutex);
switch_safe_free(sql);
@ -1959,14 +1961,14 @@ static switch_status_t load_config(int reload, int del_all)
int timeout_i = 60;
int lag_i = 10;
fifo_node_t *node;
name = switch_xml_attr(fifo, "name");
if ((importance = switch_xml_attr(fifo, "importance"))) {
if ((imp = atoi(importance)) < 0) {
imp = 0;
}
}
}
if (!name) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "fifo has no name!\n");
@ -1978,11 +1980,11 @@ static switch_status_t load_config(int reload, int del_all)
node = create_node(name, imp, globals.sql_mutex);
}
switch_mutex_unlock(globals.mutex);
switch_assert(node);
switch_mutex_lock(node->mutex);
for (member = switch_xml_child(fifo, "member"); member; member = member->next) {
const char *simo = switch_xml_attr_soft(member, "simo");
const char *lag = switch_xml_attr_soft(member, "lag");
@ -2007,12 +2009,12 @@ static switch_status_t load_config(int reload, int del_all)
lag_i = 10;
}
}
name_dup = strdup(node->name);
if ((p = strchr(name_dup, '@'))) {
*p = '\0';
}
if (switch_stristr("origination_caller_id", member->txt)) {
sql = switch_mprintf("insert into fifo_outbound "
"(uuid, fifo_name, originate_string, simo_count, use_count, timeout, lag, "
@ -2030,7 +2032,7 @@ static switch_status_t load_config(int reload, int del_all)
"'{execute_on_answer=''unset fifo_hangup_check'',fifo_hangup_check=''%q'',origination_caller_id_name=Queue,"
"origination_caller_id_number=''fifo+%q''}%q',%d,%d,%d,%d,0,0,1,0,0,'%q')",
digest, node->name, node->name, name_dup, member->txt, simo_i, 0, timeout_i, lag_i, globals.hostname);
}
switch_assert(sql);
@ -2038,14 +2040,14 @@ static switch_status_t load_config(int reload, int del_all)
free(sql);
free(name_dup);
node->has_outbound = 1;
}
node->ready = 1;
node->is_static = 1;
switch_mutex_unlock(node->mutex);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s configured\n", node->name);
}
}
switch_xml_free(xml);
@ -2057,7 +2059,7 @@ static switch_status_t load_config(int reload, int del_all)
void *val, *pop;
fifo_node_t *node;
switch_mutex_lock(globals.mutex);
top:
top:
for (hi = switch_hash_first(NULL, globals.fifo_hash); hi; hi = switch_hash_next(hi)) {
int x = 0;
switch_hash_this(hi, NULL, NULL, &val);
@ -2076,7 +2078,7 @@ static switch_status_t load_config(int reload, int del_all)
free(pop);
}
}
switch_core_hash_delete(globals.fifo_hash, node->name);
switch_core_hash_destroy(&node->caller_hash);
switch_core_hash_destroy(&node->consumer_hash);
@ -2099,15 +2101,15 @@ static void fifo_member_add(char *fifo_name, char *originate_string, int simo_co
char digest[SWITCH_MD5_DIGEST_STRING_SIZE] = { 0 };
char *sql, *name_dup, *p;
fifo_node_t *node = NULL;
switch_md5_string(digest, (void *) originate_string, strlen(originate_string));
sql = switch_mprintf("delete from fifo_outbound where fifo_name='%q' and uuid = '%q'", fifo_name, digest);
switch_assert(sql);
fifo_execute_sql(sql, globals.sql_mutex);
free(sql);
switch_mutex_lock(globals.mutex);
if (!(node = switch_core_hash_find(globals.fifo_hash, fifo_name))) {
node = create_node(fifo_name, 0, globals.sql_mutex);
@ -2115,7 +2117,7 @@ static void fifo_member_add(char *fifo_name, char *originate_string, int simo_co
}
switch_mutex_unlock(globals.mutex);
node->has_outbound = 1;
node->has_outbound = 1;
name_dup = strdup(fifo_name);
if ((p = strchr(name_dup, '@'))) {
@ -2128,13 +2130,12 @@ static void fifo_member_add(char *fifo_name, char *originate_string, int simo_co
"values ('%q','%q',"
"'{execute_on_answer=''unset fifo_hangup_check'',fifo_hangup_check=''%q'',origination_caller_id_name=Queue,"
"origination_caller_id_number=''fifo+%q''}%q',%d,%d,%d,%d,%d,%ld,0,0,0,'%q')",
digest, fifo_name, fifo_name, name_dup, originate_string, simo_count, 0, timeout, lag, 0, (long)expires, globals.hostname
);
digest, fifo_name, fifo_name, name_dup, originate_string, simo_count, 0, timeout, lag, 0, (long) expires, globals.hostname);
switch_assert(sql);
fifo_execute_sql(sql, globals.sql_mutex);
free(sql);
free(name_dup);
}
static void fifo_member_del(char *fifo_name, char *originate_string)
@ -2143,7 +2144,7 @@ static void fifo_member_del(char *fifo_name, char *originate_string)
char *sql;
switch_md5_string(digest, (void *) originate_string, strlen(originate_string));
sql = switch_mprintf("delete from fifo_outbound where fifo_name='%q' and uuid = '%q' and hostname='%q'", fifo_name, digest, globals.hostname);
switch_assert(sql);
fifo_execute_sql(sql, globals.sql_mutex);
@ -2167,7 +2168,7 @@ SWITCH_STANDARD_API(fifo_member_api_function)
return SWITCH_STATUS_FALSE;
}
if (zstr(cmd)){
if (zstr(cmd)) {
stream->write_function(stream, "-USAGE: %s\n", FIFO_MEMBER_API_SYNTAX);
return SWITCH_STATUS_SUCCESS;
}
@ -2181,11 +2182,11 @@ SWITCH_STANDARD_API(fifo_member_api_function)
stream->write_function(stream, "%s", "-ERR Invalid!\n");
goto done;
}
action = argv[0];
fifo_name = argv[1];
originate_string = argv[2];
if (action && !strcasecmp(action, "add")) {
if (argc > 3) {
simo_count = atoi(argv[3]);
@ -2208,7 +2209,7 @@ SWITCH_STANDARD_API(fifo_member_api_function)
if (lag < 0) {
lag = 5;
}
fifo_member_add(fifo_name, originate_string, simo_count, timeout, lag, expires);
stream->write_function(stream, "%s", "+OK\n");
} else if (action && !strcasecmp(action, "del")) {
@ -2240,7 +2241,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_fifo_load)
}
/* Subscribe to presence request events */
if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_PROBE, SWITCH_EVENT_SUBCLASS_ANY,
if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_PROBE, SWITCH_EVENT_SUBCLASS_ANY,
pres_event_handler, NULL, &globals.node) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't subscribe to presence request events!\n");
return SWITCH_STATUS_GENERR;
@ -2250,10 +2251,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_fifo_load)
switch_core_hash_init(&globals.fifo_hash, globals.pool);
switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool);
switch_mutex_init(&globals.sql_mutex, SWITCH_MUTEX_NESTED, globals.pool);
globals.running = 1;
if ((status = load_config(0,1)) != SWITCH_STATUS_SUCCESS) {
if ((status = load_config(0, 1)) != SWITCH_STATUS_SUCCESS) {
switch_event_unbind(&globals.node);
switch_event_free_subclass(FIFO_EVENT);
switch_core_hash_destroy(&globals.fifo_hash);
@ -2287,24 +2288,24 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_fifo_shutdown)
fifo_node_t *node;
switch_memory_pool_t *pool = globals.pool;
switch_mutex_t *mutex = globals.mutex;
switch_event_unbind(&globals.node);
switch_event_free_subclass(FIFO_EVENT);
switch_mutex_lock(mutex);
globals.running = 0;
/* Cleanup */
if (globals.node_thread_running) {
stop_node_thread();
}
while ((hi = switch_hash_first(NULL, globals.fifo_hash))) {
int x = 0;
switch_hash_this(hi, NULL, NULL, &val);
node = (fifo_node_t *) val;
switch_thread_rwlock_wrlock(node->rwlock);
for (x = 0; x < MAX_PRI; x++) {
while (switch_queue_trypop(node->fifo_list[x], &pop) == SWITCH_STATUS_SUCCESS) {

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -107,7 +107,7 @@ SWITCH_STANDARD_APP(record_fsv_function)
int fd;
switch_mutex_t *mutex = NULL;
switch_codec_t codec, *vid_codec;
switch_codec_implementation_t read_impl = {0};
switch_codec_implementation_t read_impl = { 0 };
switch_core_session_get_read_impl(session, &read_impl);
switch_channel_answer(channel);
@ -227,8 +227,8 @@ SWITCH_STANDARD_APP(play_fsv_function)
uint32_t ts = 0, last = 0;
switch_timer_t timer = { 0 };
switch_payload_t pt = 0;
switch_codec_implementation_t read_impl = {0};
switch_core_session_get_read_impl(session, &read_impl);
switch_codec_implementation_t read_impl = { 0 };
switch_core_session_get_read_impl(session, &read_impl);
aud_buffer = switch_core_session_alloc(session, SWITCH_RECOMMENDED_BUFFER_SIZE);
vid_buffer = switch_core_session_alloc(session, SWITCH_RECOMMENDED_BUFFER_SIZE);

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -122,7 +122,7 @@ struct profile_obj {
switch_bool_t profile_has_intrastate;
switch_bool_t profile_has_intralata;
switch_bool_t profile_has_npanxx;
switch_bool_t reorder_by_rate;
switch_bool_t quote_in_list;
switch_bool_t info_in_headers;
@ -173,21 +173,21 @@ static const char *do_cid(switch_memory_pool_t *pool, const char *cid, const cha
char *src_regex = NULL;
char *dst_regex = NULL;
switch_channel_t *channel = NULL;
if (!zstr(cid)) {
len = strlen(cid);
} else {
goto done;
}
src = switch_core_strdup(pool, cid);
/* check that this is a valid regexp and split the string */
if ((src[0] == '/') && src[len-1] == '/') {
if ((src[0] == '/') && src[len - 1] == '/') {
/* strip leading / trailing slashes */
src[len-1] = '\0';
src[len - 1] = '\0';
src++;
/* break on first / */
dst = strchr(src, '/');
*dst = '\0';
@ -216,12 +216,12 @@ static const char *do_cid(switch_memory_pool_t *pool, const char *cid, const cha
switch_safe_free(tmp_regex);
dst = dst_regex;
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "expanded src: %s, dst: %s\n", src, dst);
}
if ((proceed = switch_regex_perform(number, src, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
len = (uint32_t) (strlen(src) + strlen(dst) + 10) * proceed; /* guestimate size */
len = (uint32_t) (strlen(src) + strlen(dst) + 10) * proceed; /* guestimate size */
if (!(substituted = switch_core_alloc(pool, len))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Memory Error!\n");
goto done;
@ -233,77 +233,71 @@ static const char *do_cid(switch_memory_pool_t *pool, const char *cid, const cha
}
switch_regex_safe_free(re);
return substituted;
done:
done:
switch_regex_safe_free(re);
return number;
}
static char *get_bridge_data(switch_memory_pool_t *pool, char *dialed_number, char *caller_id, lcr_route cur_route, profile_t *profile, switch_core_session_t *session)
static char *get_bridge_data(switch_memory_pool_t *pool, char *dialed_number, char *caller_id, lcr_route cur_route, profile_t *profile,
switch_core_session_t *session)
{
size_t lstrip;
size_t tstrip;
size_t tstrip;
char *data = NULL;
char *destination_number = NULL;
char *orig_destination_number = NULL;
char *orig_destination_number = NULL;
char *codec = NULL;
char *cid = NULL;
char *header = NULL;
char *user_rate = NULL;
orig_destination_number = destination_number = switch_core_strdup(pool, dialed_number);
tstrip = ((cur_route->digit_len - cur_route->tstrip) + 1);
lstrip = cur_route->lstrip;
if (cur_route->tstrip > 0) {
if (strlen(destination_number) > tstrip) {
destination_number[tstrip] = '\0';
}
else {
} else {
destination_number[0] = '\0';
}
}
}
}
if (cur_route->lstrip > 0) {
if (strlen(destination_number) > lstrip) {
destination_number += lstrip;
}
else {
} else {
destination_number[0] = '\0';
}
}
}
codec = "";
if (!zstr(cur_route->codec)) {
codec = switch_core_sprintf(pool, ",absolute_codec_string=%s", cur_route->codec);
}
cid = "";
if (!zstr(cur_route->cid)) {
cid = switch_core_sprintf(pool, ",origination_caller_id_number=%s",
do_cid(pool, cur_route->cid, caller_id, session));
cid = switch_core_sprintf(pool, ",origination_caller_id_number=%s", do_cid(pool, cur_route->cid, caller_id, session));
}
header = "";
if (profile->info_in_headers) {
header = switch_core_sprintf(pool, ",sip_h_X-LCR-INFO=lcr_rate=%s;lcr_carrier=%s",
cur_route->rate_str,
cur_route->carrier_name);
header = switch_core_sprintf(pool, ",sip_h_X-LCR-INFO=lcr_rate=%s;lcr_carrier=%s", cur_route->rate_str, cur_route->carrier_name);
}
if (zstr(cur_route->user_rate_str)) {
user_rate = "";
} else {
user_rate = switch_core_sprintf(pool, ",lcr_user_rate=%s", cur_route->user_rate_str);
}
data = switch_core_sprintf(pool, "[lcr_carrier=%s,lcr_rate=%s%s%s%s%s]%s%s%s%s%s"
, cur_route->carrier_name, cur_route->rate_str
, user_rate, codec, cid, header
, cur_route->gw_prefix, cur_route->prefix
, destination_number, cur_route->suffix, cur_route->gw_suffix);
data =
switch_core_sprintf(pool, "[lcr_carrier=%s,lcr_rate=%s%s%s%s%s]%s%s%s%s%s", cur_route->carrier_name, cur_route->rate_str, user_rate, codec, cid,
header, cur_route->gw_prefix, cur_route->prefix, destination_number, cur_route->suffix, cur_route->gw_suffix);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Returning Dialstring %s\n", data);
return data;
}
@ -311,13 +305,13 @@ static char *get_bridge_data(switch_memory_pool_t *pool, char *dialed_number, ch
static profile_t *locate_profile(const char *profile_name)
{
profile_t *profile = NULL;
if (zstr(profile_name)) {
profile = globals.default_profile;
} else if (!(profile = switch_core_hash_find(globals.profile_hash, profile_name))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error invalid profile %s\n", profile_name);
}
return profile;
}
@ -365,7 +359,7 @@ static switch_status_t process_max_lengths(max_obj_t *maxes, lcr_route routes, c
if (current->digit_str != NULL) {
if (current->digit_len > maxes->digit_str) {
maxes->digit_str = current->digit_len;
}
}
}
if (current->rate_str != NULL) {
this_len = strlen(current->rate_str);
@ -374,7 +368,7 @@ static switch_status_t process_max_lengths(max_obj_t *maxes, lcr_route routes, c
}
}
if (current->codec != NULL) {
this_len= strlen(current->codec);
this_len = strlen(current->codec);
if (this_len > maxes->codec) {
maxes->codec = this_len;
}
@ -393,13 +387,14 @@ static switch_cache_db_handle_t *lcr_get_db_handle(void)
{
switch_cache_db_connection_options_t options = { {0} };
switch_cache_db_handle_t *dbh = NULL;
if (!zstr(globals.odbc_dsn)) {
options.odbc_options.dsn = globals.odbc_dsn;
options.odbc_options.user = globals.odbc_user;
options.odbc_options.pass = globals.odbc_pass;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) dbh = NULL;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS)
dbh = NULL;
}
return dbh;
}
@ -430,23 +425,23 @@ static switch_bool_t set_db_random()
db_random = "random()";
return SWITCH_TRUE;
}
return SWITCH_FALSE;
}
/* make a new string with digits only */
static char *string_digitsonly(switch_memory_pool_t *pool, const char *str)
static char *string_digitsonly(switch_memory_pool_t *pool, const char *str)
{
char *p, *np, *newstr;
size_t len;
p = (char *)str;
p = (char *) str;
len = strlen(str);
newstr = switch_core_alloc(pool, len+1);
newstr = switch_core_alloc(pool, len + 1);
np = newstr;
while(*p) {
while (*p) {
if (switch_isdigit(*p)) {
*np = *p;
np++;
@ -478,14 +473,10 @@ static char *expand_digits(switch_memory_pool_t *pool, char *digits, switch_bool
digit_len = strlen(digits);
digits_copy = switch_core_strdup(pool, digits);
for (n = digit_len; n > 0; n--) {
digits_copy[n] = '\0';
dig_stream.write_function(&dig_stream, "%s%s%s%s",
(n==digit_len ? "" : ", "),
(quote ? "'" : ""),
digits_copy,
(quote ? "'" : ""));
dig_stream.write_function(&dig_stream, "%s%s%s%s", (n == digit_len ? "" : ", "), (quote ? "'" : ""), digits_copy, (quote ? "'" : ""));
}
ret = switch_core_strdup(pool, dig_stream.data);
@ -496,42 +487,41 @@ static char *expand_digits(switch_memory_pool_t *pool, char *digits, switch_bool
/* format the custom sql */
static char *format_custom_sql(const char *custom_sql, callback_t *cb_struct, const char *digits)
{
char * tmpSQL = NULL;
char * newSQL = NULL;
char *tmpSQL = NULL;
char *newSQL = NULL;
switch_channel_t *channel;
/* first replace %s with digits to maintain backward compat */
if (cb_struct->profile->custom_sql_has_percent == SWITCH_TRUE) {
tmpSQL = switch_string_replace(custom_sql, "%q", digits);
newSQL = tmpSQL;
}
/* expand the vars */
if (cb_struct->profile->custom_sql_has_vars == SWITCH_TRUE) {
if (cb_struct->session) {
channel = switch_core_session_get_channel(cb_struct->session);
switch_assert(channel);
/*
newSQL = switch_channel_expand_variables_escape(channel,
tmpSQL ? tmpSQL : custom_sql,
escape_sql);
*/
newSQL = switch_channel_expand_variables(channel,
tmpSQL ? tmpSQL : custom_sql);
newSQL = switch_channel_expand_variables_escape(channel,
tmpSQL ? tmpSQL : custom_sql,
escape_sql);
*/
newSQL = switch_channel_expand_variables(channel, tmpSQL ? tmpSQL : custom_sql);
} else if (cb_struct->event) {
/* use event system to expand vars */
newSQL = switch_event_expand_headers(cb_struct->event, tmpSQL ? tmpSQL : custom_sql);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_CRIT,
"mod_lcr called without a valid session while using a custom_sql that has channel variables.\n");
"mod_lcr called without a valid session while using a custom_sql that has channel variables.\n");
}
}
if (tmpSQL != newSQL) {
switch_safe_free(tmpSQL);
}
if (newSQL == NULL) {
return (char *) custom_sql;
} else {
@ -543,10 +533,10 @@ static switch_bool_t lcr_execute_sql_callback(char *sql, switch_core_db_callback
{
switch_bool_t retval = SWITCH_FALSE;
switch_cache_db_handle_t *dbh = NULL;
if (globals.odbc_dsn && (dbh = lcr_get_db_handle())) {
if (switch_cache_db_execute_sql_callback(dbh, sql, callback, pdata, NULL)
== SWITCH_ODBC_FAIL) {
== SWITCH_ODBC_FAIL) {
retval = SWITCH_FALSE;
} else {
retval = SWITCH_TRUE;
@ -562,23 +552,21 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa
lcr_route current = NULL;
callback_t *cbt = (callback_t *) pArg;
char *key = NULL;
switch_memory_pool_t *pool = cbt->pool;
if (argc < LCR_QUERY_COLS_REQUIRED) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT,
"Unexpected number of columns returned for SQL. Returned column count: %d. "
"If using a custom sql for this profile, verify it is correct. Otherwise file a bug report.\n",
argc);
"Unexpected number of columns returned for SQL. Returned column count: %d. "
"If using a custom sql for this profile, verify it is correct. Otherwise file a bug report.\n", argc);
return SWITCH_STATUS_GENERR;
}
if (zstr(argv[LCR_GW_PREFIX_PLACE]) && zstr(argv[LCR_GW_SUFFIX_PLACE]) ) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"There's no way to dial this Gateway: Carrier: \"%s\" Prefix: \"%s\", Suffix \"%s\"\n",
switch_str_nil(argv[LCR_CARRIER_PLACE]),
switch_str_nil(argv[LCR_GW_PREFIX_PLACE]), switch_str_nil(argv[LCR_GW_SUFFIX_PLACE]));
if (zstr(argv[LCR_GW_PREFIX_PLACE]) && zstr(argv[LCR_GW_SUFFIX_PLACE])) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"There's no way to dial this Gateway: Carrier: \"%s\" Prefix: \"%s\", Suffix \"%s\"\n",
switch_str_nil(argv[LCR_CARRIER_PLACE]), switch_str_nil(argv[LCR_GW_PREFIX_PLACE]), switch_str_nil(argv[LCR_GW_SUFFIX_PLACE]));
return SWITCH_STATUS_SUCCESS;
}
@ -590,7 +578,7 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa
additional->suffix = switch_core_strdup(pool, switch_str_nil(argv[LCR_SUFFIX_PLACE]));
additional->prefix = switch_core_strdup(pool, switch_str_nil(argv[LCR_PREFIX_PLACE]));
additional->carrier_name = switch_core_strdup(pool, switch_str_nil(argv[LCR_CARRIER_PLACE]));
additional->rate = (float)atof(switch_str_nil(argv[LCR_RATE_PLACE]));
additional->rate = (float) atof(switch_str_nil(argv[LCR_RATE_PLACE]));
additional->rate_str = switch_core_sprintf(pool, "%0.5f", additional->rate);
additional->gw_prefix = switch_core_strdup(pool, switch_str_nil(argv[LCR_GW_PREFIX_PLACE]));
additional->gw_suffix = switch_core_strdup(pool, switch_str_nil(argv[LCR_GW_SUFFIX_PLACE]));
@ -603,7 +591,7 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa
additional->cid = switch_core_strdup(pool, switch_str_nil(argv[LCR_CID_PLACE]));
}
if (argc > LCR_USER_RATE_PLACE) {
additional->user_rate = (float)atof(switch_str_nil(argv[LCR_USER_RATE_PLACE]));
additional->user_rate = (float) atof(switch_str_nil(argv[LCR_USER_RATE_PLACE]));
additional->user_rate_str = switch_core_sprintf(pool, "%0.5f", additional->user_rate);
}
additional->dialstring = get_bridge_data(pool, cbt->lookup_number, cbt->cid, additional, cbt->profile, cbt->session);
@ -620,14 +608,12 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa
return SWITCH_STATUS_SUCCESS;
}
for (current = cbt->head; current; current = current->next) {
key = switch_core_sprintf(pool, "%s:%s", additional->gw_prefix, additional->gw_suffix);
if (switch_core_hash_find(cbt->dedup_hash, key)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"Ignoring Duplicate route for termination point (%s)\n",
key);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Ignoring Duplicate route for termination point (%s)\n", key);
break;
}
@ -647,13 +633,12 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa
if (current->rate > additional->rate) {
/* insert myself here */
if (current->prev != NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding %s before %s\n",
additional->carrier_name, current->carrier_name);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding %s before %s\n", additional->carrier_name, current->carrier_name);
current->prev->next = additional;
} else {
/* put this one at the head */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Inserting %s to list head before %s\n",
additional->carrier_name, current->carrier_name);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Inserting %s to list head before %s\n",
additional->carrier_name, current->carrier_name);
cbt->head = additional;
}
additional->next = current;
@ -665,7 +650,7 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa
break;
} else if (current->next == NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "adding %s to end of list after %s\n",
additional->carrier_name, current->carrier_name);
additional->carrier_name, current->carrier_name);
current->next = additional;
additional->prev = current;
if (switch_core_hash_insert(cbt->dedup_hash, key, additional) != SWITCH_STATUS_SUCCESS) {
@ -683,7 +668,7 @@ static int intrastatelata_callback(void *pArg, int argc, char **argv, char **col
{
int count = 0;
callback_t *cbt = (callback_t *) pArg;
count = atoi(argv[1]);
if (count == 1) {
if (!strcmp(argv[0], "state")) {
@ -693,19 +678,19 @@ static int intrastatelata_callback(void *pArg, int argc, char **argv, char **col
}
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Type: %s, Count: %d\n", argv[0], count);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Type: %s, Count: %d\n", argv[0], count);
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t is_intrastatelata(callback_t *cb_struct)
{
char *sql = NULL;
/* extract npa nxx - make some assumptions about format:
e164 format without the +
NANP only (so 11 digits starting with 1)
*/
e164 format without the +
NANP only (so 11 digits starting with 1)
*/
if (!cb_struct->lookup_number || (strlen(cb_struct->lookup_number) != 11 && *cb_struct->lookup_number != '1')) {
/* dest doesn't appear to be NANP number */
return SWITCH_STATUS_GENERR;
@ -714,29 +699,28 @@ static switch_status_t is_intrastatelata(callback_t *cb_struct)
/* cid not NANP */
return SWITCH_STATUS_GENERR;
}
/* assume that if the area code (plus leading 1) are the same we're intrastate */
/* probably a bad assumption */
/*
if (!strncmp(cb_struct->lookup_number, cb_struct->cid, 4)) {
cb_struct->intrastate = SWITCH_TRUE;
return SWITCH_STATUS_SUCCESS;
}
*/
if (!strncmp(cb_struct->lookup_number, cb_struct->cid, 4)) {
cb_struct->intrastate = SWITCH_TRUE;
return SWITCH_STATUS_SUCCESS;
}
*/
sql = switch_core_sprintf(cb_struct->pool,
"SELECT 'state', count(DISTINCT state) FROM npa_nxx_company_ocn WHERE (npa=%3.3s AND nxx=%3.3s) OR (npa=%3.3s AND nxx=%3.3s)"
" UNION "
"SELECT 'lata', count(DISTINCT lata) FROM npa_nxx_company_ocn WHERE (npa=%3.3s AND nxx=%3.3s) OR (npa=%3.3s AND nxx=%3.3s)",
cb_struct->lookup_number+1, cb_struct->lookup_number+4,
cb_struct->cid+1, cb_struct->cid+4,
cb_struct->lookup_number+1, cb_struct->lookup_number+4,
cb_struct->cid+1, cb_struct->cid+4);
"SELECT 'state', count(DISTINCT state) FROM npa_nxx_company_ocn WHERE (npa=%3.3s AND nxx=%3.3s) OR (npa=%3.3s AND nxx=%3.3s)"
" UNION "
"SELECT 'lata', count(DISTINCT lata) FROM npa_nxx_company_ocn WHERE (npa=%3.3s AND nxx=%3.3s) OR (npa=%3.3s AND nxx=%3.3s)",
cb_struct->lookup_number + 1, cb_struct->lookup_number + 4,
cb_struct->cid + 1, cb_struct->cid + 4,
cb_struct->lookup_number + 1, cb_struct->lookup_number + 4, cb_struct->cid + 1, cb_struct->cid + 4);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_DEBUG, "SQL: %s\n", sql);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_DEBUG, "SQL: %s\n", sql);
return (lcr_execute_sql_callback(sql, intrastatelata_callback, cb_struct));
return(lcr_execute_sql_callback(sql, intrastatelata_callback, cb_struct));
}
static switch_status_t lcr_do_lookup(callback_t *cb_struct)
@ -752,26 +736,26 @@ static switch_status_t lcr_do_lookup(callback_t *cb_struct)
char *safe_sql = NULL;
char *rate_field = NULL;
char *user_rate_field = NULL;
switch_assert(cb_struct->lookup_number != NULL);
digits_copy = string_digitsonly(cb_struct->pool, digits);
if (zstr(digits_copy)) {
return SWITCH_STATUS_GENERR;
}
/* allocate the dedup hash */
if (switch_core_hash_init(&cb_struct->dedup_hash, cb_struct->pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_ERROR, "Error initializing the dedup hash\n");
return SWITCH_STATUS_GENERR;
}
digits_expanded = expand_digits(cb_struct->pool, digits_copy, cb_struct->profile->quote_in_list);
if (profile->profile_has_npanxx == SWITCH_TRUE) {
is_intrastatelata(cb_struct);
}
/* set our rate field based on env and profile */
if (cb_struct->intralata == SWITCH_TRUE && profile->profile_has_intralata == SWITCH_TRUE) {
rate_field = switch_core_strdup(cb_struct->pool, "intralata_rate");
@ -785,7 +769,7 @@ static switch_status_t lcr_do_lookup(callback_t *cb_struct)
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_DEBUG, "intra routing [state:%d lata:%d] so rate field is [%s]\n",
cb_struct->intrastate, cb_struct->intralata, rate_field);
/* set some channel vars if we have a session */
if (cb_struct->session) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_DEBUG, "we have a session\n");
@ -822,10 +806,10 @@ static switch_status_t lcr_do_lookup(callback_t *cb_struct)
/* channel_expand_variables returned the same string to us, no need to free */
switch_safe_free(safe_sql);
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_DEBUG, "SQL: %s\n", (char *)sql_stream.data);
lookup_status = lcr_execute_sql_callback((char *)sql_stream.data, route_add_callback, cb_struct);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_DEBUG, "SQL: %s\n", (char *) sql_stream.data);
lookup_status = lcr_execute_sql_callback((char *) sql_stream.data, route_add_callback, cb_struct);
switch_safe_free(sql_stream.data);
switch_event_safe_destroy(&cb_struct->event);
@ -848,16 +832,15 @@ static switch_bool_t test_profile(char *lcr_profile)
switch_event_create(&event, SWITCH_EVENT_MESSAGE);
routes.event = event;
routes.pool = pool;
if (!(routes.profile = locate_profile(lcr_profile))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown profile: %s\n", lcr_profile);
return SWITCH_FALSE;
}
routes.lookup_number = "15555551212";
routes.cid = "18005551212";
return (lcr_do_lookup(&routes) == SWITCH_STATUS_SUCCESS) ?
SWITCH_TRUE : SWITCH_FALSE;
return (lcr_do_lookup(&routes) == SWITCH_STATUS_SUCCESS) ? SWITCH_TRUE : SWITCH_FALSE;
}
static switch_status_t lcr_load_config()
@ -893,19 +876,16 @@ static switch_status_t lcr_load_config()
}
}
}
/* initialize sql here, 'cause we need to verify custom_sql for each profile below */
if (globals.odbc_dsn) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG
, "dsn is \"%s\", user is \"%s\"\n"
, globals.odbc_dsn, globals.odbc_user
);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "dsn is \"%s\", user is \"%s\"\n", globals.odbc_dsn, globals.odbc_user);
if (!(dbh = lcr_get_db_handle())) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open ODBC Database!\n");
switch_goto_status(SWITCH_STATUS_FALSE, done);
}
}
if (set_db_random() == SWITCH_TRUE) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Database RANDOM function set to %s\n", db_random);
} else {
@ -926,7 +906,7 @@ static switch_status_t lcr_load_config()
char *custom_sql = NULL;
int argc, x = 0;
char *argv[4] = { 0 };
SWITCH_STANDARD_STREAM(order_by);
for (param = switch_xml_child(x_profile, "param"); param; param = param->next) {
@ -934,12 +914,12 @@ static switch_status_t lcr_load_config()
var = (char *) switch_xml_attr_soft(param, "name");
val = (char *) switch_xml_attr_soft(param, "value");
if (!strcasecmp(var, "order_by") && !zstr(val)) {
if (!strcasecmp(var, "order_by") && !zstr(val)) {
thisorder = &order_by;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "param val is %s\n", val);
if ((argc = switch_separate_string(val, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) {
for (x=0; x<argc; x++) {
for (x = 0; x < argc; x++) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "arg #%d/%d is %s\n", x, argc, argv[x]);
if (!zstr(argv[x])) {
if (!strcasecmp(argv[x], "quality")) {
@ -976,37 +956,37 @@ static switch_status_t lcr_load_config()
quote_in_list = val;
}
}
if (zstr(name)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No name specified.\n");
} else {
profile = switch_core_alloc(globals.pool, sizeof(*profile));
memset(profile, 0, sizeof(profile_t));
profile->name = switch_core_strdup(globals.pool, name);
if (!zstr((char *)order_by.data)) {
profile->order_by = switch_core_strdup(globals.pool, (char *)order_by.data);
if (!zstr((char *) order_by.data)) {
profile->order_by = switch_core_strdup(globals.pool, (char *) order_by.data);
} else {
/* default to rate */
profile->order_by = ", ${lcr_rate_field}";
}
if (!zstr(id_s)) {
profile->id = (uint16_t)atoi(id_s);
profile->id = (uint16_t) atoi(id_s);
}
/* SWITCH_STANDARD_STREAM doesn't use pools. but we only have to free sql_stream.data */
SWITCH_STANDARD_STREAM(sql_stream);
if (zstr(custom_sql)) {
/* use default sql */
sql_stream.write_function(&sql_stream,
"SELECT l.digits, c.carrier_name, l.${lcr_rate_field}, cg.prefix AS gw_prefix, cg.suffix AS gw_suffix, l.lead_strip, l.trail_strip, l.prefix, l.suffix "
);
sql_stream.write_function(&sql_stream,
"SELECT l.digits, c.carrier_name, l.${lcr_rate_field}, cg.prefix AS gw_prefix, cg.suffix AS gw_suffix, l.lead_strip, l.trail_strip, l.prefix, l.suffix ");
if (db_check("SELECT codec from carrier_gateway limit 1") == SWITCH_TRUE) {
sql_stream.write_function(&sql_stream, ", cg.codec ");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "codec field defined.\n");
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "codec field not defined, please update your lcr carrier_gateway database schema.\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"codec field not defined, please update your lcr carrier_gateway database schema.\n");
}
if (db_check("SELECT cid from lcr limit 1") == SWITCH_TRUE) {
sql_stream.write_function(&sql_stream, ", l.cid ");
@ -1014,41 +994,38 @@ static switch_status_t lcr_load_config()
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "cid field not defined, please update your lcr database schema.\n");
}
sql_stream.write_function(&sql_stream, "FROM lcr l JOIN carriers c ON l.carrier_id=c.id JOIN carrier_gateway cg ON c.id=cg.carrier_id WHERE c.enabled = '1' AND cg.enabled = '1' AND l.enabled = '1' AND digits IN (");
sql_stream.write_function(&sql_stream,
"FROM lcr l JOIN carriers c ON l.carrier_id=c.id JOIN carrier_gateway cg ON c.id=cg.carrier_id WHERE c.enabled = '1' AND cg.enabled = '1' AND l.enabled = '1' AND digits IN (");
sql_stream.write_function(&sql_stream, "${lcr_query_expanded_digits}");
sql_stream.write_function(&sql_stream, ") AND CURRENT_TIMESTAMP BETWEEN date_start AND date_end ");
if (profile->id > 0) {
sql_stream.write_function(&sql_stream, "AND lcr_profile=%d ", profile->id);
}
sql_stream.write_function(&sql_stream, "ORDER BY digits DESC%s",
profile->order_by);
sql_stream.write_function(&sql_stream, "ORDER BY digits DESC%s", profile->order_by);
if (db_random) {
sql_stream.write_function(&sql_stream, ", %s", db_random);
}
sql_stream.write_function(&sql_stream, ";");
custom_sql = sql_stream.data;
}
profile->profile_has_intralata = db_check("SELECT intralata_rate FROM lcr LIMIT 1");
if (profile->profile_has_intralata != SWITCH_TRUE) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"no \"intralata_rate\" field found in the \"lcr\" table, routing by intralata rates will be disabled until the field is added and mod_lcr is reloaded\n"
);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"no \"intralata_rate\" field found in the \"lcr\" table, routing by intralata rates will be disabled until the field is added and mod_lcr is reloaded\n");
}
profile->profile_has_intrastate = db_check("SELECT intrastate_rate FROM lcr LIMIT 1");
if (profile->profile_has_intrastate != SWITCH_TRUE) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"no \"intrastate_rate\" field found in the \"lcr\" table, routing by intrastate rates will be disabled until the field is added and mod_lcr is reloaded\n"
);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"no \"intrastate_rate\" field found in the \"lcr\" table, routing by intrastate rates will be disabled until the field is added and mod_lcr is reloaded\n");
}
profile->profile_has_npanxx = db_check("SELECT npa, nxx, state FROM npa_nxx_company_ocn LIMIT 1");
if (profile->profile_has_npanxx != SWITCH_TRUE) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"no \"npa_nxx_company_ocn\" table found in the \"lcr\" database, automatic intrastate detection will be disabled until the table is added and mod_lcr is reloaded\n"
);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"no \"npa_nxx_company_ocn\" table found in the \"lcr\" database, automatic intrastate detection will be disabled until the table is added and mod_lcr is reloaded\n");
}
if (switch_string_var_check_const(custom_sql) || switch_string_has_escaped_data(custom_sql)) {
@ -1057,20 +1034,20 @@ static switch_status_t lcr_load_config()
if (strstr(custom_sql, "%")) {
profile->custom_sql_has_percent = SWITCH_TRUE;
}
profile->custom_sql = switch_core_strdup(globals.pool, (char *)custom_sql);
profile->custom_sql = switch_core_strdup(globals.pool, (char *) custom_sql);
if (!zstr(reorder_by_rate)) {
profile->reorder_by_rate = switch_true(reorder_by_rate);
}
if (!zstr(info_in_headers)) {
profile->info_in_headers = switch_true(info_in_headers);
}
if (!zstr(quote_in_list)) {
profile->quote_in_list = switch_true(quote_in_list);
}
switch_core_hash_insert(globals.profile_hash, profile->name, profile);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Loaded lcr profile %s.\n", profile->name);
/* test the profile */
@ -1083,7 +1060,7 @@ static switch_status_t lcr_load_config()
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Removing INVALID Profile %s.\n", profile->name);
switch_core_hash_delete(globals.profile_hash, profile->name);
}
}
switch_safe_free(order_by.data);
switch_safe_free(sql_stream.data);
@ -1091,7 +1068,7 @@ static switch_status_t lcr_load_config()
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "No lcr profiles defined.\n");
}
/* define default profile */
if (!globals.default_profile) {
profile = switch_core_alloc(globals.pool, sizeof(*profile));
@ -1102,7 +1079,7 @@ static switch_status_t lcr_load_config()
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting system defined default profile.");
}
done:
done:
switch_cache_db_release_db_handle(&dbh);
switch_xml_free(xml);
return status;
@ -1138,17 +1115,17 @@ SWITCH_STANDARD_DIALPLAN(lcr_dialplan_hunt)
intralata = switch_channel_get_variable(channel, "intralata");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "intrastate channel var is [%s]\n", intrastate);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "intralata channel var is [%s]\n", intralata);
if (!zstr(intralata) && !strcasecmp((char *)intralata, "true")) {
if (!zstr(intralata) && !strcasecmp((char *) intralata, "true")) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Select routes based on intralata rates\n");
routes.intralata = SWITCH_FALSE;
} else if (!zstr(intrastate) && !strcasecmp((char *)intrastate, "true")) {
} else if (!zstr(intrastate) && !strcasecmp((char *) intrastate, "true")) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Select routes based on intrastate rates\n");
routes.intrastate = SWITCH_TRUE;
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Select routes based on interstate rates\n");
routes.intrastate = SWITCH_FALSE;
}
if (!caller_profile) {
caller_profile = switch_channel_get_caller_profile(channel);
}
@ -1173,7 +1150,7 @@ SWITCH_STANDARD_DIALPLAN(lcr_dialplan_hunt)
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "LCR lookup failed for %s\n", caller_profile->destination_number);
}
end:
end:
if (!session) {
switch_core_destroy_memory_pool(&pool);
}
@ -1184,9 +1161,9 @@ void str_repeat(size_t how_many, char *what, switch_stream_handle_t *str_stream)
{
size_t i;
/*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "repeating %d of '%s'\n", (int)how_many, what);*/
for (i=0; i<how_many; i++) {
/*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "repeating %d of '%s'\n", (int)how_many, what); */
for (i = 0; i < how_many; i++) {
str_stream->write_function(str_stream, "%s", what);
}
}
@ -1227,9 +1204,8 @@ SWITCH_STANDARD_APP(lcr_app_function)
routes.pool = pool;
intra = switch_channel_get_variable(channel, "intrastate");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "intrastate channel var is [%s]\n",
zstr(intra) ? "undef" : intra);
if (zstr(intra) || strcasecmp((char *)intra, "true")) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "intrastate channel var is [%s]\n", zstr(intra) ? "undef" : intra);
if (zstr(intra) || strcasecmp((char *) intra, "true")) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Select routes based on interstate rates\n");
routes.intrastate = SWITCH_FALSE;
} else {
@ -1248,7 +1224,7 @@ SWITCH_STANDARD_APP(lcr_app_function)
if (argc > 1) {
lcr_profile = argv[1];
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "LCR Lookup on %s using profile %s\n", dest, lcr_profile);
routes.lookup_number = dest;
if (caller_profile) {
@ -1258,7 +1234,7 @@ SWITCH_STANDARD_APP(lcr_app_function)
}
}
if (!(routes.profile = locate_profile(lcr_profile))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unknown profile: %s\n", lcr_profile);
goto end;
@ -1289,16 +1265,17 @@ SWITCH_STANDARD_APP(lcr_app_function)
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "LCR lookup failed for %s\n", dest);
}
}
end:
end:
if (!session) {
switch_core_destroy_memory_pool(&pool);
}
}
static void write_data(switch_stream_handle_t *stream, switch_bool_t as_xml, const char *key, const char *data, int indent, int maxlen) {
static void write_data(switch_stream_handle_t *stream, switch_bool_t as_xml, const char *key, const char *data, int indent, int maxlen)
{
if (as_xml) {
str_repeat(indent*2, " ", stream);
str_repeat(indent * 2, " ", stream);
stream->write_function(stream, "<%s>%s</%s>\n", key, data, key);
} else {
stream->write_function(stream, " | %s", data);
@ -1320,15 +1297,13 @@ SWITCH_STANDARD_API(dialplan_lcr_function)
switch_event_t *event;
switch_status_t lookup_status = SWITCH_STATUS_SUCCESS;
switch_bool_t as_xml = SWITCH_FALSE;
int rowcount=0;
int rowcount = 0;
if (zstr(cmd)) {
goto usage;
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG
, "data passed to lcr is [%s]\n", cmd
);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "data passed to lcr is [%s]\n", cmd);
if (session) {
pool = switch_core_session_get_pool(session);
@ -1339,7 +1314,7 @@ SWITCH_STANDARD_API(dialplan_lcr_function)
cb_struct.event = event;
}
cb_struct.pool = pool;
mydata = switch_core_strdup(pool, cmd);
if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
@ -1350,29 +1325,27 @@ SWITCH_STANDARD_API(dialplan_lcr_function)
}
if (argc > 2) {
int i;
for (i=2; i<argc; i++) {
for (i = 2; i < argc; i++) {
if (!strcasecmp(argv[i], "intrastate")) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Select routes based on intrastate rates\n");
cb_struct.intrastate = SWITCH_TRUE;
} else if (!strcasecmp(argv[i], "as")) {
i++;
if (argv[i] && !strcasecmp(argv[i], "xml")) {
as_xml = SWITCH_TRUE;
} else {
goto usage;
}
as_xml = SWITCH_TRUE;
} else {
goto usage;
}
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set Caller ID to [%s]\n", argv[i]);
/* the only other option we have right now is caller id */
cb_struct.cid = switch_core_strdup(pool, argv[i]);
}
}
}
}
if (zstr(cb_struct.cid)) {
cb_struct.cid = "18005551212";
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING
, "Using default CID [%s]\n", cb_struct.cid
);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Using default CID [%s]\n", cb_struct.cid);
}
@ -1432,7 +1405,7 @@ SWITCH_STANDARD_API(dialplan_lcr_function)
if (as_xml) {
stream->write_function(stream, " <row id=\"%d\">\n", rowcount);
}
write_data(stream, as_xml, "prefix", current->digit_str, 2, maximum_lengths.digit_str);
write_data(stream, as_xml, "carrier_name", current->carrier_name, 2, maximum_lengths.carrier_name);
write_data(stream, as_xml, "rate", current->rate_str, 2, maximum_lengths.rate);
@ -1447,7 +1420,7 @@ SWITCH_STANDARD_API(dialplan_lcr_function)
} else {
write_data(stream, as_xml, "cid", "", 2, maximum_lengths.cid);
}
write_data(stream, as_xml, "dialstring", current->dialstring, 2, maximum_lengths.dialstring);
if (as_xml) {
@ -1473,14 +1446,14 @@ SWITCH_STANDARD_API(dialplan_lcr_function)
}
}
end:
end:
if (!session) {
if (pool) {
switch_core_destroy_memory_pool(&pool);
}
}
return SWITCH_STATUS_SUCCESS;
usage:
usage:
stream->write_function(stream, "USAGE: %s\n", LCR_SYNTAX);
goto end;
}
@ -1509,7 +1482,7 @@ SWITCH_STANDARD_API(dialplan_lcr_admin_function)
for (hi = switch_hash_first(NULL, globals.profile_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, NULL, NULL, &val);
profile = (profile_t *) val;
stream->write_function(stream, "Name:\t\t%s\n", profile->name);
if (zstr(profile->custom_sql)) {
stream->write_function(stream, " ID:\t\t%d\n", profile->id);
@ -1522,12 +1495,9 @@ SWITCH_STANDARD_API(dialplan_lcr_admin_function)
stream->write_function(stream, " has intrastate:\t%s\n", profile->profile_has_intrastate ? "true" : "false");
stream->write_function(stream, " has intralata:\t%s\n", profile->profile_has_intralata ? "true" : "false");
stream->write_function(stream, " has npanxx:\t%s\n", profile->profile_has_npanxx ? "true" : "false");
stream->write_function(stream, " Reorder rate:\t%s\n",
profile->reorder_by_rate ? "enabled" : "disabled");
stream->write_function(stream, " Info in headers:\t%s\n",
profile->info_in_headers ? "enabled" : "disabled");
stream->write_function(stream, " Quote IN() List:\t%s\n",
profile->quote_in_list ? "enabled" : "disabled");
stream->write_function(stream, " Reorder rate:\t%s\n", profile->reorder_by_rate ? "enabled" : "disabled");
stream->write_function(stream, " Info in headers:\t%s\n", profile->info_in_headers ? "enabled" : "disabled");
stream->write_function(stream, " Quote IN() List:\t%s\n", profile->quote_in_list ? "enabled" : "disabled");
stream->write_function(stream, "\n");
}
} else {
@ -1536,20 +1506,20 @@ SWITCH_STANDARD_API(dialplan_lcr_admin_function)
}
switch_safe_free(mydata);
return SWITCH_STATUS_SUCCESS;
usage:
usage:
switch_safe_free(mydata);
stream->write_function(stream, "-ERR %s\n", LCR_ADMIN_SYNTAX);
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_LOAD_FUNCTION(mod_lcr_load)
{
switch_api_interface_t *dialplan_lcr_api_interface;
switch_api_interface_t *dialplan_lcr_api_admin_interface;
switch_application_interface_t *app_interface;
switch_dialplan_interface_t *dp_interface;
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
if (!switch_odbc_available()) {
@ -1573,7 +1543,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_lcr_load)
SWITCH_ADD_APP(app_interface, "lcr", "Perform an LCR lookup", "Perform an LCR lookup",
lcr_app_function, "<number>", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_DIALPLAN(dp_interface, "lcr", lcr_dialplan_hunt);
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -51,12 +51,12 @@ static struct {
char *odbc_pass;
switch_mutex_t *mutex;
switch_mutex_t *limit_hash_mutex;
switch_hash_t *limit_hash;
switch_hash_t *limit_hash;
switch_mutex_t *db_hash_mutex;
switch_hash_t *db_hash;
switch_hash_t *db_hash;
} globals;
typedef struct {
typedef struct {
uint32_t total_usage;
uint32_t rate_usage;
time_t last_check;
@ -68,43 +68,33 @@ typedef struct {
static char limit_sql[] =
"CREATE TABLE limit_data (\n"
" hostname VARCHAR(255),\n"
" realm VARCHAR(255),\n"
" id VARCHAR(255),\n"
" uuid VARCHAR(255)\n"
");\n";
" hostname VARCHAR(255),\n" " realm VARCHAR(255),\n" " id VARCHAR(255),\n" " uuid VARCHAR(255)\n" ");\n";
static char db_sql[] =
"CREATE TABLE db_data (\n"
" hostname VARCHAR(255),\n"
" realm VARCHAR(255),\n"
" data_key VARCHAR(255),\n"
" data VARCHAR(255)\n"
");\n";
" hostname VARCHAR(255),\n" " realm VARCHAR(255),\n" " data_key VARCHAR(255),\n" " data VARCHAR(255)\n" ");\n";
static char group_sql[] =
"CREATE TABLE group_data (\n"
" hostname VARCHAR(255),\n"
" groupname VARCHAR(255),\n"
" url VARCHAR(255)\n"
");\n";
"CREATE TABLE group_data (\n" " hostname VARCHAR(255),\n" " groupname VARCHAR(255),\n" " url VARCHAR(255)\n" ");\n";
switch_cache_db_handle_t *limit_get_db_handle(void)
{
switch_cache_db_connection_options_t options = { {0} };
switch_cache_db_handle_t *dbh = NULL;
if (!zstr(globals.odbc_dsn)) {
options.odbc_options.dsn = globals.odbc_dsn;
options.odbc_options.user = globals.odbc_user;
options.odbc_options.pass = globals.odbc_pass;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) dbh = NULL;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS)
dbh = NULL;
return dbh;
} else {
options.core_db_options.db_path = globals.dbname;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_CORE_DB, &options) != SWITCH_STATUS_SUCCESS) dbh = NULL;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_CORE_DB, &options) != SWITCH_STATUS_SUCCESS)
dbh = NULL;
return dbh;
}
}
@ -127,7 +117,7 @@ static switch_status_t limit_execute_sql(char *sql, switch_mutex_t *mutex)
status = switch_cache_db_execute_sql(dbh, sql, NULL);
end:
switch_cache_db_release_db_handle(&dbh);
if (mutex) {
@ -142,16 +132,16 @@ static switch_bool_t limit_execute_sql_callback(switch_mutex_t *mutex, char *sql
switch_bool_t ret = SWITCH_FALSE;
char *errmsg = NULL;
switch_cache_db_handle_t *dbh = NULL;
if (mutex) {
switch_mutex_lock(mutex);
}
if (!(dbh = limit_get_db_handle())) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n");
goto end;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n");
goto end;
}
switch_cache_db_execute_sql_callback(dbh, sql, callback, pdata, &errmsg);
if (errmsg) {
@ -174,8 +164,8 @@ static switch_bool_t limit_execute_sql_callback(switch_mutex_t *mutex, char *sql
static switch_xml_config_string_options_t limit_config_dsn = { NULL, 0, "[^:]+:[^:]+:.+" };
static switch_xml_config_item_t config_settings[] = {
SWITCH_CONFIG_ITEM("odbc-dsn", SWITCH_CONFIG_STRING, 0, &globals.odbc_dsn, NULL, &limit_config_dsn,
"dsn:username:password", "If set, the ODBC DSN used by the limit and db applications"),
SWITCH_CONFIG_ITEM("odbc-dsn", SWITCH_CONFIG_STRING, 0, &globals.odbc_dsn, NULL, &limit_config_dsn,
"dsn:username:password", "If set, the ODBC DSN used by the limit and db applications"),
SWITCH_CONFIG_ITEM_END()
};
@ -184,13 +174,13 @@ static switch_status_t do_config()
switch_cache_db_handle_t *dbh = NULL;
switch_status_t status = SWITCH_STATUS_SUCCESS;
char *sql = NULL;
limit_config_dsn.pool = globals.pool;
if (switch_xml_config_parse_module_settings("limit.conf", SWITCH_FALSE, config_settings) != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_TERM;
}
if (globals.odbc_dsn) {
if ((globals.odbc_user = strchr(globals.odbc_dsn, ':'))) {
*globals.odbc_user++ = '\0';
@ -203,7 +193,7 @@ static switch_status_t do_config()
globals.odbc_dsn = globals.odbc_user = globals.odbc_pass;
}
}
if (zstr(globals.odbc_dsn)) {
globals.dbname = "call_limit";
@ -225,16 +215,16 @@ static switch_status_t do_config()
NULL
};
switch_cache_db_test_reactive(dbh, "select * from limit_data", NULL, limit_sql);
switch_cache_db_test_reactive(dbh, "select * from db_data", NULL, db_sql);
switch_cache_db_test_reactive(dbh, "select * from group_data", NULL, group_sql);
for (x = 0; indexes[x]; x++) {
switch_cache_db_execute_sql(dbh, indexes[x], NULL);
}
switch_cache_db_release_db_handle(&dbh);
sql = switch_mprintf("delete from limit_data where hostname='%q';", globals.hostname);
@ -248,7 +238,7 @@ static switch_status_t do_config()
static void limit_fire_event(const char *realm, const char *key, uint32_t usage, uint32_t rate, uint32_t max, uint32_t ratemax)
{
switch_event_t *event;
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, LIMIT_EVENT_USAGE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "realm", realm);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", key);
@ -268,8 +258,7 @@ static switch_status_t db_state_handler(switch_core_session_t *session)
const char *vval = switch_channel_get_variable(channel, LIMIT_IGNORE_TRANSFER_VARIABLE);
if (state >= CS_HANGUP || (state == CS_ROUTING && !switch_true(vval))) {
sql = switch_mprintf("delete from limit_data where uuid='%q';",
switch_core_session_get_uuid(session));
sql = switch_mprintf("delete from limit_data where uuid='%q';", switch_core_session_get_uuid(session));
limit_execute_sql(sql, globals.mutex);
switch_safe_free(sql);
switch_core_event_hook_remove_state_change(session, db_state_handler);
@ -279,47 +268,46 @@ static switch_status_t db_state_handler(switch_core_session_t *session)
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t hash_state_handler(switch_core_session_t *session)
static switch_status_t hash_state_handler(switch_core_session_t *session)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_channel_state_t state = switch_channel_get_state(channel);
limit_hash_private_t *pvt = switch_channel_get_private(channel, "limit_hash");
const char *vval = switch_channel_get_variable(channel, LIMIT_IGNORE_TRANSFER_VARIABLE);
/* The call is either hung up, or is going back into the dialplan, decrement appropriate couters */
if (state >= CS_HANGUP || (state == CS_ROUTING && !switch_true(vval))) {
if (state >= CS_HANGUP || (state == CS_ROUTING && !switch_true(vval))) {
switch_hash_index_t *hi;
switch_mutex_lock(globals.limit_hash_mutex);
/* Loop through the channel's hashtable which contains mapping to all the limit_hash_item_t referenced by that channel */
while((hi = switch_hash_first(NULL, pvt->hash)))
{
while ((hi = switch_hash_first(NULL, pvt->hash))) {
void *val = NULL;
const void *key;
switch_ssize_t keylen;
limit_hash_item_t *item = NULL;
switch_hash_this(hi, &key, &keylen, &val);
item = (limit_hash_item_t*)val;
item->total_usage--;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s is now %d\n", (const char*)key, item->total_usage);
if (item->total_usage == 0) {
item = (limit_hash_item_t *) val;
item->total_usage--;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s is now %d\n", (const char *) key, item->total_usage);
if (item->total_usage == 0) {
/* Noone is using this item anymore */
switch_core_hash_delete(globals.limit_hash, (const char*)key);
switch_core_hash_delete(globals.limit_hash, (const char *) key);
free(item);
}
switch_core_hash_delete(pvt->hash, (const char*)key);
switch_core_hash_delete(pvt->hash, (const char *) key);
}
/* Remove handler */
switch_core_event_hook_remove_state_change(session, hash_state_handler);
switch_mutex_unlock(globals.limit_hash_mutex);
}
return SWITCH_STATUS_SUCCESS;
}
@ -474,21 +462,21 @@ SWITCH_STANDARD_APP(hash_function)
char *mydata = NULL;
char *hash_key = NULL;
char *value = NULL;
switch_mutex_lock(globals.db_hash_mutex);
if (!zstr(data)) {
mydata = strdup(data);
switch_assert(mydata);
argc = switch_separate_string(mydata, '/', argv, (sizeof(argv) / sizeof(argv[0])));
}
if (argc < 3 || !argv[0]) {
goto usage;
}
hash_key = switch_mprintf("%s_%s", argv[1], argv[2]);
if (!strcasecmp(argv[0], "insert")) {
if (argc < 4) {
goto usage;
@ -508,13 +496,13 @@ SWITCH_STANDARD_APP(hash_function)
} else {
goto usage;
}
goto done;
usage:
usage:
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "USAGE: hash %s\n", HASH_USAGE);
done:
done:
switch_mutex_unlock(globals.db_hash_mutex);
switch_safe_free(mydata);
switch_safe_free(hash_key);
@ -536,13 +524,13 @@ SWITCH_STANDARD_API(hash_api_function)
switch_assert(mydata);
argc = switch_separate_string(mydata, '/', argv, (sizeof(argv) / sizeof(argv[0])));
}
if (argc < 3 || !argv[0]) {
goto usage;
}
hash_key = switch_mprintf("%s_%s", argv[1], argv[2]);
if (!strcasecmp(argv[0], "insert")) {
if (argc < 4) {
goto usage;
@ -570,17 +558,17 @@ SWITCH_STANDARD_API(hash_api_function)
} else {
goto usage;
}
goto done;
usage:
usage:
stream->write_function(stream, "-ERR Usage: hash %s\n", HASH_API_USAGE);
done:
done:
switch_mutex_unlock(globals.db_hash_mutex);
switch_safe_free(mydata);
switch_safe_free(hash_key);
return SWITCH_STATUS_SUCCESS;
}
@ -649,7 +637,7 @@ SWITCH_STANDARD_API(group_api_function)
limit_execute_sql_callback(NULL, sql, group_callback, &cbt);
switch_safe_free(sql);
*(buf + (strlen(buf) - 1)) = '\0';
stream->write_function(stream, "%s", buf);
@ -729,9 +717,9 @@ static switch_bool_t do_limit(switch_core_session_t *session, const char *realm,
got = atoi(buf);
if (max < 0) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s_%s is now %d\n", realm, id, got+1);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s_%s is now %d\n", realm, id, got + 1);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s_%s is now %d/%d\n", realm, id, got+1, max);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s_%s is now %d/%d\n", realm, id, got + 1, max);
}
if (max >= 0 && got + 1 > max) {
@ -746,7 +734,7 @@ static switch_bool_t do_limit(switch_core_session_t *session, const char *realm,
switch_core_session_get_uuid(session));
limit_execute_sql(sql, NULL);
switch_safe_free(sql);
{
const char *susage = switch_core_session_sprintf(session, "%d", ++got);
@ -787,8 +775,8 @@ SWITCH_STANDARD_APP(limit_function)
realm = argv[0];
id = argv[1];
/* Accept '-' as unlimited (act as counter)*/
/* Accept '-' as unlimited (act as counter) */
if (argv[2][0] == '-') {
max = -1;
} else {
@ -796,7 +784,7 @@ SWITCH_STANDARD_APP(limit_function)
if (max < 0) {
max = 0;
}
}
}
if (argc >= 4) {
@ -808,12 +796,12 @@ SWITCH_STANDARD_APP(limit_function)
if (!do_limit(session, realm, id, max)) {
/* Limit exceeded */
if (*xfer_exten == '!') {
switch_channel_hangup(channel, switch_channel_str2cause(xfer_exten+1));
switch_channel_hangup(channel, switch_channel_str2cause(xfer_exten + 1));
} else {
switch_ivr_session_transfer(session, xfer_exten, argv[4], argv[5]);
}
}
}
/* !\brief Releases usage of a limit_-controlled ressource */
@ -821,8 +809,7 @@ static void limit_release(switch_core_session_t *session, const char *realm, con
{
char *sql = NULL;
sql = switch_mprintf("delete from limit_data where uuid='%q' and realm='%q' and id like '%q'",
switch_core_session_get_uuid(session), realm, id);
sql = switch_mprintf("delete from limit_data where uuid='%q' and realm='%q' and id like '%q'", switch_core_session_get_uuid(session), realm, id);
limit_execute_sql(sql, globals.mutex);
switch_safe_free(sql);
}
@ -845,16 +832,16 @@ SWITCH_STANDARD_APP(limit_execute_function)
mydata = switch_core_session_strdup(session, data);
argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
}
if (argc < 2) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "USAGE: limit_execute %s\n", LIMITEXECUTE_USAGE);
return;
}
realm = argv[0];
id = argv[1];
/* Accept '-' as unlimited (act as counter)*/
/* Accept '-' as unlimited (act as counter) */
if (argv[2][0] == '-') {
max = -1;
} else {
@ -862,7 +849,7 @@ SWITCH_STANDARD_APP(limit_execute_function)
if (max < 0) {
max = 0;
}
}
}
app = argv[3];
@ -915,7 +902,7 @@ SWITCH_STANDARD_API(limit_usage_function)
stream->write_function(stream, "%s", buf);
end:
end:
switch_safe_free(mydata);
return SWITCH_STATUS_SUCCESS;
}
@ -937,22 +924,21 @@ static switch_bool_t do_limit_hash(switch_core_session_t *session, const char *r
time_t now = switch_epoch_time_now(NULL);
limit_hash_private_t *pvt = NULL;
uint8_t increment = 1;
hashkey = switch_core_session_sprintf(session, "%s_%s", realm, id);
switch_mutex_lock(globals.limit_hash_mutex);
/* Check if that realm+id has ever been checked */
if (!(item = (limit_hash_item_t*)switch_core_hash_find(globals.limit_hash, hashkey))) {
if (!(item = (limit_hash_item_t *) switch_core_hash_find(globals.limit_hash, hashkey))) {
/* No, create an empty structure and add it, then continue like as if it existed */
item = (limit_hash_item_t*)malloc(sizeof(limit_hash_item_t));
item = (limit_hash_item_t *) malloc(sizeof(limit_hash_item_t));
switch_assert(item);
memset(item, 0, sizeof(limit_hash_item_t));
switch_core_hash_insert(globals.limit_hash, hashkey, item);
}
/* Did we already run on this channel before? */
if ((pvt = switch_channel_get_private(channel, "limit_hash")))
{
if ((pvt = switch_channel_get_private(channel, "limit_hash"))) {
/* Yes, but check if we did that realm+id
If we didnt, allow incrementing the counter.
If we did, dont touch it but do the validation anyways
@ -960,7 +946,7 @@ static switch_bool_t do_limit_hash(switch_core_session_t *session, const char *r
increment = !switch_core_hash_find(pvt->hash, hashkey);
} else {
/* This is the first limit check on this channel, create a hashtable, set our prviate data and add a state handler */
pvt = (limit_hash_private_t*)switch_core_session_alloc(session, sizeof(limit_hash_private_t));
pvt = (limit_hash_private_t *) switch_core_session_alloc(session, sizeof(limit_hash_private_t));
memset(pvt, 0, sizeof(limit_hash_private_t));
switch_core_hash_init(&pvt->hash, switch_core_session_get_pool(session));
switch_channel_set_private(channel, "limit_hash", pvt);
@ -974,13 +960,14 @@ static switch_bool_t do_limit_hash(switch_core_session_t *session, const char *r
/* Always increment rate when its checked as it doesnt depend on the channel */
item->rate_usage++;
if ((max >= 0) && (item->rate_usage > (uint32_t)max)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s exceeds maximum rate of %d/%ds, now at %d\n", hashkey, max, interval, item->rate_usage);
if ((max >= 0) && (item->rate_usage > (uint32_t) max)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s exceeds maximum rate of %d/%ds, now at %d\n",
hashkey, max, interval, item->rate_usage);
status = SWITCH_FALSE;
goto end;
}
}
} else if ((max >= 0) && (item->total_usage + increment > (uint32_t)max)) {
} else if ((max >= 0) && (item->total_usage + increment > (uint32_t) max)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s is already at max value (%d)\n", hashkey, item->total_usage);
status = SWITCH_FALSE;
goto end;
@ -994,12 +981,13 @@ static switch_bool_t do_limit_hash(switch_core_session_t *session, const char *r
if (max == -1) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s is now %d\n", hashkey, item->total_usage);
} else if (interval == 0) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s is now %d/%d\n", hashkey, item->total_usage, max);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s is now %d/%d\n", hashkey, item->total_usage, max);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s is now %d/%d for the last %d seconds\n", hashkey, item->rate_usage, max, interval);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s is now %d/%d for the last %d seconds\n", hashkey,
item->rate_usage, max, interval);
}
limit_fire_event(realm, id, item->total_usage, item->rate_usage, max, max >=0 ? (uint32_t)max : 0);
limit_fire_event(realm, id, item->total_usage, item->rate_usage, max, max >= 0 ? (uint32_t) max : 0);
}
/* Save current usage & rate into channel variables so it can be used later in the dialplan, or added to CDR records */
@ -1016,7 +1004,7 @@ static switch_bool_t do_limit_hash(switch_core_session_t *session, const char *r
switch_core_event_hook_add_state_change(session, hash_state_handler);
end:
end:
switch_mutex_unlock(globals.limit_hash_mutex);
return status;
}
@ -1028,28 +1016,28 @@ static void limit_hash_release(switch_core_session_t *session, const char *realm
limit_hash_private_t *pvt = switch_channel_get_private(channel, "limit_hash");
limit_hash_item_t *item = NULL;
char *hashkey = NULL;
if (!pvt || !pvt->hash) {
return;
}
hashkey = switch_core_session_sprintf(session, "%s_%s", realm, id);
switch_mutex_lock(globals.limit_hash_mutex);
if ((item = (limit_hash_item_t*)switch_core_hash_find(pvt->hash, hashkey))) {
item->total_usage--;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s is now %d\n", (const char*)hashkey, item->total_usage);
if ((item = (limit_hash_item_t *) switch_core_hash_find(pvt->hash, hashkey))) {
item->total_usage--;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s is now %d\n", (const char *) hashkey, item->total_usage);
switch_core_hash_delete(pvt->hash, hashkey);
if (item->total_usage == 0) {
if (item->total_usage == 0) {
/* Noone is using this item anymore */
switch_core_hash_delete(globals.limit_hash, (const char*)hashkey);
switch_core_hash_delete(globals.limit_hash, (const char *) hashkey);
free(item);
}
}
switch_mutex_unlock(globals.limit_hash_mutex);
}
@ -1072,29 +1060,28 @@ SWITCH_STANDARD_APP(limit_hash_function)
mydata = switch_core_session_strdup(session, data);
argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
}
if (argc < 2) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "USAGE: limit_hash %s\n", LIMITHASH_USAGE);
return;
}
realm = argv[0];
id = argv[1];
/* If max is omitted or negative, only act as a counter and skip maximum checks */
if (argc > 2) {
if (argv[2][0] == '-') {
max = -1;
} else {
char *szinterval = NULL;
if ((szinterval = strchr(argv[2], '/')))
{
if ((szinterval = strchr(argv[2], '/'))) {
*szinterval++ = '\0';
interval = atoi(szinterval);
}
max = atoi(argv[2]);
if (max < 0) {
max = 0;
}
@ -1106,11 +1093,11 @@ SWITCH_STANDARD_APP(limit_hash_function)
} else {
xfer_exten = limit_def_xfer_exten;
}
if (!do_limit_hash(session, realm, id, max, interval)) {
/* Limit exceeded */
if (*xfer_exten == '!') {
switch_channel_hangup(channel, switch_channel_str2cause(xfer_exten+1));
switch_channel_hangup(channel, switch_channel_str2cause(xfer_exten + 1));
} else {
switch_ivr_session_transfer(session, xfer_exten, argv[4], argv[5]);
}
@ -1137,23 +1124,22 @@ SWITCH_STANDARD_APP(limit_hash_execute_function)
mydata = switch_core_session_strdup(session, data);
argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
}
if (argc < 5) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "USAGE: limit_hash_execute %s\n", LIMITHASHEXECUTE_USAGE);
return;
}
realm = argv[0];
id = argv[1];
/* Accept '-' as unlimited (act as counter)*/
/* Accept '-' as unlimited (act as counter) */
if (argv[2][0] == '-') {
max = -1;
} else {
char *szinterval = NULL;
if ((szinterval = strchr(argv[2], '/')))
{
if ((szinterval = strchr(argv[2], '/'))) {
*szinterval++ = '\0';
interval = atoi(szinterval);
}
@ -1162,9 +1148,9 @@ SWITCH_STANDARD_APP(limit_hash_execute_function)
if (max < 0) {
max = 0;
}
}
}
app = argv[3];
app_arg = argv[4];
@ -1191,31 +1177,31 @@ SWITCH_STANDARD_API(limit_hash_usage_function)
uint32_t count = 0;
switch_mutex_lock(globals.limit_hash_mutex);
if (!zstr(cmd)) {
mydata = strdup(cmd);
switch_assert(mydata);
argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
}
if (argc < 2) {
stream->write_function(stream, "USAGE: limit_hash_usage %s\n", LIMIT_HASH_USAGE_USAGE);
goto end;
}
hash_key = switch_mprintf("%s_%s", argv[0], argv[1]);
if ((item = switch_core_hash_find(globals.limit_hash, hash_key))) {
count = item->total_usage;
}
}
stream->write_function(stream, "%d", count);
end:
end:
switch_safe_free(mydata);
switch_safe_free(hash_key);
switch_mutex_unlock(globals.limit_hash_mutex);
return SWITCH_STATUS_SUCCESS;
}
@ -1231,11 +1217,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_limit_load)
if (switch_event_reserve_subclass(LIMIT_EVENT_USAGE) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldnt register event subclass \"%s\"",
LIMIT_EVENT_USAGE);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldnt register event subclass \"%s\"", LIMIT_EVENT_USAGE);
return SWITCH_STATUS_FALSE;
}
if ((status = do_config() != SWITCH_STATUS_SUCCESS)) {
return status;
}
@ -1248,18 +1233,20 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_limit_load)
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_APP(app_interface, "limit", "Limit", LIMIT_DESC, limit_function, LIMIT_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "limit_execute", "Limit", LIMITEXECUTE_USAGE, limit_execute_function, LIMITEXECUTE_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "limit_hash", "Limit (hash)", LIMITHASH_DESC, limit_hash_function, LIMITHASH_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "limit_hash_execute", "Limit (hash)", LIMITHASHEXECUTE_USAGE, limit_hash_execute_function, LIMITHASHEXECUTE_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "limit_hash_execute", "Limit (hash)", LIMITHASHEXECUTE_USAGE, limit_hash_execute_function, LIMITHASHEXECUTE_USAGE,
SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "db", "Insert to the db", DB_DESC, db_function, DB_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "hash", "Insert into the hashtable", HASH_DESC, hash_function, HASH_USAGE, SAF_SUPPORT_NOMEDIA)
SWITCH_ADD_APP(app_interface, "group", "Manage a group", GROUP_DESC, group_function, GROUP_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "group", "Manage a group", GROUP_DESC, group_function, GROUP_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_API(commands_api_interface, "limit_hash_usage", "Gets the usage count of a limited resource", limit_hash_usage_function, LIMIT_HASH_USAGE_USAGE);
SWITCH_ADD_API(commands_api_interface, "limit_hash_usage", "Gets the usage count of a limited resource", limit_hash_usage_function,
LIMIT_HASH_USAGE_USAGE);
SWITCH_ADD_API(commands_api_interface, "limit_usage", "Gets the usage count of a limited resource", limit_usage_function, "<realm> <id>");
SWITCH_ADD_API(commands_api_interface, "db", "db get/set", db_api_function, "[insert|delete|select]/<realm>/<key>/<value>");
switch_console_set_complete("add db insert");
@ -1279,13 +1266,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_limit_load)
}
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_limit_shutdown)
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_limit_shutdown)
{
switch_event_free_subclass(LIMIT_EVENT_USAGE);
switch_xml_config_cleanup(config_settings);
switch_mutex_destroy(globals.mutex);
switch_mutex_destroy(globals.limit_hash_mutex);
switch_mutex_destroy(globals.db_hash_mutex);

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -42,11 +42,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_memcache_load);
SWITCH_MODULE_DEFINITION(mod_memcache, mod_memcache_load, mod_memcache_shutdown, NULL);
static char *SYNTAX = "memcache <set|replace|add> <key> <value> [expiration [flags]]\n"
"memcache <get|getflags> <key>\n"
"memcache <delete> <key>\n"
"memcache <increment|decrement> <key> [offset [expires [flags]]]\n"
"memcache <flush>\n"
"memcache <status> [verbose]\n";
"memcache <get|getflags> <key>\n"
"memcache <delete> <key>\n" "memcache <increment|decrement> <key> [offset [expires [flags]]]\n" "memcache <flush>\n" "memcache <status> [verbose]\n";
static struct {
memcached_st *memcached;
@ -55,7 +52,8 @@ static struct {
static switch_event_node_t *NODE = NULL;
static switch_status_t config_callback_memcached(switch_xml_config_item_t *data, const char *newvalue, switch_config_callback_type_t callback_type, switch_bool_t changed)
static switch_status_t config_callback_memcached(switch_xml_config_item_t *data, const char *newvalue, switch_config_callback_type_t callback_type,
switch_bool_t changed)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
memcached_server_st *memcached_server = NULL;
@ -64,23 +62,23 @@ static switch_status_t config_callback_memcached(switch_xml_config_item_t *data,
const char *memcached_str = NULL;
memcached_return rc;
unsigned int servercount;
if ((callback_type == CONFIG_LOAD || callback_type == CONFIG_RELOAD) && changed) {
memcached_str = newvalue;
/* initialize main ptr */
memcached_server = memcached_servers_parse(memcached_str);
if (!memcached_server) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to initialize memcached data structure (server_list).\n");
switch_goto_status(SWITCH_STATUS_GENERR, end);
}
if ((servercount = memcached_server_list_count(memcached_server)) == 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No memcache servers defined. Server string: %s.\n", memcached_str);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%u servers defined (%s).\n", servercount, memcached_str);
}
/* setup memcached */
newmemcached = memcached_create(NULL);
if (!newmemcached) {
@ -93,16 +91,16 @@ static switch_status_t config_callback_memcached(switch_xml_config_item_t *data,
switch_goto_status(SWITCH_STATUS_GENERR, end);
}
/* memcached_behavior_set(newmemcached, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1); */
/* swap pointers */
oldmemcached = globals.memcached;
globals.memcached = newmemcached;
newmemcached = NULL;
}
switch_goto_status(SWITCH_STATUS_SUCCESS, end);
end:
end:
if (memcached_server) {
memcached_server_list_free(memcached_server);
}
@ -115,12 +113,13 @@ end:
return status;
}
static switch_xml_config_string_options_t config_opt_memcache_servers = {NULL, 0, NULL}; /* anything ok */
static switch_xml_config_string_options_t config_opt_memcache_servers = { NULL, 0, NULL }; /* anything ok */
static switch_xml_config_item_t instructions[] = {
/* parameter name type reloadable pointer default value options structure */
SWITCH_CONFIG_ITEM_CALLBACK("memcache-servers", SWITCH_CONFIG_STRING, CONFIG_REQUIRED | CONFIG_RELOAD, &globals.memcached_str, "", config_callback_memcached, &config_opt_memcache_servers,
"host,host:port,host", "List of memcached servers."),
SWITCH_CONFIG_ITEM_CALLBACK("memcache-servers", SWITCH_CONFIG_STRING, CONFIG_REQUIRED | CONFIG_RELOAD, &globals.memcached_str, "",
config_callback_memcached, &config_opt_memcache_servers,
"host,host:port,host", "List of memcached servers."),
SWITCH_CONFIG_ITEM_END()
};
@ -129,8 +128,8 @@ static switch_status_t do_config(switch_bool_t reload)
if (switch_xml_config_parse_module_settings("memcache.conf", reload, instructions) != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_GENERR;
}
return SWITCH_STATUS_SUCCESS;
}
@ -154,42 +153,42 @@ SWITCH_STANDARD_API(memcache_function)
time_t expires = 0;
uint32_t flags = 0;
unsigned int server_count = 0;
memcached_return rc;
memcached_st *memcached = NULL;
memcached_stat_st *stat = NULL;
memcached_server_st *server_list;
if (zstr(cmd)) {
goto usage;
}
mydata = strdup(cmd);
if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
if (argc < 1) {
goto usage;
}
/* clone memcached struct so we're thread safe */
memcached = memcached_clone(NULL, globals.memcached);
if (!memcached) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error cloning memcached object");
stream->write_function(stream, "-ERR Error cloning memcached object\n");
}
subcmd = argv[0];
if ((!strcasecmp(subcmd, "set") || !strcasecmp(subcmd, "replace") || !strcasecmp(subcmd, "add")) && argc > 2) {
key = argv[1];
val = argv[2];
if (argc > 3) {
expires_str = argv[3];
expires = (time_t)strtol(expires_str, NULL, 10);
expires = (time_t) strtol(expires_str, NULL, 10);
}
if (argc > 4) {
flags_str = argv[4];
flags = (uint32_t)strtol(flags_str, NULL, 16);
flags = (uint32_t) strtol(flags_str, NULL, 16);
}
if (!strcasecmp(subcmd, "set")) {
rc = memcached_set(memcached, key, strlen(key), val, strlen(val), expires, flags);
@ -198,7 +197,7 @@ SWITCH_STANDARD_API(memcache_function)
} else if (!strcasecmp(subcmd, "add")) {
rc = memcached_add(memcached, key, strlen(key), val, strlen(val), expires, flags);
}
if (rc == MEMCACHED_SUCCESS) {
stream->write_function(stream, "+OK\n");
} else {
@ -206,10 +205,10 @@ SWITCH_STANDARD_API(memcache_function)
}
} else if (!strcasecmp(subcmd, "get") && argc > 1) {
key = argv[1];
val = memcached_get(memcached, key, strlen(key), &string_length, &flags, &rc);
if (rc == MEMCACHED_SUCCESS) {
stream->write_function(stream, "%.*s", (int)string_length, val);
stream->write_function(stream, "%.*s", (int) string_length, val);
} else {
switch_safe_free(val);
switch_goto_status(SWITCH_STATUS_SUCCESS, mcache_error);
@ -217,7 +216,7 @@ SWITCH_STANDARD_API(memcache_function)
switch_safe_free(val);
} else if (!strcasecmp(subcmd, "getflags") && argc > 1) {
key = argv[1];
val = memcached_get(memcached, key, strlen(key), &string_length, &flags, &rc);
if (rc == MEMCACHED_SUCCESS) {
stream->write_function(stream, "%x", flags);
@ -234,20 +233,20 @@ SWITCH_STANDARD_API(memcache_function)
key = argv[1];
if (argc > 2) {
offset = (unsigned int)strtol(argv[2], NULL, 10);
offset = (unsigned int) strtol(argv[2], NULL, 10);
svalue = argv[2];
} else {
svalue = "1";
}
if (argc > 3) {
expires_str = argv[3];
expires = (time_t)strtol(expires_str, NULL, 10);
expires = (time_t) strtol(expires_str, NULL, 10);
}
if (argc > 4) {
flags_str = argv[4];
flags = (uint32_t)strtol(flags_str, NULL, 16);
flags = (uint32_t) strtol(flags_str, NULL, 16);
}
if (!strcasecmp(subcmd, "increment")) {
increment = SWITCH_TRUE;
rc = memcached_increment(memcached, key, strlen(key), offset, &ivalue);
@ -259,18 +258,20 @@ SWITCH_STANDARD_API(memcache_function)
/* ok, trying to incr / decr a value that doesn't exist yet.
Try to add an appropriate initial value. If someone else beat
us to it, then redo incr/decr. Otherwise we're good.
*/
*/
rc = memcached_add(memcached, key, strlen(key), (increment) ? svalue : "0", strlen(svalue), expires, flags);
if (rc == MEMCACHED_SUCCESS) {
ivalue = (increment) ? offset : 0;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Initialized inc/dec memcache key: %s to value %d\n", key, offset);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Initialized inc/dec memcache key: %s to value %d\n", key,
offset);
} else {
if (increment) {
rc = memcached_increment(memcached, key, strlen(key), offset, &ivalue);
} else {
rc = memcached_decrement(memcached, key, strlen(key), offset, &ivalue);
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Someone else created incr/dec memcache key, resubmitting inc/dec request.\n");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
"Someone else created incr/dec memcache key, resubmitting inc/dec request.\n");
}
}
if (rc == MEMCACHED_SUCCESS) {
@ -282,7 +283,7 @@ SWITCH_STANDARD_API(memcache_function)
key = argv[1];
if (argc > 2) {
expires_str = argv[3];
expires = (time_t)strtol(expires_str, NULL, 10);
expires = (time_t) strtol(expires_str, NULL, 10);
}
rc = memcached_delete(memcached, key, strlen(key), expires);
if (rc == MEMCACHED_SUCCESS) {
@ -293,7 +294,7 @@ SWITCH_STANDARD_API(memcache_function)
} else if (!strcasecmp(subcmd, "flush")) {
if (argc > 1) {
expires_str = argv[3];
expires = (time_t)strtol(expires_str, NULL, 10);
expires = (time_t) strtol(expires_str, NULL, 10);
}
rc = memcached_flush(memcached, expires);
if (rc == MEMCACHED_SUCCESS) {
@ -310,7 +311,7 @@ SWITCH_STANDARD_API(memcache_function)
verbose = SWITCH_TRUE;
}
}
stream->write_function(stream, "Lib version: %s\n", memcached_lib_version());
stat = memcached_stat(memcached, NULL, &rc);
if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_SOME_ERRORS) {
@ -320,13 +321,14 @@ SWITCH_STANDARD_API(memcache_function)
server_count = memcached_server_count(memcached);
stream->write_function(stream, "Servers: %d\n", server_count);
for (x = 0; x < server_count; x++) {
stream->write_function(stream, " %s (%u)\n", memcached_server_name(memcached, server_list[x]), memcached_server_port(memcached, server_list[x]));
stream->write_function(stream, " %s (%u)\n", memcached_server_name(memcached, server_list[x]),
memcached_server_port(memcached, server_list[x]));
if (verbose == SWITCH_TRUE) {
char **list;
char **ptr;
char *value;
memcached_return rc2;
list = memcached_stat_get_keys(memcached, &stat[x], &rc);
for (ptr = list; *ptr; ptr++) {
value = memcached_stat_get_value(memcached, &stat[x], *ptr, &rc2);
@ -343,25 +345,26 @@ SWITCH_STANDARD_API(memcache_function)
}
switch_goto_status(SWITCH_STATUS_SUCCESS, done);
mcache_error:
mcache_error:
if (rc != MEMCACHED_NOTFOUND) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error while running command %s: %s\n", subcmd, memcached_strerror(memcached, rc));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error while running command %s: %s\n", subcmd,
memcached_strerror(memcached, rc));
}
stream->write_function(stream, "-ERR %s\n", memcached_strerror(memcached, rc));
goto done;
usage:
usage:
stream->write_function(stream, "-ERR\n%s\n", SYNTAX);
switch_goto_status(SWITCH_STATUS_SUCCESS, done);
done:
done:
if (memcached) {
memcached_quit(memcached);
memcached_free(memcached);
}
switch_safe_free(mydata);
switch_safe_free(stat);
return status;
}
@ -375,12 +378,12 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_memcache_load)
memset(&globals, 0, sizeof(globals));
do_config(SWITCH_FALSE);
if ((switch_event_bind_removable(modname, SWITCH_EVENT_RELOADXML, NULL, event_handler, NULL, &NODE) != SWITCH_STATUS_SUCCESS)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind event!\n");
return SWITCH_STATUS_TERM;
}
SWITCH_ADD_API(api_interface, "memcache", "Memcache API", memcache_function, "syntax");
/* indicate that the module should continue to be loaded */
@ -397,9 +400,9 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_memcache_shutdown)
if (globals.memcached) {
memcached_free(globals.memcached);
}
switch_event_unbind(&NODE);
return SWITCH_STATUS_SUCCESS;
}

View File

@ -53,31 +53,28 @@
static char SQL_LOOKUP[] = "SELECT %s FROM %s WHERE %s='%s'";
static char SQL_SAVE[] = "UPDATE %s SET %s=%s-%f WHERE %s='%s'";
typedef struct
{
switch_time_t lastts; /* Last time we did any billing */
float total; /* Total amount billed so far */
typedef struct {
switch_time_t lastts; /* Last time we did any billing */
float total; /* Total amount billed so far */
switch_time_t pausets; /* Timestamp of when a pause action started. 0 if not paused */
float bill_adjustments; /* Adjustments to make to the next billing, based on pause/resume events */
switch_time_t pausets; /* Timestamp of when a pause action started. 0 if not paused */
float bill_adjustments; /* Adjustments to make to the next billing, based on pause/resume events */
} nibble_data_t;
typedef struct nibblebill_results
{
float balance;
typedef struct nibblebill_results {
float balance;
float percall_max; /* Overrides global on a per-user level */
float lowbal_amt; /* ditto */
float percall_max; /* Overrides global on a per-user level */
float lowbal_amt; /* ditto */
} nibblebill_results_t;
/* Keep track of our config, event hooks and database connection variables, for this module only */
static struct
{
static struct {
/* Memory */
switch_memory_pool_t *pool;
switch_memory_pool_t *pool;
/* Event hooks */
switch_event_node_t *node;
@ -86,15 +83,15 @@ static struct
switch_mutex_t *mutex;
/* Global billing config options */
float percall_max_amt; /* Per-call billing limit (safety check, for fraud) */
char *percall_action; /* Exceeded length of per-call action */
float lowbal_amt; /* When we warn them they are near depletion */
char *lowbal_action; /* Low balance action */
float nobal_amt; /* Minimum amount that must remain in the account */
char *nobal_action; /* Drop action */
float percall_max_amt; /* Per-call billing limit (safety check, for fraud) */
char *percall_action; /* Exceeded length of per-call action */
float lowbal_amt; /* When we warn them they are near depletion */
char *lowbal_action; /* Low balance action */
float nobal_amt; /* Minimum amount that must remain in the account */
char *nobal_action; /* Drop action */
/* Other options */
int global_heartbeat; /* Supervise and bill every X seconds, 0 means off */
int global_heartbeat; /* Supervise and bill every X seconds, 0 means off */
/* Database settings */
char *db_username;
@ -135,7 +132,7 @@ static int nibblebill_callback(void *pArg, int argc, char **argv, char **columnN
{
nibblebill_results_t *cbt = (nibblebill_results_t *) pArg;
cbt->balance = (float)atof(argv[0]);
cbt->balance = (float) atof(argv[0]);
return 0;
}
@ -145,13 +142,13 @@ static switch_status_t load_config(void)
char *cf = "nibblebill.conf";
switch_xml_t cfg, xml = NULL, param, settings;
switch_status_t status = SWITCH_STATUS_SUCCESS;
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
status = SWITCH_STATUS_SUCCESS; /* We don't fail because we can still write to a text file or buffer */
status = SWITCH_STATUS_SUCCESS; /* We don't fail because we can still write to a text file or buffer */
goto setdefaults;
}
if ((settings = switch_xml_child(cfg, "settings"))) {
for (param = switch_xml_child(settings, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
@ -172,23 +169,23 @@ static switch_status_t load_config(void)
} else if (!strcasecmp(var, "percall_action")) {
set_global_percall_action(val);
} else if (!strcasecmp(var, "percall_max_amt")) {
globals.percall_max_amt = (float)atof(val);
globals.percall_max_amt = (float) atof(val);
} else if (!strcasecmp(var, "lowbal_action")) {
set_global_lowbal_action(val);
} else if (!strcasecmp(var, "lowbal_amt")) {
globals.lowbal_amt = (float)atof(val);
globals.lowbal_amt = (float) atof(val);
} else if (!strcasecmp(var, "nobal_action")) {
set_global_nobal_action(val);
} else if (!strcasecmp(var, "nobal_amt")) {
globals.nobal_amt = (float)atof(val);
globals.nobal_amt = (float) atof(val);
} else if (!strcasecmp(var, "global_heartbeat")) {
globals.global_heartbeat = atoi(val);
}
}
}
/* Set defaults for any variables still not set */
setdefaults:
setdefaults:
if (zstr(globals.db_username)) {
set_global_db_username("bandwidth.com");
}
@ -218,7 +215,7 @@ setdefaults:
}
if (switch_odbc_handle_connect(globals.master_odbc) != SWITCH_ODBC_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT,
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT,
"Cannot connect to ODBC driver/database %s (user: %s / pass %s)!\n",
globals.db_dsn, globals.db_username, globals.db_password);
status = SWITCH_STATUS_FALSE;
@ -232,7 +229,7 @@ setdefaults:
"ODBC does not appear to be installed in the core. You need to run ./configure --enable-core-odbc-support\n");
}
done:
done:
if (xml) {
switch_xml_free(xml);
}
@ -241,7 +238,7 @@ done:
void debug_event_handler(switch_event_t *event)
{
if (!event) {
if (!event) {
return;
}
@ -305,8 +302,9 @@ static switch_status_t bill_event(float billamount, const char *billaccount)
return SWITCH_STATUS_SUCCESS;
}
switch_snprintf(sql, 1024, SQL_SAVE, globals.db_table, globals.db_column_cash, globals.db_column_cash, billamount, globals.db_column_account, billaccount);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Doing update query\n[%s]\n", sql);
switch_snprintf(sql, 1024, SQL_SAVE, globals.db_table, globals.db_column_cash, globals.db_column_cash, billamount, globals.db_column_account,
billaccount);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Doing update query\n[%s]\n", sql);
if (switch_odbc_handle_exec(globals.master_odbc, sql, &stmt, NULL) != SWITCH_ODBC_SUCCESS) {
char *err_str;
@ -347,9 +345,9 @@ static float get_balance(const char *billaccount)
/* Successfully retrieved! */
balance = pdata.balance;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Retrieved current balance for account %s (balance = %f)\n", billaccount, balance);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Retrieved current balance for account %s (balance = %f)\n", billaccount, balance);
}
return balance;
}
@ -394,7 +392,8 @@ static switch_status_t do_billing(switch_core_session_t *session)
return SWITCH_STATUS_SUCCESS;
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Attempting to bill at $%s per minute to account %s\n", billrate, billaccount);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Attempting to bill at $%s per minute to account %s\n", billrate,
billaccount);
/* Get caller profile info from channel */
profile = switch_channel_get_caller_profile(channel);
@ -409,10 +408,11 @@ static switch_status_t do_billing(switch_core_session_t *session)
/* See if this person has enough money left to continue the call */
balance = get_balance(billaccount);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Comparing %f to hangup balance of %f\n", balance, globals.nobal_amt);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Comparing %f to hangup balance of %f\n", balance, globals.nobal_amt);
if (balance <= globals.nobal_amt) {
/* Not enough money - reroute call to nobal location */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Balance of %f fell below allowed amount of %f! (Account %s)\n", balance, globals.nobal_amt, billaccount);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Balance of %f fell below allowed amount of %f! (Account %s)\n",
balance, globals.nobal_amt, billaccount);
transfer_call(session, globals.nobal_action);
}
@ -443,7 +443,7 @@ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Compar
memset(nibble_data, 0, sizeof(*nibble_data));
/* Setup new billing data (based on call answer time, in case this module started late with active calls) */
nibble_data->lastts = profile->times->answered; /* Set the initial answer time to match when the call was really answered */
nibble_data->lastts = profile->times->answered; /* Set the initial answer time to match when the call was really answered */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Beginning new billing on %s\n", uuid);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Last successful billing time was %s\n", date);
@ -452,13 +452,15 @@ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Compar
switch_time_exp_lt(&tm, nibble_data->lastts);
switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%d seconds passed since last bill time of %s\n", (int) ((ts - nibble_data->lastts) / 1000000), date);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%d seconds passed since last bill time of %s\n",
(int) ((ts - nibble_data->lastts) / 1000000), date);
if ((ts - nibble_data->lastts) >= 0) {
/* Convert billrate into microseconds and multiply by # of microseconds that have passed since last *successful* bill */
billamount = ((float)atof(billrate) / 1000000 / 60) * ((ts - nibble_data->lastts)) - nibble_data->bill_adjustments;
billamount = ((float) atof(billrate) / 1000000 / 60) * ((ts - nibble_data->lastts)) - nibble_data->bill_adjustments;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Billing $%f to %s (Call: %s / %f so far)\n", billamount, billaccount, uuid, nibble_data->total);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Billing $%f to %s (Call: %s / %f so far)\n", billamount, billaccount,
uuid, nibble_data->total);
/* DO ODBC BILLING HERE and reset counters if it's successful! */
if (bill_event(billamount, billaccount) == SWITCH_STATUS_SUCCESS) {
@ -474,7 +476,8 @@ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Compar
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Failed to log to database!\n");
}
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Just tried to bill %s negative minutes! That should be impossible.\n", uuid);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Just tried to bill %s negative minutes! That should be impossible.\n",
uuid);
}
/* Update the last time we billed */
@ -488,7 +491,8 @@ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Compar
balance = get_balance(billaccount);
if (balance <= globals.nobal_amt) {
/* Not enough money - reroute call to nobal location */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Balance of %f fell below allowed amount of %f! (Account %s)\n", balance, globals.nobal_amt, billaccount);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Balance of %f fell below allowed amount of %f! (Account %s)\n",
balance, globals.nobal_amt, billaccount);
/* IMPORTANT: Billing must be paused before the transfer occurs! This prevents infinite loops, since the transfer will result */
/* in nibblebill checking the call again in the routing process for an allowed balance! */
@ -496,7 +500,7 @@ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Compar
nibblebill_pause(session);
transfer_call(session, globals.nobal_action);
}
}
}
/* Done changing - release lock */
@ -515,18 +519,18 @@ static void event_handler(switch_event_t *event)
switch_core_session_t *session;
char *uuid;
if (!event){
if (!event) {
/* We should never get here - it means an event came in without the event info */
return;
}
/* Make sure everything is sane */
if (!(uuid = switch_event_get_header(event, "Unique-ID"))){
if (!(uuid = switch_event_get_header(event, "Unique-ID"))) {
/* Donde esta channel? */
return;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Received request via %s!\n", switch_event_name (event->event_id));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Received request via %s!\n", switch_event_name(event->event_id));
/* Display debugging info */
if (switch_event_get_header(event, "nibble_debug")) {
@ -594,12 +598,14 @@ static void nibblebill_resume(switch_core_session_t *session)
nibble_data = (nibble_data_t *) switch_channel_get_private(channel, "_nibble_data_");
if (!nibble_data) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Can't resume - channel is not initialized for billing (This is expected at hangup time)!\n");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
"Can't resume - channel is not initialized for billing (This is expected at hangup time)!\n");
return;
}
if (nibble_data->pausets == 0) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Can't resume - channel is not paused! (This is expected at hangup time)\n");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
"Can't resume - channel is not paused! (This is expected at hangup time)\n");
return;
}
@ -611,8 +617,9 @@ static void nibblebill_resume(switch_core_session_t *session)
billrate = switch_channel_get_variable(channel, "nibble_rate");
/* Calculate how much was "lost" to billings during pause - we do this here because you never know when the billrate may change during a call */
nibble_data->bill_adjustments += ((float)atof(billrate) / 1000000 / 60) * ((ts - nibble_data->pausets));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Resumed billing! Subtracted %f from this billing cycle.\n", (atof(billrate) / 1000000 / 60) * ((ts - nibble_data->pausets)));
nibble_data->bill_adjustments += ((float) atof(billrate) / 1000000 / 60) * ((ts - nibble_data->pausets));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Resumed billing! Subtracted %f from this billing cycle.\n",
(atof(billrate) / 1000000 / 60) * ((ts - nibble_data->pausets)));
nibble_data->pausets = 0;
@ -699,7 +706,7 @@ static void nibblebill_adjust(switch_core_session_t *session, float amount)
}
/* Variables kept in FS but relevant only to this module */
billaccount = switch_channel_get_variable(channel, "nibble_account");
/* Return if there's no billing information on this session */
@ -725,7 +732,7 @@ SWITCH_STANDARD_APP(nibblebill_app_function)
if (!zstr(data) && (lbuf = strdup(data))
&& (argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
if (!strcasecmp(argv[0], "adjust") && argc == 2) {
nibblebill_adjust(session, (float)atof(argv[1]));
nibblebill_adjust(session, (float) atof(argv[1]));
} else if (!strcasecmp(argv[0], "flush")) {
do_billing(session);
} else if (!strcasecmp(argv[0], "pause")) {
@ -760,7 +767,7 @@ SWITCH_STANDARD_API(nibblebill_api_function)
channel = switch_core_session_get_channel(psession);
if (!strcasecmp(argv[1], "adjust") && argc == 3) {
nibblebill_adjust(psession, (float)atof(argv[2]));
nibblebill_adjust(psession, (float) atof(argv[2]));
} else if (!strcasecmp(argv[1], "flush")) {
do_billing(psession);
} else if (!strcasecmp(argv[1], "pause")) {
@ -805,7 +812,7 @@ static switch_status_t sched_billing(switch_core_session_t *session)
static switch_status_t process_hangup(switch_core_session_t *session)
{
/* Resume any paused billings, just in case */
// nibblebill_resume(session);
// nibblebill_resume(session);
/* Now go handle like normal billing */
do_billing(session);
@ -813,17 +820,19 @@ static switch_status_t process_hangup(switch_core_session_t *session)
return SWITCH_STATUS_SUCCESS;
}
switch_state_handler_table_t nibble_state_handler =
{
/* on_init */ NULL,
/* on_routing */ process_hangup, /* Need to add a check here for anything in their account before routing */
/* on_execute */ sched_billing, /* Turn on heartbeat for this session and do an initial account check */
/* on_hangup */ process_hangup, /* On hangup - most important place to go bill */
/* on_exch_media */ sched_billing,
/* on_soft_exec */ NULL,
/* on_consume_med */ NULL,
/* on_hibernate */ NULL,
/* on_reset */ NULL
switch_state_handler_table_t nibble_state_handler = {
/* on_init */ NULL,
/* on_routing */ process_hangup,
/* Need to add a check here for anything in their account before routing */
/* on_execute */ sched_billing,
/* Turn on heartbeat for this session and do an initial account check */
/* on_hangup */ process_hangup,
/* On hangup - most important place to go bill */
/* on_exch_media */ sched_billing,
/* on_soft_exec */ NULL,
/* on_consume_med */ NULL,
/* on_hibernate */ NULL,
/* on_reset */ NULL
};
SWITCH_MODULE_LOAD_FUNCTION(mod_nibblebill_load)
@ -831,13 +840,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_nibblebill_load)
switch_api_interface_t *api_interface;
switch_application_interface_t *app_interface;
/* Set every byte in this structure to 0 */
/* Set every byte in this structure to 0 */
memset(&globals, 0, sizeof(globals));
globals.pool = pool;
switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool);
load_config();
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
@ -845,13 +854,16 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_nibblebill_load)
SWITCH_ADD_API(api_interface, "nibblebill", "Manage billing parameters for a channel/call", nibblebill_api_function, API_SYNTAX);
/* Add dialplan applications */
SWITCH_ADD_APP(app_interface, "nibblebill", "Handle billing for the current channel/call", "Pause, resume, reset, adjust, flush, heartbeat commands to handle billing.", nibblebill_app_function, APP_SYNTAX, SAF_NONE | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "nibblebill", "Handle billing for the current channel/call",
"Pause, resume, reset, adjust, flush, heartbeat commands to handle billing.", nibblebill_app_function, APP_SYNTAX,
SAF_NONE | SAF_ROUTING_EXEC);
/* register state handlers for billing */
switch_core_add_state_handler(&nibble_state_handler);
/* bind to heartbeat events */
if (switch_event_bind_removable(modname, SWITCH_EVENT_SESSION_HEARTBEAT, SWITCH_EVENT_SUBCLASS_ANY, event_handler, NULL, &globals.node) != SWITCH_STATUS_SUCCESS) {
if (switch_event_bind_removable(modname, SWITCH_EVENT_SESSION_HEARTBEAT, SWITCH_EVENT_SUBCLASS_ANY, event_handler, NULL, &globals.node) !=
SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind event to monitor for session heartbeats!\n");
return SWITCH_STATUS_GENERR;
}
@ -861,7 +873,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_nibblebill_load)
}
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_nibblebill_shutdown)
{
{
switch_event_unbind(&globals.node);
switch_core_remove_state_handler(&nibble_state_handler);
switch_odbc_handle_disconnect(globals.master_odbc);

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -184,9 +184,9 @@ SWITCH_STANDARD_APP(rss_function)
switch_input_args_t args = { 0 };
const char *vcf = NULL;
char *chanvars = switch_channel_build_param_string(channel, NULL, NULL);
switch_codec_implementation_t read_impl = {0};
switch_codec_implementation_t read_impl = { 0 };
uint32_t rate, interval;
switch_core_session_get_read_impl(session, &read_impl);
switch_core_session_get_read_impl(session, &read_impl);
interval = read_impl.microseconds_per_packet / 1000;
if ((vcf = switch_channel_get_variable(channel, "rss_alt_config"))) {

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -55,42 +55,46 @@ static struct {
int integer;
} globals;
static switch_status_t config_callback_siptrace(switch_xml_config_item_t *data, switch_config_callback_type_t callback_type, switch_bool_t changed)
static switch_status_t config_callback_siptrace(switch_xml_config_item_t *data, switch_config_callback_type_t callback_type, switch_bool_t changed)
{
switch_bool_t value = *(switch_bool_t*)data->ptr;
switch_bool_t value = *(switch_bool_t *) data->ptr;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "In siptrace callback: value %s changed %s\n",
value ? "true" : "false", changed ? "true" : "false");
value ? "true" : "false", changed ? "true" : "false");
/*
if ((callback_type == CONFIG_LOG || callback_type == CONFIG_RELOAD) && changed) {
nua_set_params(((sofia_profile_t*)data->functiondata)->nua, TPTAG_LOG(value), TAG_END());
}
*/
if ((callback_type == CONFIG_LOG || callback_type == CONFIG_RELOAD) && changed) {
nua_set_params(((sofia_profile_t*)data->functiondata)->nua, TPTAG_LOG(value), TAG_END());
}
*/
return SWITCH_STATUS_SUCCESS;
}
static switch_xml_config_string_options_t config_opt_codec_negotiation = { NULL, 0, "greedy|generous|evil" };
/* enforce_min, min, enforce_max, max */
static switch_xml_config_int_options_t config_opt_integer = { SWITCH_TRUE, 0, SWITCH_TRUE, 10 };
static switch_xml_config_enum_item_t config_opt_codec_negotiation_enum[] = {
{ "greedy", CODEC_NEGOTIATION_GREEDY },
{ "generous", CODEC_NEGOTIATION_GENEROUS },
{ "evil", CODEC_NEGOTIATION_EVIL },
{ NULL, 0 }
static switch_xml_config_enum_item_t config_opt_codec_negotiation_enum[] = {
{"greedy", CODEC_NEGOTIATION_GREEDY},
{"generous", CODEC_NEGOTIATION_GENEROUS},
{"evil", CODEC_NEGOTIATION_EVIL},
{NULL, 0}
};
static switch_xml_config_item_t instructions[] = {
/* parameter name type reloadable pointer default value options structure */
SWITCH_CONFIG_ITEM("codec-negotiation-str", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &globals.codec_negotiation_str, "greedy", &config_opt_codec_negotiation, \
"greedy|generous|evil", "Specifies the codec negotiation scheme to be used."),
SWITCH_CONFIG_ITEM("codec-negotiation", SWITCH_CONFIG_ENUM, CONFIG_RELOADABLE, &globals.codec_negotiation, (void*)CODEC_NEGOTIATION_GREEDY, &config_opt_codec_negotiation_enum,
"greedy|generous|evil", "Specifies the codec negotiation scheme to be used."),
SWITCH_CONFIG_ITEM_CALLBACK("sip-trace", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &globals.sip_trace, (void*)SWITCH_FALSE, (switch_xml_config_callback_t)config_callback_siptrace, NULL,
"yes|no", "If enabled, print out sip messages on the console."),
SWITCH_CONFIG_ITEM("integer", SWITCH_CONFIG_INT, CONFIG_RELOADABLE, &globals.integer, (void*)100, &config_opt_integer,
NULL, NULL),
SWITCH_CONFIG_ITEM("codec-negotiation-str", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &globals.codec_negotiation_str, "greedy",
&config_opt_codec_negotiation,
"greedy|generous|evil", "Specifies the codec negotiation scheme to be used."),
SWITCH_CONFIG_ITEM("codec-negotiation", SWITCH_CONFIG_ENUM, CONFIG_RELOADABLE, &globals.codec_negotiation, (void *) CODEC_NEGOTIATION_GREEDY,
&config_opt_codec_negotiation_enum,
"greedy|generous|evil", "Specifies the codec negotiation scheme to be used."),
SWITCH_CONFIG_ITEM_CALLBACK("sip-trace", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &globals.sip_trace, (void *) SWITCH_FALSE,
(switch_xml_config_callback_t) config_callback_siptrace, NULL,
"yes|no", "If enabled, print out sip messages on the console."),
SWITCH_CONFIG_ITEM("integer", SWITCH_CONFIG_INT, CONFIG_RELOADABLE, &globals.integer, (void *) 100, &config_opt_integer,
NULL, NULL),
SWITCH_CONFIG_ITEM_END()
};
@ -102,14 +106,14 @@ static switch_status_t do_config(switch_bool_t reload)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not open skel.conf\n");
return SWITCH_STATUS_FALSE;
}
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_API(skel_function)
{
do_config(SWITCH_TRUE);
return SWITCH_STATUS_SUCCESS;
}
@ -121,9 +125,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skel_load)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Hello World!\n");
do_config(SWITCH_FALSE);
SWITCH_ADD_API(api_interface, "skel", "Skel API", skel_function, "syntax");
/* indicate that the module should continue to be loaded */

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -65,17 +65,18 @@ static switch_bool_t capture_callback(switch_media_bug_t *bug, void *user_data,
break;
case SWITCH_ABC_TYPE_READ:
if (cb->buffer) {
uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE];
switch_frame_t frame = { 0 };
frame.data = data;
frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
if (switch_mutex_trylock(cb->mutex) == SWITCH_STATUS_SUCCESS) {
while (switch_core_media_bug_read(bug, &frame, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS && !switch_test_flag((&frame), SFF_CNG)) {
if (frame.datalen) switch_buffer_slide_write(cb->buffer, frame.data, frame.datalen);
if (frame.datalen)
switch_buffer_slide_write(cb->buffer, frame.data, frame.datalen);
}
switch_mutex_unlock(cb->mutex);
}
@ -95,7 +96,7 @@ static switch_status_t start_capture(switch_core_session_t *session, unsigned in
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_media_bug_t *bug;
switch_status_t status;
switch_codec_implementation_t read_impl = {0};
switch_codec_implementation_t read_impl = { 0 };
struct cap_cb *cb;
switch_size_t bytes;
switch_bind_flag_t bind_flags = 0;
@ -109,8 +110,8 @@ static switch_status_t start_capture(switch_core_session_t *session, unsigned in
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Must be at least 5 seconds!\n");
return SWITCH_STATUS_FALSE;
}
switch_core_session_get_read_impl(session, &read_impl);
switch_core_session_get_read_impl(session, &read_impl);
if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
@ -118,7 +119,7 @@ static switch_status_t start_capture(switch_core_session_t *session, unsigned in
cb = switch_core_session_alloc(session, sizeof(*cb));
cb->base = switch_core_session_strdup(session, base);
bytes = read_impl.samples_per_second * seconds * 2;
switch_buffer_create_dynamic(&cb->buffer, bytes, bytes, bytes);
@ -132,7 +133,7 @@ static switch_status_t start_capture(switch_core_session_t *session, unsigned in
switch_ivr_bind_dtmf_meta_session(session, 7, bind_flags, "snapshot::snap");
switch_channel_set_private(channel, "snapshot", bug);
return SWITCH_STATUS_SUCCESS;
}
@ -141,11 +142,11 @@ static switch_status_t do_snap(switch_core_session_t *session)
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_media_bug_t *bug = switch_channel_get_private(channel, "snapshot");
char *file;
switch_file_handle_t fh = {0};
switch_codec_implementation_t read_impl = {0};
switch_file_handle_t fh = { 0 };
switch_codec_implementation_t read_impl = { 0 };
switch_size_t bytes_read;
int16_t pdata[4096] = {0};
int16_t pdata[4096] = { 0 };
if (bug) {
switch_time_exp_t tm;
switch_size_t retsize;
@ -158,19 +159,17 @@ static switch_status_t do_snap(switch_core_session_t *session)
switch_time_exp_lt(&tm, switch_time_make(switch_epoch_time_now(NULL), 0));
switch_strftime(date, &retsize, sizeof(date), "%Y_%m_%d_%H_%M_%S", &tm);
file = switch_core_session_sprintf(session, "%s%s%s_%s.wav", SWITCH_GLOBAL_dirs.sounds_dir,
SWITCH_PATH_SEPARATOR, cb->base, date);
file = switch_core_session_sprintf(session, "%s%s%s_%s.wav", SWITCH_GLOBAL_dirs.sounds_dir, SWITCH_PATH_SEPARATOR, cb->base, date);
switch_core_session_get_read_impl(session, &read_impl);
fh.channels = 0;
fh.native_rate = read_impl.actual_samples_per_second;
if (switch_core_file_open(&fh,
file,
0,
read_impl.actual_samples_per_second,
SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error opening %s\n", file);
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
@ -180,7 +179,7 @@ static switch_status_t do_snap(switch_core_session_t *session)
switch_mutex_lock(cb->mutex);
while ((bytes_read = switch_buffer_read(cb->buffer, pdata, sizeof(pdata)))) {
switch_size_t samples = bytes_read / 2;
if (switch_core_file_write(&fh, pdata, &samples) != SWITCH_STATUS_SUCCESS) {
break;
}
@ -205,8 +204,8 @@ SWITCH_STANDARD_APP(snapshot_app_function)
if (!zstr(data) && (lbuf = switch_core_session_strdup(session, data))) {
argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
}
}
if (argc < 1) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Usage: %s\n", SNAP_SYNTAX);
return;
@ -240,7 +239,7 @@ SWITCH_STANDARD_APP(snapshot_app_function)
}
start_capture(session, seconds, flags, base);
}
if (!strcasecmp(argv[0], "snap")) {
@ -276,7 +275,7 @@ SWITCH_STANDARD_API(snapshot_function)
const char *base = argv[3];
int seconds = 5;
switch_media_bug_flag_t flags = SMBF_READ_STREAM | SMBF_WRITE_STREAM | SMBF_READ_PING;
if (sec) {
int tmp = atoi(sec);
if (tmp > 5) {
@ -297,7 +296,7 @@ SWITCH_STANDARD_API(snapshot_function)
if (!base) {
base = "mod_snapshot";
}
status = start_capture(lsession, seconds, flags, base);
}
@ -311,7 +310,7 @@ SWITCH_STANDARD_API(snapshot_function)
stream->write_function(stream, "-ERR Operation Failed\n");
}
done:
done:
switch_safe_free(mycmd);
return SWITCH_STATUS_SUCCESS;
@ -327,7 +326,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_snapshot_load)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Hello World!\n");
SWITCH_ADD_API(api_interface, "uuid_snapshot", "Snapshot API", snapshot_function, SNAP_API_SYNTAX);
SWITCH_ADD_APP(app_interface, "snapshot", "", "", snapshot_app_function, SNAP_SYNTAX, SAF_SUPPORT_NOMEDIA);

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -55,42 +55,46 @@ static struct {
int integer;
} globals;
static switch_status_t config_callback_siptrace(switch_xml_config_item_t *data, switch_config_callback_type_t callback_type, switch_bool_t changed)
static switch_status_t config_callback_siptrace(switch_xml_config_item_t *data, switch_config_callback_type_t callback_type, switch_bool_t changed)
{
switch_bool_t value = *(switch_bool_t*)data->ptr;
switch_bool_t value = *(switch_bool_t *) data->ptr;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "In siptrace callback: value %s changed %s\n",
value ? "true" : "false", changed ? "true" : "false");
value ? "true" : "false", changed ? "true" : "false");
/*
if ((callback_type == CONFIG_LOG || callback_type == CONFIG_RELOAD) && changed) {
nua_set_params(((sofia_profile_t*)data->functiondata)->nua, TPTAG_LOG(value), TAG_END());
}
*/
if ((callback_type == CONFIG_LOG || callback_type == CONFIG_RELOAD) && changed) {
nua_set_params(((sofia_profile_t*)data->functiondata)->nua, TPTAG_LOG(value), TAG_END());
}
*/
return SWITCH_STATUS_SUCCESS;
}
static switch_xml_config_string_options_t config_opt_codec_negotiation = { NULL, 0, "greedy|generous|evil" };
/* enforce_min, min, enforce_max, max */
static switch_xml_config_int_options_t config_opt_integer = { SWITCH_TRUE, 0, SWITCH_TRUE, 10 };
static switch_xml_config_enum_item_t config_opt_codec_negotiation_enum[] = {
{ "greedy", CODEC_NEGOTIATION_GREEDY },
{ "generous", CODEC_NEGOTIATION_GENEROUS },
{ "evil", CODEC_NEGOTIATION_EVIL },
{ NULL, 0 }
static switch_xml_config_enum_item_t config_opt_codec_negotiation_enum[] = {
{"greedy", CODEC_NEGOTIATION_GREEDY},
{"generous", CODEC_NEGOTIATION_GENEROUS},
{"evil", CODEC_NEGOTIATION_EVIL},
{NULL, 0}
};
static switch_xml_config_item_t instructions[] = {
/* parameter name type reloadable pointer default value options structure */
SWITCH_CONFIG_ITEM("codec-negotiation-str", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &globals.codec_negotiation_str, "greedy", &config_opt_codec_negotiation, \
"greedy|generous|evil", "Specifies the codec negotiation scheme to be used."),
SWITCH_CONFIG_ITEM("codec-negotiation", SWITCH_CONFIG_ENUM, CONFIG_RELOADABLE, &globals.codec_negotiation, (void*)CODEC_NEGOTIATION_GREEDY, &config_opt_codec_negotiation_enum,
"greedy|generous|evil", "Specifies the codec negotiation scheme to be used."),
SWITCH_CONFIG_ITEM_CALLBACK("sip-trace", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &globals.sip_trace, (void*)SWITCH_FALSE, (switch_xml_config_callback_t)config_callback_siptrace, NULL,
"yes|no", "If enabled, print out sip messages on the console."),
SWITCH_CONFIG_ITEM("integer", SWITCH_CONFIG_INT, CONFIG_RELOADABLE, &globals.integer, (void*)100, &config_opt_integer,
NULL, NULL),
SWITCH_CONFIG_ITEM("codec-negotiation-str", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &globals.codec_negotiation_str, "greedy",
&config_opt_codec_negotiation,
"greedy|generous|evil", "Specifies the codec negotiation scheme to be used."),
SWITCH_CONFIG_ITEM("codec-negotiation", SWITCH_CONFIG_ENUM, CONFIG_RELOADABLE, &globals.codec_negotiation, (void *) CODEC_NEGOTIATION_GREEDY,
&config_opt_codec_negotiation_enum,
"greedy|generous|evil", "Specifies the codec negotiation scheme to be used."),
SWITCH_CONFIG_ITEM_CALLBACK("sip-trace", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &globals.sip_trace, (void *) SWITCH_FALSE,
(switch_xml_config_callback_t) config_callback_siptrace, NULL,
"yes|no", "If enabled, print out sip messages on the console."),
SWITCH_CONFIG_ITEM("integer", SWITCH_CONFIG_INT, CONFIG_RELOADABLE, &globals.integer, (void *) 100, &config_opt_integer,
NULL, NULL),
SWITCH_CONFIG_ITEM_END()
};
@ -102,14 +106,14 @@ static switch_status_t do_config(switch_bool_t reload)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not open snipe_hunt.conf\n");
return SWITCH_STATUS_FALSE;
}
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_API(snipe_hunt_function)
{
do_config(SWITCH_TRUE);
return SWITCH_STATUS_SUCCESS;
}
@ -121,9 +125,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_snipe_hunt_load)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Hello World!\n");
do_config(SWITCH_FALSE);
SWITCH_ADD_API(api_interface, "snipe_hunt", "Snipe_Hunt API", snipe_hunt_function, "syntax");
/* indicate that the module should continue to be loaded */

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -33,14 +33,9 @@
SWITCH_MODULE_LOAD_FUNCTION(mod_snom_load);
SWITCH_MODULE_DEFINITION(mod_snom, mod_snom_load, NULL, NULL);
static switch_bool_t snom_bind_key(const char *key,
const char *light,
const char *label,
const char *user,
const char *host,
const char *profile,
const char *action_name,
const char *action)
static switch_bool_t snom_bind_key(const char *key,
const char *light,
const char *label, const char *user, const char *host, const char *profile, const char *action_name, const char *action)
{
switch_event_t *event;
@ -61,7 +56,7 @@ static switch_bool_t snom_bind_key(const char *key,
}
return SWITCH_TRUE;
}
return SWITCH_FALSE;
}
@ -92,17 +87,17 @@ SWITCH_STANDARD_API(snom_bind_key_api_function)
if (argc < 6) {
goto err;
}
if (snom_bind_key(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7])) {
stream->write_function(stream, "+OK %s\n", cmd);
goto end;
}
err:
err:
stream->write_function(stream, "-Error %s\n", KEY_BIND_SYNTAX);
end:
end:
free(mydata);
@ -122,7 +117,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_snom_load)
SWITCH_ADD_API(commands_api_interface, "snom_bind_key", "Bind a key", snom_bind_key_api_function, KEY_BIND_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "snom_url", "url", snom_url_api_function, URL_SYNTAX);
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -39,10 +39,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_spy_load);
SWITCH_MODULE_DEFINITION(mod_spy, mod_spy_load, mod_spy_shutdown, NULL);
struct mod_spy_globals {
switch_memory_pool_t* pool;
switch_event_node_t* node;
switch_hash_t* spy_hash;
switch_thread_rwlock_t* spy_hash_lock;
switch_memory_pool_t *pool;
switch_event_node_t *node;
switch_hash_t *spy_hash;
switch_thread_rwlock_t *spy_hash_lock;
uint32_t spy_count;
} globals;
@ -50,14 +50,14 @@ static switch_status_t spy_on_hangup(switch_core_session_t *session)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
char* data = switch_channel_get_private(channel,"_userspy_");
char *data = switch_channel_get_private(channel, "_userspy_");
switch_thread_rwlock_wrlock(globals.spy_hash_lock);
if ((switch_core_hash_delete(globals.spy_hash,data) != SWITCH_STATUS_SUCCESS)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,"No such key in userspy: %s \n",data);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,"Userspy deactivated on %s\n",data);
if ((switch_core_hash_delete(globals.spy_hash, data) != SWITCH_STATUS_SUCCESS)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No such key in userspy: %s \n", data);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Userspy deactivated on %s\n", data);
globals.spy_count--;
}
@ -68,16 +68,16 @@ static switch_status_t spy_on_hangup(switch_core_session_t *session)
static switch_status_t spy_on_exchange_media(switch_core_session_t *session)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
const char* spy_uuid = switch_channel_get_variable(channel,"spy_uuid");
const char *spy_uuid = switch_channel_get_variable(channel, "spy_uuid");
if (spy_uuid) {
if (switch_ivr_eavesdrop_session(session,spy_uuid,NULL,ED_DTMF) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,"Can't eavesdrop on uuid %s\n",spy_uuid);
if (switch_ivr_eavesdrop_session(session, spy_uuid, NULL, ED_DTMF) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't eavesdrop on uuid %s\n", spy_uuid);
}
}
switch_channel_set_state(channel,CS_PARK);
return SWITCH_STATUS_FALSE;
switch_channel_set_state(channel, CS_PARK);
return SWITCH_STATUS_FALSE;
}
static switch_status_t spy_on_park(switch_core_session_t *session)
@ -85,7 +85,7 @@ static switch_status_t spy_on_park(switch_core_session_t *session)
switch_channel_t *channel = switch_core_session_get_channel(session);
const char *moh = switch_channel_get_variable(channel, "hold_music");
while(switch_channel_ready(channel) && switch_channel_get_state(channel) == CS_PARK) {
while (switch_channel_ready(channel) && switch_channel_get_state(channel) == CS_PARK) {
if (moh) {
switch_status_t status = switch_ivr_play_file(session, NULL, moh, NULL);
if (!SWITCH_READ_ACCEPTABLE(status)) {
@ -98,13 +98,13 @@ static switch_status_t spy_on_park(switch_core_session_t *session)
static const switch_state_handler_table_t spy_state_handlers = {
/*.on_init */ NULL,
/*.on_routing */ NULL,
/*.on_execute */ NULL,
/*.on_hangup */ spy_on_hangup,
/*.on_exchange_media */ spy_on_exchange_media,
/*.on_soft_execute */ NULL,
/*.on_consume_media */ NULL,
/*.on_init */ NULL,
/*.on_routing */ NULL,
/*.on_execute */ NULL,
/*.on_hangup */ spy_on_hangup,
/*.on_exchange_media */ spy_on_exchange_media,
/*.on_soft_execute */ NULL,
/*.on_consume_media */ NULL,
/* on_hibernate */ NULL,
/* on reset */ NULL,
/* on_park */ spy_on_park,
@ -113,29 +113,29 @@ static const switch_state_handler_table_t spy_state_handlers = {
SWITCH_STANDARD_API(dump_hash)
{
switch_hash_index_t *hi;
const void* key;
void* val;
const void *key;
void *val;
switch_thread_rwlock_rdlock(globals.spy_hash_lock);
for (hi = switch_hash_first(NULL,globals.spy_hash);hi; hi = switch_hash_next(hi)){
switch_hash_this(hi,&key,NULL,&val);
stream->write_function(stream,"%s : %s\n",(char*)key,(const char*)val);
for (hi = switch_hash_first(NULL, globals.spy_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, &key, NULL, &val);
stream->write_function(stream, "%s : %s\n", (char *) key, (const char *) val);
}
stream->write_function(stream,"\n%d total spy\n",globals.spy_count);
stream->write_function(stream, "\n%d total spy\n", globals.spy_count);
switch_thread_rwlock_unlock(globals.spy_hash_lock);
return SWITCH_STATUS_SUCCESS;
}
static void event_handler(switch_event_t* event)
static void event_handler(switch_event_t *event)
{
switch_core_session_t *session = NULL;
switch_channel_t *channel;
char *username[2] = {0};
char* domain[2] = {0};
char *username[2] = { 0 };
char *domain[2] = { 0 };
char key[512];
char* uuid = NULL, *my_uuid = NULL;
char *uuid = NULL, *my_uuid = NULL;
int i;
switch_thread_rwlock_rdlock(globals.spy_hash_lock);
@ -144,22 +144,22 @@ static void event_handler(switch_event_t* event)
goto done;
}
username[0] = switch_event_get_header(event,"Caller-Username");
domain[0] = switch_event_get_header(event,"variable_domain_name");
domain[1] = switch_event_get_header(event,"variable_dialed_domain");
username[1] = switch_event_get_header(event,"variable_dialed_user");
username[0] = switch_event_get_header(event, "Caller-Username");
domain[0] = switch_event_get_header(event, "variable_domain_name");
domain[1] = switch_event_get_header(event, "variable_dialed_domain");
username[1] = switch_event_get_header(event, "variable_dialed_user");
for (i = 0; i < 2; i++) {
if (username[i] && domain[i]) {
switch_snprintf(key,sizeof(key),"%s@%s",username[i],domain[i]);
switch_snprintf(key, sizeof(key), "%s@%s", username[i], domain[i]);
if ((uuid = switch_core_hash_find(globals.spy_hash,key))) {
if ((uuid = switch_core_hash_find(globals.spy_hash, key))) {
break;
}
}
}
done:
done:
switch_thread_rwlock_unlock(globals.spy_hash_lock);
if (!uuid) {
@ -169,64 +169,64 @@ static void event_handler(switch_event_t* event)
session = switch_core_session_locate(uuid);
channel = switch_core_session_get_channel(session);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,"UserSpy retrieved uuid %s for key %s, activating eavesdrop \n",uuid,key);
my_uuid = switch_event_get_header(event,"Unique-ID");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "UserSpy retrieved uuid %s for key %s, activating eavesdrop \n", uuid, key);
my_uuid = switch_event_get_header(event, "Unique-ID");
switch_channel_set_variable(channel,"spy_uuid",my_uuid);
switch_channel_set_variable(channel, "spy_uuid", my_uuid);
switch_channel_set_state(channel,CS_EXCHANGE_MEDIA);
switch_channel_set_flag(channel,CF_BREAK);
switch_channel_set_state(channel, CS_EXCHANGE_MEDIA);
switch_channel_set_flag(channel, CF_BREAK);
switch_core_session_rwunlock(session);
}
#define USERSPY_SYNTAX "<user@domain> [uuid]"
SWITCH_STANDARD_APP(userspy_function)
SWITCH_STANDARD_APP(userspy_function)
{
int argc = 0;
char* argv[2] = {0};
char* params = NULL;
char *argv[2] = { 0 };
char *params = NULL;
if (!zstr(data) && (params = switch_core_session_strdup(session,data))) {
if (!zstr(data) && (params = switch_core_session_strdup(session, data))) {
if ((argc = switch_separate_string(params, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 1) {
switch_channel_t *channel = switch_core_session_get_channel(session);
char* uuid = switch_core_session_get_uuid(session);
char *uuid = switch_core_session_get_uuid(session);
switch_status_t status;
switch_thread_rwlock_wrlock(globals.spy_hash_lock);
if (switch_core_hash_find(globals.spy_hash,argv[0])) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,"Spy already exists for %s\n",argv[0]);
switch_channel_hangup(channel,SWITCH_CAUSE_NORMAL_CLEARING);
if (switch_core_hash_find(globals.spy_hash, argv[0])) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Spy already exists for %s\n", argv[0]);
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
switch_thread_rwlock_unlock(globals.spy_hash_lock);
return;
}
status = switch_core_hash_insert(globals.spy_hash,argv[0],(void*) uuid);
status = switch_core_hash_insert(globals.spy_hash, argv[0], (void *) uuid);
if ((status != SWITCH_STATUS_SUCCESS)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,"Cant insert to spy hash\n");
switch_channel_hangup(channel,SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED);
switch_thread_rwlock_unlock(globals.spy_hash_lock);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cant insert to spy hash\n");
switch_channel_hangup(channel, SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED);
switch_thread_rwlock_unlock(globals.spy_hash_lock);
return;
}
globals.spy_count++;
switch_thread_rwlock_unlock(globals.spy_hash_lock);
switch_channel_set_private(channel,"_userspy_",(void*) argv[0]);
switch_channel_add_state_handler(channel,&spy_state_handlers);
switch_channel_set_private(channel, "_userspy_", (void *) argv[0]);
switch_channel_add_state_handler(channel, &spy_state_handlers);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE,"UserSpy activated on %s \n",argv[0]);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "UserSpy activated on %s \n", argv[0]);
if (argv[1]) {
switch_channel_set_variable(channel,"spy_uuid",argv[1]);
switch_channel_set_state(channel,CS_EXCHANGE_MEDIA);
switch_channel_set_variable(channel, "spy_uuid", argv[1]);
switch_channel_set_state(channel, CS_EXCHANGE_MEDIA);
return;
}
switch_channel_set_state(channel,CS_PARK);
switch_channel_set_state(channel, CS_PARK);
return;
}
return;
@ -244,15 +244,15 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_spy_load)
globals.pool = pool;
switch_core_hash_init(&globals.spy_hash,pool);
switch_thread_rwlock_create(&globals.spy_hash_lock,pool);
switch_core_hash_init(&globals.spy_hash, pool);
switch_thread_rwlock_create(&globals.spy_hash_lock, pool);
globals.spy_count = 0;
switch_event_bind_removable(modname, SWITCH_EVENT_CHANNEL_BRIDGE, NULL, event_handler, NULL, &globals.node);
SWITCH_ADD_APP(app_interface,"userspy","Spy on a user constantly","Spy on a user constantly",userspy_function,USERSPY_SYNTAX,SAF_NONE);
SWITCH_ADD_API(api_interface,"userspy_show","Show current spies",dump_hash,"userspy_show");
SWITCH_ADD_APP(app_interface, "userspy", "Spy on a user constantly", "Spy on a user constantly", userspy_function, USERSPY_SYNTAX, SAF_NONE);
SWITCH_ADD_API(api_interface, "userspy_show", "Show current spies", dump_hash, "userspy_show");
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}
@ -261,12 +261,12 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_spy_shutdown)
{
int sanity = 0;
while (globals.spy_count) {
switch_cond_next();
if (++sanity >= 60000) {
break;
}
}
while (globals.spy_count) {
switch_cond_next();
if (++sanity >= 60000) {
break;
}
}
switch_event_unbind(&globals.node);
switch_core_hash_destroy(&globals.spy_hash);

View File

@ -14,7 +14,7 @@
#if defined (FFTReal_CURRENT_HEADER)
#error Recursive inclusion of FFTReal header file.
#error Recursive inclusion of FFTReal header file.
#endif
#define FFTReal_CURRENT_HEADER
@ -25,89 +25,83 @@
#if defined (_MSC_VER)
#pragma pack (push, 8)
#endif // _MSC_VER
#endif // _MSC_VER
class FFTReal
{
class FFTReal {
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
public:
public:
/* Change this typedef to use a different floating point type in your FFTs
(i.e. float, double or long double). */
typedef float flt_t;
(i.e. float, double or long double). */
typedef float flt_t;
explicit FFTReal (const long length);
~FFTReal ();
void do_fft (flt_t f [], const flt_t x []) const;
void do_ifft (const flt_t f [], flt_t x []) const;
void rescale (flt_t x []) const;
explicit FFTReal(const long length);
~FFTReal();
void do_fft(flt_t f[], const flt_t x[]) const;
void do_ifft(const flt_t f[], flt_t x[]) const;
void rescale(flt_t x[]) const;
/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
private:
private:
/* Bit-reversed look-up table nested class */
class BitReversedLUT
{
public:
explicit BitReversedLUT (const int nbr_bits);
~BitReversedLUT ();
const long * get_ptr () const
{
class BitReversedLUT {
public:
explicit BitReversedLUT(const int nbr_bits);
~BitReversedLUT();
const long *get_ptr() const {
return (_ptr);
}
private:
long * _ptr;
} private:
long *_ptr;
};
/* Trigonometric look-up table nested class */
class TrigoLUT
{
public:
explicit TrigoLUT (const int nbr_bits);
~TrigoLUT ();
const flt_t * get_ptr (const int level) const
{
class TrigoLUT {
public:
explicit TrigoLUT(const int nbr_bits);
~TrigoLUT();
const flt_t *get_ptr(const int level) const {
return (_ptr + (1L << (level - 1)) - 4);
};
private:
flt_t * _ptr;
private:
flt_t *_ptr;
};
const BitReversedLUT _bit_rev_lut;
const TrigoLUT _trigo_lut;
const flt_t _sqrt2_2;
const long _length;
const int _nbr_bits;
flt_t * _buffer_ptr;
const BitReversedLUT _bit_rev_lut;
const TrigoLUT _trigo_lut;
const flt_t _sqrt2_2;
const long _length;
const int _nbr_bits;
flt_t *_buffer_ptr;
/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
private:
private:
FFTReal (const FFTReal &other);
const FFTReal& operator = (const FFTReal &other);
int operator == (const FFTReal &other);
int operator != (const FFTReal &other);
FFTReal(const FFTReal & other);
const FFTReal & operator =(const FFTReal & other);
int operator ==(const FFTReal & other);
int operator !=(const FFTReal & other);
};
#if defined (_MSC_VER)
#pragma pack (pop)
#endif // _MSC_VER
#endif // _MSC_VER
#endif // FFTReal_HEADER_INCLUDED
#endif // FFTReal_HEADER_INCLUDED
#undef FFTReal_CURRENT_HEADER

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*

View File

@ -54,40 +54,42 @@ SWITCH_STANDARD_APP(t38gateway_start_function);
/*! Type that holds codec information. */
typedef struct {
/*! The sampling rate of the audio stream. */
int rate;
/*! The number of channels. */
int channels;
/*! The sampling rate of the audio stream. */
int rate;
/*! The number of channels. */
int channels;
} t38gateway_codec_info_t;
/*! Type that holds session information pertinent to the t38gateway module. */
typedef struct {
/*! Internal FreeSWITCH session. */
switch_core_session_t *session;
/*! Codec information for the session. */
t38gateway_codec_info_t t38gateway_codec;
t38_gateway_state_t *t38;
t38_core_state_t *t38_core;
udptl_state_t *udptl;
/*! Internal FreeSWITCH session. */
switch_core_session_t *session;
/*! Codec information for the session. */
t38gateway_codec_info_t t38gateway_codec;
t38_gateway_state_t *t38;
t38_core_state_t *t38_core;
udptl_state_t *udptl;
} t38gateway_session_info_t;
static int tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count)
{
t38gateway_session_info_t *t;
t38gateway_session_info_t *t;
t = (t38gateway_session_info_t *) user_data;
return 0;
t = (t38gateway_session_info_t *) user_data;
return 0;
}
/*- End of function --------------------------------------------------------*/
static int rx_packet_handler(void *user_data, const uint8_t *buf, int len, int seq_no)
{
t38gateway_session_info_t *t;
t38gateway_session_info_t *t;
t = (t38gateway_session_info_t *) user_data;
t38_core_rx_ifp_packet(t->t38_core, buf, len, seq_no);
return 0;
t = (t38gateway_session_info_t *) user_data;
t38_core_rx_ifp_packet(t->t38_core, buf, len, seq_no);
return 0;
}
/*- End of function --------------------------------------------------------*/
/*! \brief The callback function that is called when new audio data becomes available
@ -98,39 +100,39 @@ static int rx_packet_handler(void *user_data, const uint8_t *buf, int len, int s
* @param type The switch callback type.
* @return The success or failure of the function.
*/
static switch_bool_t t38gateway_callback(switch_media_bug_t * bug, void *user_data, switch_abc_type_t type)
static switch_bool_t t38gateway_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
{
t38gateway_session_info_t *t38gateway_info;
switch_codec_t *read_codec;
switch_frame_t *frame;
int16_t *amp;
t38gateway_session_info_t *t38gateway_info;
switch_codec_t *read_codec;
switch_frame_t *frame;
int16_t *amp;
t38gateway_info = (t38gateway_session_info_t *) user_data;
if (t38gateway_info == NULL) {
return SWITCH_FALSE;
}
t38gateway_info = (t38gateway_session_info_t *) user_data;
if (t38gateway_info == NULL) {
return SWITCH_FALSE;
}
switch (type) {
case SWITCH_ABC_TYPE_INIT:
read_codec = switch_core_session_get_read_codec(t38gateway_info->session);
t38gateway_info->t38gateway_codec.rate = read_codec->implementation->samples_per_second;
t38gateway_info->t38gateway_codec.channels = read_codec->implementation->number_of_channels;
break;
case SWITCH_ABC_TYPE_READ_PING:
case SWITCH_ABC_TYPE_CLOSE:
break;
case SWITCH_ABC_TYPE_READ:
frame = switch_core_media_bug_get_read_replace_frame(bug);
amp = (int16_t *) frame->data;
t38_gateway_rx(t38gateway_info->t38, amp, frame->samples);
break;
case SWITCH_ABC_TYPE_WRITE:
case SWITCH_ABC_TYPE_READ_REPLACE:
case SWITCH_ABC_TYPE_WRITE_REPLACE:
break;
}
switch (type) {
case SWITCH_ABC_TYPE_INIT:
read_codec = switch_core_session_get_read_codec(t38gateway_info->session);
t38gateway_info->t38gateway_codec.rate = read_codec->implementation->samples_per_second;
t38gateway_info->t38gateway_codec.channels = read_codec->implementation->number_of_channels;
break;
case SWITCH_ABC_TYPE_READ_PING:
case SWITCH_ABC_TYPE_CLOSE:
break;
case SWITCH_ABC_TYPE_READ:
frame = switch_core_media_bug_get_read_replace_frame(bug);
amp = (int16_t *) frame->data;
t38_gateway_rx(t38gateway_info->t38, amp, frame->samples);
break;
case SWITCH_ABC_TYPE_WRITE:
case SWITCH_ABC_TYPE_READ_REPLACE:
case SWITCH_ABC_TYPE_WRITE_REPLACE:
break;
}
return SWITCH_TRUE;
return SWITCH_TRUE;
}
/*! \brief FreeSWITCH module loading function
@ -140,19 +142,19 @@ static switch_bool_t t38gateway_callback(switch_media_bug_t * bug, void *user_da
*/
SWITCH_MODULE_LOAD_FUNCTION(mod_t38gateway_load)
{
switch_application_interface_t *app_interface;
switch_api_interface_t *api_interface;
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
switch_application_interface_t *app_interface;
switch_api_interface_t *api_interface;
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "T.38 gateway enabled\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "T.38 gateway enabled\n");
SWITCH_ADD_APP(app_interface, "t38gateway", "T.38 gateway", "T.38 gateway", t38gateway_start_function, "[start] [stop]", SAF_NONE);
SWITCH_ADD_APP(app_interface, "t38gateway", "T.38 gateway", "T.38 gateway", t38gateway_start_function, "[start] [stop]", SAF_NONE);
SWITCH_ADD_API(api_interface, "t38gateway", "T.38 gateway", t38gateway_api_main, T38GATEWAY_SYNTAX);
SWITCH_ADD_API(api_interface, "t38gateway", "T.38 gateway", t38gateway_api_main, T38GATEWAY_SYNTAX);
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}
/*! \brief FreeSWITCH application handler function.
@ -163,48 +165,48 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_t38gateway_load)
*/
SWITCH_STANDARD_APP(t38gateway_start_function)
{
switch_media_bug_t *bug;
switch_status_t status;
switch_channel_t *channel;
t38gateway_session_info_t *t38gateway_info;
switch_media_bug_t *bug;
switch_status_t status;
switch_channel_t *channel;
t38gateway_session_info_t *t38gateway_info;
if (session == NULL)
return;
if (session == NULL)
return;
channel = switch_core_session_get_channel(session);
channel = switch_core_session_get_channel(session);
/* Is this channel already set? */
bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_t38gateway_");
/* If yes */
if (bug != NULL) {
/* If we have a stop remove audio bug */
if (strcasecmp(data, "stop") == 0) {
switch_channel_set_private(channel, "_t38gateway_", NULL);
switch_core_media_bug_remove(session, &bug);
return;
}
/* Is this channel already set? */
bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_t38gateway_");
/* If yes */
if (bug != NULL) {
/* If we have a stop remove audio bug */
if (strcasecmp(data, "stop") == 0) {
switch_channel_set_private(channel, "_t38gateway_", NULL);
switch_core_media_bug_remove(session, &bug);
return;
}
/* We have already started */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n");
/* We have already started */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n");
return;
}
return;
}
t38gateway_info = (t38gateway_session_info_t *) switch_core_session_alloc(session, sizeof(t38gateway_session_info_t));
t38gateway_info = (t38gateway_session_info_t *) switch_core_session_alloc(session, sizeof(t38gateway_session_info_t));
t38gateway_info->session = session;
t38gateway_info->t38 = t38_gateway_init(NULL, tx_packet_handler, (void *) t38gateway_info);
t38gateway_info->t38_core = t38_gateway_get_t38_core_state(t38gateway_info->t38);
t38gateway_info->udptl = udptl_init(NULL, UDPTL_ERROR_CORRECTION_REDUNDANCY, 3, 3, rx_packet_handler, (void *) t38gateway_info);
t38gateway_info->session = session;
t38gateway_info->t38 = t38_gateway_init(NULL, tx_packet_handler, (void *) t38gateway_info);
t38gateway_info->t38_core = t38_gateway_get_t38_core_state(t38gateway_info->t38);
t38gateway_info->udptl = udptl_init(NULL, UDPTL_ERROR_CORRECTION_REDUNDANCY, 3, 3, rx_packet_handler, (void *) t38gateway_info);
status = switch_core_media_bug_add(session, t38gateway_callback, t38gateway_info, 0, SMBF_READ_STREAM, &bug);
status = switch_core_media_bug_add(session, t38gateway_callback, t38gateway_info, 0, SMBF_READ_STREAM, &bug);
if (status != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failure hooking to stream\n");
return;
}
if (status != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failure hooking to stream\n");
return;
}
switch_channel_set_private(channel, "_t38gateway_", bug);
switch_channel_set_private(channel, "_t38gateway_", bug);
}
/*! \brief Called when the module shuts down
@ -214,9 +216,9 @@ SWITCH_STANDARD_APP(t38gateway_start_function)
*/
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_t38gateway_shutdown)
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "T.38 gateway disabled\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "T.38 gateway disabled\n");
return SWITCH_STATUS_SUCCESS;
return SWITCH_STATUS_SUCCESS;
}
/*! \brief FreeSWITCH API handler function.
@ -228,110 +230,110 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_t38gateway_shutdown)
*/
SWITCH_STANDARD_API(t38gateway_api_main)
{
switch_core_session_t *t38gateway_session;
switch_media_bug_t *bug;
t38gateway_session_info_t *t38gateway_info;
switch_channel_t *channel;
switch_status_t status;
int argc;
char *argv[T38GATEWAY_PARAMS];
char *ccmd;
char *uuid;
char *command;
switch_core_session_t *t38gateway_session;
switch_media_bug_t *bug;
t38gateway_session_info_t *t38gateway_info;
switch_channel_t *channel;
switch_status_t status;
int argc;
char *argv[T38GATEWAY_PARAMS];
char *ccmd;
char *uuid;
char *command;
/* No command? Display usage */
if (cmd == NULL) {
stream->write_function(stream, "-USAGE: %s\n", T38GATEWAY_SYNTAX);
return SWITCH_STATUS_SUCCESS;
}
/* No command? Display usage */
if (cmd == NULL) {
stream->write_function(stream, "-USAGE: %s\n", T38GATEWAY_SYNTAX);
return SWITCH_STATUS_SUCCESS;
}
/* Duplicated contents of original string */
ccmd = strdup(cmd);
/* Separate the arguments */
argc = switch_separate_string(ccmd, ' ', argv, T38GATEWAY_PARAMS);
/* Duplicated contents of original string */
ccmd = strdup(cmd);
/* Separate the arguments */
argc = switch_separate_string(ccmd, ' ', argv, T38GATEWAY_PARAMS);
/* If we don't have the expected number of parameters
* display usage */
if (argc != T38GATEWAY_PARAMS) {
stream->write_function(stream, "-USAGE: %s\n", T38GATEWAY_SYNTAX);
switch_safe_free(ccmd);
return SWITCH_STATUS_SUCCESS;
}
/* If we don't have the expected number of parameters
* display usage */
if (argc != T38GATEWAY_PARAMS) {
stream->write_function(stream, "-USAGE: %s\n", T38GATEWAY_SYNTAX);
switch_safe_free(ccmd);
return SWITCH_STATUS_SUCCESS;
}
uuid = argv[0];
command = argv[1];
uuid = argv[0];
command = argv[1];
/* using uuid locate a reference to the FreeSWITCH session */
t38gateway_session = switch_core_session_locate(uuid);
/* using uuid locate a reference to the FreeSWITCH session */
t38gateway_session = switch_core_session_locate(uuid);
/* If the session was not found exit */
if (t38gateway_session == NULL) {
switch_safe_free(ccmd);
stream->write_function(stream, "-USAGE: %s\n", T38GATEWAY_SYNTAX);
return SWITCH_STATUS_FALSE;
}
/* If the session was not found exit */
if (t38gateway_session == NULL) {
switch_safe_free(ccmd);
stream->write_function(stream, "-USAGE: %s\n", T38GATEWAY_SYNTAX);
return SWITCH_STATUS_FALSE;
}
/* Get current channel of the session to tag the session
* This indicates that our module is present */
channel = switch_core_session_get_channel(t38gateway_session);
/* Get current channel of the session to tag the session
* This indicates that our module is present */
channel = switch_core_session_get_channel(t38gateway_session);
/* Is this channel already set? */
bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_t38gateway_");
/* If yes */
if (bug != NULL) {
/* If we have a stop remove audio bug */
if (strcasecmp(command, "stop") == 0) {
switch_channel_set_private(channel, "_t38gateway_", NULL);
switch_core_media_bug_remove(t38gateway_session, &bug);
switch_safe_free(ccmd);
stream->write_function(stream, "+OK\n");
return SWITCH_STATUS_SUCCESS;
}
/* Is this channel already set? */
bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_t38gateway_");
/* If yes */
if (bug != NULL) {
/* If we have a stop remove audio bug */
if (strcasecmp(command, "stop") == 0) {
switch_channel_set_private(channel, "_t38gateway_", NULL);
switch_core_media_bug_remove(t38gateway_session, &bug);
switch_safe_free(ccmd);
stream->write_function(stream, "+OK\n");
return SWITCH_STATUS_SUCCESS;
}
/* We have already started */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n");
/* We have already started */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n");
switch_safe_free(ccmd);
return SWITCH_STATUS_FALSE;
}
switch_safe_free(ccmd);
return SWITCH_STATUS_FALSE;
}
/* If we don't see the expected start exit */
if (strcasecmp(command, "start") != 0) {
switch_safe_free(ccmd);
stream->write_function(stream, "-USAGE: %s\n", T38GATEWAY_SYNTAX);
return SWITCH_STATUS_FALSE;
}
/* If we don't see the expected start exit */
if (strcasecmp(command, "start") != 0) {
switch_safe_free(ccmd);
stream->write_function(stream, "-USAGE: %s\n", T38GATEWAY_SYNTAX);
return SWITCH_STATUS_FALSE;
}
/* Allocate memory attached to this FreeSWITCH session for
* use in the callback routine and to store state information */
t38gateway_info = (t38gateway_session_info_t *) switch_core_session_alloc(t38gateway_session, sizeof(t38gateway_session_info_t));
/* Allocate memory attached to this FreeSWITCH session for
* use in the callback routine and to store state information */
t38gateway_info = (t38gateway_session_info_t *) switch_core_session_alloc(t38gateway_session, sizeof(t38gateway_session_info_t));
/* Set initial values and states */
t38gateway_info->session = t38gateway_session;
t38gateway_info->t38 = t38_gateway_init(NULL, tx_packet_handler, (void *) t38gateway_info);
t38gateway_info->t38_core = t38_gateway_get_t38_core_state(t38gateway_info->t38);
t38gateway_info->udptl = udptl_init(NULL, UDPTL_ERROR_CORRECTION_REDUNDANCY, 3, 3, rx_packet_handler, (void *) t38gateway_info);
/* Set initial values and states */
t38gateway_info->session = t38gateway_session;
t38gateway_info->t38 = t38_gateway_init(NULL, tx_packet_handler, (void *) t38gateway_info);
t38gateway_info->t38_core = t38_gateway_get_t38_core_state(t38gateway_info->t38);
t38gateway_info->udptl = udptl_init(NULL, UDPTL_ERROR_CORRECTION_REDUNDANCY, 3, 3, rx_packet_handler, (void *) t38gateway_info);
/* Add a media bug that allows me to intercept the
* reading leg of the audio stream */
status = switch_core_media_bug_add(t38gateway_session, t38gateway_callback, t38gateway_info, 0, SMBF_READ_STREAM, &bug);
/* Add a media bug that allows me to intercept the
* reading leg of the audio stream */
status = switch_core_media_bug_add(t38gateway_session, t38gateway_callback, t38gateway_info, 0, SMBF_READ_STREAM, &bug);
/* If adding a media bug fails exit */
if (status != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failure hooking to stream\n");
/* If adding a media bug fails exit */
if (status != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failure hooking to stream\n");
switch_safe_free(ccmd);
return SWITCH_STATUS_FALSE;
}
switch_safe_free(ccmd);
return SWITCH_STATUS_FALSE;
}
/* Set the t38gateway tag to detect an existing t38gateway media bug */
switch_channel_set_private(channel, "_t38gateway_", bug);
/* Set the t38gateway tag to detect an existing t38gateway media bug */
switch_channel_set_private(channel, "_t38gateway_", bug);
/* Everything went according to plan! Notify the user */
stream->write_function(stream, "+OK\n");
/* Everything went according to plan! Notify the user */
stream->write_function(stream, "+OK\n");
switch_safe_free(ccmd);
return SWITCH_STATUS_SUCCESS;
switch_safe_free(ccmd);
return SWITCH_STATUS_SUCCESS;
}

View File

@ -36,561 +36,528 @@
static int decode_length(const uint8_t *buf, int limit, int *len, int *pvalue)
{
if (*len >= limit)
return -1;
if ((buf[*len] & 0x80) == 0)
{
*pvalue = buf[(*len)++];
return 0;
}
if ((buf[*len] & 0x40) == 0)
{
if (*len >= limit - 1)
return -1;
*pvalue = (buf[(*len)++] & 0x3F) << 8;
*pvalue |= buf[(*len)++];
return 0;
}
*pvalue = (buf[(*len)++] & 0x3F) << 14;
/* Indicate we have a fragment */
return 1;
if (*len >= limit)
return -1;
if ((buf[*len] & 0x80) == 0) {
*pvalue = buf[(*len)++];
return 0;
}
if ((buf[*len] & 0x40) == 0) {
if (*len >= limit - 1)
return -1;
*pvalue = (buf[(*len)++] & 0x3F) << 8;
*pvalue |= buf[(*len)++];
return 0;
}
*pvalue = (buf[(*len)++] & 0x3F) << 14;
/* Indicate we have a fragment */
return 1;
}
/*- End of function --------------------------------------------------------*/
static int decode_open_type(const uint8_t *buf, int limit, int *len, const uint8_t **p_object, int *p_num_octets)
static int decode_open_type(const uint8_t *buf, int limit, int *len, const uint8_t ** p_object, int *p_num_octets)
{
int octet_cnt;
int octet_idx;
int stat;
int i;
const uint8_t **pbuf;
int octet_cnt;
int octet_idx;
int stat;
int i;
const uint8_t **pbuf;
for (octet_idx = 0, *p_num_octets = 0; ; octet_idx += octet_cnt)
{
if ((stat = decode_length(buf, limit, len, &octet_cnt)) < 0)
return -1;
if (octet_cnt > 0)
{
*p_num_octets += octet_cnt;
for (octet_idx = 0, *p_num_octets = 0;; octet_idx += octet_cnt) {
if ((stat = decode_length(buf, limit, len, &octet_cnt)) < 0)
return -1;
if (octet_cnt > 0) {
*p_num_octets += octet_cnt;
pbuf = &p_object[octet_idx];
i = 0;
/* Make sure the buffer contains at least the number of bits requested */
if ((*len + octet_cnt) > limit)
return -1;
pbuf = &p_object[octet_idx];
i = 0;
/* Make sure the buffer contains at least the number of bits requested */
if ((*len + octet_cnt) > limit)
return -1;
*pbuf = &buf[*len];
*len += octet_cnt;
}
if (stat == 0)
break;
}
return 0;
*pbuf = &buf[*len];
*len += octet_cnt;
}
if (stat == 0)
break;
}
return 0;
}
/*- End of function --------------------------------------------------------*/
static int encode_length(uint8_t *buf, int *len, int value)
{
int multiplier;
int multiplier;
if (value < 0x80)
{
/* 1 octet */
buf[(*len)++] = value;
return value;
}
if (value < 0x4000)
{
/* 2 octets */
/* Set the first bit of the first octet */
buf[(*len)++] = ((0x8000 | value) >> 8) & 0xFF;
buf[(*len)++] = value & 0xFF;
return value;
}
/* Fragmentation */
multiplier = (value < 0x10000) ? (value >> 14) : 4;
/* Set the first 2 bits of the octet */
buf[(*len)++] = 0xC0 | multiplier;
return multiplier << 14;
if (value < 0x80) {
/* 1 octet */
buf[(*len)++] = value;
return value;
}
if (value < 0x4000) {
/* 2 octets */
/* Set the first bit of the first octet */
buf[(*len)++] = ((0x8000 | value) >> 8) & 0xFF;
buf[(*len)++] = value & 0xFF;
return value;
}
/* Fragmentation */
multiplier = (value < 0x10000) ? (value >> 14) : 4;
/* Set the first 2 bits of the octet */
buf[(*len)++] = 0xC0 | multiplier;
return multiplier << 14;
}
/*- End of function --------------------------------------------------------*/
static int encode_open_type(uint8_t *buf, int *len, const uint8_t *data, int num_octets)
{
int enclen;
int octet_idx;
uint8_t zero_byte;
int enclen;
int octet_idx;
uint8_t zero_byte;
/* If open type is of zero length, add a single zero byte (10.1) */
if (num_octets == 0)
{
zero_byte = 0;
data = &zero_byte;
num_octets = 1;
}
/* Encode the open type */
for (octet_idx = 0; ; num_octets -= enclen, octet_idx += enclen)
{
if ((enclen = encode_length(buf, len, num_octets)) < 0)
return -1;
if (enclen > 0)
{
memcpy(&buf[*len], &data[octet_idx], enclen);
*len += enclen;
}
if (enclen >= num_octets)
break;
}
/* If open type is of zero length, add a single zero byte (10.1) */
if (num_octets == 0) {
zero_byte = 0;
data = &zero_byte;
num_octets = 1;
}
/* Encode the open type */
for (octet_idx = 0;; num_octets -= enclen, octet_idx += enclen) {
if ((enclen = encode_length(buf, len, num_octets)) < 0)
return -1;
if (enclen > 0) {
memcpy(&buf[*len], &data[octet_idx], enclen);
*len += enclen;
}
if (enclen >= num_octets)
break;
}
return 0;
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_rx_packet(udptl_state_t *s, const uint8_t buf[], int len)
{
int stat;
int stat2;
int i;
int j;
int k;
int l;
int m;
int x;
int limit;
int which;
int ptr;
int count;
int total_count;
int seq_no;
const uint8_t *msg;
const uint8_t *data;
int msg_len;
int repaired[16];
const uint8_t *bufs[16];
int lengths[16];
int span;
int entries;
int stat;
int stat2;
int i;
int j;
int k;
int l;
int m;
int x;
int limit;
int which;
int ptr;
int count;
int total_count;
int seq_no;
const uint8_t *msg;
const uint8_t *data;
int msg_len;
int repaired[16];
const uint8_t *bufs[16];
int lengths[16];
int span;
int entries;
ptr = 0;
/* Decode seq_number */
if (ptr + 2 > len)
return -1;
seq_no = (buf[0] << 8) | buf[1];
ptr += 2;
/* Break out the primary packet */
if ((stat = decode_open_type(buf, len, &ptr, &msg, &msg_len)) != 0)
return -1;
/* Decode error_recovery */
if (ptr + 1 > len)
return -1;
/* Our buffers cannot tolerate overlength packets */
if (msg_len > LOCAL_FAX_MAX_DATAGRAM)
return -1;
/* Update any missed slots in the buffer */
for (i = s->rx_seq_no; seq_no > i; i++)
{
x = i & UDPTL_BUF_MASK;
s->rx[x].buf_len = -1;
s->rx[x].fec_len[0] = 0;
s->rx[x].fec_span = 0;
s->rx[x].fec_entries = 0;
}
/* Save the new packet. Pure redundancy mode won't use this, but some systems will switch
into FEC mode after sending some redundant packets. */
x = seq_no & UDPTL_BUF_MASK;
memcpy(s->rx[x].buf, msg, msg_len);
s->rx[x].buf_len = msg_len;
s->rx[x].fec_len[0] = 0;
s->rx[x].fec_span = 0;
s->rx[x].fec_entries = 0;
if ((buf[ptr++] & 0x80) == 0)
{
/* Secondary packet mode for error recovery */
/* We might have the packet we want, but we need to check through
the redundant stuff, and verify the integrity of the UDPTL.
This greatly reduces our chances of accepting garbage. */
total_count = 0;
do
{
if ((stat2 = decode_length(buf, len, &ptr, &count)) < 0)
return -1;
for (i = 0; i < count; i++)
{
if ((stat = decode_open_type(buf, len, &ptr, &bufs[total_count + i], &lengths[total_count + i])) != 0)
return -1;
}
total_count += count;
}
while (stat2 > 0);
/* We should now be exactly at the end of the packet. If not, this is a fault. */
if (ptr != len)
return -1;
if (seq_no > s->rx_seq_no)
{
/* We received a later packet than we expected, so we need to check if we can fill in the gap from the
secondary packets. */
/* Step through in reverse order, so we go oldest to newest */
for (i = total_count; i > 0; i--)
{
if (seq_no - i >= s->rx_seq_no)
{
/* This one wasn't seen before */
/* Decode the secondary packet */
ptr = 0;
/* Decode seq_number */
if (ptr + 2 > len)
return -1;
seq_no = (buf[0] << 8) | buf[1];
ptr += 2;
/* Break out the primary packet */
if ((stat = decode_open_type(buf, len, &ptr, &msg, &msg_len)) != 0)
return -1;
/* Decode error_recovery */
if (ptr + 1 > len)
return -1;
/* Our buffers cannot tolerate overlength packets */
if (msg_len > LOCAL_FAX_MAX_DATAGRAM)
return -1;
/* Update any missed slots in the buffer */
for (i = s->rx_seq_no; seq_no > i; i++) {
x = i & UDPTL_BUF_MASK;
s->rx[x].buf_len = -1;
s->rx[x].fec_len[0] = 0;
s->rx[x].fec_span = 0;
s->rx[x].fec_entries = 0;
}
/* Save the new packet. Pure redundancy mode won't use this, but some systems will switch
into FEC mode after sending some redundant packets. */
x = seq_no & UDPTL_BUF_MASK;
memcpy(s->rx[x].buf, msg, msg_len);
s->rx[x].buf_len = msg_len;
s->rx[x].fec_len[0] = 0;
s->rx[x].fec_span = 0;
s->rx[x].fec_entries = 0;
if ((buf[ptr++] & 0x80) == 0) {
/* Secondary packet mode for error recovery */
/* We might have the packet we want, but we need to check through
the redundant stuff, and verify the integrity of the UDPTL.
This greatly reduces our chances of accepting garbage. */
total_count = 0;
do {
if ((stat2 = decode_length(buf, len, &ptr, &count)) < 0)
return -1;
for (i = 0; i < count; i++) {
if ((stat = decode_open_type(buf, len, &ptr, &bufs[total_count + i], &lengths[total_count + i])) != 0)
return -1;
}
total_count += count;
}
while (stat2 > 0);
/* We should now be exactly at the end of the packet. If not, this is a fault. */
if (ptr != len)
return -1;
if (seq_no > s->rx_seq_no) {
/* We received a later packet than we expected, so we need to check if we can fill in the gap from the
secondary packets. */
/* Step through in reverse order, so we go oldest to newest */
for (i = total_count; i > 0; i--) {
if (seq_no - i >= s->rx_seq_no) {
/* This one wasn't seen before */
/* Decode the secondary packet */
#if defined(UDPTL_DEBUG)
fprintf(stderr, "Secondary %d, len %d\n", seq_no - i, lengths[i - 1]);
fprintf(stderr, "Secondary %d, len %d\n", seq_no - i, lengths[i - 1]);
#endif
/* Save the new packet. Redundancy mode won't use this, but some systems will switch into
FEC mode after sending some redundant packets, and this may then be important. */
x = (seq_no - i) & UDPTL_BUF_MASK;
memcpy(s->rx[x].buf, bufs[i - 1], lengths[i - 1]);
s->rx[x].buf_len = lengths[i - 1];
s->rx[x].fec_len[0] = 0;
s->rx[x].fec_span = 0;
s->rx[x].fec_entries = 0;
if (s->rx_packet_handler(s->user_data, bufs[i - 1], lengths[i - 1], seq_no - i) < 0)
fprintf(stderr, "Bad IFP\n");
}
}
}
}
else
{
/* FEC mode for error recovery */
/* Save the new packet. Redundancy mode won't use this, but some systems will switch into
FEC mode after sending some redundant packets, and this may then be important. */
x = (seq_no - i) & UDPTL_BUF_MASK;
memcpy(s->rx[x].buf, bufs[i - 1], lengths[i - 1]);
s->rx[x].buf_len = lengths[i - 1];
s->rx[x].fec_len[0] = 0;
s->rx[x].fec_span = 0;
s->rx[x].fec_entries = 0;
if (s->rx_packet_handler(s->user_data, bufs[i - 1], lengths[i - 1], seq_no - i) < 0)
fprintf(stderr, "Bad IFP\n");
}
}
}
} else {
/* FEC mode for error recovery */
/* Decode the FEC packets */
/* The span is defined as an unconstrained integer, but will never be more
than a small value. */
if (ptr + 2 > len)
return -1;
if (buf[ptr++] != 1)
return -1;
span = buf[ptr++];
/* Decode the FEC packets */
/* The span is defined as an unconstrained integer, but will never be more
than a small value. */
if (ptr + 2 > len)
return -1;
if (buf[ptr++] != 1)
return -1;
span = buf[ptr++];
x = seq_no & UDPTL_BUF_MASK;
x = seq_no & UDPTL_BUF_MASK;
s->rx[x].fec_span = span;
s->rx[x].fec_span = span;
memset(repaired, 0, sizeof(repaired));
repaired[x] = TRUE;
memset(repaired, 0, sizeof(repaired));
repaired[x] = TRUE;
/* The number of entries is defined as a length, but will only ever be a small
value. Treat it as such. */
if (ptr + 1 > len)
return -1;
entries = buf[ptr++];
s->rx[x].fec_entries = entries;
/* The number of entries is defined as a length, but will only ever be a small
value. Treat it as such. */
if (ptr + 1 > len)
return -1;
entries = buf[ptr++];
s->rx[x].fec_entries = entries;
/* Decode the elements */
for (i = 0; i < entries; i++)
{
if ((stat = decode_open_type(buf, len, &ptr, &data, &s->rx[x].fec_len[i])) != 0)
return -1;
if (s->rx[x].fec_len[i] > LOCAL_FAX_MAX_DATAGRAM)
return -1;
/* Decode the elements */
for (i = 0; i < entries; i++) {
if ((stat = decode_open_type(buf, len, &ptr, &data, &s->rx[x].fec_len[i])) != 0)
return -1;
if (s->rx[x].fec_len[i] > LOCAL_FAX_MAX_DATAGRAM)
return -1;
/* Save the new FEC data */
memcpy(s->rx[x].fec[i], data, s->rx[x].fec_len[i]);
/* Save the new FEC data */
memcpy(s->rx[x].fec[i], data, s->rx[x].fec_len[i]);
#if 0
fprintf(stderr, "FEC: ");
for (j = 0; j < s->rx[x].fec_len[i]; j++)
fprintf(stderr, "%02X ", data[j]);
fprintf(stderr, "\n");
fprintf(stderr, "FEC: ");
for (j = 0; j < s->rx[x].fec_len[i]; j++)
fprintf(stderr, "%02X ", data[j]);
fprintf(stderr, "\n");
#endif
}
/* We should now be exactly at the end of the packet. If not, this is a fault. */
if (ptr != len)
return -1;
/* See if we can reconstruct anything which is missing */
/* TODO: this does not comprehensively hunt back and repair everything that is possible */
for (l = x; l != ((x - (16 - span*entries)) & UDPTL_BUF_MASK); l = (l - 1) & UDPTL_BUF_MASK)
{
if (s->rx[l].fec_len[0] <= 0)
continue;
for (m = 0; m < s->rx[l].fec_entries; m++)
{
limit = (l + m) & UDPTL_BUF_MASK;
for (which = -1, k = (limit - s->rx[l].fec_span*s->rx[l].fec_entries) & UDPTL_BUF_MASK; k != limit; k = (k + s->rx[l].fec_entries) & UDPTL_BUF_MASK)
{
if (s->rx[k].buf_len <= 0)
which = (which == -1) ? k : -2;
}
if (which >= 0)
{
/* Repairable */
for (j = 0; j < s->rx[l].fec_len[m]; j++)
{
s->rx[which].buf[j] = s->rx[l].fec[m][j];
for (k = (limit - s->rx[l].fec_span*s->rx[l].fec_entries) & UDPTL_BUF_MASK; k != limit; k = (k + s->rx[l].fec_entries) & UDPTL_BUF_MASK)
s->rx[which].buf[j] ^= (s->rx[k].buf_len > j) ? s->rx[k].buf[j] : 0;
}
s->rx[which].buf_len = s->rx[l].fec_len[m];
repaired[which] = TRUE;
}
}
}
/* Now play any new packets forwards in time */
for (l = (x + 1) & UDPTL_BUF_MASK, j = seq_no - UDPTL_BUF_MASK; l != x; l = (l + 1) & UDPTL_BUF_MASK, j++)
{
if (repaired[l])
{
}
/* We should now be exactly at the end of the packet. If not, this is a fault. */
if (ptr != len)
return -1;
/* See if we can reconstruct anything which is missing */
/* TODO: this does not comprehensively hunt back and repair everything that is possible */
for (l = x; l != ((x - (16 - span * entries)) & UDPTL_BUF_MASK); l = (l - 1) & UDPTL_BUF_MASK) {
if (s->rx[l].fec_len[0] <= 0)
continue;
for (m = 0; m < s->rx[l].fec_entries; m++) {
limit = (l + m) & UDPTL_BUF_MASK;
for (which = -1, k = (limit - s->rx[l].fec_span * s->rx[l].fec_entries) & UDPTL_BUF_MASK; k != limit;
k = (k + s->rx[l].fec_entries) & UDPTL_BUF_MASK) {
if (s->rx[k].buf_len <= 0)
which = (which == -1) ? k : -2;
}
if (which >= 0) {
/* Repairable */
for (j = 0; j < s->rx[l].fec_len[m]; j++) {
s->rx[which].buf[j] = s->rx[l].fec[m][j];
for (k = (limit - s->rx[l].fec_span * s->rx[l].fec_entries) & UDPTL_BUF_MASK; k != limit;
k = (k + s->rx[l].fec_entries) & UDPTL_BUF_MASK)
s->rx[which].buf[j] ^= (s->rx[k].buf_len > j) ? s->rx[k].buf[j] : 0;
}
s->rx[which].buf_len = s->rx[l].fec_len[m];
repaired[which] = TRUE;
}
}
}
/* Now play any new packets forwards in time */
for (l = (x + 1) & UDPTL_BUF_MASK, j = seq_no - UDPTL_BUF_MASK; l != x; l = (l + 1) & UDPTL_BUF_MASK, j++) {
if (repaired[l]) {
#if defined(UDPTL_DEBUG)
fprintf(stderr, "Fixed packet %d, len %d\n", j, l);
fprintf(stderr, "Fixed packet %d, len %d\n", j, l);
#endif
if (s->rx_packet_handler(s->user_data, s->rx[l].buf, s->rx[l].buf_len, j) < 0)
fprintf(stderr, "Bad IFP\n");
}
}
}
/* If packets are received out of sequence, we may have already processed this packet from the error
recovery information in a packet already received. */
if (seq_no >= s->rx_seq_no)
{
/* Decode the primary packet */
if (s->rx_packet_handler(s->user_data, s->rx[l].buf, s->rx[l].buf_len, j) < 0)
fprintf(stderr, "Bad IFP\n");
}
}
}
/* If packets are received out of sequence, we may have already processed this packet from the error
recovery information in a packet already received. */
if (seq_no >= s->rx_seq_no) {
/* Decode the primary packet */
#if defined(UDPTL_DEBUG)
fprintf(stderr, "Primary packet %d, len %d\n", seq_no, msg_len);
fprintf(stderr, "Primary packet %d, len %d\n", seq_no, msg_len);
#endif
if (s->rx_packet_handler(s->user_data, msg, msg_len, seq_no) < 0)
fprintf(stderr, "Bad IFP\n");
}
if (s->rx_packet_handler(s->user_data, msg, msg_len, seq_no) < 0)
fprintf(stderr, "Bad IFP\n");
}
s->rx_seq_no = (seq_no + 1) & 0xFFFF;
return 0;
s->rx_seq_no = (seq_no + 1) & 0xFFFF;
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_build_packet(udptl_state_t *s, uint8_t buf[], const uint8_t msg[], int msg_len)
{
uint8_t fec[LOCAL_FAX_MAX_DATAGRAM];
int i;
int j;
int seq;
int entry;
int entries;
int span;
int m;
int len;
int limit;
int high_tide;
uint8_t fec[LOCAL_FAX_MAX_DATAGRAM];
int i;
int j;
int seq;
int entry;
int entries;
int span;
int m;
int len;
int limit;
int high_tide;
/* UDPTL cannot cope with zero length messages, and our buffering for redundancy limits their
maximum length. */
if (msg_len < 1 || msg_len > LOCAL_FAX_MAX_DATAGRAM)
return -1;
seq = s->tx_seq_no & 0xFFFF;
/* UDPTL cannot cope with zero length messages, and our buffering for redundancy limits their
maximum length. */
if (msg_len < 1 || msg_len > LOCAL_FAX_MAX_DATAGRAM)
return -1;
seq = s->tx_seq_no & 0xFFFF;
/* Map the sequence number to an entry in the circular buffer */
entry = seq & UDPTL_BUF_MASK;
/* Map the sequence number to an entry in the circular buffer */
entry = seq & UDPTL_BUF_MASK;
/* We save the message in a circular buffer, for generating FEC or
redundancy sets later on. */
s->tx[entry].buf_len = msg_len;
memcpy(s->tx[entry].buf, msg, msg_len);
/* Build the UDPTL packet */
/* We save the message in a circular buffer, for generating FEC or
redundancy sets later on. */
s->tx[entry].buf_len = msg_len;
memcpy(s->tx[entry].buf, msg, msg_len);
len = 0;
/* Encode the sequence number */
buf[len++] = (seq >> 8) & 0xFF;
buf[len++] = seq & 0xFF;
/* Build the UDPTL packet */
/* Encode the primary packet */
if (encode_open_type(buf, &len, msg, msg_len) < 0)
return -1;
len = 0;
/* Encode the sequence number */
buf[len++] = (seq >> 8) & 0xFF;
buf[len++] = seq & 0xFF;
/* Encode the appropriate type of error recovery information */
switch (s->error_correction_scheme)
{
case UDPTL_ERROR_CORRECTION_NONE:
/* Encode the error recovery type */
buf[len++] = 0x00;
/* The number of entries will always be zero, so it is pointless allowing
for the fragmented case here. */
if (encode_length(buf, &len, 0) < 0)
return -1;
break;
case UDPTL_ERROR_CORRECTION_REDUNDANCY:
/* Encode the error recovery type */
buf[len++] = 0x00;
if (s->tx_seq_no > s->error_correction_entries)
entries = s->error_correction_entries;
else
entries = s->tx_seq_no;
/* The number of entries will always be small, so it is pointless allowing
for the fragmented case here. */
if (encode_length(buf, &len, entries) < 0)
return -1;
/* Encode the elements */
for (i = 0; i < entries; i++)
{
j = (entry - i - 1) & UDPTL_BUF_MASK;
if (encode_open_type(buf, &len, s->tx[j].buf, s->tx[j].buf_len) < 0)
return -1;
}
break;
case UDPTL_ERROR_CORRECTION_FEC:
span = s->error_correction_span;
entries = s->error_correction_entries;
if (seq < s->error_correction_span*s->error_correction_entries)
{
/* In the initial stages, wind up the FEC smoothly */
entries = seq/s->error_correction_span;
if (seq < s->error_correction_span)
span = 0;
}
/* Encode the error recovery type */
buf[len++] = 0x80;
/* Span is defined as an inconstrained integer, which it dumb. It will only
ever be a small value. Treat it as such. */
buf[len++] = 1;
buf[len++] = span;
/* The number of entries is defined as a length, but will only ever be a small
value. Treat it as such. */
buf[len++] = entries;
for (m = 0; m < entries; m++)
{
/* Make an XOR'ed entry the maximum length */
limit = (entry + m) & UDPTL_BUF_MASK;
high_tide = 0;
for (i = (limit - span*entries) & UDPTL_BUF_MASK; i != limit; i = (i + entries) & UDPTL_BUF_MASK)
{
if (high_tide < s->tx[i].buf_len)
{
for (j = 0; j < high_tide; j++)
fec[j] ^= s->tx[i].buf[j];
for ( ; j < s->tx[i].buf_len; j++)
fec[j] = s->tx[i].buf[j];
high_tide = s->tx[i].buf_len;
}
else
{
for (j = 0; j < s->tx[i].buf_len; j++)
fec[j] ^= s->tx[i].buf[j];
}
}
if (encode_open_type(buf, &len, fec, high_tide) < 0)
return -1;
}
break;
}
/* Encode the primary packet */
if (encode_open_type(buf, &len, msg, msg_len) < 0)
return -1;
if (s->verbose)
fprintf(stderr, "\n");
s->tx_seq_no++;
return len;
/* Encode the appropriate type of error recovery information */
switch (s->error_correction_scheme) {
case UDPTL_ERROR_CORRECTION_NONE:
/* Encode the error recovery type */
buf[len++] = 0x00;
/* The number of entries will always be zero, so it is pointless allowing
for the fragmented case here. */
if (encode_length(buf, &len, 0) < 0)
return -1;
break;
case UDPTL_ERROR_CORRECTION_REDUNDANCY:
/* Encode the error recovery type */
buf[len++] = 0x00;
if (s->tx_seq_no > s->error_correction_entries)
entries = s->error_correction_entries;
else
entries = s->tx_seq_no;
/* The number of entries will always be small, so it is pointless allowing
for the fragmented case here. */
if (encode_length(buf, &len, entries) < 0)
return -1;
/* Encode the elements */
for (i = 0; i < entries; i++) {
j = (entry - i - 1) & UDPTL_BUF_MASK;
if (encode_open_type(buf, &len, s->tx[j].buf, s->tx[j].buf_len) < 0)
return -1;
}
break;
case UDPTL_ERROR_CORRECTION_FEC:
span = s->error_correction_span;
entries = s->error_correction_entries;
if (seq < s->error_correction_span * s->error_correction_entries) {
/* In the initial stages, wind up the FEC smoothly */
entries = seq / s->error_correction_span;
if (seq < s->error_correction_span)
span = 0;
}
/* Encode the error recovery type */
buf[len++] = 0x80;
/* Span is defined as an inconstrained integer, which it dumb. It will only
ever be a small value. Treat it as such. */
buf[len++] = 1;
buf[len++] = span;
/* The number of entries is defined as a length, but will only ever be a small
value. Treat it as such. */
buf[len++] = entries;
for (m = 0; m < entries; m++) {
/* Make an XOR'ed entry the maximum length */
limit = (entry + m) & UDPTL_BUF_MASK;
high_tide = 0;
for (i = (limit - span * entries) & UDPTL_BUF_MASK; i != limit; i = (i + entries) & UDPTL_BUF_MASK) {
if (high_tide < s->tx[i].buf_len) {
for (j = 0; j < high_tide; j++)
fec[j] ^= s->tx[i].buf[j];
for (; j < s->tx[i].buf_len; j++)
fec[j] = s->tx[i].buf[j];
high_tide = s->tx[i].buf_len;
} else {
for (j = 0; j < s->tx[i].buf_len; j++)
fec[j] ^= s->tx[i].buf[j];
}
}
if (encode_open_type(buf, &len, fec, high_tide) < 0)
return -1;
}
break;
}
if (s->verbose)
fprintf(stderr, "\n");
s->tx_seq_no++;
return len;
}
/*- End of function --------------------------------------------------------*/
int udptl_set_error_correction(udptl_state_t *s,
int ec_scheme,
int span,
int entries)
int udptl_set_error_correction(udptl_state_t *s, int ec_scheme, int span, int entries)
{
switch (ec_scheme)
{
case UDPTL_ERROR_CORRECTION_FEC:
case UDPTL_ERROR_CORRECTION_REDUNDANCY:
case UDPTL_ERROR_CORRECTION_NONE:
s->error_correction_scheme = ec_scheme;
break;
case -1:
/* Just don't change the scheme */
break;
default:
return -1;
}
if (span >= 0)
s->error_correction_span = span;
if (entries >= 0)
s->error_correction_entries = entries;
return 0;
switch (ec_scheme) {
case UDPTL_ERROR_CORRECTION_FEC:
case UDPTL_ERROR_CORRECTION_REDUNDANCY:
case UDPTL_ERROR_CORRECTION_NONE:
s->error_correction_scheme = ec_scheme;
break;
case -1:
/* Just don't change the scheme */
break;
default:
return -1;
}
if (span >= 0)
s->error_correction_span = span;
if (entries >= 0)
s->error_correction_entries = entries;
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_get_error_correction(udptl_state_t *s,
int *ec_scheme,
int *span,
int *entries)
int udptl_get_error_correction(udptl_state_t *s, int *ec_scheme, int *span, int *entries)
{
if (ec_scheme)
*ec_scheme = s->error_correction_scheme;
if (span)
*span = s->error_correction_span;
if (entries)
*entries = s->error_correction_entries;
return 0;
if (ec_scheme)
*ec_scheme = s->error_correction_scheme;
if (span)
*span = s->error_correction_span;
if (entries)
*entries = s->error_correction_entries;
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_set_local_max_datagram(udptl_state_t *s, int max_datagram)
{
s->local_max_datagram_size = max_datagram;
return 0;
s->local_max_datagram_size = max_datagram;
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_get_local_max_datagram(udptl_state_t *s)
{
return s->local_max_datagram_size;
return s->local_max_datagram_size;
}
/*- End of function --------------------------------------------------------*/
int udptl_set_far_max_datagram(udptl_state_t *s, int max_datagram)
{
s->far_max_datagram_size = max_datagram;
return 0;
s->far_max_datagram_size = max_datagram;
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_get_far_max_datagram(udptl_state_t *s)
{
return s->far_max_datagram_size;
return s->far_max_datagram_size;
}
/*- End of function --------------------------------------------------------*/
udptl_state_t *udptl_init(udptl_state_t *s,
int ec_scheme,
int span,
int entries,
udptl_rx_packet_handler_t rx_packet_handler,
void *user_data)
udptl_state_t *udptl_init(udptl_state_t *s, int ec_scheme, int span, int entries, udptl_rx_packet_handler_t rx_packet_handler, void *user_data)
{
int i;
int i;
if (rx_packet_handler == NULL)
return NULL;
if (rx_packet_handler == NULL)
return NULL;
if (s == NULL)
{
if ((s = (udptl_state_t *) malloc(sizeof(*s))) == NULL)
return NULL;
}
memset(s, 0, sizeof(*s));
s->error_correction_scheme = ec_scheme;
s->error_correction_span = span;
s->error_correction_entries = entries;
s->far_max_datagram_size = LOCAL_FAX_MAX_DATAGRAM;
s->local_max_datagram_size = LOCAL_FAX_MAX_DATAGRAM;
if (s == NULL) {
if ((s = (udptl_state_t *) malloc(sizeof(*s))) == NULL)
return NULL;
}
memset(s, 0, sizeof(*s));
memset(&s->rx, 0, sizeof(s->rx));
memset(&s->tx, 0, sizeof(s->tx));
for (i = 0; i <= UDPTL_BUF_MASK; i++)
{
s->rx[i].buf_len = -1;
s->tx[i].buf_len = -1;
}
s->error_correction_scheme = ec_scheme;
s->error_correction_span = span;
s->error_correction_entries = entries;
s->rx_packet_handler = rx_packet_handler;
s->user_data = user_data;
s->far_max_datagram_size = LOCAL_FAX_MAX_DATAGRAM;
s->local_max_datagram_size = LOCAL_FAX_MAX_DATAGRAM;
return s;
memset(&s->rx, 0, sizeof(s->rx));
memset(&s->tx, 0, sizeof(s->tx));
for (i = 0; i <= UDPTL_BUF_MASK; i++) {
s->rx[i].buf_len = -1;
s->tx[i].buf_len = -1;
}
s->rx_packet_handler = rx_packet_handler;
s->user_data = user_data;
return s;
}
/*- End of function --------------------------------------------------------*/
int udptl_release(udptl_state_t *s)
{
return 0;
return 0;
}
/*- End of function --------------------------------------------------------*/
/*- End of file ------------------------------------------------------------*/

View File

@ -30,71 +30,66 @@
#define UDPTL_BUF_MASK 15
typedef int (udptl_rx_packet_handler_t)(void *user_data, const uint8_t msg[], int len, int seq_no);
typedef int (udptl_rx_packet_handler_t) (void *user_data, const uint8_t msg[], int len, int seq_no);
typedef struct
{
int buf_len;
uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
typedef struct {
int buf_len;
uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
} udptl_fec_tx_buffer_t;
typedef struct
{
int buf_len;
uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
int fec_len[LOCAL_FAX_MAX_FEC_PACKETS];
uint8_t fec[LOCAL_FAX_MAX_FEC_PACKETS][LOCAL_FAX_MAX_DATAGRAM];
int fec_span;
int fec_entries;
typedef struct {
int buf_len;
uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
int fec_len[LOCAL_FAX_MAX_FEC_PACKETS];
uint8_t fec[LOCAL_FAX_MAX_FEC_PACKETS][LOCAL_FAX_MAX_DATAGRAM];
int fec_span;
int fec_entries;
} udptl_fec_rx_buffer_t;
struct udptl_state_s
{
udptl_rx_packet_handler_t *rx_packet_handler;
void *user_data;
struct udptl_state_s {
udptl_rx_packet_handler_t *rx_packet_handler;
void *user_data;
/*! This option indicates the error correction scheme used in transmitted UDPTL
packets. */
int error_correction_scheme;
/*! This option indicates the error correction scheme used in transmitted UDPTL
packets. */
int error_correction_scheme;
/*! This option indicates the number of error correction entries transmitted in
UDPTL packets. */
int error_correction_entries;
/*! This option indicates the number of error correction entries transmitted in
UDPTL packets. */
int error_correction_entries;
/*! This option indicates the span of the error correction entries in transmitted
UDPTL packets (FEC only). */
int error_correction_span;
/*! This option indicates the span of the error correction entries in transmitted
UDPTL packets (FEC only). */
int error_correction_span;
/*! This option indicates the maximum size of a datagram that can be accepted by
the remote device. */
int far_max_datagram_size;
/*! This option indicates the maximum size of a datagram that can be accepted by
the remote device. */
int far_max_datagram_size;
/*! This option indicates the maximum size of a datagram that we are prepared to
accept. */
int local_max_datagram_size;
/*! This option indicates the maximum size of a datagram that we are prepared to
accept. */
int local_max_datagram_size;
int verbose;
int verbose;
int tx_seq_no;
int rx_seq_no;
int rx_expected_seq_no;
int tx_seq_no;
int rx_seq_no;
int rx_expected_seq_no;
udptl_fec_tx_buffer_t tx[UDPTL_BUF_MASK + 1];
udptl_fec_rx_buffer_t rx[UDPTL_BUF_MASK + 1];
udptl_fec_tx_buffer_t tx[UDPTL_BUF_MASK + 1];
udptl_fec_rx_buffer_t rx[UDPTL_BUF_MASK + 1];
};
enum
{
UDPTL_ERROR_CORRECTION_NONE,
UDPTL_ERROR_CORRECTION_FEC,
UDPTL_ERROR_CORRECTION_REDUNDANCY
enum {
UDPTL_ERROR_CORRECTION_NONE,
UDPTL_ERROR_CORRECTION_FEC,
UDPTL_ERROR_CORRECTION_REDUNDANCY
};
typedef struct udptl_state_s udptl_state_t;
#if defined(__cplusplus)
extern "C"
{
extern "C" {
#endif
/*! \brief Process an arriving UDPTL packet.
@ -102,7 +97,7 @@ extern "C"
\param buf The UDPTL packet buffer.
\param len The length of the packet.
\return 0 for OK. */
int udptl_rx_packet(udptl_state_t *s, const uint8_t buf[], int len);
int udptl_rx_packet(udptl_state_t *s, const uint8_t buf[], int len);
/*! \brief Construct a UDPTL packet, ready for transmission.
\param s The UDPTL context.
@ -110,7 +105,7 @@ int udptl_rx_packet(udptl_state_t *s, const uint8_t buf[], int len);
\param msg The primary packet.
\param len The length of the primary packet.
\return The length of the constructed UDPTL packet. */
int udptl_build_packet(udptl_state_t *s, uint8_t buf[], const uint8_t msg[], int msg_len);
int udptl_build_packet(udptl_state_t *s, uint8_t buf[], const uint8_t msg[], int msg_len);
/*! \brief Change the error correction settings of a UDPTL context.
\param s The UDPTL context.
@ -118,10 +113,7 @@ int udptl_build_packet(udptl_state_t *s, uint8_t buf[], const uint8_t msg[], int
\param span The packet span over which error correction should be applied.
\param entries The number of error correction entries to include in packets.
\return 0 for OK. */
int udptl_set_error_correction(udptl_state_t *s,
int ec_scheme,
int span,
int entries);
int udptl_set_error_correction(udptl_state_t *s, int ec_scheme, int span, int entries);
/*! \brief Check the error correction settings of a UDPTL context.
\param s The UDPTL context.
@ -129,18 +121,15 @@ int udptl_set_error_correction(udptl_state_t *s,
\param span The packet span over which error correction is being applied.
\param entries The number of error correction being included in packets.
\return 0 for OK. */
int udptl_get_error_correction(udptl_state_t *s,
int *ec_scheme,
int *span,
int *entries);
int udptl_get_error_correction(udptl_state_t *s, int *ec_scheme, int *span, int *entries);
int udptl_set_local_max_datagram(udptl_state_t *s, int max_datagram);
int udptl_set_local_max_datagram(udptl_state_t *s, int max_datagram);
int udptl_get_local_max_datagram(udptl_state_t *s);
int udptl_get_local_max_datagram(udptl_state_t *s);
int udptl_set_far_max_datagram(udptl_state_t *s, int max_datagram);
int udptl_set_far_max_datagram(udptl_state_t *s, int max_datagram);
int udptl_get_far_max_datagram(udptl_state_t *s);
int udptl_get_far_max_datagram(udptl_state_t *s);
/*! \brief Initialise a UDPTL context.
\param s The UDPTL context.
@ -150,21 +139,15 @@ int udptl_get_far_max_datagram(udptl_state_t *s);
\param rx_packet_handler The callback function, used to report arriving IFP packets.
\param user_data An opaque pointer supplied to rx_packet_handler.
\return A pointer to the UDPTL context, or NULL if there was a problem. */
udptl_state_t *udptl_init(udptl_state_t *s,
int ec_scheme,
int span,
int entries,
udptl_rx_packet_handler_t rx_packet_handler,
void *user_data);
udptl_state_t *udptl_init(udptl_state_t *s, int ec_scheme, int span, int entries, udptl_rx_packet_handler_t rx_packet_handler, void *user_data);
/*! \brief Release a UDPTL context.
\param s The UDPTL context.
\return 0 for OK. */
int udptl_release(udptl_state_t *s);
int udptl_release(udptl_state_t *s);
#if defined(__cplusplus)
}
#endif
#endif
/*- End of file ------------------------------------------------------------*/

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -87,10 +87,11 @@ static int next_id(valet_lot_t *lot, int min, int max, int in)
int i, r = 0, m;
char buf[128] = "";
if (!min) min = 1;
if (!min)
min = 1;
switch_mutex_lock(globals.mutex);
for(i = min ; (i < max || max == 0) ; i++) {
for (i = min; (i < max || max == 0); i++) {
switch_snprintf(buf, sizeof(buf), "%d", i);
m = !!switch_core_hash_find(lot->hash, buf);
@ -131,7 +132,7 @@ SWITCH_STANDARD_APP(valet_parking_function)
lot = valet_find_lot(lot_name);
switch_assert(lot);
if (!strcasecmp(ext, "auto")) {
if (!strcasecmp(ext, "auto")) {
const char *io = argv[2];
const char *min = argv[3];
const char *max = argv[4];
@ -165,7 +166,7 @@ SWITCH_STANDARD_APP(valet_parking_function)
switch_mutex_unlock(lot->mutex);
return;
}
switch_snprintf(dtmf_buf, sizeof(dtmf_buf), "%d", id);
ext = dtmf_buf;
} else if (!strcasecmp(ext, "ask")) {
@ -174,28 +175,28 @@ SWITCH_STANDARD_APP(valet_parking_function)
int max = 11;
int to = 10000;
int i;
tmp = argv[2] ? argv[2] : switch_channel_get_variable(channel, "valet_ext_min");
if (tmp) {
if ((i = atoi(tmp)) > 0) {
min = i;
}
}
tmp = argv[3] ? argv[3] : switch_channel_get_variable(channel, "valet_ext_max");
if (tmp) {
if ((i = atoi(tmp)) > 0) {
max = i;
}
}
tmp = argv[4] ? argv[4] : switch_channel_get_variable(channel, "valet_ext_to");
if (tmp) {
if ((i = atoi(tmp)) > 0) {
to = i;
}
}
tmp = argv[5] ? argv[5] : switch_channel_get_variable(channel, "valet_ext_prompt");
if (tmp) {
prompt = tmp;
@ -211,7 +212,7 @@ SWITCH_STANDARD_APP(valet_parking_function)
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
}
}
switch_mutex_lock(lot->mutex);
if ((uuid = switch_core_hash_find(lot->hash, ext))) {
switch_core_session_t *b_session;
@ -224,7 +225,7 @@ SWITCH_STANDARD_APP(valet_parking_function)
switch_channel_event_set_data(switch_core_session_get_channel(b_session), event);
switch_event_fire(&event);
switch_core_session_rwunlock(b_session);
switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), uuid);
switch_mutex_unlock(lot->mutex);
return;
@ -241,7 +242,7 @@ SWITCH_STANDARD_APP(valet_parking_function)
if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) {
switch_core_session_t *b_session;
if ((b_session = switch_core_session_locate(uuid))) {
switch_ivr_phrase_macro(session, "valet_announce_ext", tmp, NULL, NULL);
switch_ivr_session_transfer(b_session, dest, "inline", NULL);
@ -254,8 +255,8 @@ SWITCH_STANDARD_APP(valet_parking_function)
switch_ivr_phrase_macro(session, "valet_announce_ext", tmp, NULL, NULL);
}
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, VALET_EVENT) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Valet-Lot-Name", lot_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Valet-Extension", ext);
@ -263,14 +264,15 @@ SWITCH_STANDARD_APP(valet_parking_function)
switch_event_fire(&event);
}
if (!(tmp = switch_channel_get_variable(channel, "valet_hold_music"))) {
tmp = switch_channel_get_variable(channel, "hold_music");
}
if (tmp) music = tmp;
if (tmp)
music = tmp;
switch_core_hash_insert(lot->hash, ext, switch_core_session_get_uuid(session));
args.input_callback = valet_on_dtmf;
args.buf = dbuf;
args.buflen = sizeof(dbuf);
@ -293,7 +295,7 @@ SWITCH_STANDARD_API(valet_info_function)
{
switch_hash_index_t *hi;
const void *var;
void *val;
void *val;
char *name;
valet_lot_t *lot;
@ -310,9 +312,10 @@ SWITCH_STANDARD_API(valet_info_function)
switch_hash_this(hi, &var, NULL, &val);
name = (char *) var;
lot = (valet_lot_t *) val;
if (!zstr(cmd) && strcasecmp(cmd, name)) continue;
if (!zstr(cmd) && strcasecmp(cmd, name))
continue;
stream->write_function(stream, " <lot name=\"%s\">\n", name);
for (i_hi = switch_hash_first(NULL, lot->hash); i_hi; i_hi = switch_hash_next(i_hi)) {

View File

@ -128,50 +128,50 @@ SWITCH_STANDARD_APP(vmd_start_function);
/*! Type that holds state information about the beep. */
typedef enum vmd_state {
BEEP_DETECTED, BEEP_NOT_DETECTED
BEEP_DETECTED, BEEP_NOT_DETECTED
} vmd_state_t;
/*! Type that holds data for 5 points of discreet energy separation */
typedef struct vmd_point {
double freq;
double ampl;
double freq;
double ampl;
} vmd_point_t;
/*! Type that holds codec information. */
typedef struct vmd_codec_info {
/*! The sampling rate of the audio stream. */
int rate;
/*! The number of channels. */
int channels;
/*! The sampling rate of the audio stream. */
int rate;
/*! The number of channels. */
int channels;
} vmd_codec_info_t;
/*! Type that holds session information pertinent to the vmd module. */
typedef struct vmd_session_info {
/*! State of the session. */
vmd_state_t state;
/*! Snapshot of DESA samples. */
vmd_point_t points[POINTS];
/*! Internal FreeSWITCH session. */
switch_core_session_t *session;
/*! Codec information for the session. */
vmd_codec_info_t vmd_codec;
/*! Current position in the snapshot. */
unsigned int pos;
/*! Frequency aproximation of a detected beep. */
double beep_freq;
/*! A count of how long a distinct beep was detected
* by the discreet energy separation algorithm. */
switch_size_t timestamp;
/*! State of the session. */
vmd_state_t state;
/*! Snapshot of DESA samples. */
vmd_point_t points[POINTS];
/*! Internal FreeSWITCH session. */
switch_core_session_t *session;
/*! Codec information for the session. */
vmd_codec_info_t vmd_codec;
/*! Current position in the snapshot. */
unsigned int pos;
/*! Frequency aproximation of a detected beep. */
double beep_freq;
/*! A count of how long a distinct beep was detected
* by the discreet energy separation algorithm. */
switch_size_t timestamp;
/*! The MIN_TIME to use for this call */
int minTime;
} vmd_session_info_t;
static switch_bool_t process_data(vmd_session_info_t * vmd_info, switch_frame_t * frame);
static switch_bool_t vmd_callback(switch_media_bug_t * bug, void *user_data, switch_abc_type_t type);
static switch_bool_t process_data(vmd_session_info_t *vmd_info, switch_frame_t *frame);
static switch_bool_t vmd_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type);
static double freq_estimator(double *x);
static double ampl_estimator(double *x);
static void convert_pts(int16_t * i_pts, double *d_pts, int16_t max);
static void find_beep(vmd_session_info_t * vmd_info, switch_frame_t * frame);
static void convert_pts(int16_t *i_pts, double *d_pts, int16_t max);
static void find_beep(vmd_session_info_t *vmd_info, switch_frame_t *frame);
static double median(double *m, int n);
/*
@ -187,40 +187,40 @@ static double median(double *m, int n);
* @param type The switch callback type.
* @return The success or failure of the function.
*/
static switch_bool_t vmd_callback(switch_media_bug_t * bug, void *user_data, switch_abc_type_t type)
static switch_bool_t vmd_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
{
vmd_session_info_t *vmd_info;
switch_codec_t *read_codec;
switch_frame_t *frame;
vmd_session_info_t *vmd_info;
switch_codec_t *read_codec;
switch_frame_t *frame;
vmd_info = (vmd_session_info_t *) user_data;
if (vmd_info == NULL) {
return SWITCH_FALSE;
}
vmd_info = (vmd_session_info_t *) user_data;
if (vmd_info == NULL) {
return SWITCH_FALSE;
}
switch (type) {
switch (type) {
case SWITCH_ABC_TYPE_INIT:
read_codec = switch_core_session_get_read_codec(vmd_info->session);
vmd_info->vmd_codec.rate = read_codec->implementation->samples_per_second;
vmd_info->vmd_codec.channels = read_codec->implementation->number_of_channels;
break;
case SWITCH_ABC_TYPE_INIT:
read_codec = switch_core_session_get_read_codec(vmd_info->session);
vmd_info->vmd_codec.rate = read_codec->implementation->samples_per_second;
vmd_info->vmd_codec.channels = read_codec->implementation->number_of_channels;
break;
case SWITCH_ABC_TYPE_READ_PING:
case SWITCH_ABC_TYPE_CLOSE:
case SWITCH_ABC_TYPE_READ:
case SWITCH_ABC_TYPE_WRITE:
break;
case SWITCH_ABC_TYPE_READ_PING:
case SWITCH_ABC_TYPE_CLOSE:
case SWITCH_ABC_TYPE_READ:
case SWITCH_ABC_TYPE_WRITE:
break;
case SWITCH_ABC_TYPE_READ_REPLACE:
frame = switch_core_media_bug_get_read_replace_frame(bug);
return process_data(vmd_info, frame);
case SWITCH_ABC_TYPE_READ_REPLACE:
frame = switch_core_media_bug_get_read_replace_frame(bug);
return process_data(vmd_info, frame);
case SWITCH_ABC_TYPE_WRITE_REPLACE:
break;
}
case SWITCH_ABC_TYPE_WRITE_REPLACE:
break;
}
return SWITCH_TRUE;
return SWITCH_TRUE;
}
/*! \brief Process and convert data to be used by the find_beep() function
@ -230,23 +230,23 @@ static switch_bool_t vmd_callback(switch_media_bug_t * bug, void *user_data, swi
* @param frame The audio data.
* @return The success or failure of the function.
*/
static switch_bool_t process_data(vmd_session_info_t * vmd_info, switch_frame_t * frame)
static switch_bool_t process_data(vmd_session_info_t *vmd_info, switch_frame_t *frame)
{
uint32_t i;
unsigned int j;
double pts[P];
int16_t *data;
int16_t max;
switch_ssize_t len;
uint32_t i;
unsigned int j;
double pts[P];
int16_t *data;
int16_t max;
switch_ssize_t len;
len = frame->samples * sizeof(int16_t);
data = (int16_t *) frame->data;
len = frame->samples * sizeof(int16_t);
data = (int16_t *) frame->data;
for (max = (int16_t) abs(data[0]), i = 1; i < frame->samples; i++) {
if ((int16_t) abs(data[i]) > max) {
max = (int16_t) abs(data[i]);
}
}
for (max = (int16_t) abs(data[0]), i = 1; i < frame->samples; i++) {
if ((int16_t) abs(data[i]) > max) {
max = (int16_t) abs(data[i]);
}
}
/*
if (vmd_info->data_len != len){
@ -269,16 +269,16 @@ static switch_bool_t process_data(vmd_session_info_t * vmd_info, switch_frame_t
}
*/
for (i = 0, j = vmd_info->pos; i < frame->samples; j++, j %= POINTS, i += 5) {
/* convert_pts(vmd_info->data + i, pts); */
convert_pts(data + i, pts, max);
vmd_info->points[j].freq = TO_HZ(freq_estimator(pts));
vmd_info->points[j].ampl = ampl_estimator(pts);
vmd_info->pos = j % POINTS;
find_beep(vmd_info, frame);
}
for (i = 0, j = vmd_info->pos; i < frame->samples; j++, j %= POINTS, i += 5) {
/* convert_pts(vmd_info->data + i, pts); */
convert_pts(data + i, pts, max);
vmd_info->points[j].freq = TO_HZ(freq_estimator(pts));
vmd_info->points[j].ampl = ampl_estimator(pts);
vmd_info->pos = j % POINTS;
find_beep(vmd_info, frame);
}
return SWITCH_TRUE;
return SWITCH_TRUE;
}
/*! \brief Find voicemail beep in the audio stream
@ -288,98 +288,96 @@ static switch_bool_t process_data(vmd_session_info_t * vmd_info, switch_frame_t
* @param frame The audio data.
* @return The success or failure of the function.
*/
static void find_beep(vmd_session_info_t * vmd_info, switch_frame_t * frame)
static void find_beep(vmd_session_info_t *vmd_info, switch_frame_t *frame)
{
int i;
int c;
double m[POINTS];
double med;
unsigned int j = (vmd_info->pos + 1) % POINTS;
unsigned int k = j;
switch_event_t *event;
switch_status_t status;
switch_event_t *event_copy;
switch_channel_t *channel = switch_core_session_get_channel(vmd_info->session);
int i;
int c;
double m[POINTS];
double med;
unsigned int j = (vmd_info->pos + 1) % POINTS;
unsigned int k = j;
switch_event_t *event;
switch_status_t status;
switch_event_t *event_copy;
switch_channel_t *channel = switch_core_session_get_channel(vmd_info->session);
switch (vmd_info->state) {
case BEEP_DETECTED:
for (c = 0, i = 0; i < POINTS; j++, j %= POINTS, i++) {
vmd_info->timestamp++;
if (vmd_info->points[j].freq < TOLERANCE_T(vmd_info->beep_freq) &&
vmd_info->points[j].freq > TOLERANCE_B(vmd_info->beep_freq)) {
c++;
vmd_info->beep_freq = (vmd_info->beep_freq * 0.95) + (vmd_info->points[j].freq * 0.05);
}
}
switch (vmd_info->state) {
case BEEP_DETECTED:
for (c = 0, i = 0; i < POINTS; j++, j %= POINTS, i++) {
vmd_info->timestamp++;
if (vmd_info->points[j].freq < TOLERANCE_T(vmd_info->beep_freq) && vmd_info->points[j].freq > TOLERANCE_B(vmd_info->beep_freq)) {
c++;
vmd_info->beep_freq = (vmd_info->beep_freq * 0.95) + (vmd_info->points[j].freq * 0.05);
}
}
if (c < (POINTS - MAX_CHIRP)) {
vmd_info->state = BEEP_NOT_DETECTED;
if (vmd_info->timestamp < (switch_size_t)vmd_info->minTime) {
break;
}
if (c < (POINTS - MAX_CHIRP)) {
vmd_info->state = BEEP_NOT_DETECTED;
if (vmd_info->timestamp < (switch_size_t) vmd_info->minTime) {
break;
}
status = switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, VMD_EVENT_BEEP);
if (status != SWITCH_STATUS_SUCCESS) {
return;
}
status = switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, VMD_EVENT_BEEP);
if (status != SWITCH_STATUS_SUCCESS) {
return;
}
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Beep-Status", "stop");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Beep-Time", "%d", (int) vmd_info->timestamp / POINTS);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(vmd_info->session));
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Frequency", "%6.4lf", vmd_info->beep_freq);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "vmd");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Beep-Status", "stop");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Beep-Time", "%d", (int) vmd_info->timestamp / POINTS);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(vmd_info->session));
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Frequency", "%6.4lf", vmd_info->beep_freq);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "vmd");
if ((switch_event_dup(&event_copy, event)) != SWITCH_STATUS_SUCCESS) {
return;
}
if ((switch_event_dup(&event_copy, event)) != SWITCH_STATUS_SUCCESS) {
return;
}
switch_core_session_queue_event(vmd_info->session, &event);
switch_event_fire(&event_copy);
switch_core_session_queue_event(vmd_info->session, &event);
switch_event_fire(&event_copy);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(vmd_info->session), SWITCH_LOG_INFO, "<<< VMD - Beep Detected >>>\n");
switch_channel_set_variable(channel, "vmd_detect", "TRUE");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(vmd_info->session), SWITCH_LOG_INFO, "<<< VMD - Beep Detected >>>\n");
switch_channel_set_variable(channel, "vmd_detect", "TRUE");
vmd_info->timestamp = 0;
}
vmd_info->timestamp = 0;
}
break;
break;
case BEEP_NOT_DETECTED:
case BEEP_NOT_DETECTED:
for (i = 0; i < POINTS; k++, k %= POINTS, i++) {
m[i] = vmd_info->points[k].freq;
if (ISNAN(m[i])) {
m[i] = 0.0;
}
}
for (i = 0; i < POINTS; k++, k %= POINTS, i++) {
m[i] = vmd_info->points[k].freq;
if (ISNAN(m[i])) {
m[i] = 0.0;
}
}
med = median(m, POINTS);
if (ISNAN(med)) {
for (i = 0; i < POINTS; i++) {
if (!ISNAN(m[i])) {
med = m[i];
break;
}
}
}
med = median(m, POINTS);
if (ISNAN(med)) {
for (i = 0; i < POINTS; i++) {
if (!ISNAN(m[i])) {
med = m[i];
break;
}
}
}
for (c = 0, i = 0; i < POINTS; j++, j %= POINTS, i++) {
if (vmd_info->points[j].freq < TOLERANCE_T(med) && vmd_info->points[j].freq > TOLERANCE_B(med)) {
if (vmd_info->points[j].ampl > MIN_AMPL &&
vmd_info->points[j].freq > MIN_FREQ && vmd_info->points[j].freq < MAX_FREQ) {
c++;
}
}
}
for (c = 0, i = 0; i < POINTS; j++, j %= POINTS, i++) {
if (vmd_info->points[j].freq < TOLERANCE_T(med) && vmd_info->points[j].freq > TOLERANCE_B(med)) {
if (vmd_info->points[j].ampl > MIN_AMPL && vmd_info->points[j].freq > MIN_FREQ && vmd_info->points[j].freq < MAX_FREQ) {
c++;
}
}
}
if (c >= VALID) {
vmd_info->state = BEEP_DETECTED;
vmd_info->beep_freq = med;
vmd_info->timestamp = 0;
}
if (c >= VALID) {
vmd_info->state = BEEP_DETECTED;
vmd_info->beep_freq = med;
vmd_info->timestamp = 0;
}
break;
}
break;
}
}
/*! \brief Find the median of an array of doubles
@ -390,65 +388,65 @@ static void find_beep(vmd_session_info_t * vmd_info, switch_frame_t * frame)
*/
static double median(double *m, int n)
{
int i;
int less;
int greater;
int equal;
double min;
double max;
double guess;
double maxltguess;
double mingtguess;
int i;
int less;
int greater;
int equal;
double min;
double max;
double guess;
double maxltguess;
double mingtguess;
min = max = m[0];
min = max = m[0];
for (i = 1; i < n; i++) {
if (m[i] < min)
min = m[i];
if (m[i] > max)
max = m[i];
}
for (i = 1; i < n; i++) {
if (m[i] < min)
min = m[i];
if (m[i] > max)
max = m[i];
}
for (;;) {
guess = (min + max) / 2;
less = 0;
greater = 0;
equal = 0;
maxltguess = min;
mingtguess = max;
for (;;) {
guess = (min + max) / 2;
less = 0;
greater = 0;
equal = 0;
maxltguess = min;
mingtguess = max;
for (i = 0; i < n; i++) {
if (m[i] < guess) {
less++;
if (m[i] > maxltguess) {
maxltguess = m[i];
}
} else if (m[i] > guess) {
greater++;
if (m[i] < mingtguess) {
mingtguess = m[i];
}
} else {
equal++;
}
}
for (i = 0; i < n; i++) {
if (m[i] < guess) {
less++;
if (m[i] > maxltguess) {
maxltguess = m[i];
}
} else if (m[i] > guess) {
greater++;
if (m[i] < mingtguess) {
mingtguess = m[i];
}
} else {
equal++;
}
}
if (less <= (n + 1) / 2 && greater <= (n + 1) / 2) {
break;
} else if (less > greater) {
max = maxltguess;
} else {
min = mingtguess;
}
}
if (less <= (n + 1) / 2 && greater <= (n + 1) / 2) {
break;
} else if (less > greater) {
max = maxltguess;
} else {
min = mingtguess;
}
}
if (less >= (n + 1) / 2) {
return maxltguess;
} else if (less + equal >= (n + 1) / 2) {
return guess;
}
if (less >= (n + 1) / 2) {
return maxltguess;
} else if (less + equal >= (n + 1) / 2) {
return guess;
}
return mingtguess;
return mingtguess;
}
/*! \brief Convert many points for Signed L16 to relative floating point
@ -459,13 +457,13 @@ static double median(double *m, int n)
* @param max The maximum value in the entire audio frame.
* @return Nothing.
*/
static void convert_pts(int16_t * i_pts, double *d_pts, int16_t max)
static void convert_pts(int16_t *i_pts, double *d_pts, int16_t max)
{
int i;
for (i = 0; i < P; i++) {
/*! Signed L16 to relative floating point conversion */
d_pts[i] = ((((double) (i_pts[i]) + (double) max) / (double) (2 * max)) - 0.5) * 2.0;
}
int i;
for (i = 0; i < P; i++) {
/*! Signed L16 to relative floating point conversion */
d_pts[i] = ((((double) (i_pts[i]) + (double) max) / (double) (2 * max)) - 0.5) * 2.0;
}
}
/*! \brief Amplitude estimator for DESA-2
@ -478,12 +476,12 @@ static void convert_pts(int16_t * i_pts, double *d_pts, int16_t max)
*/
double ampl_estimator(double *x)
{
double freq_sq;
double freq_sq;
freq_sq = freq_estimator(x);
freq_sq *= freq_sq;
freq_sq = freq_estimator(x);
freq_sq *= freq_sq;
return sqrt(PSI(x) / sin(freq_sq));
return sqrt(PSI(x) / sin(freq_sq));
}
/*! \brief The DESA-2 algorithm
@ -500,12 +498,12 @@ double ampl_estimator(double *x)
*/
double freq_estimator(double *x)
{
return 0.5 * acos((((x[2] * x[2]) - (x[0] * x[4]))
- ((x[1] * x[1]) - (x[0] * x[2]))
- ((x[3] * x[3]) - (x[2] * x[4])))
/ (2.0 * ((x[2] * x[2]) - (x[1] * x[3])))
return 0.5 * acos((((x[2] * x[2]) - (x[0] * x[4]))
- ((x[1] * x[1]) - (x[0] * x[2]))
- ((x[3] * x[3]) - (x[2] * x[4])))
/ (2.0 * ((x[2] * x[2]) - (x[1] * x[3])))
);
);
}
/*! \brief FreeSWITCH module loading function
@ -515,19 +513,19 @@ double freq_estimator(double *x)
*/
SWITCH_MODULE_LOAD_FUNCTION(mod_vmd_load)
{
switch_application_interface_t *app_interface;
switch_api_interface_t *api_interface;
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
switch_application_interface_t *app_interface;
switch_api_interface_t *api_interface;
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Voicemail detection enabled\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Voicemail detection enabled\n");
SWITCH_ADD_APP(app_interface, "vmd", "Detect beeps", "Detect voicemail beeps", vmd_start_function, "[start] [stop]", SAF_NONE);
SWITCH_ADD_APP(app_interface, "vmd", "Detect beeps", "Detect voicemail beeps", vmd_start_function, "[start] [stop]", SAF_NONE);
SWITCH_ADD_API(api_interface, "vmd", "Detected voicemail beeps", vmd_api_main, VMD_SYNTAX);
SWITCH_ADD_API(api_interface, "vmd", "Detected voicemail beeps", vmd_api_main, VMD_SYNTAX);
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}
/*! \brief FreeSWITCH application handler function.
@ -538,59 +536,59 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_vmd_load)
*/
SWITCH_STANDARD_APP(vmd_start_function)
{
switch_media_bug_t *bug;
switch_status_t status;
switch_channel_t *channel;
vmd_session_info_t *vmd_info;
int i;
switch_media_bug_t *bug;
switch_status_t status;
switch_channel_t *channel;
vmd_session_info_t *vmd_info;
int i;
const char *minTimeString;
int mintime = 0;
if (session == NULL)
return;
if (session == NULL)
return;
channel = switch_core_session_get_channel(session);
channel = switch_core_session_get_channel(session);
/* Is this channel already set? */
bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_vmd_");
/* If yes */
if (bug != NULL) {
/* If we have a stop remove audio bug */
if (strcasecmp(data, "stop") == 0) {
switch_channel_set_private(channel, "_vmd_", NULL);
switch_core_media_bug_remove(session, &bug);
return;
}
/* Is this channel already set? */
bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_vmd_");
/* If yes */
if (bug != NULL) {
/* If we have a stop remove audio bug */
if (strcasecmp(data, "stop") == 0) {
switch_channel_set_private(channel, "_vmd_", NULL);
switch_core_media_bug_remove(session, &bug);
return;
}
/* We have already started */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n");
/* We have already started */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n");
return;
}
return;
}
vmd_info = (vmd_session_info_t *) switch_core_session_alloc(session, sizeof(vmd_session_info_t)
);
vmd_info = (vmd_session_info_t *) switch_core_session_alloc(session, sizeof(vmd_session_info_t)
);
vmd_info->state = BEEP_NOT_DETECTED;
vmd_info->session = session;
vmd_info->pos = 0;
/*
vmd_info->data = NULL;
vmd_info->data_len = 0;
*/
for (i = 0; i < POINTS; i++) {
vmd_info->points[i].freq = 0.0;
vmd_info->points[i].ampl = 0.0;
}
vmd_info->state = BEEP_NOT_DETECTED;
vmd_info->session = session;
vmd_info->pos = 0;
/*
vmd_info->data = NULL;
vmd_info->data_len = 0;
*/
for (i = 0; i < POINTS; i++) {
vmd_info->points[i].freq = 0.0;
vmd_info->points[i].ampl = 0.0;
}
status = switch_core_media_bug_add(session, vmd_callback, vmd_info, 0, SMBF_READ_REPLACE, &bug);
status = switch_core_media_bug_add(session, vmd_callback, vmd_info, 0, SMBF_READ_REPLACE, &bug);
if (status != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failure hooking to stream\n");
return;
}
if (status != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failure hooking to stream\n");
return;
}
switch_channel_set_private(channel, "_vmd_", bug);
switch_channel_set_private(channel, "_vmd_", bug);
if ((minTimeString = switch_channel_get_variable(channel, "vmd_min_time")) && (mintime = atoi(minTimeString))) {
vmd_info->minTime = mintime;
@ -598,7 +596,7 @@ SWITCH_STANDARD_APP(vmd_start_function)
vmd_info->minTime = MIN_TIME;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "MIN_TIME for call: %d\n",vmd_info->minTime);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "MIN_TIME for call: %d\n", vmd_info->minTime);
}
/*! \brief Called when the module shuts down
@ -608,9 +606,9 @@ SWITCH_STANDARD_APP(vmd_start_function)
*/
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_vmd_shutdown)
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Voicemail detection disabled\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Voicemail detection disabled\n");
return SWITCH_STATUS_SUCCESS;
return SWITCH_STATUS_SUCCESS;
}
/*! \brief FreeSWITCH API handler function.
@ -622,121 +620,121 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_vmd_shutdown)
*/
SWITCH_STANDARD_API(vmd_api_main)
{
switch_core_session_t *vmd_session = NULL;
switch_media_bug_t *bug;
vmd_session_info_t *vmd_info;
switch_channel_t *channel;
switch_status_t status;
int argc;
char *argv[VMD_PARAMS];
char *ccmd = NULL;
char *uuid;
char *command;
int i;
switch_core_session_t *vmd_session = NULL;
switch_media_bug_t *bug;
vmd_session_info_t *vmd_info;
switch_channel_t *channel;
switch_status_t status;
int argc;
char *argv[VMD_PARAMS];
char *ccmd = NULL;
char *uuid;
char *command;
int i;
/* No command? Display usage */
if (zstr(cmd)) {
stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);
return SWITCH_STATUS_SUCCESS;
}
/* No command? Display usage */
if (zstr(cmd)) {
stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);
return SWITCH_STATUS_SUCCESS;
}
/* Duplicated contents of original string */
ccmd = strdup(cmd);
/* Separate the arguments */
argc = switch_separate_string(ccmd, ' ', argv, VMD_PARAMS);
/* Duplicated contents of original string */
ccmd = strdup(cmd);
/* Separate the arguments */
argc = switch_separate_string(ccmd, ' ', argv, VMD_PARAMS);
/* If we don't have the expected number of parameters
* display usage */
if (argc != VMD_PARAMS) {
stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);
/* If we don't have the expected number of parameters
* display usage */
if (argc != VMD_PARAMS) {
stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);
goto end;
}
}
uuid = argv[0];
command = argv[1];
uuid = argv[0];
command = argv[1];
/* using uuid locate a reference to the FreeSWITCH session */
vmd_session = switch_core_session_locate(uuid);
/* using uuid locate a reference to the FreeSWITCH session */
vmd_session = switch_core_session_locate(uuid);
/* If the session was not found exit */
if (vmd_session == NULL) {
stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);
/* If the session was not found exit */
if (vmd_session == NULL) {
stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);
goto end;
}
}
/* Get current channel of the session to tag the session
* This indicates that our module is present */
channel = switch_core_session_get_channel(vmd_session);
/* Get current channel of the session to tag the session
* This indicates that our module is present */
channel = switch_core_session_get_channel(vmd_session);
/* Is this channel already set? */
bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_vmd_");
/* If yes */
if (bug != NULL) {
/* If we have a stop remove audio bug */
if (strcasecmp(command, "stop") == 0) {
switch_channel_set_private(channel, "_vmd_", NULL);
switch_core_media_bug_remove(vmd_session, &bug);
switch_safe_free(ccmd);
stream->write_function(stream, "+OK\n");
/* Is this channel already set? */
bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_vmd_");
/* If yes */
if (bug != NULL) {
/* If we have a stop remove audio bug */
if (strcasecmp(command, "stop") == 0) {
switch_channel_set_private(channel, "_vmd_", NULL);
switch_core_media_bug_remove(vmd_session, &bug);
switch_safe_free(ccmd);
stream->write_function(stream, "+OK\n");
goto end;
}
}
/* We have already started */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n");
/* We have already started */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n");
goto end;
}
}
/* If we don't see the expected start exit */
if (strcasecmp(command, "start") != 0) {
stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);
/* If we don't see the expected start exit */
if (strcasecmp(command, "start") != 0) {
stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);
goto end;
}
}
/* Allocate memory attached to this FreeSWITCH session for
* use in the callback routine and to store state information */
vmd_info = (vmd_session_info_t *) switch_core_session_alloc(vmd_session, sizeof(vmd_session_info_t)
);
/* Allocate memory attached to this FreeSWITCH session for
* use in the callback routine and to store state information */
vmd_info = (vmd_session_info_t *) switch_core_session_alloc(vmd_session, sizeof(vmd_session_info_t)
);
/* Set initial values and states */
vmd_info->state = BEEP_NOT_DETECTED;
vmd_info->session = vmd_session;
vmd_info->pos = 0;
/* Set initial values and states */
vmd_info->state = BEEP_NOT_DETECTED;
vmd_info->session = vmd_session;
vmd_info->pos = 0;
/*
vmd_info->data = NULL;
vmd_info->data_len = 0;
*/
for (i = 0; i < POINTS; i++) {
vmd_info->points[i].freq = 0.0;
vmd_info->points[i].ampl = 0.0;
}
for (i = 0; i < POINTS; i++) {
vmd_info->points[i].freq = 0.0;
vmd_info->points[i].ampl = 0.0;
}
/* Add a media bug that allows me to intercept the
* reading leg of the audio stream */
status = switch_core_media_bug_add(vmd_session, vmd_callback, vmd_info, 0, SMBF_READ_REPLACE, &bug);
/* Add a media bug that allows me to intercept the
* reading leg of the audio stream */
status = switch_core_media_bug_add(vmd_session, vmd_callback, vmd_info, 0, SMBF_READ_REPLACE, &bug);
/* If adding a media bug fails exit */
if (status != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failure hooking to stream\n");
goto end;
}
/* If adding a media bug fails exit */
if (status != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failure hooking to stream\n");
goto end;
}
/* Set the vmd tag to detect an existing vmd media bug */
switch_channel_set_private(channel, "_vmd_", bug);
/* Set the vmd tag to detect an existing vmd media bug */
switch_channel_set_private(channel, "_vmd_", bug);
/* Everything went according to plan! Notify the user */
stream->write_function(stream, "+OK\n");
/* Everything went according to plan! Notify the user */
stream->write_function(stream, "+OK\n");
end:
end:
if (vmd_session) {
switch_core_session_rwunlock(vmd_session);
}
switch_safe_free(ccmd);
switch_safe_free(ccmd);
return SWITCH_STATUS_SUCCESS;
return SWITCH_STATUS_SUCCESS;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -71,7 +71,7 @@ static switch_status_t flite_speech_open(switch_speech_handle_t *sh, const char
flite_t *flite = switch_core_alloc(sh->memory_pool, sizeof(*flite));
sh->native_rate = 16000;
if (!strcasecmp(voice_name, "awb")) {
flite->v = globals.awb;
} else if (!strcasecmp(voice_name, "kal")) {
@ -108,9 +108,9 @@ static switch_status_t flite_speech_close(switch_speech_handle_t *sh, switch_spe
static switch_status_t flite_speech_feed_tts(switch_speech_handle_t *sh, char *text, switch_speech_flag_t *flags)
{
flite_t *flite = (flite_t *) sh->private_info;
flite->w = flite_text_to_wave(text, flite->v);
return SWITCH_STATUS_SUCCESS;
}
@ -128,10 +128,10 @@ static switch_status_t flite_speech_read_tts(switch_speech_handle_t *sh, void *d
{
size_t bytes_read;
flite_t *flite = (flite_t *) sh->private_info;
if (!flite->audio_buffer) {
int32_t len;
if (flite->w) {
len = flite->w->num_samples * 2;
} else {
@ -146,28 +146,28 @@ static switch_status_t flite_speech_read_tts(switch_speech_handle_t *sh, void *d
switch_buffer_write(flite->audio_buffer, flite->w->samples, flite->w->num_samples * 2);
free_wave(flite->w);
}
if ((bytes_read = switch_buffer_read(flite->audio_buffer, data, *datalen))) {
*datalen = bytes_read;
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_FALSE;
}
static void flite_text_param_tts(switch_speech_handle_t *sh, char *param, const char *val)
{
}
static void flite_numeric_param_tts(switch_speech_handle_t *sh, char *param, int val)
{
}
static void flite_float_param_tts(switch_speech_handle_t *sh, char *param, double val)
{
}
SWITCH_MODULE_LOAD_FUNCTION(mod_flite_load)
@ -179,7 +179,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_flite_load)
globals.kal = register_cmu_us_kal();
globals.rms = register_cmu_us_rms();
globals.slt = register_cmu_us_slt();
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
speech_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_SPEECH_INTERFACE);

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -87,23 +87,23 @@ static switch_status_t pocketsphinx_asr_open(switch_asr_handle_t *ah, const char
if (!(ps = (pocketsphinx_t *) switch_core_alloc(ah->memory_pool, sizeof(*ps)))) {
return SWITCH_STATUS_MEMERR;
}
switch_mutex_init(&ps->flag_mutex, SWITCH_MUTEX_NESTED, ah->memory_pool);
ah->private_info = ps;
if (rate == 8000) {
if (rate == 8000) {
ah->rate = 8000;
} else if (rate == 16000) {
ah->rate = 16000;
} else {
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid rate %d. Only 8000 and 16000 are supported.\n", rate);
}
codec = "L16";
ah->codec = switch_core_strdup(ah->memory_pool, codec);
ah->codec = switch_core_strdup(ah->memory_pool, codec);
ps->thresh = globals.thresh;
ps->silence_hits = globals.silence_hits;
ps->listen_hits = globals.listen_hits;
@ -139,34 +139,28 @@ static switch_status_t pocketsphinx_asr_load_grammar(switch_asr_handle_t *ah, co
dic = switch_mprintf("%s%s%s", SWITCH_GLOBAL_dirs.grammar_dir, SWITCH_PATH_SEPARATOR, globals.dictionary);
if (switch_file_exists(dic, ah->memory_pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open dictionary %s.\n", dic);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open dictionary %s.\n", dic);
goto end;
}
if (switch_file_exists(model, ah->memory_pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't open speech model %s.\n", model);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't open speech model %s.\n", model);
goto end;
}
if (switch_file_exists(jsgf, ah->memory_pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't open grammar file %s.\n", jsgf);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't open grammar file %s.\n", jsgf);
goto end;
}
rate = switch_mprintf("%d", ah->rate);
rate = switch_mprintf("%d", ah->rate);
switch_assert(jsgf && dic && model);
ps->config = cmd_ln_init(ps->config, ps_args(), FALSE,
"-samprate", rate,
"-hmm", model,
"-jsgf", jsgf,
"-lw", globals.language_weight,
"-dict", dic,
"-frate", "50",
"-silprob", "0.005",
NULL);
"-hmm", model, "-jsgf", jsgf, "-lw", globals.language_weight, "-dict", dic, "-frate", "50", "-silprob", "0.005", NULL);
if (ps->config == NULL) {
status = SWITCH_STATUS_GENERR;
goto end;
@ -185,19 +179,19 @@ static switch_status_t pocketsphinx_asr_load_grammar(switch_asr_handle_t *ah, co
switch_mutex_unlock(ps->flag_mutex);
ps_start_utt(ps->ps, NULL);
switch_set_flag(ps, PSFLAG_READY);
switch_set_flag(ps, PSFLAG_READY);
switch_safe_free(ps->grammar);
ps->grammar = strdup(grammar);
status = SWITCH_STATUS_SUCCESS;
end:
end:
switch_safe_free(rate);
switch_safe_free(jsgf);
switch_safe_free(dic);
switch_safe_free(model);
return status;
}
@ -224,7 +218,7 @@ static switch_status_t pocketsphinx_asr_close(switch_asr_handle_t *ah, switch_as
switch_mutex_unlock(ps->flag_mutex);
switch_clear_flag(ps, PSFLAG_HAS_TEXT);
switch_clear_flag(ps, PSFLAG_READY);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Port Closed.\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Port Closed.\n");
switch_set_flag(ah, SWITCH_ASR_FLAG_CLOSED);
return SWITCH_STATUS_SUCCESS;
}
@ -233,7 +227,7 @@ static switch_bool_t stop_detect(pocketsphinx_t *ps, int16_t *data, unsigned int
{
uint32_t score, count = 0, j = 0;
double energy = 0;
if (ps->countdown) {
if (!--ps->countdown) {
ps->silence_hits = ps->org_silence_hits;
@ -242,12 +236,12 @@ static switch_bool_t stop_detect(pocketsphinx_t *ps, int16_t *data, unsigned int
}
return SWITCH_FALSE;
}
for (count = 0; count < samples; count++) {
energy += abs(data[j]);
}
score = (uint32_t) (energy / samples);
if (score >= ps->thresh) {
@ -274,20 +268,21 @@ static switch_status_t pocketsphinx_asr_feed(switch_asr_handle_t *ah, void *data
pocketsphinx_t *ps = (pocketsphinx_t *) ah->private_info;
int rv = 0;
if (switch_test_flag(ah, SWITCH_ASR_FLAG_CLOSED)) return SWITCH_STATUS_BREAK;
if (switch_test_flag(ah, SWITCH_ASR_FLAG_CLOSED))
return SWITCH_STATUS_BREAK;
if (!switch_test_flag(ps, PSFLAG_HAS_TEXT) && switch_test_flag(ps, PSFLAG_READY)) {
if (stop_detect(ps, (int16_t *)data, len / 2)) {
if (stop_detect(ps, (int16_t *) data, len / 2)) {
char const *hyp;
switch_mutex_lock(ps->flag_mutex);
switch_mutex_lock(ps->flag_mutex);
if ((hyp = ps_get_hyp(ps->ps, &ps->score, &ps->uttid))) {
if (!zstr(hyp)) {
ps_end_utt(ps->ps);
switch_clear_flag(ps, PSFLAG_READY);
if ((hyp = ps_get_hyp(ps->ps, &ps->score, &ps->uttid))) {
if (zstr(hyp)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Lost the text, never mind....\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Lost the text, never mind....\n");
ps_start_utt(ps->ps, NULL);
switch_set_flag(ps, PSFLAG_READY);
} else {
@ -303,7 +298,7 @@ static switch_status_t pocketsphinx_asr_feed(switch_asr_handle_t *ah, void *data
/* only feed ps_process_raw when we are listening */
if (ps->listening) {
switch_mutex_lock(ps->flag_mutex);
rv = ps_process_raw(ps->ps, (int16 *)data, len / 2 , FALSE, FALSE);
rv = ps_process_raw(ps->ps, (int16 *) data, len / 2, FALSE, FALSE);
switch_mutex_unlock(ps->flag_mutex);
}
@ -321,13 +316,13 @@ static switch_status_t pocketsphinx_asr_pause(switch_asr_handle_t *ah)
pocketsphinx_t *ps = (pocketsphinx_t *) ah->private_info;
switch_status_t status = SWITCH_STATUS_FALSE;
switch_mutex_lock(ps->flag_mutex);
switch_mutex_lock(ps->flag_mutex);
if (switch_test_flag(ps, PSFLAG_READY)) {
ps_end_utt(ps->ps);
switch_clear_flag(ps, PSFLAG_READY);
status = SWITCH_STATUS_SUCCESS;
}
switch_mutex_unlock(ps->flag_mutex);
switch_mutex_unlock(ps->flag_mutex);
return status;
}
@ -337,19 +332,19 @@ static switch_status_t pocketsphinx_asr_resume(switch_asr_handle_t *ah)
{
pocketsphinx_t *ps = (pocketsphinx_t *) ah->private_info;
switch_status_t status = SWITCH_STATUS_FALSE;
switch_mutex_lock(ps->flag_mutex);
switch_mutex_lock(ps->flag_mutex);
switch_clear_flag(ps, PSFLAG_HAS_TEXT);
if (!switch_test_flag(ps, PSFLAG_READY)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Manually Resuming\n");
if (!switch_test_flag(ps, PSFLAG_READY)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Manually Resuming\n");
if (ps_start_utt(ps->ps, NULL)) {
status = SWITCH_STATUS_GENERR;
} else {
switch_set_flag(ps, PSFLAG_READY);
switch_set_flag(ps, PSFLAG_READY);
}
}
switch_mutex_unlock(ps->flag_mutex);
switch_mutex_unlock(ps->flag_mutex);
return status;
}
@ -365,7 +360,7 @@ static switch_status_t pocketsphinx_asr_check_results(switch_asr_handle_t *ah, s
/*! function to read results from the ASR*/
static switch_status_t pocketsphinx_asr_get_results(switch_asr_handle_t *ah, char **xmlstr, switch_asr_flag_t *flags)
{
pocketsphinx_t *ps = (pocketsphinx_t *) ah->private_info;
pocketsphinx_t *ps = (pocketsphinx_t *) ah->private_info;
switch_status_t status = SWITCH_STATUS_SUCCESS;
int32_t conf;
@ -375,7 +370,7 @@ static switch_status_t pocketsphinx_asr_get_results(switch_asr_handle_t *ah, cha
}
if (switch_test_flag(ps, PSFLAG_HAS_TEXT)) {
switch_mutex_lock(ps->flag_mutex);
switch_mutex_lock(ps->flag_mutex);
switch_clear_flag(ps, PSFLAG_HAS_TEXT);
conf = ps_get_prob(ps->ps, &ps->uttid);
@ -386,20 +381,18 @@ static switch_status_t pocketsphinx_asr_get_results(switch_asr_handle_t *ah, cha
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Recognized: %s, Confidence: %d\n", ps->hyp, ps->confidence);
switch_mutex_unlock(ps->flag_mutex);
switch_mutex_unlock(ps->flag_mutex);
*xmlstr = switch_mprintf("<?xml version=\"1.0\"?>\n"
"<result grammar=\"%s\">\n"
" <interpretation grammar=\"%s\" confidence=\"%d\">\n"
" <input mode=\"speech\">%s</input>\n"
" </interpretation>\n"
"</result>\n",
ps->grammar, ps->grammar, ps->confidence, ps->hyp);
" </interpretation>\n" "</result>\n", ps->grammar, ps->grammar, ps->confidence, ps->hyp);
if (switch_test_flag(ps, SWITCH_ASR_FLAG_AUTO_RESUME)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Auto Resuming\n");
switch_set_flag(ps, PSFLAG_READY);
ps_start_utt(ps->ps, NULL);
}
@ -467,7 +460,7 @@ static switch_status_t load_config(void)
globals.language_weight = switch_core_strdup(globals.pool, "6.5");
}
done:
done:
if (xml) {
switch_xml_free(xml);
}
@ -495,7 +488,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_pocketsphinx_load)
switch_asr_interface_t *asr_interface;
switch_mutex_init(&MUTEX, SWITCH_MUTEX_NESTED, pool);
globals.pool = pool;
if ((switch_event_bind_removable(modname, SWITCH_EVENT_RELOADXML, NULL, event_handler, NULL, &NODE) != SWITCH_STATUS_SUCCESS)) {

View File

@ -76,7 +76,7 @@ static int load_tts_commandline_config(void)
}
if (zstr(globals.command)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No command set, please edit %s\n", cf);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No command set, please edit %s\n", cf);
}
return SWITCH_STATUS_SUCCESS;
@ -96,7 +96,7 @@ static switch_status_t tts_commandline_speech_open(switch_speech_handle_t *sh, c
switch_uuid_t uuid;
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
char outfile[512] = "";
tts_commandline_t *info = switch_core_alloc(sh->memory_pool, sizeof(*info));
info->voice_name = switch_core_strdup(sh->memory_pool, voice_name);
@ -107,11 +107,11 @@ static switch_status_t tts_commandline_speech_open(switch_speech_handle_t *sh, c
switch_uuid_format(uuid_str, &uuid);
switch_snprintf(outfile, sizeof(outfile), "%s%s.tmp.wav", SWITCH_GLOBAL_dirs.temp_dir, uuid_str);
info->file = switch_core_strdup(sh->memory_pool, outfile);
info->fh = (switch_file_handle_t *) switch_core_alloc(sh->memory_pool, sizeof(switch_file_handle_t));
sh->private_info = info;
return SWITCH_STATUS_SUCCESS;
}
@ -119,7 +119,7 @@ static switch_status_t tts_commandline_speech_close(switch_speech_handle_t *sh,
{
tts_commandline_t *info = (tts_commandline_t *) sh->private_info;
assert(info != NULL);
return SWITCH_STATUS_SUCCESS;
}
@ -129,37 +129,35 @@ static switch_status_t tts_commandline_speech_feed_tts(switch_speech_handle_t *s
tts_commandline_t *info = (tts_commandline_t *) sh->private_info;
assert(info != NULL);
message = switch_core_strdup(sh->memory_pool, globals.command);
tmp = switch_util_quote_shell_arg(text);
message = switch_string_replace(message, "${text}", tmp);
tmp = switch_util_quote_shell_arg(info->voice_name);
message = switch_string_replace(message, "${voice}", tmp);
rate = switch_core_sprintf(sh->memory_pool, "%d", info->rate);
message = switch_string_replace(message, "${rate}", rate);
tmp = switch_util_quote_shell_arg(info->file);
message = switch_string_replace(message, "${file}", tmp);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Executing: %s\n", message);
if (switch_system(message, SWITCH_TRUE) < 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to execute command: %s\n", message);
return SWITCH_STATUS_FALSE;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to execute command: %s\n", message);
return SWITCH_STATUS_FALSE;
}
if (switch_core_file_open(info->fh,
info->file,
0, //number_of_channels,
0, //samples_per_second,
SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open file: %s\n", info->file);
return SWITCH_STATUS_FALSE;
if (switch_core_file_open(info->fh, info->file, 0, //number_of_channels,
0, //samples_per_second,
SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open file: %s\n", info->file);
return SWITCH_STATUS_FALSE;
}
sh->private_info = info;
return SWITCH_STATUS_SUCCESS;
@ -170,8 +168,8 @@ static switch_status_t tts_commandline_speech_read_tts(switch_speech_handle_t *s
tts_commandline_t *info = (tts_commandline_t *) sh->private_info;
size_t my_datalen = *datalen / 2;
assert(info != NULL);
assert(info != NULL);
if (switch_core_file_read(info->fh, data, &my_datalen) != SWITCH_STATUS_SUCCESS) {
*datalen = my_datalen * 2;
return SWITCH_STATUS_FALSE;
@ -188,7 +186,7 @@ static void tts_commandline_speech_flush_tts(switch_speech_handle_t *sh)
{
tts_commandline_t *info = (tts_commandline_t *) sh->private_info;
assert(info != NULL);
switch_core_file_close(info->fh);
if (unlink(info->file) != 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Sound file [%s] delete failed\n", info->file);

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -250,7 +250,8 @@ static switch_status_t switch_amr_encode(switch_codec_t *codec,
switch_codec_t *other_codec,
void *decoded_data,
uint32_t decoded_data_len,
uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate, unsigned int *flag)
uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate,
unsigned int *flag)
{
#ifdef AMR_PASSTHROUGH
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "This codec is only usable in passthrough mode!\n");
@ -272,7 +273,8 @@ static switch_status_t switch_amr_decode(switch_codec_t *codec,
switch_codec_t *other_codec,
void *encoded_data,
uint32_t encoded_data_len,
uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate, unsigned int *flag)
uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate,
unsigned int *flag)
{
#ifdef AMR_PASSTHROUGH
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "This codec is only usable in passthrough mode!\n");
@ -319,24 +321,23 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_amr_load)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_CODEC(codec_interface, "AMR");
switch_core_codec_add_implementation(pool, codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
96, /* the IANA code number */
"AMR", /* the IANA code name */
"octet-align=0", /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
12200, /* bits transferred per second */
20000, /* number of microseconds per frame */
160, /* number of samples per frame */
320, /* number of bytes per frame decompressed */
0, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_amr_init, /* function to initialize a codec handle using this implementation */
switch_amr_encode, /* function to encode raw data into encoded data */
switch_amr_decode, /* function to decode encoded data into raw data */
switch_amr_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
96, /* the IANA code number */
"AMR", /* the IANA code name */
"octet-align=0", /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
12200, /* bits transferred per second */
20000, /* number of microseconds per frame */
160, /* number of samples per frame */
320, /* number of bytes per frame decompressed */
0, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_amr_init, /* function to initialize a codec handle using this implementation */
switch_amr_encode, /* function to encode raw data into encoded data */
switch_amr_decode, /* function to decode encoded data into raw data */
switch_amr_destroy); /* deinitalize a codec handle using this implementation */
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthmct@yahoo.com>
* Copyright (C) 2005-2010, Anthony Minessale II <anthmct@yahoo.com>
*
* Version: MPL 1.1
*
@ -166,7 +166,8 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla
context->enc_mode = globals.default_bitrate;
}
switch_snprintf(fmtptmp, sizeof(fmtptmp), "octet-align=%d; mode-set=%d", switch_test_flag(context, AMRWB_OPT_OCTET_ALIGN) ? 1 : 0, context->enc_mode);
switch_snprintf(fmtptmp, sizeof(fmtptmp), "octet-align=%d; mode-set=%d", switch_test_flag(context, AMRWB_OPT_OCTET_ALIGN) ? 1 : 0,
context->enc_mode);
codec->fmtp_out = switch_core_strdup(codec->memory_pool, fmtptmp);
context->enc_mode = AMRWB_DEFAULT_BITRATE;
@ -205,11 +206,11 @@ static switch_status_t switch_amrwb_destroy(switch_codec_t *codec)
}
static switch_status_t switch_amrwb_encode(switch_codec_t *codec,
switch_codec_t *other_codec,
void *decoded_data,
uint32_t decoded_data_len,
uint32_t decoded_rate, void *encoded_data, uint32_t * encoded_data_len, uint32_t * encoded_rate,
unsigned int *flag)
switch_codec_t *other_codec,
void *decoded_data,
uint32_t decoded_data_len,
uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate,
unsigned int *flag)
{
#ifdef AMRWB_PASSTHROUGH
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "This codec is only usable in passthrough mode!\n");
@ -228,11 +229,11 @@ static switch_status_t switch_amrwb_encode(switch_codec_t *codec,
}
static switch_status_t switch_amrwb_decode(switch_codec_t *codec,
switch_codec_t *other_codec,
void *encoded_data,
uint32_t encoded_data_len,
uint32_t encoded_rate, void *decoded_data, uint32_t * decoded_data_len, uint32_t * decoded_rate,
unsigned int *flag)
switch_codec_t *other_codec,
void *encoded_data,
uint32_t encoded_data_len,
uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate,
unsigned int *flag)
{
#ifdef AMRWB_PASSTHROUGH
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "This codec is only usable in passthrough mode!\n");
@ -279,10 +280,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_amrwb_load)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_CODEC(codec_interface, "AMR-WB");
switch_core_codec_add_implementation(pool, codec_interface,
SWITCH_CODEC_TYPE_AUDIO, 100, "AMR-WB", "octet-align=0", 16000, 16000, 23850,
20000, 320, 640, 0, 1, 1,
switch_amrwb_init, switch_amrwb_encode, switch_amrwb_decode, switch_amrwb_destroy);
switch_core_codec_add_implementation(pool, codec_interface,
SWITCH_CODEC_TYPE_AUDIO, 100, "AMR-WB", "octet-align=0", 16000, 16000, 23850,
20000, 320, 640, 0, 1, 1, switch_amrwb_init, switch_amrwb_encode, switch_amrwb_decode, switch_amrwb_destroy);
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -51,16 +51,16 @@ static switch_status_t switch_bv16_init(switch_codec_t *codec, switch_codec_flag
if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) {
return SWITCH_STATUS_FALSE;
}
}
if (encoding) {
context->encoder_object = bv16_encode_init(NULL);
}
if (decoding) {
context->decoder_object = bv16_decode_init(NULL);
}
codec->private_info = context;
return SWITCH_STATUS_SUCCESS;
}
@ -68,7 +68,7 @@ static switch_status_t switch_bv16_init(switch_codec_t *codec, switch_codec_flag
static switch_status_t switch_bv16_destroy(switch_codec_t *codec)
{
struct bv16_context *context = codec->private_info;
if (context->encoder_object) {
bv16_encode_free(context->encoder_object);
}
@ -134,16 +134,16 @@ static switch_status_t switch_bv32_init(switch_codec_t *codec, switch_codec_flag
if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) {
return SWITCH_STATUS_FALSE;
}
}
if (encoding) {
context->encoder_object = bv32_encode_init(NULL);
}
if (decoding) {
context->decoder_object = bv32_decode_init(NULL);
}
codec->private_info = context;
return SWITCH_STATUS_SUCCESS;
}
@ -180,7 +180,7 @@ static switch_status_t switch_bv32_encode(switch_codec_t *codec,
}
*encoded_data_len = bv32_encode(context->encoder_object, (uint8_t *) encoded_data, (int16_t *) decoded_data, decoded_data_len / 2);
return SWITCH_STATUS_SUCCESS;
}
@ -208,61 +208,57 @@ static switch_status_t switch_bv32_decode(switch_codec_t *codec,
SWITCH_MODULE_LOAD_FUNCTION(mod_bv_load)
{
switch_codec_interface_t *codec_interface;
int mpf, spf, bpf, ebpf, count;
int mpf, spf, bpf, ebpf, count;
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_CODEC(codec_interface, "BroadVoice16 (BV16)");
SWITCH_ADD_CODEC(codec_interface, "BroadVoice16 (BV16)");
mpf = 10000, spf = 80, bpf = 160, ebpf = 20;
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
106, /* the IANA code number */
"BV16", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
16000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_bv16_init, /* function to initialize a codec handle using this implementation */
switch_bv16_encode, /* function to encode raw data into encoded data */
switch_bv16_decode, /* function to decode encoded data into raw data */
switch_bv16_destroy); /* deinitalize a codec handle using this implementation */
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
106, /* the IANA code number */
"BV16", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
16000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_bv16_init, /* function to initialize a codec handle using this implementation */
switch_bv16_encode, /* function to encode raw data into encoded data */
switch_bv16_decode, /* function to decode encoded data into raw data */
switch_bv16_destroy); /* deinitalize a codec handle using this implementation */
}
SWITCH_ADD_CODEC(codec_interface, "BroadVoice32 (BV32)");
SWITCH_ADD_CODEC(codec_interface, "BroadVoice32 (BV32)");
mpf = 10000, spf = 160, bpf = 320 , ebpf = 40;
mpf = 10000, spf = 160, bpf = 320, ebpf = 40;
for (count = 6; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
127, /* the IANA code number */
"BV32", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
16000, /* samples transferred per second */
16000, /* actual samples transferred per second */
32000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_bv32_init, /* function to initialize a codec handle using this implementation */
switch_bv32_encode, /* function to encode raw data into encoded data */
switch_bv32_decode, /* function to decode encoded data into raw data */
switch_bv32_destroy); /* deinitalize a codec handle using this implementation */
for (count = 6; count > 0; count--) {
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
127, /* the IANA code number */
"BV32", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
16000, /* samples transferred per second */
16000, /* actual samples transferred per second */
32000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_bv32_init, /* function to initialize a codec handle using this implementation */
switch_bv32_encode, /* function to encode raw data into encoded data */
switch_bv32_decode, /* function to decode encoded data into raw data */
switch_bv32_destroy); /* deinitalize a codec handle using this implementation */
}
/* indicate that the module should continue to be loaded */

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -51,43 +51,43 @@ static switch_status_t switch_celt_init(switch_codec_t *codec, switch_codec_flag
if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) {
return SWITCH_STATUS_FALSE;
}
}
context->mode_object = celt_mode_create(codec->implementation->actual_samples_per_second, codec->implementation->samples_per_packet, NULL);
context->mode_object = celt_mode_create(codec->implementation->actual_samples_per_second, codec->implementation->samples_per_packet, NULL);
celt_mode_info(context->mode_object, CELT_GET_FRAME_SIZE, &context->frame_size);
context->bytes_per_packet = (codec->implementation->bits_per_second * context->frame_size/codec->implementation->actual_samples_per_second + 4) / 8;
context->bytes_per_packet = (codec->implementation->bits_per_second * context->frame_size / codec->implementation->actual_samples_per_second + 4) / 8;
/*
if (codec->fmtp_in) {
int x, argc;
char *argv[10];
argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0])));
for (x = 0; x < argc; x++) {
char *data = argv[x];
char *arg;
switch_assert(data);
while (*data == ' ') {
data++;
}
if ((arg = strchr(data, '='))) {
*arg++ = '\0';
if (!strcasecmp(data, "bitrate")) {
bit_rate = atoi(arg);
}
}
}
}
codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "bitrate=%d", bit_rate);
*/
if (codec->fmtp_in) {
int x, argc;
char *argv[10];
argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0])));
for (x = 0; x < argc; x++) {
char *data = argv[x];
char *arg;
switch_assert(data);
while (*data == ' ') {
data++;
}
if ((arg = strchr(data, '='))) {
*arg++ = '\0';
if (!strcasecmp(data, "bitrate")) {
bit_rate = atoi(arg);
}
}
}
}
codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "bitrate=%d", bit_rate);
*/
if (encoding) {
context->encoder_object = celt_encoder_create(context->mode_object, 1, NULL);
}
if (decoding) {
context->decoder_object = celt_decoder_create(context->mode_object, 1, NULL);
}
codec->private_info = context;
return SWITCH_STATUS_SUCCESS;
}
@ -111,8 +111,8 @@ static switch_status_t switch_celt_encode(switch_codec_t *codec,
return SWITCH_STATUS_FALSE;
}
*encoded_data_len = (uint32_t) celt_encode(context->encoder_object, (void *)decoded_data, NULL,
(unsigned char *)encoded_data, context->bytes_per_packet);
*encoded_data_len = (uint32_t) celt_encode(context->encoder_object, (void *) decoded_data, NULL,
(unsigned char *) encoded_data, context->bytes_per_packet);
return SWITCH_STATUS_SUCCESS;
}
@ -149,52 +149,48 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_celt_load)
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_CODEC(codec_interface, "CELT ultra-low delay");
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
114, /* the IANA code number */
"CELT", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
32000, /* samples transferred per second */
32000, /* actual samples transferred per second */
32000, /* bits transferred per second */
10000, /* number of microseconds per frame */
320, /* number of samples per frame */
640, /* number of bytes per frame decompressed */
0, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_celt_init, /* function to initialize a codec handle using this implementation */
switch_celt_encode, /* function to encode raw data into encoded data */
switch_celt_decode, /* function to decode encoded data into raw data */
switch_celt_destroy); /* deinitalize a codec handle using this implementation */
SWITCH_ADD_CODEC(codec_interface, "CELT ultra-low delay");
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
114, /* the IANA code number */
"CELT", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
32000, /* samples transferred per second */
32000, /* actual samples transferred per second */
32000, /* bits transferred per second */
10000, /* number of microseconds per frame */
320, /* number of samples per frame */
640, /* number of bytes per frame decompressed */
0, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_celt_init, /* function to initialize a codec handle using this implementation */
switch_celt_encode, /* function to encode raw data into encoded data */
switch_celt_decode, /* function to decode encoded data into raw data */
switch_celt_destroy); /* deinitalize a codec handle using this implementation */
ms_per_frame = 2000;
samples_per_frame = 96;
bytes_per_frame = 192;
for (x = 0; x < 5; x++) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
114, /* the IANA code number */
"CELT", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
48000, /* samples transferred per second */
48000, /* actual samples transferred per second */
48000, /* bits transferred per second */
ms_per_frame, /* number of microseconds per frame */
samples_per_frame, /* number of samples per frame */
bytes_per_frame, /* number of bytes per frame decompressed */
0, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_celt_init, /* function to initialize a codec handle using this implementation */
switch_celt_encode, /* function to encode raw data into encoded data */
switch_celt_decode, /* function to decode encoded data into raw data */
switch_celt_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
114, /* the IANA code number */
"CELT", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
48000, /* samples transferred per second */
48000, /* actual samples transferred per second */
48000, /* bits transferred per second */
ms_per_frame, /* number of microseconds per frame */
samples_per_frame, /* number of samples per frame */
bytes_per_frame, /* number of bytes per frame decompressed */
0, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_celt_init, /* function to initialize a codec handle using this implementation */
switch_celt_encode, /* function to encode raw data into encoded data */
switch_celt_decode, /* function to decode encoded data into raw data */
switch_celt_destroy); /* deinitalize a codec handle using this implementation */
ms_per_frame += 2000;
samples_per_frame += 96;
bytes_per_frame += 192;

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -33,7 +33,7 @@
#include <switch.h>
#include <g711.h>
#include <poll.h>
#include <linux/types.h> /* __u32 */
#include <linux/types.h> /* __u32 */
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
@ -75,8 +75,8 @@ static uint32_t total_decoders_usage = 0;
#define DAHDI_FORMAT_G729A (1 << 8)
struct dahdi_transcoder_formats {
__u32 srcfmt;
__u32 dstfmt;
__u32 srcfmt;
__u32 dstfmt;
};
struct dahdi_transcoder_info {
@ -108,15 +108,11 @@ static int32_t switch_dahdi_get_transcoder(struct dahdi_transcoder_formats *fmts
int32_t fdflags;
int32_t fd = open(transcoding_device, O_RDWR);
if (fd < 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"Failed to open %s transcoder device: %s.\n",
transcoder_name, strerror(errno));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open %s transcoder device: %s.\n", transcoder_name, strerror(errno));
return -1;
}
if (ioctl(fd, DAHDI_TC_ALLOCATE, fmts)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"Failed to attach to transcoder: %s.\n",
strerror(errno));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to attach to transcoder: %s.\n", strerror(errno));
close(fd);
return -1;
}
@ -124,15 +120,14 @@ static int32_t switch_dahdi_get_transcoder(struct dahdi_transcoder_formats *fmts
if (fdflags > -1) {
fdflags |= O_NONBLOCK;
if (fcntl(fd, F_SETFL, fdflags)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not set non-block mode in %s transcoder FD: %s\n",
transcoder_name, strerror(errno));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not set non-block mode in %s transcoder FD: %s\n",
transcoder_name, strerror(errno));
/* should we abort? this may cause channels to hangup when overruning the device
* see jira dahdi codec issue MODCODEC-8 (Hung Calls and Codec DAHDI G.729A 8.0k decoder error!)
* */
}
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not get flags from %s transcoder FD: %s\n",
transcoder_name, strerror(errno));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not get flags from %s transcoder FD: %s\n", transcoder_name, strerror(errno));
}
if (fmts->srcfmt & DAHDI_FORMAT_ULAW) {
@ -154,19 +149,17 @@ static switch_status_t init_encoder(switch_codec_t *codec)
struct dahdi_context *context = codec->private_info;
fmts.srcfmt = DAHDI_FORMAT_ULAW;
fmts.dstfmt = (codec->implementation->ianacode == CODEC_G729_IANA_CODE)
fmts.dstfmt = (codec->implementation->ianacode == CODEC_G729_IANA_CODE)
? DAHDI_FORMAT_G729A : DAHDI_FORMAT_G723_1;
context->encoding_fd = switch_dahdi_get_transcoder(&fmts);
if (context->encoding_fd < 0) {
#ifdef DEBUG_DAHDI_CODEC
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "encoding requested and denied with %d/%d.\n",
fmts.srcfmt, fmts.dstfmt);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "encoding requested and denied with %d/%d.\n", fmts.srcfmt, fmts.dstfmt);
#endif
return SWITCH_STATUS_FALSE;
}
#ifdef DEBUG_DAHDI_CODEC
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Encoding requested and granted with %d/%d.\n",
fmts.srcfmt, fmts.dstfmt);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Encoding requested and granted with %d/%d.\n", fmts.srcfmt, fmts.dstfmt);
#endif
@ -176,23 +169,21 @@ static switch_status_t init_encoder(switch_codec_t *codec)
static switch_status_t init_decoder(switch_codec_t *codec)
{
struct dahdi_transcoder_formats fmts;
struct dahdi_context *context = codec->private_info;
struct dahdi_transcoder_formats fmts;
struct dahdi_context *context = codec->private_info;
fmts.dstfmt = DAHDI_FORMAT_ULAW;
fmts.srcfmt = (codec->implementation->ianacode == CODEC_G729_IANA_CODE)
fmts.srcfmt = (codec->implementation->ianacode == CODEC_G729_IANA_CODE)
? DAHDI_FORMAT_G729A : DAHDI_FORMAT_G723_1;
context->decoding_fd = switch_dahdi_get_transcoder(&fmts);
if (context->decoding_fd < 0) {
#ifdef DEBUG_DAHDI_CODEC
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Decoding requested and denied with %d/%d.\n",
fmts.srcfmt, fmts.dstfmt);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Decoding requested and denied with %d/%d.\n", fmts.srcfmt, fmts.dstfmt);
#endif
return SWITCH_STATUS_FALSE;
}
#ifdef DEBUG_DAHDI_CODEC
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Decoding requested and granted with %d/%d.\n",
fmts.srcfmt, fmts.dstfmt);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Decoding requested and granted with %d/%d.\n", fmts.srcfmt, fmts.dstfmt);
#endif
return SWITCH_STATUS_SUCCESS;
@ -228,7 +219,7 @@ static switch_status_t switch_dahdi_init(switch_codec_t *codec, switch_codec_fla
/* ulaw requires 8 times more storage than g729 and 12 times more than G723, right?
* this can be used to calculate the target buffer when encoding and decoding
* */
context->codec_r = (codec->implementation->ianacode == CODEC_G729_IANA_CODE)
context->codec_r = (codec->implementation->ianacode == CODEC_G729_IANA_CODE)
? 8 : 12;
@ -238,7 +229,7 @@ static switch_status_t switch_dahdi_init(switch_codec_t *codec, switch_codec_fla
static int wait_for_transcoder(int fd)
{
/* let's wait a bit for the transcoder, if in 20msthe driver does not notify us that its ready to give us something
then just bail out with 0 bytes encoded/decoded as result, I'd expect the card to hold that buffer and return it later */
then just bail out with 0 bytes encoded/decoded as result, I'd expect the card to hold that buffer and return it later */
int res = 0;
struct pollfd readpoll;
memset(&readpoll, 0, sizeof(readpoll));
@ -246,21 +237,21 @@ static int wait_for_transcoder(int fd)
readpoll.events = POLLIN;
/* my testing shows that it does not take more than 1ms to encode a 160 bytes frame ulaw to g729,
I dont think there is much difference decoding and for g723, waiting 10ms seems more than reasonable */
res = poll(&readpoll, 1, 10);
res = poll(&readpoll, 1, 10);
return res;
}
static switch_status_t switch_dahdi_encode(switch_codec_t *codec,
switch_codec_t *other_codec,
void *decoded_data,
uint32_t decoded_data_len,
uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate,
unsigned int *flag)
switch_codec_t *other_codec,
void *decoded_data,
uint32_t decoded_data_len,
uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate,
unsigned int *flag)
{
int32_t res;
short *dbuf_linear;
unsigned char *ebuf_g729;
unsigned char ebuf_ulaw[decoded_data_len/2];
unsigned char ebuf_ulaw[decoded_data_len / 2];
uint32_t i;
struct dahdi_context *context = NULL;
switch_status_t status;
@ -290,7 +281,8 @@ static switch_status_t switch_dahdi_encode(switch_codec_t *codec,
return SWITCH_STATUS_FALSE;
}
if (i != res) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested to write %d bytes to %s encoder device, but only wrote %d bytes.\n", i, transcoder_name, res);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested to write %d bytes to %s encoder device, but only wrote %d bytes.\n", i,
transcoder_name, res);
return SWITCH_STATUS_FALSE;
}
res = wait_for_transcoder(context->encoding_fd);
@ -333,7 +325,7 @@ static switch_status_t switch_dahdi_decode(switch_codec_t *codec,
int32_t res;
short *dbuf_linear;
// we only can decode up to half ulaw bytes of whatever their destiny linear buffer is
unsigned char dbuf_ulaw[*decoded_data_len/2];
unsigned char dbuf_ulaw[*decoded_data_len / 2];
unsigned char *ebuf_g729;
uint32_t i;
struct dahdi_context *context;
@ -360,7 +352,7 @@ static switch_status_t switch_dahdi_decode(switch_codec_t *codec,
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Switch DAHDI decode in silence returned %d bytes.\n", *decoded_data_len);
#endif
return SWITCH_STATUS_SUCCESS;
}
}
#ifdef DEBUG_DAHDI_CODEC
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Writing %d bytes to decode.\n", encoded_data_len);
#endif
@ -370,12 +362,12 @@ static switch_status_t switch_dahdi_decode(switch_codec_t *codec,
return SWITCH_STATUS_FALSE;
}
if (encoded_data_len != res) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested to write %d bytes to %s decoder device, but only wrote %d bytes.\n", encoded_data_len, transcoder_name, res);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested to write %d bytes to %s decoder device, but only wrote %d bytes.\n",
encoded_data_len, transcoder_name, res);
return SWITCH_STATUS_FALSE;
}
#ifdef DEBUG_DAHDI_CODEC
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Attempting to read from device %d bytes of decoded ulaw data.\n",
sizeof(dbuf_ulaw));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Attempting to read from device %d bytes of decoded ulaw data.\n", sizeof(dbuf_ulaw));
#endif
res = wait_for_transcoder(context->decoding_fd);
if (-1 == res) {
@ -386,7 +378,8 @@ static switch_status_t switch_dahdi_decode(switch_codec_t *codec,
memset(dbuf_linear, 0, codec->implementation->decoded_bytes_per_packet);
*decoded_data_len = codec->implementation->decoded_bytes_per_packet;
#ifdef DEBUG_DAHDI_CODEC
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No output on %s decoder device, returning silence frame of %d bytes.\n", transcoder_name, *decoded_data_len);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No output on %s decoder device, returning silence frame of %d bytes.\n", transcoder_name,
*decoded_data_len);
#endif
return SWITCH_STATUS_SUCCESS;
}
@ -437,10 +430,8 @@ SWITCH_STANDARD_API(dahdi_transcode_usage)
return SWITCH_STATUS_SUCCESS;
}
switch_mutex_lock(transcoder_counter_mutex);
stream->write_function(stream, "Using %d encoders of a total of %d available.\n",
total_encoders_usage, total_encoders);
stream->write_function(stream, "Using %d decoders of a total of %d available.\n",
total_decoders_usage, total_decoders);
stream->write_function(stream, "Using %d encoders of a total of %d available.\n", total_encoders_usage, total_encoders);
stream->write_function(stream, "Using %d decoders of a total of %d available.\n", total_decoders_usage, total_decoders);
switch_mutex_unlock(transcoder_counter_mutex);
return SWITCH_STATUS_SUCCESS;
}
@ -452,10 +443,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dahdi_codec_load)
struct stat statbuf;
struct dahdi_transcoder_info info = { 0 };
int32_t fd, res;
int mpf = 20000; /* Algorithmic delay of 15ms with 5ms of look-ahead delay */
int spf = 160;
int bpfd = 320;
int bpfc = 20;
int mpf = 20000; /* Algorithmic delay of 15ms with 5ms of look-ahead delay */
int spf = 160;
int bpfd = 320;
int bpfc = 20;
int fpnp = 20;
total_encoders = 0;
@ -479,8 +470,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dahdi_codec_load)
fd = open(transcoding_device, O_RDWR);
if (fd < 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open %s transcoder device: %s.\n",
transcoder_name, strerror(errno));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open %s transcoder device: %s.\n", transcoder_name, strerror(errno));
return SWITCH_STATUS_FALSE;
}
@ -491,14 +481,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dahdi_codec_load)
continue;
}
if ((info.dstfmts & DAHDI_FORMAT_ULAW) && (info.srcfmts & (DAHDI_FORMAT_G729A | DAHDI_FORMAT_G723_1))) {
total_decoders += info.numchannels;
total_decoders += info.numchannels;
continue;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,
"Not using transcoder %s, we just support ULAW and G723.1/G729A", info.name);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Not using transcoder %s, we just support ULAW and G723.1/G729A", info.name);
}
close(fd);
if (!total_encoders && !total_decoders) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No DAHDI transcoders found.\n");
return SWITCH_STATUS_FALSE;
@ -510,79 +499,73 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dahdi_codec_load)
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_CODEC(codec_interface, "DAHDI G.729A 8.0k"); /* 8.0kbit */
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
18, /* the IANA code number */
"G729", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
8000, /* bits transferred per second */
mpf, /* number of microseconds per frame */
spf, /* number of samples per frame */
bpfd, /* number of bytes per frame decompressed */
bpfc, /* number of bytes per frame compressed */
1, /* number of channels represented */
fpnp, /* number of frames per network packet */
switch_dahdi_init, /* function to initialize a codec handle using this implementation */
switch_dahdi_encode, /* function to encode raw data into encoded data */
switch_dahdi_decode, /* function to decode encoded data into raw data */
switch_dahdi_destroy); /* deinitalize a codec handle using this implementation */
SWITCH_ADD_CODEC(codec_interface, "DAHDI G.729A 8.0k"); /* 8.0kbit */
mpf = 30000;
spf = 240;
bpfd = 480;
bpfc = 30;
fpnp = 30;
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
18, /* the IANA code number */
"G729", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
8000, /* bits transferred per second */
mpf, /* number of microseconds per frame */
spf, /* number of samples per frame */
bpfd, /* number of bytes per frame decompressed */
bpfc, /* number of bytes per frame compressed */
1, /* number of channels represented */
fpnp, /* number of frames per network packet */
switch_dahdi_init, /* function to initialize a codec handle using this implementation */
switch_dahdi_encode, /* function to encode raw data into encoded data */
switch_dahdi_decode, /* function to decode encoded data into raw data */
switch_dahdi_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
18, /* the IANA code number */
"G729", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
8000, /* bits transferred per second */
mpf, /* number of microseconds per frame */
spf, /* number of samples per frame */
bpfd, /* number of bytes per frame decompressed */
bpfc, /* number of bytes per frame compressed */
1, /* number of channels represented */
fpnp, /* number of frames per network packet */
switch_dahdi_init, /* function to initialize a codec handle using this implementation */
switch_dahdi_encode, /* function to encode raw data into encoded data */
switch_dahdi_decode, /* function to decode encoded data into raw data */
switch_dahdi_destroy); /* deinitalize a codec handle using this implementation */
SWITCH_ADD_CODEC(codec_interface, "DAHDI G.723.1 5.3k"); /* 5.3kbit */
mpf = 30000; /* Algorithmic delay of 37.5ms with 7.5ms of look-ahead delay */
mpf = 30000;
spf = 240;
bpfd = 480;
bpfc = 30;
fpnp = 30;
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
18, /* the IANA code number */
"G729", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
8000, /* bits transferred per second */
mpf, /* number of microseconds per frame */
spf, /* number of samples per frame */
bpfd, /* number of bytes per frame decompressed */
bpfc, /* number of bytes per frame compressed */
1, /* number of channels represented */
fpnp, /* number of frames per network packet */
switch_dahdi_init, /* function to initialize a codec handle using this implementation */
switch_dahdi_encode, /* function to encode raw data into encoded data */
switch_dahdi_decode, /* function to decode encoded data into raw data */
switch_dahdi_destroy); /* deinitalize a codec handle using this implementation */
SWITCH_ADD_CODEC(codec_interface, "DAHDI G.723.1 5.3k"); /* 5.3kbit */
mpf = 30000; /* Algorithmic delay of 37.5ms with 7.5ms of look-ahead delay */
spf = 240;
bpfd = 480;
bpfc = 20;
fpnp = 10;
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
4, /* the IANA code number */
"G723", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
8000, /* bits transferred per second */
mpf, /* number of microseconds per frame */
spf, /* number of samples per frame */
bpfd, /* number of bytes per frame decompressed */
bpfc, /* number of bytes per frame compressed */
1, /* number of channels represented */
fpnp, /* number of frames per network packet */
switch_dahdi_init, /* function to initialize a codec handle using this implementation */
switch_dahdi_encode, /* function to encode raw data into encoded data */
switch_dahdi_decode, /* function to decode encoded data into raw data */
switch_dahdi_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
4, /* the IANA code number */
"G723", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
8000, /* bits transferred per second */
mpf, /* number of microseconds per frame */
spf, /* number of samples per frame */
bpfd, /* number of bytes per frame decompressed */
bpfc, /* number of bytes per frame compressed */
1, /* number of channels represented */
fpnp, /* number of frames per network packet */
switch_dahdi_init, /* function to initialize a codec handle using this implementation */
switch_dahdi_encode, /* function to encode raw data into encoded data */
switch_dahdi_decode, /* function to decode encoded data into raw data */
switch_dahdi_destroy); /* deinitalize a codec handle using this implementation */
SWITCH_ADD_API(api_interface, "dahdi_transcode", "DAHDI Transcode", dahdi_transcode_usage, NULL);
switch_console_set_complete("add dahdi_transcode");

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -171,8 +171,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_g723_1_load)
{
switch_codec_interface_t *codec_interface;
int ompf = 30000, ospf = 240, obpf = 480, oebpf = 24, count = 0;
int mpf = ompf , spf = ospf , bpf = obpf , ebpf = oebpf ;
int mpf = ompf, spf = ospf, bpf = obpf, ebpf = oebpf;
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_CODEC(codec_interface, "G.723.1 6.3k");
@ -180,8 +180,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_g723_1_load)
for (count = 0; count < 4; count++) {
switch_core_codec_add_implementation(pool, codec_interface,
SWITCH_CODEC_TYPE_AUDIO, 4, "G723", NULL, 8000, 8000, 6300,
mpf , spf , bpf , ebpf , 1, count,
switch_g723_init, switch_g723_encode, switch_g723_decode, switch_g723_destroy);
mpf, spf, bpf, ebpf, 1, count, switch_g723_init, switch_g723_encode, switch_g723_decode, switch_g723_destroy);
mpf += ompf;
spf += ospf;
bpf += obpf;

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -46,10 +46,10 @@ static switch_status_t switch_ilbc_init(switch_codec_t *codec, switch_codec_flag
int encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
int decoding = (flags & SWITCH_CODEC_FLAG_DECODE);
int mode = codec->implementation->microseconds_per_packet / 1000;
if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) {
return SWITCH_STATUS_FALSE;
}
}
if (codec->fmtp_in) {
int x, argc;
@ -70,9 +70,9 @@ static switch_status_t switch_ilbc_init(switch_codec_t *codec, switch_codec_flag
}
}
}
codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "mode=%d", mode);
if (encoding) {
ilbc_encode_init(&context->encoder_object, mode);
}
@ -80,7 +80,7 @@ static switch_status_t switch_ilbc_init(switch_codec_t *codec, switch_codec_flag
if (decoding) {
ilbc_decode_init(&context->decoder_object, mode, 0);
}
codec->private_info = context;
return SWITCH_STATUS_SUCCESS;
}
@ -122,7 +122,7 @@ static switch_status_t switch_ilbc_decode(switch_codec_t *codec,
return SWITCH_STATUS_FALSE;
}
*decoded_data_len = (2 *ilbc_decode(&context->decoder_object, (int16_t *) decoded_data, (uint8_t *) encoded_data, encoded_data_len));
*decoded_data_len = (2 * ilbc_decode(&context->decoder_object, (int16_t *) decoded_data, (uint8_t *) encoded_data, encoded_data_len));
return SWITCH_STATUS_SUCCESS;
}
@ -137,45 +137,41 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_ilbc_load)
SWITCH_ADD_CODEC(codec_interface, "iLBC");
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
98, /* the IANA code number */
"iLBC", /* the IANA code name */
"mode=20", /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
15200, /* bits transferred per second */
20000, /* number of microseconds per frame */
ILBC_BLOCK_LEN_20MS, /* number of samples per frame */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
98, /* the IANA code number */
"iLBC", /* the IANA code name */
"mode=20", /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
15200, /* bits transferred per second */
20000, /* number of microseconds per frame */
ILBC_BLOCK_LEN_20MS, /* number of samples per frame */
ILBC_BLOCK_LEN_20MS * 2, /* number of bytes per frame decompressed */
ILBC_NO_OF_BYTES_20MS, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_ilbc_init, /* function to initialize a codec handle using this implementation */
switch_ilbc_encode, /* function to encode raw data into encoded data */
switch_ilbc_decode, /* function to decode encoded data into raw data */
switch_ilbc_destroy); /* deinitalize a codec handle using this implementation */
ILBC_NO_OF_BYTES_20MS, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_ilbc_init, /* function to initialize a codec handle using this implementation */
switch_ilbc_encode, /* function to encode raw data into encoded data */
switch_ilbc_decode, /* function to decode encoded data into raw data */
switch_ilbc_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
97, /* the IANA code number */
"iLBC", /* the IANA code name */
"mode=30", /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
13300, /* bits transferred per second */
30000, /* number of microseconds per frame */
ILBC_BLOCK_LEN_30MS, /* number of samples per frame */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
97, /* the IANA code number */
"iLBC", /* the IANA code name */
"mode=30", /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
13300, /* bits transferred per second */
30000, /* number of microseconds per frame */
ILBC_BLOCK_LEN_30MS, /* number of samples per frame */
ILBC_BLOCK_LEN_30MS * 2, /* number of bytes per frame decompressed */
ILBC_NO_OF_BYTES_30MS, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_ilbc_init, /* function to initialize a codec handle using this implementation */
switch_ilbc_encode, /* function to encode raw data into encoded data */
switch_ilbc_decode, /* function to decode encoded data into raw data */
switch_ilbc_destroy); /* deinitalize a codec handle using this implementation */
ILBC_NO_OF_BYTES_30MS, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_ilbc_init, /* function to initialize a codec handle using this implementation */
switch_ilbc_encode, /* function to encode raw data into encoded data */
switch_ilbc_decode, /* function to decode encoded data into raw data */
switch_ilbc_destroy); /* deinitalize a codec handle using this implementation */
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -56,7 +56,7 @@ static switch_status_t switch_siren_init(switch_codec_t *codec, switch_codec_fla
if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) {
return SWITCH_STATUS_FALSE;
}
}
if (codec->fmtp_in) {
int x, argc;
@ -77,9 +77,9 @@ static switch_status_t switch_siren_init(switch_codec_t *codec, switch_codec_fla
}
}
}
codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "bitrate=%d", bit_rate);
if (encoding) {
g722_1_encode_init(&context->encoder_object, bit_rate, codec->implementation->samples_per_second);
}
@ -87,7 +87,7 @@ static switch_status_t switch_siren_init(switch_codec_t *codec, switch_codec_fla
if (decoding) {
g722_1_decode_init(&context->decoder_object, bit_rate, codec->implementation->samples_per_second);
}
codec->private_info = context;
return SWITCH_STATUS_SUCCESS;
}
@ -99,11 +99,11 @@ static switch_status_t switch_siren_destroy(switch_codec_t *codec)
}
static switch_status_t switch_siren_encode(switch_codec_t *codec,
switch_codec_t *other_codec,
void *decoded_data,
uint32_t decoded_data_len,
uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate,
unsigned int *flag)
switch_codec_t *other_codec,
void *decoded_data,
uint32_t decoded_data_len,
uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate,
unsigned int *flag)
{
struct siren_context *context = codec->private_info;
@ -116,14 +116,14 @@ static switch_status_t switch_siren_encode(switch_codec_t *codec,
}
static switch_status_t switch_siren_decode(switch_codec_t *codec,
switch_codec_t *other_codec,
void *encoded_data,
uint32_t encoded_data_len,
uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate,
unsigned int *flag)
switch_codec_t *other_codec,
void *encoded_data,
uint32_t encoded_data_len,
uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate,
unsigned int *flag)
{
struct siren_context *context = codec->private_info;
if (!context) {
return SWITCH_STATUS_FALSE;
}
@ -148,47 +148,43 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_siren_load)
spf = 320, bpf = 640;
for (count = 3; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
107, /* the IANA code number */
"G7221", /* the IANA code name */
"bitrate=32000", /* default fmtp to send (can be overridden by the init function) */
16000, /* samples transferred per second */
16000, /* actual samples transferred per second */
32000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
0, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_siren_init, /* function to initialize a codec handle using this implementation */
switch_siren_encode, /* function to encode raw data into encoded data */
switch_siren_decode, /* function to decode encoded data into raw data */
switch_siren_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
107, /* the IANA code number */
"G7221", /* the IANA code name */
"bitrate=32000", /* default fmtp to send (can be overridden by the init function) */
16000, /* samples transferred per second */
16000, /* actual samples transferred per second */
32000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
0, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_siren_init, /* function to initialize a codec handle using this implementation */
switch_siren_encode, /* function to encode raw data into encoded data */
switch_siren_decode, /* function to decode encoded data into raw data */
switch_siren_destroy); /* deinitalize a codec handle using this implementation */
}
spf = 640, bpf = 1280;
for (count = 3; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
115, /* the IANA code number */
"G7221", /* the IANA code name */
"bitrate=48000", /* default fmtp to send (can be overridden by the init function) */
32000, /* samples transferred per second */
32000, /* actual samples transferred per second */
48000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
0, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_siren_init, /* function to initialize a codec handle using this implementation */
switch_siren_encode, /* function to encode raw data into encoded data */
switch_siren_decode, /* function to decode encoded data into raw data */
switch_siren_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
115, /* the IANA code number */
"G7221", /* the IANA code name */
"bitrate=48000", /* default fmtp to send (can be overridden by the init function) */
32000, /* samples transferred per second */
32000, /* actual samples transferred per second */
48000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
0, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_siren_init, /* function to initialize a codec handle using this implementation */
switch_siren_encode, /* function to encode raw data into encoded data */
switch_siren_decode, /* function to decode encoded data into raw data */
switch_siren_destroy); /* deinitalize a codec handle using this implementation */
}
/* indicate that the module should continue to be loaded */

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -94,15 +94,14 @@ static switch_status_t switch_skel_init(switch_codec_t *codec, switch_codec_flag
* SWITCH_STATUS_NOOP, NOOP indicates that the audio in is already the same as the audio out, so no conversion was necessary.
* SWITCH_STATUS_NOT_INITALIZED, failure to init, you can use this to init on first usage and no in switch_skel_init?
* */
static switch_status_t switch_skel_encode(switch_codec_t *codec,
switch_codec_t *other_codec, /* codec that was used by the other side */
void *decoded_data, /* decoded data that we must encode */
uint32_t decoded_data_len /* decoded data length */,
uint32_t decoded_rate /* rate of the decoded data */,
void *encoded_data, /* here we will store the encoded data */
uint32_t *encoded_data_len, /* here we will set the length of the encoded data */
uint32_t *encoded_rate /* here we will set the rate of the encoded data */,
unsigned int *flag /* frame flag, see switch_frame_flag_enum_t */)
static switch_status_t switch_skel_encode(switch_codec_t *codec, switch_codec_t *other_codec, /* codec that was used by the other side */
void *decoded_data, /* decoded data that we must encode */
uint32_t decoded_data_len /* decoded data length */ ,
uint32_t decoded_rate /* rate of the decoded data */ ,
void *encoded_data, /* here we will store the encoded data */
uint32_t *encoded_data_len, /* here we will set the length of the encoded data */
uint32_t *encoded_rate /* here we will set the rate of the encoded data */ ,
unsigned int *flag /* frame flag, see switch_frame_flag_enum_t */ )
{
struct skel_context *context = codec->private_info;
/* FS core checks the actual samples per second and microseconds per packet to determine the buffer size in the worst case scenario, no need to check
@ -123,15 +122,15 @@ static switch_status_t switch_skel_encode(switch_codec_t *codec,
* SWITCH_STATUS_NOOP, NOOP indicates that the audio in is already the same as the audio out, so no conversion was necessary.
* SWITCH_STATUS_NOT_INITALIZED, failure to init, you can use this to init on first usage and no in switch_skel_init?
* */
static switch_status_t switch_skel_decode(switch_codec_t *codec, /* codec session handle */
switch_codec_t *other_codec, /* what is this? */
void *encoded_data, /* data that we must decode into slinear and put it in decoded_data */
uint32_t encoded_data_len, /* length in bytes of the encoded data */
uint32_t encoded_rate, /* at which rate was the data encoded */
void *decoded_data, /* buffer where we must put the decoded data */
uint32_t *decoded_data_len, /* we must set this value to the size of the decoded data */
uint32_t *decoded_rate, /* rate of the decoded data */
unsigned int *flag /* frame flag, see switch_frame_flag_enum_t */)
static switch_status_t switch_skel_decode(switch_codec_t *codec, /* codec session handle */
switch_codec_t *other_codec, /* what is this? */
void *encoded_data, /* data that we must decode into slinear and put it in decoded_data */
uint32_t encoded_data_len, /* length in bytes of the encoded data */
uint32_t encoded_rate, /* at which rate was the data encoded */
void *decoded_data, /* buffer where we must put the decoded data */
uint32_t *decoded_data_len, /* we must set this value to the size of the decoded data */
uint32_t *decoded_rate, /* rate of the decoded data */
unsigned int *flag /* frame flag, see switch_frame_flag_enum_t */ )
{
struct skel_context *context = codec->private_info;
/* FS core checks the actual samples per second and microseconds per packet to determine the buffer size in the worst case scenario, no need to check
@ -150,7 +149,7 @@ static switch_status_t switch_skel_destroy(switch_codec_t *codec)
* no need to free memory allocated from the pool though, the owner of the pool takes care of that */
struct skel_context *context = codec->private_info;
context->encodes = 0;
context->decodes = 0; /* silly, context was allocated in the pool and therefore will be destroyed soon, exact time is not guaranteed though */
context->decodes = 0; /* silly, context was allocated in the pool and therefore will be destroyed soon, exact time is not guaranteed though */
return SWITCH_STATUS_SUCCESS;
}
@ -180,32 +179,31 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skel_codec_load)
/* SWITCH_ADD_CODEC allocates a codec interface structure from the pool the core gave us and adds it to the internal interface list the core keeps,
* gets a codec id and set the given codec name to it.
* At this point there is an empty shell codec interface registered, but not yet implementations */
SWITCH_ADD_CODEC(codec_interface, "SKEL 8.0k"); /* 8.0kbit */
SWITCH_ADD_CODEC(codec_interface, "SKEL 8.0k"); /* 8.0kbit */
/* Now add as many codec implementations as needed, typically this is done inside a for loop where the packetization size is
* incremented (10ms, 20ms, 30ms etc) as needed */
switch_core_codec_add_implementation(pool,
codec_interface, /* the codec interface we allocated and we want to register with the core */
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
0, /* the IANA code number, ie http://www.iana.org/assignments/rtp-parameters */
"SKEL", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function), fmtp is used in SDP for format specific parameters */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
8000, /* bits transferred per second */
20000, /* for 20ms (milliseconds) frames, 20,000 microseconds and so on, you can register the same codec with different packetization */
160, /* number of samples per frame, for this dummy implementation is 160, which is the number of samples in 20ms at 8000 samples per second */
320, /* number of bytes per frame decompressed */
320, /* number of bytes per frame compressed, since we dont really compress anything, is the same number as per frame decompressed */
1, /* number of channels represented */
20, /* number of frames per network packet */
switch_skel_init, /* function to initialize a codec session using this implementation */
switch_skel_encode, /* function to encode slinear data into encoded data */
switch_skel_decode, /* function to decode encoded data into slinear data */
switch_skel_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, /* the codec interface we allocated and we want to register with the core */
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
0, /* the IANA code number, ie http://www.iana.org/assignments/rtp-parameters */
"SKEL", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function), fmtp is used in SDP for format specific parameters */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
8000, /* bits transferred per second */
20000, /* for 20ms (milliseconds) frames, 20,000 microseconds and so on, you can register the same codec with different packetization */
160, /* number of samples per frame, for this dummy implementation is 160, which is the number of samples in 20ms at 8000 samples per second */
320, /* number of bytes per frame decompressed */
320, /* number of bytes per frame compressed, since we dont really compress anything, is the same number as per frame decompressed */
1, /* number of channels represented */
20, /* number of frames per network packet */
switch_skel_init, /* function to initialize a codec session using this implementation */
switch_skel_encode, /* function to encode slinear data into encoded data */
switch_skel_decode, /* function to decode encoded data into slinear data */
switch_skel_destroy); /* deinitalize a codec handle using this implementation */
SWITCH_ADD_API(api_interface, "skel_sayhi", "Skel Codec Says Hi", skel_sayhi, NULL);
switch_console_set_complete("add skel_sayhi"); /* For CLI completion */
switch_console_set_complete("add skel_sayhi"); /* For CLI completion */
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -272,25 +272,23 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_speex_load)
SWITCH_ADD_CODEC(codec_interface, "Speex");
for (counta = 1; counta <= 3; counta++) {
for (countb = 1; countb > 0; countb--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
ianacode[counta], /* the IANA code number */
"SPEEX", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
rate, /* samples transferred per second */
rate, /* actual samples transferred per second */
bps[counta], /* bits transferred per second */
mpf * countb, /* number of microseconds per frame */
spf * countb, /* number of samples per frame */
bpf * countb, /* number of bytes per frame decompressed */
0, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_speex_init, /* function to initialize a codec handle using this implementation */
switch_speex_encode, /* function to encode raw data into encoded data */
switch_speex_decode, /* function to decode encoded data into raw data */
switch_speex_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
ianacode[counta], /* the IANA code number */
"SPEEX", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
rate, /* samples transferred per second */
rate, /* actual samples transferred per second */
bps[counta], /* bits transferred per second */
mpf * countb, /* number of microseconds per frame */
spf * countb, /* number of samples per frame */
bpf * countb, /* number of bytes per frame decompressed */
0, /* number of bytes per frame compressed */
1, /* number of channels represented */
1, /* number of frames per network packet */
switch_speex_init, /* function to initialize a codec handle using this implementation */
switch_speex_encode, /* function to encode raw data into encoded data */
switch_speex_decode, /* function to decode encoded data into raw data */
switch_speex_destroy); /* deinitalize a codec handle using this implementation */
}
rate = rate * 2;
spf = spf * 2;

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -80,9 +80,11 @@ static switch_status_t switch_lpc10_destroy(switch_codec_t *codec)
return SWITCH_STATUS_FALSE;
}
if (context->encoder_object) lpc10_encode_free(context->encoder_object);
if (context->encoder_object)
lpc10_encode_free(context->encoder_object);
context->encoder_object = NULL;
if (context->decoder_object) lpc10_decode_free(context->decoder_object);
if (context->decoder_object)
lpc10_decode_free(context->decoder_object);
context->decoder_object = NULL;
return SWITCH_STATUS_SUCCESS;
@ -160,7 +162,8 @@ static switch_status_t switch_gsm_encode(switch_codec_t *codec,
switch_codec_t *other_codec,
void *decoded_data,
uint32_t decoded_data_len,
uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate, unsigned int *flag)
uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate,
unsigned int *flag)
{
struct gsm_context *context = codec->private_info;
@ -177,7 +180,8 @@ static switch_status_t switch_gsm_decode(switch_codec_t *codec,
switch_codec_t *other_codec,
void *encoded_data,
uint32_t encoded_data_len,
uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate, unsigned int *flag)
uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate,
unsigned int *flag)
{
struct gsm_context *context = codec->private_info;
@ -200,9 +204,11 @@ static switch_status_t switch_gsm_destroy(switch_codec_t *codec)
return SWITCH_STATUS_FALSE;
}
if (context->decoder_object) gsm0610_free(context->decoder_object);
if (context->decoder_object)
gsm0610_free(context->decoder_object);
context->decoder_object = NULL;
if (context->encoder_object) gsm0610_free(context->encoder_object);
if (context->encoder_object)
gsm0610_free(context->encoder_object);
context->encoder_object = NULL;
return SWITCH_STATUS_SUCCESS;
@ -433,9 +439,11 @@ static switch_status_t switch_g722_destroy(switch_codec_t *codec)
return SWITCH_STATUS_FALSE;
}
if (context->decoder_object) g722_decode_free(context->decoder_object);
if (context->decoder_object)
g722_decode_free(context->decoder_object);
context->decoder_object = NULL;
if (context->encoder_object) g722_encode_free(context->encoder_object);
if (context->encoder_object)
g722_encode_free(context->encoder_object);
context->encoder_object = NULL;
return SWITCH_STATUS_SUCCESS;
@ -456,14 +464,14 @@ static switch_status_t switch_g726_init(switch_codec_t *codec, switch_codec_flag
if (!(encoding || decoding)) {
return SWITCH_STATUS_FALSE;
}
}
if ((flags & SWITCH_CODEC_FLAG_AAL2 || strstr(codec->implementation->iananame, "AAL2"))) {
packing = G726_PACKING_LEFT;
}
context = g726_init(context, codec->implementation->bits_per_second, G726_ENCODING_LINEAR, packing);
codec->private_info = context;
return SWITCH_STATUS_SUCCESS;
@ -597,9 +605,11 @@ static switch_status_t switch_adpcm_destroy(switch_codec_t *codec)
return SWITCH_STATUS_FALSE;
}
if (context->decoder_object) ima_adpcm_free(context->decoder_object);
if (context->decoder_object)
ima_adpcm_free(context->decoder_object);
context->decoder_object = NULL;
if (context->encoder_object) ima_adpcm_free(context->encoder_object);
if (context->encoder_object)
ima_adpcm_free(context->encoder_object);
context->encoder_object = NULL;
return SWITCH_STATUS_SUCCESS;
@ -620,260 +630,238 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_voipcodecs_load)
mpf = 10000, spf = 80, bpf = 160, ebpf = 80;
SWITCH_ADD_CODEC(codec_interface, "ADPCM (IMA)");
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
5, /* the IANA code number */
"DVI4", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
32000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
(ebpf * count) + 4, /* number of bytes per frame compressed */
1, /* number of channels represented */
spf * count, /* number of frames per network packet */
switch_adpcm_init, /* function to initialize a codec handle using this implementation */
switch_adpcm_encode, /* function to encode raw data into encoded data */
switch_adpcm_decode, /* function to decode encoded data into raw data */
switch_adpcm_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
5, /* the IANA code number */
"DVI4", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
32000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
(ebpf * count) + 4, /* number of bytes per frame compressed */
1, /* number of channels represented */
spf * count, /* number of frames per network packet */
switch_adpcm_init, /* function to initialize a codec handle using this implementation */
switch_adpcm_encode, /* function to encode raw data into encoded data */
switch_adpcm_decode, /* function to decode encoded data into raw data */
switch_adpcm_destroy); /* deinitalize a codec handle using this implementation */
}
mpf = 10000, spf = 160, bpf = 320, ebpf = 160;
for (count = 6; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
6, /* the IANA code number */
"DVI4", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
16000, /* samples transferred per second */
16000, /* actual samples transferred per second */
64000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
(ebpf * count) + 4, /* number of bytes per frame compressed */
1, /* number of channels represented */
spf * count, /* number of frames per network packet */
switch_adpcm_init, /* function to initialize a codec handle using this implementation */
switch_adpcm_encode, /* function to encode raw data into encoded data */
switch_adpcm_decode, /* function to decode encoded data into raw data */
switch_adpcm_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
6, /* the IANA code number */
"DVI4", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
16000, /* samples transferred per second */
16000, /* actual samples transferred per second */
64000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
(ebpf * count) + 4, /* number of bytes per frame compressed */
1, /* number of channels represented */
spf * count, /* number of frames per network packet */
switch_adpcm_init, /* function to initialize a codec handle using this implementation */
switch_adpcm_encode, /* function to encode raw data into encoded data */
switch_adpcm_decode, /* function to decode encoded data into raw data */
switch_adpcm_destroy); /* deinitalize a codec handle using this implementation */
}
/* G726 */
mpf = 10000, spf = 80, bpf = 160, ebpf = 20;
SWITCH_ADD_CODEC(codec_interface, "G.726 16k (AAL2)");
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
124, /* the IANA code number */
"AAL2-G726-16", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
16000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
124, /* the IANA code number */
"AAL2-G726-16", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
16000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
}
SWITCH_ADD_CODEC(codec_interface, "G.726 16k");
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
124, /* the IANA code number */
"G726-16", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
16000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
124, /* the IANA code number */
"G726-16", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
16000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
}
/* Increase encoded bytes per frame by 10 */
ebpf = ebpf + 10;
SWITCH_ADD_CODEC(codec_interface, "G.726 24k (AAL2)");
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
123, /* the IANA code number */
"AAL2-G726-24", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
24000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
123, /* the IANA code number */
"AAL2-G726-24", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
24000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
}
SWITCH_ADD_CODEC(codec_interface, "G.726 24k");
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
123, /* the IANA code number */
"G726-24", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
24000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
123, /* the IANA code number */
"G726-24", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
24000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
}
/* Increase encoded bytes per frame by 10 */
ebpf = ebpf + 10;
SWITCH_ADD_CODEC(codec_interface, "G.726 32k (AAL2)");
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
122, /* the IANA code number */
"AAL2-G726-32", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
32000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
122, /* the IANA code number */
"AAL2-G726-32", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
32000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
}
SWITCH_ADD_CODEC(codec_interface, "G.726 32k");
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
122, /* the IANA code number */
"G726-32", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
32000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
122, /* the IANA code number */
"G726-32", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
32000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
}
/* Increase encoded bytes per frame by 10 */
ebpf = ebpf + 10;
SWITCH_ADD_CODEC(codec_interface, "G.726 40k (AAL2)");
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
121, /* the IANA code number */
"AAL2-G726-40", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
40000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
121, /* the IANA code number */
"AAL2-G726-40", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
40000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
}
SWITCH_ADD_CODEC(codec_interface, "G.726 40k");
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
121, /* the IANA code number */
"G726-40", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
40000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
121, /* the IANA code number */
"G726-40", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
40000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count * 10, /* number of frames per network packet */
switch_g726_init, /* function to initialize a codec handle using this implementation */
switch_g726_encode, /* function to encode raw data into encoded data */
switch_g726_decode, /* function to decode encoded data into raw data */
switch_g726_destroy); /* deinitalize a codec handle using this implementation */
}
/* G722 */
mpf = 10000, spf = 80, bpf = 320, ebpf = 80;
SWITCH_ADD_CODEC(codec_interface, "G.722");
for (count = 6; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
9, /* the IANA code number */
"G722", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
16000, /* actual samples transferred per second */
64000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
spf * count, /* number of frames per network packet */
switch_g722_init, /* function to initialize a codec handle using this implementation */
switch_g722_encode, /* function to encode raw data into encoded data */
switch_g722_decode, /* function to decode encoded data into raw data */
switch_g722_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
9, /* the IANA code number */
"G722", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
16000, /* actual samples transferred per second */
64000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
spf * count, /* number of frames per network packet */
switch_g722_init, /* function to initialize a codec handle using this implementation */
switch_g722_encode, /* function to encode raw data into encoded data */
switch_g722_decode, /* function to decode encoded data into raw data */
switch_g722_destroy); /* deinitalize a codec handle using this implementation */
}
#ifdef ENABLE_G711
@ -881,48 +869,44 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_voipcodecs_load)
mpf = 10000, spf = 80, bpf = 160, ebpf = 80;
SWITCH_ADD_CODEC(codec_interface, "G.711 ulaw");
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
0, /* the IANA code number */
"PCMU", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
64000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
spf * count, /* number of frames per network packet */
switch_g711u_init, /* function to initialize a codec handle using this implementation */
switch_g711u_encode, /* function to encode raw data into encoded data */
switch_g711u_decode, /* function to decode encoded data into raw data */
switch_g711u_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
0, /* the IANA code number */
"PCMU", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
64000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
spf * count, /* number of frames per network packet */
switch_g711u_init, /* function to initialize a codec handle using this implementation */
switch_g711u_encode, /* function to encode raw data into encoded data */
switch_g711u_decode, /* function to decode encoded data into raw data */
switch_g711u_destroy); /* deinitalize a codec handle using this implementation */
}
SWITCH_ADD_CODEC(codec_interface, "G.711 alaw");
for (count = 12; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
8, /* the IANA code number */
"PCMA", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
64000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
spf * count, /* number of frames per network packet */
switch_g711a_init, /* function to initialize a codec handle using this implementation */
switch_g711a_encode, /* function to encode raw data into encoded data */
switch_g711a_decode, /* function to decode encoded data into raw data */
switch_g711a_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
8, /* the IANA code number */
"PCMA", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
64000, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
spf * count, /* number of frames per network packet */
switch_g711a_init, /* function to initialize a codec handle using this implementation */
switch_g711a_encode, /* function to encode raw data into encoded data */
switch_g711a_decode, /* function to decode encoded data into raw data */
switch_g711a_destroy); /* deinitalize a codec handle using this implementation */
}
#endif
@ -930,47 +914,44 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_voipcodecs_load)
mpf = 20000, spf = 160, bpf = 320, ebpf = 33;
SWITCH_ADD_CODEC(codec_interface, "GSM");
for (count = 6; count > 0; count--) {
switch_core_codec_add_implementation(pool,
codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
3, /* the IANA code number */
"GSM", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
13200, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count, /* number of frames per network packet */
switch_gsm_init, /* function to initialize a codec handle using this implementation */
switch_gsm_encode, /* function to encode raw data into encoded data */
switch_gsm_decode, /* function to decode encoded data into raw data */
switch_gsm_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
3, /* the IANA code number */
"GSM", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
13200, /* bits transferred per second */
mpf * count, /* number of microseconds per frame */
spf * count, /* number of samples per frame */
bpf * count, /* number of bytes per frame decompressed */
ebpf * count, /* number of bytes per frame compressed */
1, /* number of channels represented */
count, /* number of frames per network packet */
switch_gsm_init, /* function to initialize a codec handle using this implementation */
switch_gsm_encode, /* function to encode raw data into encoded data */
switch_gsm_decode, /* function to decode encoded data into raw data */
switch_gsm_destroy); /* deinitalize a codec handle using this implementation */
}
/* LPC10 */
#if SWITCH_MAX_INTERVAL >= 90
SWITCH_ADD_CODEC(codec_interface, "LPC-10");
switch_core_codec_add_implementation(pool, codec_interface,
SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
7, /* the IANA code number */
"LPC", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
2400, /* bits transferred per second */
90000, /* number of microseconds per frame */
720, /* number of samples per frame */
1440, /* number of bytes per frame decompressed */
28, /* number of bytes per frame compressed */
1, /* number of channels represented */
4, /* number of frames per network packet */
switch_lpc10_init, /* function to initialize a codec handle using this implementation */
switch_lpc10_encode, /* function to encode raw data into encoded data */
switch_lpc10_decode, /* function to decode encoded data into raw data */
switch_lpc10_destroy); /* deinitalize a codec handle using this implementation */
switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
7, /* the IANA code number */
"LPC", /* the IANA code name */
NULL, /* default fmtp to send (can be overridden by the init function) */
8000, /* samples transferred per second */
8000, /* actual samples transferred per second */
2400, /* bits transferred per second */
90000, /* number of microseconds per frame */
720, /* number of samples per frame */
1440, /* number of bytes per frame decompressed */
28, /* number of bytes per frame compressed */
1, /* number of channels represented */
4, /* number of frames per network packet */
switch_lpc10_init, /* function to initialize a codec handle using this implementation */
switch_lpc10_encode, /* function to encode raw data into encoded data */
switch_lpc10_decode, /* function to decode encoded data into raw data */
switch_lpc10_destroy); /* deinitalize a codec handle using this implementation */
#endif
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -297,14 +297,16 @@ SWITCH_STANDARD_DIALPLAN(asterisk_dialplan_hunt)
switch_endpoint_interface_t *sip_endpoint_interface;
static switch_call_cause_t sip_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause);
switch_io_routines_t sip_io_routines = {
/*.outgoing_channel */ sip_outgoing_channel
};
static switch_call_cause_t sip_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause)
{
const char *profile;
@ -331,14 +333,16 @@ static switch_call_cause_t sip_outgoing_channel(switch_core_session_t *session,
switch_endpoint_interface_t *iax2_endpoint_interface;
static switch_call_cause_t iax2_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause);
switch_io_routines_t iax2_io_routines = {
/*.outgoing_channel */ iax2_outgoing_channel
};
static switch_call_cause_t iax2_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause)
{
UNPROTECT_INTERFACE(iax2_endpoint_interface);

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -150,7 +150,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_dialplan_directory_shutdown)
switch_safe_free(globals.dn);
switch_safe_free(globals.pass);
switch_safe_free(globals.base);
return SWITCH_STATUS_SUCCESS;
}
@ -161,7 +161,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dialplan_directory_load)
memset(&globals, 0, sizeof(globals));
load_config();
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_DIALPLAN(dp_interface, "directory", directory_dialplan_hunt);

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -72,10 +72,10 @@ static switch_status_t exec_app(switch_core_session_t *session, const char *app,
switch_core_session_exec(session, application_interface, arg);
done:
done:
UNPROTECT_INTERFACE(application_interface);
return status;
}
@ -100,7 +100,7 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
int ovector[30];
switch_bool_t anti_action = SWITCH_TRUE;
break_t do_break_i = BREAK_ON_FALSE;
const char *xyear = switch_xml_attr(xcond, "year");
const char *xyday = switch_xml_attr(xcond, "yday");
const char *xmon = switch_xml_attr(xcond, "mon");
@ -125,7 +125,7 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
}
switch_time_exp_lt(&tm, ts);
if (time_match && xyear) {
int test = tm.tm_year + 1900;
time_match = switch_number_cmp(xyear, test);
@ -164,7 +164,7 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
if (time_match && xmweek) {
/* calculate the day of the week of the first of the month (0-6) */
int firstdow = (int) (7 - (tm.tm_mday - (tm.tm_wday + 1)) % 7) % 7;
/* calculate the week of the month (1-6)*/
/* calculate the week of the month (1-6) */
int test = (int) ceil((tm.tm_mday + firstdow) / 7.0);
time_match = switch_number_cmp(xmweek, test);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
@ -198,7 +198,7 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: minute of day[%d] =~ %s (%s)\n", test, xminday, time_match ? "PASS" : "FAIL");
}
field = (char *) switch_xml_attr(xcond, "field");
if ((xexpression = switch_xml_child(xcond, "expression"))) {
@ -229,13 +229,13 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
if (time_match == 1) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s Date/Time Match (PASS) [%s] break=%s\n",
switch_channel_get_name(channel), exten_name, do_break_a ? do_break_a : "on-false");
"Dialplan: %s Date/Time Match (PASS) [%s] break=%s\n",
switch_channel_get_name(channel), exten_name, do_break_a ? do_break_a : "on-false");
anti_action = SWITCH_FALSE;
} else if (time_match == 0) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s Date/Time Match (FAIL) [%s] break=%s\n",
switch_channel_get_name(channel), exten_name, do_break_a ? do_break_a : "on-false");
"Dialplan: %s Date/Time Match (FAIL) [%s] break=%s\n",
switch_channel_get_name(channel), exten_name, do_break_a ? do_break_a : "on-false");
}
if (field) {
@ -252,21 +252,20 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
if (!field_data) {
field_data = "";
}
if ((proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ break=%s\n",
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ break=%s\n",
switch_channel_get_name(channel), exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false");
anti_action = SWITCH_FALSE;
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s Regex (FAIL) [%s] %s(%s) =~ /%s/ break=%s\n",
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s Regex (FAIL) [%s] %s(%s) =~ /%s/ break=%s\n",
switch_channel_get_name(channel), exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false");
}
} else if (time_match == -1) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s Absolute Condition [%s]\n",
switch_channel_get_name(channel), exten_name);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s Absolute Condition [%s]\n", switch_channel_get_name(channel), exten_name);
anti_action = SWITCH_FALSE;
}
@ -275,7 +274,7 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
const char *application = switch_xml_attr_soft(xaction, "application");
const char *data;
const char *inline_ = switch_xml_attr_soft(xaction, "inline");
int xinline = switch_true(inline_);
int xinline = switch_true(inline_);
if (!zstr(xaction->txt)) {
data = xaction->txt;
@ -284,8 +283,7 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s ANTI-Action %s(%s) %s\n",
switch_channel_get_name(channel), application, data, xinline ? "INLINE" : "");
"Dialplan: %s ANTI-Action %s(%s) %s\n", switch_channel_get_name(channel), application, data, xinline ? "INLINE" : "");
if (!*extension) {
if ((*extension = switch_caller_extension_new(session, exten_name, caller_profile->destination_number)) == 0) {
@ -340,9 +338,8 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
}
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s Action %s(%s) %s\n",
switch_channel_get_name(channel), application, app_data, xinline ? "INLINE" : "");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s Action %s(%s) %s\n", switch_channel_get_name(channel), application, app_data, xinline ? "INLINE" : "");
if (xinline) {
@ -356,9 +353,8 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
}
switch_regex_safe_free(re);
if (((anti_action == SWITCH_FALSE && do_break_i == BREAK_ON_TRUE) ||
(anti_action == SWITCH_TRUE && do_break_i == BREAK_ON_FALSE)) ||
do_break_i == BREAK_ALWAYS) {
if (((anti_action == SWITCH_FALSE && do_break_i == BREAK_ON_TRUE) ||
(anti_action == SWITCH_TRUE && do_break_i == BREAK_ON_FALSE)) || do_break_i == BREAK_ALWAYS) {
break;
}
}
@ -370,7 +366,8 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
return proceed;
}
static switch_status_t dialplan_xml_locate(switch_core_session_t *session, switch_caller_profile_t *caller_profile, switch_xml_t *root, switch_xml_t *node)
static switch_status_t dialplan_xml_locate(switch_core_session_t *session, switch_caller_profile_t *caller_profile, switch_xml_t *root,
switch_xml_t *node)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_status_t status = SWITCH_STATUS_GENERR;
@ -457,8 +454,8 @@ SWITCH_STANDARD_DIALPLAN(dialplan_hunt)
exten_name = "UNKNOWN";
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s parsing [%s->%s] continue=%s\n",
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
"Dialplan: %s parsing [%s->%s] continue=%s\n",
switch_channel_get_name(channel), caller_profile->context, exten_name, cont ? cont : "false");
proceed = parse_exten(session, caller_profile, xexten, &extension);

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -151,7 +151,8 @@ static switch_status_t channel_on_exchange_media(switch_core_session_t *session)
static switch_status_t channel_on_soft_execute(switch_core_session_t *session);
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause);
static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
@ -730,12 +731,12 @@ static switch_state_handler_table_t channel_event_handlers = {
/*.on_hangup */ channel_on_hangup,
/*.on_exchange_media */ channel_on_exchange_media,
/*.on_soft_execute */ channel_on_soft_execute,
/*.on_consume_media*/ NULL,
/*.on_hibernate*/ NULL,
/*.on_reset*/ NULL,
/*.on_park*/ NULL,
/*.on_reporting*/ NULL,
/*.on_destroy*/ channel_on_destroy
/*.on_consume_media */ NULL,
/*.on_hibernate */ NULL,
/*.on_reset */ NULL,
/*.on_park */ NULL,
/*.on_reporting */ NULL,
/*.on_destroy */ channel_on_destroy
};
static switch_io_routines_t channel_io_routines = {
@ -761,7 +762,8 @@ static switch_endpoint_interface_t channel_endpoint_interface = {
*/
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause)
{
if ((*new_session = switch_core_session_request(&channel_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, pool)) != 0) {
@ -799,7 +801,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
}
switch_channel_set_flag(channel, CF_OUTBOUND);
switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND);
switch_channel_set_state(channel, CS_INIT);
return SWITCH_CAUSE_SUCCESS;
@ -824,7 +825,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_alsa_load)
alsa_endpoint_interface->state_handler = &channel_event_handlers;
SWITCH_ADD_API(api_interface, "alsa", "Alsa", pa_cmd, "<command> [<args>]");
if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
@ -954,7 +955,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_alsa_shutdown)
switch_core_codec_destroy(&globals.write_codec);
}
switch_core_hash_destroy(&globals.call_hash);
switch_safe_free(globals.dialplan);
switch_safe_free(globals.cid_name);
switch_safe_free(globals.cid_num);
@ -1013,7 +1014,8 @@ static switch_status_t engage_device(unsigned int sample_rate, int codec_ms)
}
if (switch_core_timer_init(&globals.timer,
globals.timer_name, codec_ms, globals.read_codec.implementation->samples_per_packet, module_pool) != SWITCH_STATUS_SUCCESS) {
globals.timer_name, codec_ms, globals.read_codec.implementation->samples_per_packet,
module_pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup timer failed!\n");
switch_core_codec_destroy(&globals.read_codec);
switch_core_codec_destroy(&globals.write_codec);

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -206,7 +206,8 @@ static switch_status_t channel_on_exchange_media(switch_core_session_t *session)
static switch_status_t channel_on_soft_execute(switch_core_session_t *session);
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause);
static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
@ -459,7 +460,8 @@ static void pres_event_handler(switch_event_t *event)
}
sql =
switch_mprintf("select sub_from, sub_to,'%q','%q','%q','%q' from jabber_subscriptions where sub_to = '%q%q'", type, rpid, status, proto, pstr, from);
switch_mprintf("select sub_from, sub_to,'%q','%q','%q','%q' from jabber_subscriptions where sub_to = '%q%q'", type, rpid, status, proto, pstr,
from);
for (hi = switch_hash_first(NULL, globals.profile_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, NULL, NULL, &val);
@ -485,7 +487,7 @@ static void pres_event_handler(switch_event_t *event)
}
static switch_status_t chat_send(const char *proto, const char *from, const char *to, const char *subject,
const char *body, const char *type, const char *hint)
const char *body, const char *type, const char *hint)
{
char *user, *host, *f_user = NULL, *ffrom = NULL, *f_host = NULL, *f_resource = NULL;
mdl_profile_t *profile = NULL;
@ -518,7 +520,7 @@ static switch_status_t chat_send(const char *proto, const char *from, const char
*p = '\0';
}
}
ldl_handle_send_msg(profile->handle, (char*)from, (char*)to, NULL, switch_str_nil(body));
ldl_handle_send_msg(profile->handle, (char *) from, (char *) to, NULL, switch_str_nil(body));
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile %s\n", f_host ? f_host : "NULL");
return SWITCH_STATUS_FALSE;
@ -699,7 +701,8 @@ static void terminate_session(switch_core_session_t **session, int line, switch_
switch_channel_state_t state = switch_channel_get_state(channel);
struct private_object *tech_pvt = NULL;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*session), SWITCH_LOG_DEBUG, "Terminate called from line %d state=%s\n", line, switch_channel_state_name(state));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*session), SWITCH_LOG_DEBUG, "Terminate called from line %d state=%s\n", line,
switch_channel_state_name(state));
tech_pvt = switch_core_session_get_private(*session);
@ -874,10 +877,9 @@ static int activate_rtp(struct private_object *tech_pvt)
switch_core_session_set_read_codec(tech_pvt->session, &tech_pvt->read_codec);
switch_core_session_set_write_codec(tech_pvt->session, &tech_pvt->write_codec);
if (globals.auto_nat && tech_pvt->profile->local_network &&
!switch_check_network_list_ip(tech_pvt->remote_ip, tech_pvt->profile->local_network)) {
if (globals.auto_nat && tech_pvt->profile->local_network && !switch_check_network_list_ip(tech_pvt->remote_ip, tech_pvt->profile->local_network)) {
switch_port_t external_port = 0;
switch_nat_add_mapping((switch_port_t)tech_pvt->local_port, SWITCH_NAT_UDP, &external_port, SWITCH_FALSE);
switch_nat_add_mapping((switch_port_t) tech_pvt->local_port, SWITCH_NAT_UDP, &external_port, SWITCH_FALSE);
tech_pvt->local_port = external_port;
}
@ -885,7 +887,7 @@ static int activate_rtp(struct private_object *tech_pvt)
tech_pvt->local_port, tech_pvt->remote_ip, tech_pvt->remote_port);
flags = SWITCH_RTP_FLAG_DATAWAIT | SWITCH_RTP_FLAG_GOOGLEHACK | SWITCH_RTP_FLAG_AUTOADJ | SWITCH_RTP_FLAG_RAW_WRITE | SWITCH_RTP_FLAG_AUTO_CNG;
if (switch_test_flag(tech_pvt->profile, TFLAG_TIMER)) {
flags |= SWITCH_RTP_FLAG_USE_TIMER;
@ -973,11 +975,13 @@ static int do_candidates(struct private_object *tech_pvt, int force)
}
cand[0].address = tech_pvt->profile->ip;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Stun Lookup Local %s:%d\n", cand[0].address, cand[0].port);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Stun Lookup Local %s:%d\n", cand[0].address,
cand[0].port);
if (switch_stun_lookup
(&cand[0].address, &cand[0].port, stun_ip, SWITCH_STUN_DEFAULT_PORT, &err,
switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "Stun Failed! %s:%d [%s]\n", stun_ip, SWITCH_STUN_DEFAULT_PORT, err);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "Stun Failed! %s:%d [%s]\n", stun_ip,
SWITCH_STUN_DEFAULT_PORT, err);
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
return 0;
}
@ -995,7 +999,8 @@ static int do_candidates(struct private_object *tech_pvt, int force)
cand[0].password = tech_pvt->local_pass;
cand[0].pref = 1;
cand[0].protocol = "udp";
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Send Candidate %s:%d [%s]\n", cand[0].address, cand[0].port, cand[0].username);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Send Candidate %s:%d [%s]\n", cand[0].address, cand[0].port,
cand[0].username);
tech_pvt->cand_id = ldl_session_candidates(tech_pvt->dlsession, cand, 1);
switch_set_flag_locked(tech_pvt, TFLAG_TRANSPORT);
switch_set_flag_locked(tech_pvt, TFLAG_RTP_READY);
@ -1232,9 +1237,8 @@ static switch_status_t channel_on_destroy(switch_core_session_t *session)
tech_pvt->rtp_session = NULL;
}
if (globals.auto_nat && tech_pvt->profile->local_network &&
!switch_check_network_list_ip(tech_pvt->remote_ip, tech_pvt->profile->local_network)) {
switch_nat_del_mapping((switch_port_t)tech_pvt->local_port, SWITCH_NAT_UDP);
if (globals.auto_nat && tech_pvt->profile->local_network && !switch_check_network_list_ip(tech_pvt->remote_ip, tech_pvt->profile->local_network)) {
switch_nat_del_mapping((switch_port_t) tech_pvt->local_port, SWITCH_NAT_UDP);
}
if (switch_core_codec_ready(&tech_pvt->read_codec)) {
@ -1593,12 +1597,12 @@ switch_state_handler_table_t dingaling_event_handlers = {
/*.on_hangup */ channel_on_hangup,
/*.on_exchange_media */ channel_on_exchange_media,
/*.on_soft_execute */ channel_on_soft_execute,
/*.on_consume_media*/ NULL,
/*.on_hibernate*/ NULL,
/*.on_reset*/ NULL,
/*.on_park*/ NULL,
/*.on_reporting*/ NULL,
/*.on_destroy*/ channel_on_destroy
/*.on_consume_media */ NULL,
/*.on_hibernate */ NULL,
/*.on_reset */ NULL,
/*.on_park */ NULL,
/*.on_reporting */ NULL,
/*.on_destroy */ channel_on_destroy
};
switch_io_routines_t dingaling_io_routines = {
@ -1618,7 +1622,8 @@ switch_io_routines_t dingaling_io_routines = {
*/
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause)
{
if ((*new_session = switch_core_session_request(dingaling_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, pool)) != 0) {
struct private_object *tech_pvt;
@ -1686,7 +1691,8 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
}
if (mdl_profile->purge) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile '%s' is marked for deletion, disallowing outgoing call\n", mdl_profile->name);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile '%s' is marked for deletion, disallowing outgoing call\n",
mdl_profile->name);
terminate_session(new_session, __LINE__, SWITCH_CAUSE_NORMAL_UNSPECIFIED);
return SWITCH_CAUSE_NORMAL_UNSPECIFIED;
}
@ -1754,7 +1760,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
}
switch_channel_set_flag(channel, CF_OUTBOUND);
switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND);
switch_stun_random_string(sess_id, 10, "0123456789");
@ -1811,7 +1816,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dingaling_load)
switch_api_interface_t *api_interface;
module_pool = pool;
memset(&globals, 0, sizeof(globals));
load_config();
@ -1831,17 +1836,20 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dingaling_load)
return SWITCH_STATUS_GENERR;
}
if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_IN, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL, &globals.in_node) != SWITCH_STATUS_SUCCESS) {
if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_IN, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL, &globals.in_node) !=
SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
return SWITCH_STATUS_GENERR;
}
if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_PROBE, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL, &globals.probe_node) != SWITCH_STATUS_SUCCESS) {
if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_PROBE, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL, &globals.probe_node) !=
SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
return SWITCH_STATUS_GENERR;
}
if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_OUT, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL, &globals.out_node) != SWITCH_STATUS_SUCCESS) {
if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_OUT, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL, &globals.out_node) !=
SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
return SWITCH_STATUS_GENERR;
}
@ -1857,7 +1865,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dingaling_load)
return SWITCH_STATUS_GENERR;
}
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
dingaling_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
@ -1903,13 +1911,10 @@ static switch_status_t init_profile(mdl_profile_t *profile, uint8_t login)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"Invalid Profile\n" "login[%s]\n" "pass[%s]\n" "dialplan[%s]\n"
"message[%s]\n" "rtp-ip[%s]\n" "name[%s]\n" "exten[%s]\n",
switch_str_nil(profile->login),
switch_str_nil(profile->password),
switch_str_nil(profile->dialplan),
switch_str_nil(profile->message),
switch_str_nil(profile->ip),
switch_str_nil(profile->name),
switch_str_nil(profile->exten));
switch_str_nil(profile->login),
switch_str_nil(profile->password),
switch_str_nil(profile->dialplan),
switch_str_nil(profile->message), switch_str_nil(profile->ip), switch_str_nil(profile->name), switch_str_nil(profile->exten));
return SWITCH_STATUS_FALSE;
}
@ -1976,8 +1981,8 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_dingaling_shutdown)
switch_safe_free(globals.dialplan);
switch_safe_free(globals.codec_string);
switch_safe_free(globals.codec_rates_string);
switch_safe_free(globals.codec_rates_string);
return SWITCH_STATUS_SUCCESS;
}
@ -2160,7 +2165,8 @@ SWITCH_STANDARD_API(dingaling)
switch_hash_index_t *hi;
switch_status_t status = SWITCH_STATUS_SUCCESS;
if (session) return status;
if (session)
return status;
if (zstr(cmd) || !(myarg = strdup(cmd))) {
stream->write_function(stream, "USAGE: %s\n", DINGALING_SYNTAX);
@ -2179,9 +2185,9 @@ SWITCH_STANDARD_API(dingaling)
switch_hash_this(hi, NULL, NULL, &val);
profile = (mdl_profile_t *) val;
stream->write_function(stream, "%s | ", profile->login);
if (profile->handle && ldl_handle_authorized(profile->handle)){
if (profile->handle && ldl_handle_authorized(profile->handle)) {
stream->write_function(stream, "AUTHORIZED");
} else if (profile->handle && ldl_handle_connected(profile->handle)){
} else if (profile->handle && ldl_handle_connected(profile->handle)) {
stream->write_function(stream, "CONNECTED");
} else {
stream->write_function(stream, "UNCONNECTED");
@ -2195,7 +2201,7 @@ SWITCH_STANDARD_API(dingaling)
stream->write_function(stream, "USAGE: %s\n", DINGALING_SYNTAX);
}
done:
done:
switch_safe_free(myarg);
return status;
}
@ -2261,7 +2267,7 @@ SWITCH_STANDARD_API(dl_login)
} else {
stream->write_function(stream, "FAIL\n");
}
done:
done:
switch_safe_free(myarg);
return status;
@ -2274,56 +2280,53 @@ static switch_bool_t match_profile(mdl_profile_t *profile, mdl_profile_t *new_pr
return SWITCH_TRUE;
}
if (
((!new_profile->name && !profile->name) ||
(new_profile->name && profile->name && !strcasecmp(new_profile->name, profile->name))) &&
((!new_profile->login && !profile->login) ||
(new_profile->login && profile->login && !strcasecmp(new_profile->login, profile->login))) &&
((!new_profile->password && !profile->password) ||
(new_profile->password && profile->password && !strcasecmp(new_profile->password, profile->password))) &&
((!new_profile->message && !profile->message) ||
(new_profile->message && profile->message && !strcasecmp(new_profile->message, profile->message))) &&
((!new_profile->avatar && !profile->avatar) ||
(new_profile->avatar && profile->avatar && !strcasecmp(new_profile->avatar, profile->avatar))) &&
if (((!new_profile->name && !profile->name) ||
(new_profile->name && profile->name && !strcasecmp(new_profile->name, profile->name))) &&
((!new_profile->login && !profile->login) ||
(new_profile->login && profile->login && !strcasecmp(new_profile->login, profile->login))) &&
((!new_profile->password && !profile->password) ||
(new_profile->password && profile->password && !strcasecmp(new_profile->password, profile->password))) &&
((!new_profile->message && !profile->message) ||
(new_profile->message && profile->message && !strcasecmp(new_profile->message, profile->message))) &&
((!new_profile->avatar && !profile->avatar) || (new_profile->avatar && profile->avatar && !strcasecmp(new_profile->avatar, profile->avatar))) &&
#ifdef AUTO_REPLY
((!new_profile->auto_reply && !profile->auto_reply) ||
(new_profile->auto_reply && profile->auto_reply && !strcasecmp(new_profile->auto_reply, profile->auto_reply))) &&
((!new_profile->auto_reply && !profile->auto_reply) ||
(new_profile->auto_reply && profile->auto_reply && !strcasecmp(new_profile->auto_reply, profile->auto_reply))) &&
#endif
((!new_profile->dialplan && !profile->dialplan) ||
(new_profile->dialplan && profile->dialplan && !strcasecmp(new_profile->dialplan, profile->dialplan))) &&
((!new_profile->local_network && !profile->local_network) ||
(new_profile->local_network && profile->local_network && !strcasecmp(new_profile->local_network, profile->local_network))) &&
((!new_profile->ip && !profile->ip) ||
(new_profile->ip && profile->ip && !strcasecmp(new_profile->ip, profile->ip))) &&
((!new_profile->extip && !profile->extip) ||
(new_profile->extip && profile->extip && !strcasecmp(new_profile->extip, profile->extip))) &&
((!new_profile->server && !profile->server) ||
(new_profile->server && profile->server && !strcasecmp(new_profile->server, profile->server))) &&
((!new_profile->timer_name && !profile->timer_name) ||
(new_profile->timer_name && profile->timer_name && !strcasecmp(new_profile->timer_name, profile->timer_name))) &&
((!new_profile->lanaddr && !profile->lanaddr) ||
(new_profile->lanaddr && profile->lanaddr && !strcasecmp(new_profile->lanaddr, profile->lanaddr))) &&
((!new_profile->exten && !profile->exten) ||
(new_profile->exten && profile->exten && !strcasecmp(new_profile->exten, profile->exten))) &&
((!new_profile->context && !profile->context) ||
(new_profile->context && profile->context && !strcasecmp(new_profile->context, profile->context))) &&
(new_profile->user_flags == profile->user_flags) && (new_profile->acl_count == profile->acl_count)
) {
((!new_profile->dialplan && !profile->dialplan) ||
(new_profile->dialplan && profile->dialplan && !strcasecmp(new_profile->dialplan, profile->dialplan))) &&
((!new_profile->local_network && !profile->local_network) ||
(new_profile->local_network && profile->local_network && !strcasecmp(new_profile->local_network, profile->local_network))) &&
((!new_profile->ip && !profile->ip) ||
(new_profile->ip && profile->ip && !strcasecmp(new_profile->ip, profile->ip))) &&
((!new_profile->extip && !profile->extip) ||
(new_profile->extip && profile->extip && !strcasecmp(new_profile->extip, profile->extip))) &&
((!new_profile->server && !profile->server) ||
(new_profile->server && profile->server && !strcasecmp(new_profile->server, profile->server))) &&
((!new_profile->timer_name && !profile->timer_name) ||
(new_profile->timer_name && profile->timer_name && !strcasecmp(new_profile->timer_name, profile->timer_name))) &&
((!new_profile->lanaddr && !profile->lanaddr) ||
(new_profile->lanaddr && profile->lanaddr && !strcasecmp(new_profile->lanaddr, profile->lanaddr))) &&
((!new_profile->exten && !profile->exten) ||
(new_profile->exten && profile->exten && !strcasecmp(new_profile->exten, profile->exten))) &&
((!new_profile->context && !profile->context) ||
(new_profile->context && profile->context && !strcasecmp(new_profile->context, profile->context))) &&
(new_profile->user_flags == profile->user_flags) && (new_profile->acl_count == profile->acl_count)
) {
uint32_t i;
if (switch_odbc_available()) {
if (!(
((!new_profile->odbc_dsn && !profile->odbc_dsn) ||
(new_profile->odbc_dsn && profile->odbc_dsn && !strcasecmp(new_profile->odbc_dsn, profile->odbc_dsn))) &&
((!new_profile->odbc_user && !profile->odbc_user) ||
(new_profile->odbc_user && profile->odbc_user && !strcasecmp(new_profile->odbc_user, profile->odbc_user))) &&
((!new_profile->odbc_pass && !profile->odbc_pass) ||
(new_profile->odbc_pass && profile->odbc_pass && !strcasecmp(new_profile->odbc_pass, profile->odbc_pass)))
)) {
if (!(((!new_profile->odbc_dsn && !profile->odbc_dsn) ||
(new_profile->odbc_dsn && profile->odbc_dsn && !strcasecmp(new_profile->odbc_dsn, profile->odbc_dsn))) &&
((!new_profile->odbc_user && !profile->odbc_user) ||
(new_profile->odbc_user && profile->odbc_user && !strcasecmp(new_profile->odbc_user, profile->odbc_user))) &&
((!new_profile->odbc_pass && !profile->odbc_pass) ||
(new_profile->odbc_pass && profile->odbc_pass && !strcasecmp(new_profile->odbc_pass, profile->odbc_pass)))
)) {
return SWITCH_FALSE;
}
}
for(i=0; i<new_profile->acl_count; i++) {
for (i = 0; i < new_profile->acl_count; i++) {
if (strcasecmp(new_profile->acl[i], profile->acl[i]) != 0) {
return SWITCH_FALSE;
}
@ -2333,7 +2336,7 @@ static switch_bool_t match_profile(mdl_profile_t *profile, mdl_profile_t *new_pr
return SWITCH_TRUE;
}
static switch_status_t destroy_profile(char *name)
static switch_status_t destroy_profile(char *name)
{
mdl_profile_t *profile = NULL;
@ -2374,7 +2377,7 @@ static switch_status_t soft_reload(void)
{
char *cf = "dingaling.conf";
mdl_profile_t *profile = NULL, *old_profile = NULL;
switch_xml_t cfg, xml, /*settings,*/ param, xmlint;
switch_xml_t cfg, xml, /*settings, */ param, xmlint;
void *data = NULL;
switch_hash_t *name_hash;
@ -2398,7 +2401,7 @@ static switch_status_t soft_reload(void)
char *var = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value");
if (!profile) {
if (!profile) {
profile = switch_core_alloc(module_pool, sizeof(*profile));
}
@ -2481,7 +2484,7 @@ static switch_status_t soft_reload(void)
for (hi = switch_hash_first(NULL, name_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, NULL, NULL, &data);
if ((profile = switch_core_hash_find(globals.profile_hash, (char*)data))) {
if ((profile = switch_core_hash_find(globals.profile_hash, (char *) data))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Deleting unused profile %s [%s]\n", profile->name, profile->login);
destroy_profile(profile->name);
}
@ -2695,7 +2698,8 @@ static void do_vcard(ldl_handle_t *handle, char *to, char *from, char *id)
switch_safe_free(xmlstr);
}
static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsession, ldl_signal_t dl_signal, char *to, char *from, char *subject, char *msg)
static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsession, ldl_signal_t dl_signal, char *to, char *from, char *subject,
char *msg)
{
mdl_profile_t *profile = NULL;
switch_core_session_t *session = NULL;
@ -2730,7 +2734,8 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
case LDL_SIGNAL_SUBSCRIBE:
if (profile->user_flags & LDL_FLAG_COMPONENT && ldl_jid_domcmp(from, to)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Attempt to add presence from/to our own domain [%s][%s]\n", from, to);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Attempt to add presence from/to our own domain [%s][%s]\n",
from, to);
} else {
switch_mutex_lock(profile->mutex);
if ((sql = switch_mprintf("delete from jabber_subscriptions where sub_from='%q' and sub_to='%q'", from, to))) {
@ -2839,9 +2844,9 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
switch (dl_signal) {
case LDL_SIGNAL_MSG:{
char *proto = MDL_CHAT_PROTO;
char *pproto = NULL, *ffrom = NULL;
char *hint;
char *proto = MDL_CHAT_PROTO;
char *pproto = NULL, *ffrom = NULL;
char *hint;
#ifdef AUTO_REPLY
if (profile->auto_reply) {
ldl_handle_send_msg(handle,
@ -2867,8 +2872,8 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
}
from = ffrom;
}
if (strcasecmp(proto, MDL_CHAT_PROTO)) { /* yes no ! on purpose */
if (strcasecmp(proto, MDL_CHAT_PROTO)) { /* yes no ! on purpose */
switch_core_chat_send(proto, MDL_CHAT_PROTO, from, to, subject, switch_str_nil(msg), NULL, hint);
}
@ -2920,7 +2925,7 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
status = LDL_STATUS_FALSE;
goto done;
}
} else {
if (dl_signal != LDL_SIGNAL_INITIATE && !msg) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Session is already dead\n");
@ -3156,7 +3161,8 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
unsigned int x, y;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%u payloads\n", len);
for (x = 0; x < len; x++) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Available Payload %s %u\n", payloads[x].name, payloads[x].id);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Available Payload %s %u\n", payloads[x].name,
payloads[x].id);
for (y = 0; y < tech_pvt->num_codecs; y++) {
char *name = tech_pvt->codecs[y]->iananame;
@ -3174,8 +3180,8 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
if (match && payloads[x].rate == tech_pvt->codecs[y]->samples_per_second) {
tech_pvt->codec_index = y;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Choosing Payload index %u %s %u\n", y, payloads[x].name,
payloads[x].id);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Choosing Payload index %u %s %u\n", y,
payloads[x].name, payloads[x].id);
tech_pvt->codec_name = tech_pvt->codecs[y]->iananame;
tech_pvt->codec_num = tech_pvt->codecs[y]->ianacode;
tech_pvt->r_codec_num = (switch_payload_t) (payloads[x].id);
@ -3252,7 +3258,8 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
lanaddr = strncasecmp(candidates[x].address, profile->lanaddr, strlen(profile->lanaddr)) ? 0 : 1;
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "candidates %s:%d\n", candidates[x].address, candidates[x].port);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "candidates %s:%d\n", candidates[x].address,
candidates[x].port);
// 192.0.0.0 - 192.0.127.255 is marked as reserved, should we filter all of them?
if (!strcasecmp(candidates[x].protocol, "udp") &&

View File

@ -54,10 +54,10 @@ typedef enum {
} TFLAGS;
struct mod_h323_globals {
int trace_level;
char *codec_string;
char *context;
char *dialplan;
int trace_level;
char *codec_string;
char *context;
char *dialplan;
};
extern struct mod_h323_globals mod_h323_globals;
@ -67,19 +67,19 @@ class FSH323_ExternalRTPChannel;
typedef struct {
unsigned int flags;
switch_timer_t read_timer;
switch_codec_t read_codec;
switch_codec_t write_codec;
switch_timer_t read_timer;
switch_codec_t read_codec;
switch_codec_t write_codec;
switch_frame_t read_frame;
switch_timer_t vid_read_timer;
switch_codec_t vid_read_codec;
switch_codec_t vid_write_codec;
switch_timer_t vid_read_timer;
switch_codec_t vid_read_codec;
switch_codec_t vid_write_codec;
switch_rtp_t *rtp_session;
switch_mutex_t *flag_mutex;
switch_mutex_t *h323_mutex;
FSH323Connection *me;
FSH323Connection *me;
} h323_private_t;
#define DECLARE_CALLBACK0(name) \
@ -101,161 +101,142 @@ switch_status_t name(type1 name1)
switch_status_t name(type1 name1, type2 name2, type3 name3)
class FSH323EndPoint;
class FSProcess : public PLibraryProcess {
PCLASSINFO(FSProcess, PLibraryProcess);
class FSProcess:public PLibraryProcess {
PCLASSINFO(FSProcess, PLibraryProcess);
public:
FSProcess();
~FSProcess();
public:
FSProcess();
~FSProcess();
bool Initialise(switch_loadable_module_interface_t *iface);
bool Initialise(switch_loadable_module_interface_t *iface);
FSH323EndPoint & GetH323EndPoint() const { return *m_h323endpoint; }
protected:
FSH323EndPoint * m_h323endpoint;
FSH323EndPoint & GetH323EndPoint() const {
return *m_h323endpoint;
} protected:
FSH323EndPoint * m_h323endpoint;
};
struct FSListener {
FSListener() {
}
PString name;
H323ListenerTCP *listenAddress;
PString localUserName;
PString gatekeeper;
FSListener() {
} PString name;
H323ListenerTCP *listenAddress;
PString localUserName;
PString gatekeeper;
};
class FSGkRegThread;
class FSH323EndPoint:public H323EndPoint {
PCLASSINFO(FSH323EndPoint, H323EndPoint);
public:
FSH323EndPoint();
~FSH323EndPoint();
PCLASSINFO(FSH323EndPoint, H323EndPoint);
public:
FSH323EndPoint();
~FSH323EndPoint();
/**Create a connection that uses the specified call.
*/
virtual H323Connection* CreateConnection(
unsigned callReference,
void* userData,
H323Transport* transport,
H323SignalPDU* setupPDU
);
virtual H323Connection *CreateConnection(unsigned callReference, void *userData, H323Transport * transport, H323SignalPDU * setupPDU);
virtual bool OnSetGatewayPrefixes(PStringList & prefixes) const;
bool Initialise(switch_loadable_module_interface_t *iface);
switch_status_t ReadConfig(int reload);
void StartGkClient(int retry, PString* gkAddress,PString* gkIdentifer,PString* gkInterface);
switch_status_t ReadConfig(int reload);
void StartGkClient(int retry, PString * gkAddress, PString * gkIdentifer, PString * gkInterface);
void StopGkClient();
switch_endpoint_interface_t *GetSwitchInterface() const {
return m_freeswitch;
}
FSH323Connection * FSMakeCall(const PString & dest,void *userData);
list <FSListener> m_listeners;
return m_freeswitch;
} FSH323Connection *FSMakeCall(const PString & dest, void *userData);
list < FSListener > m_listeners;
int m_ai;
int m_pi;
protected:
PStringList m_gkPrefixes;
switch_endpoint_interface_t *m_freeswitch;
PString m_gkAddress;
PString m_gkIdentifer;
PString m_gkInterface;
bool m_faststart;
bool m_h245tunneling;
bool m_h245insetup;
int m_gkretry;
FSGkRegThread* m_thread;
protected:
PStringList m_gkPrefixes;
switch_endpoint_interface_t *m_freeswitch;
PString m_gkAddress;
PString m_gkIdentifer;
PString m_gkInterface;
bool m_faststart;
bool m_h245tunneling;
bool m_h245insetup;
int m_gkretry;
FSGkRegThread *m_thread;
};
class FSGkRegThread : public PThread
{
PCLASSINFO(FSGkRegThread, PThread);
public:
FSGkRegThread(FSH323EndPoint* endpoint, PString* gkAddress, PString* gkIdentifer, PString* gkInterface, int retry = 0)
: PThread(10000), m_ep(endpoint), m_retry(retry), m_gkAddress(gkAddress),m_gkIdentifer(gkIdentifer),m_gkInterface(gkInterface)
{ }
void Main()
{ m_ep->StartGkClient(m_retry,m_gkAddress,m_gkIdentifer,m_gkInterface); }
protected:
FSH323EndPoint* m_ep;
int m_retry;
PString* m_gkAddress;
PString* m_gkIdentifer;
PString* m_gkInterface;
class FSGkRegThread:public PThread {
PCLASSINFO(FSGkRegThread, PThread);
public:
FSGkRegThread(FSH323EndPoint * endpoint, PString * gkAddress, PString * gkIdentifer, PString * gkInterface, int retry = 0)
: PThread(10000), m_ep(endpoint), m_retry(retry), m_gkAddress(gkAddress), m_gkIdentifer(gkIdentifer), m_gkInterface(gkInterface) {
} void Main() {
m_ep->StartGkClient(m_retry, m_gkAddress, m_gkIdentifer, m_gkInterface);
}
protected:
FSH323EndPoint * m_ep;
int m_retry;
PString *m_gkAddress;
PString *m_gkIdentifer;
PString *m_gkInterface;
};
class FSH323Connection:public H323Connection {
PCLASSINFO(FSH323Connection, H323Connection)
PCLASSINFO(FSH323Connection, H323Connection)
public:
FSH323Connection(FSH323EndPoint& endpoint,
H323Transport* transport,
unsigned callReference,
switch_caller_profile_t *outbound_profile,
switch_core_session_t *fsSession,
switch_channel_t *fsChannel);
FSH323Connection(FSH323EndPoint & endpoint,
H323Transport * transport,
unsigned callReference, switch_caller_profile_t *outbound_profile, switch_core_session_t *fsSession, switch_channel_t *fsChannel);
~FSH323Connection();
~FSH323Connection();
virtual H323Channel* CreateRealTimeLogicalChannel(
const H323Capability& capability,
H323Channel::Directions dir,
unsigned sessionID,
const H245_H2250LogicalChannelParameters* param,
RTP_QOS * rtpqos = NULL
);
virtual PBoolean OnStartLogicalChannel(H323Channel& channel);
virtual PBoolean OnCreateLogicalChannel(const H323Capability& capability, H323Channel::Directions dir, unsigned& errorCode);
virtual bool OnReceivedSignalSetup(const H323SignalPDU & setupPDU);
virtual bool OnReceivedCallProceeding(const H323SignalPDU & pdu);
virtual H323Channel *CreateRealTimeLogicalChannel(const H323Capability & capability,
H323Channel::Directions dir,
unsigned sessionID, const H245_H2250LogicalChannelParameters * param, RTP_QOS * rtpqos = NULL);
virtual PBoolean OnStartLogicalChannel(H323Channel & channel);
virtual PBoolean OnCreateLogicalChannel(const H323Capability & capability, H323Channel::Directions dir, unsigned &errorCode);
virtual bool OnReceivedSignalSetup(const H323SignalPDU & setupPDU);
virtual bool OnReceivedCallProceeding(const H323SignalPDU & pdu);
virtual void OnReceivedReleaseComplete(const H323SignalPDU & pdu);
virtual bool OnReceivedProgress(const H323SignalPDU &);
virtual bool OnReceivedProgress(const H323SignalPDU &);
virtual bool OnSendCallProceeding(H323SignalPDU & callProceedingPDU);
virtual bool OnSendReleaseComplete(H323SignalPDU & pdu);
virtual PBoolean OpenLogicalChannel(const H323Capability& capability, unsigned sessionID, H323Channel::Directions dir);
void setRemoteAddress(const char* remoteIP, WORD remotePort);
virtual PBoolean OpenLogicalChannel(const H323Capability & capability, unsigned sessionID, H323Channel::Directions dir);
void setRemoteAddress(const char *remoteIP, WORD remotePort);
virtual void OnSetLocalCapabilities();
virtual bool OnAlerting(const H323SignalPDU &alertingPDU, const PString &user);
virtual bool OnAlerting(const H323SignalPDU & alertingPDU, const PString & user);
virtual void AnsweringCall(AnswerCallResponse response);
virtual void OnEstablished();
bool SetLocalCapabilities();
static bool decodeCapability(const H323Capability& capability, const char** dataFormat, int* payload = 0, PString* capabName = 0);
virtual H323Connection::AnswerCallResponse OnAnswerCall(const PString& caller,
const H323SignalPDU& signalPDU, H323SignalPDU& connectPDU);
static bool decodeCapability(const H323Capability & capability, const char **dataFormat, int *payload = 0, PString * capabName = 0);
virtual H323Connection::AnswerCallResponse OnAnswerCall(const PString & caller, const H323SignalPDU & signalPDU, H323SignalPDU & connectPDU);
virtual bool OnReceivedCapabilitySet(const H323Capabilities & remoteCaps,
const H245_MultiplexCapability * muxCap,
H245_TerminalCapabilitySetReject & reject);
const H245_MultiplexCapability * muxCap, H245_TerminalCapabilitySetReject & reject);
switch_core_session_t *GetSession() const {
return m_fsSession;
}
virtual void SendUserInputTone(char tone, unsigned duration = 0, unsigned logicalChannel = 0, unsigned rtpTimestamp = 0);
return m_fsSession;
} virtual void SendUserInputTone(char tone, unsigned duration = 0, unsigned logicalChannel = 0, unsigned rtpTimestamp = 0);
virtual void OnUserInputTone(char, unsigned, unsigned, unsigned);
virtual void OnUserInputString(const PString &value);
DECLARE_CALLBACK0(on_init);
DECLARE_CALLBACK0(on_routing);
DECLARE_CALLBACK0(on_execute);
virtual void OnUserInputString(const PString & value);
DECLARE_CALLBACK0(on_init);
DECLARE_CALLBACK0(on_routing);
DECLARE_CALLBACK0(on_execute);
DECLARE_CALLBACK0(on_exchange_media);
DECLARE_CALLBACK0(on_soft_execute);
DECLARE_CALLBACK0(on_exchange_media);
DECLARE_CALLBACK0(on_soft_execute);
DECLARE_CALLBACK1(kill_channel, int, sig);
DECLARE_CALLBACK1(send_dtmf, const switch_dtmf_t *, dtmf);
DECLARE_CALLBACK1(receive_message, switch_core_session_message_t *, msg);
DECLARE_CALLBACK1(receive_event, switch_event_t *, event);
DECLARE_CALLBACK0(state_change);
DECLARE_CALLBACK1(kill_channel, int, sig);
DECLARE_CALLBACK1(send_dtmf, const switch_dtmf_t *, dtmf);
DECLARE_CALLBACK1(receive_message, switch_core_session_message_t *, msg);
DECLARE_CALLBACK1(receive_event, switch_event_t *, event);
DECLARE_CALLBACK0(state_change);
DECLARE_CALLBACK3(read_audio_frame, switch_frame_t **, frame, switch_io_flag_t, flags, int, stream_id);
DECLARE_CALLBACK3(write_audio_frame, switch_frame_t *, frame, switch_io_flag_t, flags, int, stream_id);
DECLARE_CALLBACK3(read_video_frame, switch_frame_t **, frame, switch_io_flag_t, flag, int, stream_id);
DECLARE_CALLBACK3(write_video_frame, switch_frame_t *, frame, switch_io_flag_t, flag, int, stream_id);
DECLARE_CALLBACK3(read_audio_frame, switch_frame_t **, frame, switch_io_flag_t, flags, int, stream_id);
DECLARE_CALLBACK3(write_audio_frame, switch_frame_t *, frame, switch_io_flag_t, flags, int, stream_id);
DECLARE_CALLBACK3(read_video_frame, switch_frame_t **, frame, switch_io_flag_t, flag, int, stream_id);
DECLARE_CALLBACK3(write_video_frame, switch_frame_t *, frame, switch_io_flag_t, flag, int, stream_id);
bool m_callOnPreAnswer;
bool m_startRTP;
bool m_rxChennel;
@ -263,44 +244,38 @@ class FSH323Connection:public H323Connection {
bool m_ChennelAnswer;
bool m_ChennelProgress;
PSyncPoint m_rxAudioOpened;
PSyncPoint m_txAudioOpened;
PSyncPoint m_txAudioOpened;
protected:
FSH323EndPoint * m_endpoint;
FSH323EndPoint * m_endpoint;
PString m_remoteAddr;
int m_remotePort;
int m_remotePort;
switch_core_session_t *m_fsSession;
switch_channel_t *m_fsChannel;
PIPSocket::Address m_RTPlocalIP;
switch_channel_t *m_fsChannel;
PIPSocket::Address m_RTPlocalIP;
WORD m_RTPlocalPort;
unsigned char m_buf[SWITCH_RECOMMENDED_BUFFER_SIZE];
};
class FSH323_ExternalRTPChannel : public H323_ExternalRTPChannel{
PCLASSINFO(FSH323_ExternalRTPChannel, H323_ExternalRTPChannel);
public:
/* Create a new channel. */
FSH323_ExternalRTPChannel(
FSH323Connection& connection,
const H323Capability& capability,
Directions direction,
unsigned sessionID,
const PIPSocket::Address& ip,
WORD dataPort
);
/* Destructor */
~FSH323_ExternalRTPChannel();
class FSH323_ExternalRTPChannel:public H323_ExternalRTPChannel {
PCLASSINFO(FSH323_ExternalRTPChannel, H323_ExternalRTPChannel);
public:
/* Create a new channel. */
FSH323_ExternalRTPChannel(FSH323Connection & connection,
const H323Capability & capability, Directions direction, unsigned sessionID, const PIPSocket::Address & ip, WORD dataPort);
/* Destructor */
~FSH323_ExternalRTPChannel();
virtual PBoolean Start();
virtual PBoolean OnReceivedAckPDU(const H245_H2250LogicalChannelAckParameters& param);
virtual PBoolean OnSendingPDU(H245_H2250LogicalChannelParameters& param);
virtual PBoolean OnReceivedPDU(const H245_H2250LogicalChannelParameters& param,unsigned& errorCode);
virtual void OnSendOpenAck(H245_H2250LogicalChannelAckParameters& param);
virtual PBoolean Start();
virtual PBoolean OnReceivedAckPDU(const H245_H2250LogicalChannelAckParameters & param);
virtual PBoolean OnSendingPDU(H245_H2250LogicalChannelParameters & param);
virtual PBoolean OnReceivedPDU(const H245_H2250LogicalChannelParameters & param, unsigned &errorCode);
virtual void OnSendOpenAck(H245_H2250LogicalChannelAckParameters & param);
private:
FSH323Connection* m_conn;
const H323Capability* m_capability;
private:
FSH323Connection * m_conn;
const H323Capability *m_capability;
switch_core_session_t *m_fsSession;
switch_channel_t *m_fsChannel;
switch_codec_t *m_switchCodec;
@ -312,124 +287,95 @@ private:
PString m_RTPlocalIP;
WORD m_RTPlocalPort;
BYTE payloadCode;
};
class BaseG7231Capab : public H323AudioCapability
{
PCLASSINFO(BaseG7231Capab, H323AudioCapability);
public:
BaseG7231Capab(const char* fname, bool annexA = true)
: H323AudioCapability(7,4), m_name(fname), m_aa(annexA)
{ }
virtual PObject* Clone() const{
return new BaseG7231Capab(*this);
}
virtual unsigned GetSubType() const{
return H245_AudioCapability::e_g7231;
}
virtual PString GetFormatName() const{
return m_name;
}
virtual H323Codec* CreateCodec(H323Codec::Direction direction) const{
return 0;
}
virtual Comparison Compare(const PObject& obj) const{
Comparison res = H323AudioCapability::Compare(obj);
if (res != EqualTo)
return res;
bool aa = static_cast<const BaseG7231Capab&>(obj).m_aa;
if (aa && !m_aa)
return LessThan;
if (m_aa && !aa)
return GreaterThan;
return EqualTo;
}
virtual bool OnSendingPDU(H245_AudioCapability& pdu, unsigned packetSize) const {
pdu.SetTag(GetSubType());
H245_AudioCapability_g7231& g7231 = pdu;
g7231.m_maxAl_sduAudioFrames = packetSize;
g7231.m_silenceSuppression = m_aa;
return true;
}
virtual bool OnReceivedPDU(const H245_AudioCapability& pdu, unsigned& packetSize){
if (pdu.GetTag() != H245_AudioCapability::e_g7231)
class BaseG7231Capab:public H323AudioCapability {
PCLASSINFO(BaseG7231Capab, H323AudioCapability);
public:
BaseG7231Capab(const char *fname, bool annexA = true)
: H323AudioCapability(7, 4), m_name(fname), m_aa(annexA) {
} virtual PObject *Clone() const {
return new BaseG7231Capab(*this);
} virtual unsigned GetSubType() const {
return H245_AudioCapability::e_g7231;
} virtual PString GetFormatName() const {
return m_name;
} virtual H323Codec *CreateCodec(H323Codec::Direction direction) const {
return 0;
} virtual Comparison Compare(const PObject & obj) const {
Comparison res = H323AudioCapability::Compare(obj);
if (res != EqualTo)
return res;
bool aa = static_cast < const BaseG7231Capab & >(obj).m_aa;
if (aa && !m_aa)
return LessThan;
if (m_aa && !aa)
return GreaterThan;
return EqualTo;
} virtual bool OnSendingPDU(H245_AudioCapability & pdu, unsigned packetSize) const {
pdu.SetTag(GetSubType());
H245_AudioCapability_g7231 & g7231 = pdu;
g7231.m_maxAl_sduAudioFrames = packetSize;
g7231.m_silenceSuppression = m_aa;
return true;
} virtual bool OnReceivedPDU(const H245_AudioCapability & pdu, unsigned &packetSize) {
if (pdu.GetTag() != H245_AudioCapability::e_g7231)
return false;
const H245_AudioCapability_g7231& g7231 = pdu;
packetSize = g7231.m_maxAl_sduAudioFrames;
m_aa = (g7231.m_silenceSuppression != 0);
return true;
const H245_AudioCapability_g7231 & g7231 = pdu;
packetSize = g7231.m_maxAl_sduAudioFrames;
m_aa = (g7231.m_silenceSuppression != 0);
return true;
}
protected:
const char* m_name;
bool m_aa;
protected:
const char *m_name;
bool m_aa;
};
class BaseG729Capab : public H323AudioCapability
{
PCLASSINFO(BaseG729Capab, H323AudioCapability);
public:
BaseG729Capab(const char* fname, unsigned type = H245_AudioCapability::e_g729)
: H323AudioCapability(24,6), m_name(fname), m_type(type)
{ }
virtual PObject* Clone() const
// default copy constructor - take care!
{ return new BaseG729Capab(*this); }
virtual unsigned GetSubType() const
{ return m_type; }
virtual PString GetFormatName() const
{ return m_name; }
virtual H323Codec* CreateCodec(H323Codec::Direction direction) const
{ return 0; }
protected:
const char* m_name;
unsigned m_type;
class BaseG729Capab:public H323AudioCapability {
PCLASSINFO(BaseG729Capab, H323AudioCapability);
public:
BaseG729Capab(const char *fname, unsigned type = H245_AudioCapability::e_g729)
: H323AudioCapability(24, 6), m_name(fname), m_type(type) {
} virtual PObject *Clone() const
// default copy constructor - take care!
{
return new BaseG729Capab(*this);
} virtual unsigned GetSubType() const {
return m_type;
} virtual PString GetFormatName() const {
return m_name;
} virtual H323Codec *CreateCodec(H323Codec::Direction direction) const {
return 0;
} protected:
const char *m_name;
unsigned m_type;
};
class BaseGSM0610Cap : public H323AudioCapability
{
class BaseGSM0610Cap:public H323AudioCapability {
PCLASSINFO(BaseGSM0610Cap, H323AudioCapability);
public:
BaseGSM0610Cap(const char* fname, unsigned type = H245_AudioCapability::e_gsmFullRate)
: H323AudioCapability(24,2), m_name(fname), m_type(type),m_comfortNoise(0),m_scrambled(0)
{ }
virtual PObject * Clone() const{
public:
BaseGSM0610Cap(const char *fname, unsigned type = H245_AudioCapability::e_gsmFullRate)
: H323AudioCapability(24, 2), m_name(fname), m_type(type), m_comfortNoise(0), m_scrambled(0) {
} virtual PObject *Clone() const {
return new BaseGSM0610Cap(*this);
}
virtual H323Codec* CreateCodec(H323Codec::Direction direction) const{
} virtual H323Codec *CreateCodec(H323Codec::Direction direction) const {
return 0;
}
virtual unsigned GetSubType() const{
} virtual unsigned GetSubType() const {
return H245_AudioCapability::e_gsmFullRate;
}
virtual PString GetFormatName() const{
} virtual PString GetFormatName() const {
return m_name;
}
virtual bool OnSendingPDU(H245_AudioCapability & pdu, unsigned packetSize) const{
} virtual bool OnSendingPDU(H245_AudioCapability & pdu, unsigned packetSize) const {
pdu.SetTag(H245_AudioCapability::e_gsmFullRate);
H245_GSMAudioCapability & gsm = pdu;
gsm.m_audioUnitSize = packetSize * 33;
gsm.m_comfortNoise = m_comfortNoise;
gsm.m_scrambled = m_scrambled;
return true;
}
virtual bool OnReceivedPDU(const H245_AudioCapability & pdu, unsigned & packetSize){
} virtual bool OnReceivedPDU(const H245_AudioCapability & pdu, unsigned &packetSize) {
PTRACE(2, "mod_h323\t==============>BaseGSM0610Cap::OnReceivedPDU");
if (pdu.GetTag() != H245_AudioCapability::e_gsmFullRate)
return false;
@ -440,8 +386,8 @@ public:
return true;
}
protected:
const char* m_name;
protected:
const char *m_name;
int m_comfortNoise;
int m_scrambled;
unsigned m_type;
@ -458,15 +404,15 @@ H323_REGISTER_CAPABILITY(cls,name) \
DEFINE_H323_CAPAB(FS_G7231_5,BaseG7231Capab,false,OPAL_G7231_5k3"{sw}")
DEFINE_H323_CAPAB(FS_G7231_6,BaseG7231Capab,false,OPAL_G7231_6k3"{sw}")
DEFINE_H323_CAPAB(FS_G7231A_5,BaseG7231Capab,true,OPAL_G7231A_5k3"{sw}")
DEFINE_H323_CAPAB(FS_G7231A_6,BaseG7231Capab,true,OPAL_G7231A_6k3"{sw}")
DEFINE_H323_CAPAB(FS_G729,BaseG729Capab,H245_AudioCapability::e_g729,OPAL_G729"{sw}")
DEFINE_H323_CAPAB(FS_G729A,BaseG729Capab,H245_AudioCapability::e_g729AnnexA,OPAL_G729A"{sw}")
DEFINE_H323_CAPAB(FS_G729B,BaseG729Capab,H245_AudioCapability::e_g729wAnnexB,OPAL_G729B"{sw}")
DEFINE_H323_CAPAB(FS_G729AB,BaseG729Capab,H245_AudioCapability::e_g729AnnexAwAnnexB,OPAL_G729AB"{sw}")
DEFINE_H323_CAPAB(FS_GSM,BaseGSM0610Cap,H245_AudioCapability::e_gsmFullRate,OPAL_GSM0610"{sw}")
DEFINE_H323_CAPAB(FS_G7231_5, BaseG7231Capab, false, OPAL_G7231_5k3 "{sw}")
DEFINE_H323_CAPAB(FS_G7231_6, BaseG7231Capab, false, OPAL_G7231_6k3 "{sw}")
DEFINE_H323_CAPAB(FS_G7231A_5, BaseG7231Capab, true, OPAL_G7231A_5k3 "{sw}")
DEFINE_H323_CAPAB(FS_G7231A_6, BaseG7231Capab, true, OPAL_G7231A_6k3 "{sw}")
DEFINE_H323_CAPAB(FS_G729, BaseG729Capab, H245_AudioCapability::e_g729, OPAL_G729 "{sw}")
DEFINE_H323_CAPAB(FS_G729A, BaseG729Capab, H245_AudioCapability::e_g729AnnexA, OPAL_G729A "{sw}")
DEFINE_H323_CAPAB(FS_G729B, BaseG729Capab, H245_AudioCapability::e_g729wAnnexB, OPAL_G729B "{sw}")
DEFINE_H323_CAPAB(FS_G729AB, BaseG729Capab, H245_AudioCapability::e_g729AnnexAwAnnexB, OPAL_G729AB "{sw}")
DEFINE_H323_CAPAB(FS_GSM, BaseGSM0610Cap, H245_AudioCapability::e_gsmFullRate, OPAL_GSM0610 "{sw}")
static FSProcess *h323_process = NULL;
static FSProcess *h323_process = NULL;

Some files were not shown because too many files have changed in this diff Show More