#include "asterisk.h"
#include <math.h>
#include "asterisk/channel.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/pbx.h"
#include "asterisk/acl.h"
#include "include/sip.h"
#include "include/globals.h"
#include "include/dialog.h"
#include "include/dialplan_functions.h"
#include "include/sip_utils.h"
Go to the source code of this file.
Functions | |
int | sip_acf_channel_read (struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen) |
void | sip_dialplan_function_register_tests (void) |
SIP test registration. | |
void | sip_dialplan_function_unregister_tests (void) |
SIP test registration. |
Definition in file dialplan_functions.c.
int sip_acf_channel_read | ( | struct ast_channel * | chan, | |
const char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) |
Definition at line 44 of file dialplan_functions.c.
References args, AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_MAX_USER_FIELD, ast_ouraddrfor(), ast_rtp_instance_get_local_address(), ast_rtp_instance_get_quality(), ast_rtp_instance_get_remote_address(), ast_rtp_instance_get_stats(), AST_RTP_INSTANCE_STAT_ALL, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_rtp_instance_stats::local_maxjitter, ast_rtp_instance_stats::local_maxrxploss, ast_rtp_instance_stats::local_minjitter, ast_rtp_instance_stats::local_minrxploss, ast_rtp_instance_stats::local_normdevjitter, ast_rtp_instance_stats::local_normdevrxploss, ast_rtp_instance_stats::local_ssrc, ast_rtp_instance_stats::local_stdevjitter, ast_rtp_instance_stats::local_stdevrxploss, LOG_ERROR, LOG_WARNING, ast_rtp_instance_stats::maxrtt, ast_rtp_instance_stats::minrtt, name, ast_rtp_instance_stats::normdevrtt, parse(), ast_rtp_instance_stats::remote_maxjitter, ast_rtp_instance_stats::remote_maxrxploss, ast_rtp_instance_stats::remote_minjitter, ast_rtp_instance_stats::remote_minrxploss, ast_rtp_instance_stats::remote_normdevjitter, ast_rtp_instance_stats::remote_normdevrxploss, ast_rtp_instance_stats::remote_ssrc, ast_rtp_instance_stats::remote_stdevjitter, ast_rtp_instance_stats::remote_stdevrxploss, ast_rtp_instance_stats::rtt, ast_rtp_instance_stats::rxcount, ast_rtp_instance_stats::rxjitter, ast_rtp_instance_stats::rxploss, ast_rtp_instance_stats::stdevrtt, ast_channel::tech, ast_channel::tech_pvt, ast_rtp_instance_stats::txcount, ast_rtp_instance_stats::txjitter, ast_rtp_instance_stats::txploss, and type.
00045 { 00046 struct sip_pvt *p = chan->tech_pvt; 00047 char *parse = ast_strdupa(preparse); 00048 int res = 0; 00049 AST_DECLARE_APP_ARGS(args, 00050 AST_APP_ARG(param); 00051 AST_APP_ARG(type); 00052 AST_APP_ARG(field); 00053 ); 00054 00055 /* Check for zero arguments */ 00056 if (ast_strlen_zero(parse)) { 00057 ast_log(LOG_ERROR, "Cannot call %s without arguments\n", funcname); 00058 return -1; 00059 } 00060 00061 AST_STANDARD_APP_ARGS(args, parse); 00062 00063 /* Sanity check */ 00064 if (!IS_SIP_TECH(chan->tech)) { 00065 ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname); 00066 return 0; 00067 } 00068 00069 memset(buf, 0, buflen); 00070 00071 if (p == NULL) { 00072 return -1; 00073 } 00074 00075 if (!strcasecmp(args.param, "peerip")) { 00076 ast_copy_string(buf, ast_sockaddr_isnull(&p->sa) ? "" : ast_sockaddr_stringify_addr(&p->sa), buflen); 00077 } else if (!strcasecmp(args.param, "recvip")) { 00078 ast_copy_string(buf, ast_sockaddr_isnull(&p->recv) ? "" : ast_sockaddr_stringify_addr(&p->recv), buflen); 00079 } else if (!strcasecmp(args.param, "from")) { 00080 ast_copy_string(buf, p->from, buflen); 00081 } else if (!strcasecmp(args.param, "uri")) { 00082 ast_copy_string(buf, p->uri, buflen); 00083 } else if (!strcasecmp(args.param, "useragent")) { 00084 ast_copy_string(buf, p->useragent, buflen); 00085 } else if (!strcasecmp(args.param, "peername")) { 00086 ast_copy_string(buf, p->peername, buflen); 00087 } else if (!strcasecmp(args.param, "t38passthrough")) { 00088 ast_copy_string(buf, (p->t38.state == T38_DISABLED) ? "0" : "1", buflen); 00089 } else if (!strcasecmp(args.param, "rtpdest")) { 00090 struct ast_sockaddr addr; 00091 struct ast_rtp_instance *stream; 00092 00093 if (ast_strlen_zero(args.type)) 00094 args.type = "audio"; 00095 00096 if (!strcasecmp(args.type, "audio")) 00097 stream = p->rtp; 00098 else if (!strcasecmp(args.type, "video")) 00099 stream = p->vrtp; 00100 else if (!strcasecmp(args.type, "text")) 00101 stream = p->trtp; 00102 else 00103 return -1; 00104 00105 /* Return 0 to suppress a console warning message */ 00106 if (!stream) { 00107 return 0; 00108 } 00109 00110 ast_rtp_instance_get_remote_address(stream, &addr); 00111 snprintf(buf, buflen, "%s", ast_sockaddr_stringify(&addr)); 00112 } else if (!strcasecmp(args.param, "rtpsource")) { 00113 struct ast_sockaddr sa; 00114 struct ast_rtp_instance *stream; 00115 00116 if (ast_strlen_zero(args.type)) 00117 args.type = "audio"; 00118 00119 if (!strcasecmp(args.type, "audio")) 00120 stream = p->rtp; 00121 else if (!strcasecmp(args.type, "video")) 00122 stream = p->vrtp; 00123 else if (!strcasecmp(args.type, "text")) 00124 stream = p->trtp; 00125 else 00126 return -1; 00127 00128 /* Return 0 to suppress a console warning message */ 00129 if (!stream) { 00130 return 0; 00131 } 00132 00133 ast_rtp_instance_get_local_address(stream, &sa); 00134 00135 if (ast_sockaddr_isnull(&sa)) { 00136 struct ast_sockaddr dest_sa; 00137 ast_rtp_instance_get_remote_address(stream, &dest_sa); 00138 ast_ouraddrfor(&dest_sa, &sa); 00139 } 00140 00141 snprintf(buf, buflen, "%s", ast_sockaddr_stringify(&sa)); 00142 } else if (!strcasecmp(args.param, "rtpqos")) { 00143 struct ast_rtp_instance *rtp = NULL; 00144 00145 if (ast_strlen_zero(args.type)) { 00146 args.type = "audio"; 00147 } 00148 00149 if (!strcasecmp(args.type, "audio")) { 00150 rtp = p->rtp; 00151 } else if (!strcasecmp(args.type, "video")) { 00152 rtp = p->vrtp; 00153 } else if (!strcasecmp(args.type, "text")) { 00154 rtp = p->trtp; 00155 } else { 00156 return -1; 00157 } 00158 00159 if (ast_strlen_zero(args.field) || !strcasecmp(args.field, "all")) { 00160 char quality_buf[AST_MAX_USER_FIELD]; 00161 00162 if (!ast_rtp_instance_get_quality(rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf))) { 00163 return -1; 00164 } 00165 00166 ast_copy_string(buf, quality_buf, buflen); 00167 return res; 00168 } else { 00169 struct ast_rtp_instance_stats stats; 00170 int i; 00171 struct { 00172 const char *name; 00173 enum { INT, DBL } type; 00174 union { 00175 unsigned int *i4; 00176 double *d8; 00177 }; 00178 } lookup[] = { 00179 { "txcount", INT, { .i4 = &stats.txcount, }, }, 00180 { "rxcount", INT, { .i4 = &stats.rxcount, }, }, 00181 { "txjitter", DBL, { .d8 = &stats.txjitter, }, }, 00182 { "rxjitter", DBL, { .d8 = &stats.rxjitter, }, }, 00183 { "remote_maxjitter", DBL, { .d8 = &stats.remote_maxjitter, }, }, 00184 { "remote_minjitter", DBL, { .d8 = &stats.remote_minjitter, }, }, 00185 { "remote_normdevjitter", DBL, { .d8 = &stats.remote_normdevjitter, }, }, 00186 { "remote_stdevjitter", DBL, { .d8 = &stats.remote_stdevjitter, }, }, 00187 { "local_maxjitter", DBL, { .d8 = &stats.local_maxjitter, }, }, 00188 { "local_minjitter", DBL, { .d8 = &stats.local_minjitter, }, }, 00189 { "local_normdevjitter", DBL, { .d8 = &stats.local_normdevjitter, }, }, 00190 { "local_stdevjitter", DBL, { .d8 = &stats.local_stdevjitter, }, }, 00191 { "txploss", INT, { .i4 = &stats.txploss, }, }, 00192 { "rxploss", INT, { .i4 = &stats.rxploss, }, }, 00193 { "remote_maxrxploss", DBL, { .d8 = &stats.remote_maxrxploss, }, }, 00194 { "remote_minrxploss", DBL, { .d8 = &stats.remote_minrxploss, }, }, 00195 { "remote_normdevrxploss", DBL, { .d8 = &stats.remote_normdevrxploss, }, }, 00196 { "remote_stdevrxploss", DBL, { .d8 = &stats.remote_stdevrxploss, }, }, 00197 { "local_maxrxploss", DBL, { .d8 = &stats.local_maxrxploss, }, }, 00198 { "local_minrxploss", DBL, { .d8 = &stats.local_minrxploss, }, }, 00199 { "local_normdevrxploss", DBL, { .d8 = &stats.local_normdevrxploss, }, }, 00200 { "local_stdevrxploss", DBL, { .d8 = &stats.local_stdevrxploss, }, }, 00201 { "rtt", DBL, { .d8 = &stats.rtt, }, }, 00202 { "maxrtt", DBL, { .d8 = &stats.maxrtt, }, }, 00203 { "minrtt", DBL, { .d8 = &stats.minrtt, }, }, 00204 { "normdevrtt", DBL, { .d8 = &stats.normdevrtt, }, }, 00205 { "stdevrtt", DBL, { .d8 = &stats.stdevrtt, }, }, 00206 { "local_ssrc", INT, { .i4 = &stats.local_ssrc, }, }, 00207 { "remote_ssrc", INT, { .i4 = &stats.remote_ssrc, }, }, 00208 { NULL, }, 00209 }; 00210 00211 if (ast_rtp_instance_get_stats(rtp, &stats, AST_RTP_INSTANCE_STAT_ALL)) { 00212 return -1; 00213 } 00214 00215 for (i = 0; !ast_strlen_zero(lookup[i].name); i++) { 00216 if (!strcasecmp(args.field, lookup[i].name)) { 00217 if (lookup[i].type == INT) { 00218 snprintf(buf, buflen, "%u", *lookup[i].i4); 00219 } else { 00220 snprintf(buf, buflen, "%f", *lookup[i].d8); 00221 } 00222 return 0; 00223 } 00224 } 00225 ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname); 00226 return -1; 00227 } 00228 } else if (!strcasecmp(args.param, "secure_signaling")) { 00229 snprintf(buf, buflen, "%s", p->socket.type == SIP_TRANSPORT_TLS ? "1" : ""); 00230 } else if (!strcasecmp(args.param, "secure_media")) { 00231 snprintf(buf, buflen, "%s", p->srtp ? "1" : ""); 00232 } else { 00233 res = -1; 00234 } 00235 return res; 00236 }
void sip_dialplan_function_register_tests | ( | void | ) |
SIP test registration.
Definition at line 410 of file dialplan_functions.c.
References AST_TEST_REGISTER.
Referenced by sip_register_tests().
00411 { 00412 AST_TEST_REGISTER(test_sip_rtpqos_1); 00413 }
void sip_dialplan_function_unregister_tests | ( | void | ) |
SIP test registration.
Definition at line 416 of file dialplan_functions.c.
References AST_TEST_UNREGISTER.
Referenced by sip_unregister_tests().
00417 { 00418 AST_TEST_UNREGISTER(test_sip_rtpqos_1); 00419 }