mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-17 01:02:12 +00:00
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:
parent
7b347417e5
commit
886e1ddb4d
@ -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
|
||||
|
76
src/g711.c
76
src/g711.c
@ -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 ------------------------------------------------------------*/
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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, ...);
|
||||
|
||||
|
||||
/*!
|
||||
|
@ -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);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
*/
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
///\}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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) {\
|
||||
|
@ -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__)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
249
src/inet_pton.c
249
src/inet_pton.c
@ -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 */
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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(¶ms);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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_ */
|
||||
|
@ -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
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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"))) {
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 ------------------------------------------------------------*/
|
||||
|
@ -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 ------------------------------------------------------------*/
|
||||
|
@ -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)) {
|
||||
|
@ -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
@ -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
|
||||
*
|
||||
|
@ -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);
|
||||
|
@ -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)) {
|
||||
|
@ -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
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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);
|
||||
|
@ -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") &&
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user